X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/55e303ae13a4cf49d70f2294092726f2fffb9ef2..4a3eedf9ecc9bbe3f3a5c6ce5e53ad199d639d32:/osfmk/ppc/commpage/commpage_asm.s diff --git a/osfmk/ppc/commpage/commpage_asm.s b/osfmk/ppc/commpage/commpage_asm.s index 3c30b32a5..d3ea83c24 100644 --- a/osfmk/ppc/commpage/commpage_asm.s +++ b/osfmk/ppc/commpage/commpage_asm.s @@ -1,16 +1,19 @@ /* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003-2005 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER @@ -20,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ #include @@ -76,8 +79,8 @@ Ldata: * * C O M M P A G E _ S E T _ T I M E S T A M P * * *********************************************** * - * Update the gettimeofday() shared data on the commpage, as follows: - * _COMM_PAGE_TIMESTAMP = a BSD-style pair of uint_32's for secs and usecs + * Update the gettimeofday() shared data on the commpages, as follows: + * _COMM_PAGE_TIMESTAMP = the clock offset at timebase (seconds) * _COMM_PAGE_TIMEBASE = the timebase at which the timestamp was valid * _COMM_PAGE_SEC_PER_TICK = multiply timebase ticks by this to get seconds (double) * The convention is that if the timebase is 0, the data is invalid. Because other @@ -97,18 +100,19 @@ Ldata: * When called: * r3 = upper half of timebase (timebase is disabled if 0) * r4 = lower half of timebase - * r5 = seconds part of timestamp - * r6 = useconds part of timestamp + * r5 = upper half of timestamp + * r6 = lower half of timestamp * r7 = divisor (ie, timebase ticks per sec) * We set up: * r8 = ptr to our static data (kkBinary0, kkDouble1, kkTicksPerSec) - * r9 = ptr to comm page in kernel map + * r9 = ptr to 32-bit commpage in kernel map + * r10 = ptr to 64-bit commpage in kernel map * * --> Interrupts must be disabled and rtclock locked when called. <-- */ .align 5 -LEXT(commpage_set_timestamp) // void commpage_set_timestamp(tbr,secs,usecs,divisor) +LEXT(commpage_set_timestamp) // void commpage_set_timestamp(tbr,secs,divisor) mfmsr r11 // get MSR ori r2,r11,MASK(MSR_FP) // turn FP on mtmsr r2 @@ -116,16 +120,24 @@ LEXT(commpage_set_timestamp) // void commpage_set_timestamp(tbr,secs,usecs,di or. r0,r3,r4 // is timebase 0? (thus disabled) lis r8,hi16(Ldata) // point to our data - lis r9,ha16(EXT(commPagePtr)) // get ptr to address of commpage in kernel map + lis r9,ha16(EXT(commPagePtr32)) // get ptrs to address of commpages in kernel map + lis r10,ha16(EXT(commPagePtr64)) stfd f1,rzSaveF1(r1) // save a FPR in the red zone ori r8,r8,lo16(Ldata) - lwz r9,lo16(EXT(commPagePtr))(r9) // r9 <- commPagePtr + lwz r9,lo16(EXT(commPagePtr32))(r9) // r9 <- 32-bit commpage ptr + lwz r10,lo16(EXT(commPagePtr64))(r10) // r10 <- 64-bit commpage ptr lfd f1,kkBinary0(r8) // get fixed 0s li r0,_COMM_PAGE_BASE_ADDRESS // get va in user space of commpage - cmpwi cr1,r9,0 // is commpage allocated yet? - sub r9,r9,r0 // r9 <- commpage address, biased by user va - beq-- cr1,3f // skip if not allocated - stfd f1,_COMM_PAGE_TIMEBASE(r9) // turn off the timestamp (atomically) + cmpwi cr1,r9,0 // is 32-bit commpage allocated yet? + cmpwi cr6,r10,0 // is 64-bit commpage allocated yet? + sub r9,r9,r0 // r9 <- 32-bit commpage address, biased by user va + sub r10,r10,r0 // r10<- 64-bit commpage address + beq-- cr1,3f // skip if 32-bit commpage not allocated (64-bit won't be either) + bne++ cr6,1f // skip if 64-bit commpage is allocated + mr r10,r9 // if no 64-bit commpage, point to 32-bit version with r10 too +1: + stfd f1,_COMM_PAGE_TIMEBASE(r9) // turn off the 32-bit-commpage timestamp (atomically) + stfd f1,_COMM_PAGE_TIMEBASE(r10) // and the 64-bit one too eieio // make sure all CPUs see it is off beq 3f // all we had to do is turn off timestamp @@ -133,8 +145,10 @@ LEXT(commpage_set_timestamp) // void commpage_set_timestamp(tbr,secs,usecs,di stw r3,rzNewTimeBase(r1) // store new timebase so we can lfd stw r4,rzNewTimeBase+4(r1) cmpw r0,r7 // do we need to recompute _COMM_PAGE_SEC_PER_TICK? - stw r5,_COMM_PAGE_TIMESTAMP(r9) // store the new timestamp + stw r5,_COMM_PAGE_TIMESTAMP(r9) // store the new timestamp in the 32-bit page stw r6,_COMM_PAGE_TIMESTAMP+4(r9) + stw r5,_COMM_PAGE_TIMESTAMP(r10)// and the 64-bit commpage + stw r6,_COMM_PAGE_TIMESTAMP+4(r10) lfd f1,rzNewTimeBase(r1) // get timebase in a FPR so we can store atomically beq++ 2f // same ticks_per_sec, no need to recompute @@ -147,10 +161,11 @@ LEXT(commpage_set_timestamp) // void commpage_set_timestamp(tbr,secs,usecs,di lfd f3,kkTicksPerSec(r8) // float new ticks_per_sec + 2**52 lfd f4,kkDouble1(r8) // f4 <- double(1.0) mffs f5 // save caller's FPSCR - mtfsfi 7,0 // clear Inexeact Exception bit, set round-to-nearest + mtfsfi 7,1 // clear Inexeact Exception bit, set round-to-zero fsub f3,f3,f2 // get ticks_per_sec fdiv f3,f4,f3 // divide 1 by ticks_per_sec to get SEC_PER_TICK stfd f3,_COMM_PAGE_SEC_PER_TICK(r9) + stfd f3,_COMM_PAGE_SEC_PER_TICK(r10) mtfsf 0xFF,f5 // restore FPSCR lfd f2,rzSaveF2(r1) // restore FPRs lfd f3,rzSaveF3(r1) @@ -159,6 +174,7 @@ LEXT(commpage_set_timestamp) // void commpage_set_timestamp(tbr,secs,usecs,di 2: // f1 == new timestamp eieio // wait until the stores take stfd f1,_COMM_PAGE_TIMEBASE(r9) // then turn the timestamp back on (atomically) + stfd f1,_COMM_PAGE_TIMEBASE(r10) // both 3: // here once all fields updated lfd f1,rzSaveF1(r1) // restore last FPR mtmsr r11 // turn FP back off