X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/91447636331957f3d9b5ca5b508f07c526b0074d..ff6e181ae92fc6f1e89841290f461d1f2f9badd9:/osfmk/ppc/lowmem_vectors.s diff --git a/osfmk/ppc/lowmem_vectors.s b/osfmk/ppc/lowmem_vectors.s index 9bdf98f95..658eda39b 100644 --- a/osfmk/ppc/lowmem_vectors.s +++ b/osfmk/ppc/lowmem_vectors.s @@ -3,19 +3,20 @@ * * @APPLE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * 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. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -354,10 +355,11 @@ notDCache: mtcrf 255,r13 ; Restore CRs ; System Calls (sc instruction) ; -; The syscall number is in r0. All we do here is munge the number into a -; 7-bit index into the "scTable", and dispatch on it to handle the Ultra +; The syscall number is in r0. All we do here is munge the number into an +; 8-bit index into the "scTable", and dispatch on it to handle the Ultra ; Fast Traps (UFTs.) The index is: ; +; 0x80 - set if syscall number is 0x80000000 (CutTrace) ; 0x40 - set if syscall number is 0x00006004 ; 0x20 - set if upper 29 bits of syscall number are 0xFFFFFFF8 ; 0x10 - set if upper 29 bits of syscall number are 0x00007FF0 @@ -373,7 +375,11 @@ notDCache: mtcrf 255,r13 ; Restore CRs addi r11,r11,8 ; make a 0 iff this is a 0xFFFFFFF8 trap cntlzw r13,r13 ; set bit 0x20 iff a 0x7FFx trap cntlzw r11,r11 ; set bit 0x20 iff a 0xFFFFFFF8 trap + xoris r0,r0,0x8000 ; Flip bit to make 0 iff 0x80000000 rlwimi r11,r13,31,0x10 ; move 0x7FFx bit into position + cntlzw r13,r0 ; Set bit 0x20 iff 0x80000000 + xoris r0,r0,0x8000 ; Flip bit to restore R0 + rlwimi r11,r13,2,0x80 ; Set bit 0x80 iff CutTrace xori r13,r0,0x6004 ; start to check for 0x6004 rlwimi r11,r0,1,0xE ; move in low 3 bits of syscall number cntlzw r13,r13 ; set bit 0x20 iff 0x6004 @@ -650,7 +656,8 @@ EXT(exception_entry): * 3. If (syscall & 0xFFFFFFF0) == 0xFFFFFFF0, then it is also a UFT and is dispatched here. * * 4. If (syscall & 0xFFFFF000) == 0x80000000, then it is a "firmware" call and is dispatched in - * Firmware.s, though the special "Cut Trace" trap (0x80000000) is handled here in xcpSyscall. + * Firmware.s, though the special "Cut Trace" trap (0x80000000) is handled here as an ultra + * fast trap. * * 5. If (syscall & 0xFFFFF000) == 0xFFFFF000, and it is not one of the above, then it is a Mach * syscall, which are dispatched in hw_exceptions.s via "mach_trap_table". @@ -672,62 +679,162 @@ EXT(exception_entry): * "scTable" is an array of 2-byte addresses, accessed using a 7-bit index derived from the syscall * number as follows: * - * 0x40 (A) - set if syscall number is 0x00006004 - * 0x20 (B) - set if upper 29 bits of syscall number are 0xFFFFFFF8 - * 0x10 (C) - set if upper 29 bits of syscall number are 0x00007FF0 - * 0x0E (D) - low three bits of syscall number + * 0x80 (A) - set if syscall number is 0x80000000 + * 0x40 (B) - set if syscall number is 0x00006004 + * 0x20 (C) - set if upper 29 bits of syscall number are 0xFFFFFFF8 + * 0x10 (D) - set if upper 29 bits of syscall number are 0x00007FF0 + * 0x0E (E) - low three bits of syscall number * * If you define another UFT, try to use a number in one of the currently decoded ranges, ie one marked * "unassigned" below. The dispatch table and the UFT handlers must reside in the first 32KB of * physical memory. */ - .align 7 ; start this table on a cache line -scTable: ; ABC D - .short uftNormalSyscall-baseR ; 000 0 these syscalls are not in a reserved range - .short uftNormalSyscall-baseR ; 000 1 these syscalls are not in a reserved range - .short uftNormalSyscall-baseR ; 000 2 these syscalls are not in a reserved range - .short uftNormalSyscall-baseR ; 000 3 these syscalls are not in a reserved range - .short uftNormalSyscall-baseR ; 000 4 these syscalls are not in a reserved range - .short uftNormalSyscall-baseR ; 000 5 these syscalls are not in a reserved range - .short uftNormalSyscall-baseR ; 000 6 these syscalls are not in a reserved range - .short uftNormalSyscall-baseR ; 000 7 these syscalls are not in a reserved range - - .short uftNormalSyscall-baseR ; 001 0 0x7FF0 is unassigned - .short uftNormalSyscall-baseR ; 001 1 0x7FF1 is Set Thread Info Fast Trap (pass up) - .short uftThreadInfo-baseR ; 001 2 0x7FF2 is Thread Info - .short uftFacilityStatus-baseR ; 001 3 0x7FF3 is Facility Status - .short uftLoadMSR-baseR ; 001 4 0x7FF4 is Load MSR - .short uftNormalSyscall-baseR ; 001 5 0x7FF5 is the Null FastPath Trap (pass up) - .short uftNormalSyscall-baseR ; 001 6 0x7FF6 is unassigned - .short uftNormalSyscall-baseR ; 001 7 0x7FF7 is unassigned - - .short uftNormalSyscall-baseR ; 010 0 0xFFFFFFF0 is unassigned - .short uftNormalSyscall-baseR ; 010 1 0xFFFFFFF1 is unassigned - .short uftNormalSyscall-baseR ; 010 2 0xFFFFFFF2 is unassigned - .short uftNormalSyscall-baseR ; 010 3 0xFFFFFFF3 is unassigned - .short uftNormalSyscall-baseR ; 010 4 0xFFFFFFF4 is unassigned - .short uftNormalSyscall-baseR ; 010 5 0xFFFFFFF5 is unassigned - .short uftIsPreemptiveTaskEnv-baseR ; 010 6 0xFFFFFFFE is Blue Box uftIsPreemptiveTaskEnv - .short uftIsPreemptiveTask-baseR ; 010 7 0xFFFFFFFF is Blue Box IsPreemptiveTask - - .short WhoaBaby-baseR ; 011 0 impossible combination - .short WhoaBaby-baseR ; 011 1 impossible combination - .short WhoaBaby-baseR ; 011 2 impossible combination - .short WhoaBaby-baseR ; 011 3 impossible combination - .short WhoaBaby-baseR ; 011 4 impossible combination - .short WhoaBaby-baseR ; 011 5 impossible combination - .short WhoaBaby-baseR ; 011 6 impossible combination - .short WhoaBaby-baseR ; 011 7 impossible combination - - .short WhoaBaby-baseR ; 100 0 0x6000 is an impossible index (diagCall) - .short WhoaBaby-baseR ; 100 1 0x6001 is an impossible index (vmm_get_version) - .short WhoaBaby-baseR ; 100 2 0x6002 is an impossible index (vmm_get_features) - .short WhoaBaby-baseR ; 100 3 0x6003 is an impossible index (vmm_init_context) - .short uftVMM-baseR ; 100 4 0x6004 is vmm_dispatch (only some of which are UFTs) - .short WhoaBaby-baseR ; 100 5 0x6005 is an impossible index (bb_enable_bluebox) - .short WhoaBaby-baseR ; 100 6 0x6006 is an impossible index (bb_disable_bluebox) - .short WhoaBaby-baseR ; 100 7 0x6007 is an impossible index (bb_settaskenv) + .align 8 ; start this table on a 256-byte boundry +scTable: ; ABCD E + .short uftNormalSyscall-baseR ; 0000 0 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0000 1 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0000 2 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0000 3 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0000 4 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0000 5 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0000 6 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0000 7 these syscalls are not in a reserved range + + .short uftNormalSyscall-baseR ; 0001 0 0x7FF0 is unassigned + .short uftNormalSyscall-baseR ; 0001 1 0x7FF1 is Set Thread Info Fast Trap (pass up) + .short uftThreadInfo-baseR ; 0001 2 0x7FF2 is Thread Info + .short uftFacilityStatus-baseR ; 0001 3 0x7FF3 is Facility Status + .short uftLoadMSR-baseR ; 0001 4 0x7FF4 is Load MSR + .short uftNormalSyscall-baseR ; 0001 5 0x7FF5 is the Null FastPath Trap (pass up) + .short uftNormalSyscall-baseR ; 0001 6 0x7FF6 is unassigned + .short uftNormalSyscall-baseR ; 0001 7 0x7FF7 is unassigned + + .short uftNormalSyscall-baseR ; 0010 0 0xFFFFFFF0 is unassigned + .short uftNormalSyscall-baseR ; 0010 1 0xFFFFFFF1 is unassigned + .short uftNormalSyscall-baseR ; 0010 2 0xFFFFFFF2 is unassigned + .short uftNormalSyscall-baseR ; 0010 3 0xFFFFFFF3 is unassigned + .short uftNormalSyscall-baseR ; 0010 4 0xFFFFFFF4 is unassigned + .short uftNormalSyscall-baseR ; 0010 5 0xFFFFFFF5 is unassigned + .short uftIsPreemptiveTaskEnv-baseR ; 0010 6 0xFFFFFFFE is Blue Box uftIsPreemptiveTaskEnv + .short uftIsPreemptiveTask-baseR ; 0010 7 0xFFFFFFFF is Blue Box IsPreemptiveTask + + .short WhoaBaby-baseR ; 0011 0 impossible combination + .short WhoaBaby-baseR ; 0011 1 impossible combination + .short WhoaBaby-baseR ; 0011 2 impossible combination + .short WhoaBaby-baseR ; 0011 3 impossible combination + .short WhoaBaby-baseR ; 0011 4 impossible combination + .short WhoaBaby-baseR ; 0011 5 impossible combination + .short WhoaBaby-baseR ; 0011 6 impossible combination + .short WhoaBaby-baseR ; 0011 7 impossible combination + + .short WhoaBaby-baseR ; 0100 0 0x6000 is an impossible index (diagCall) + .short WhoaBaby-baseR ; 0100 1 0x6001 is an impossible index (vmm_get_version) + .short WhoaBaby-baseR ; 0100 2 0x6002 is an impossible index (vmm_get_features) + .short WhoaBaby-baseR ; 0100 3 0x6003 is an impossible index (vmm_init_context) + .short uftVMM-baseR ; 0100 4 0x6004 is vmm_dispatch (only some of which are UFTs) + .short WhoaBaby-baseR ; 0100 5 0x6005 is an impossible index (bb_enable_bluebox) + .short WhoaBaby-baseR ; 0100 6 0x6006 is an impossible index (bb_disable_bluebox) + .short WhoaBaby-baseR ; 0100 7 0x6007 is an impossible index (bb_settaskenv) + + .short uftNormalSyscall-baseR ; 0101 0 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0101 1 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0101 2 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0101 3 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0101 4 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0101 5 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0101 6 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0101 7 these syscalls are not in a reserved range + + .short uftNormalSyscall-baseR ; 0110 0 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0110 1 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0110 2 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0110 3 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0110 4 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0110 5 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0110 6 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0110 7 these syscalls are not in a reserved range + + .short uftNormalSyscall-baseR ; 0111 0 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0111 1 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0111 2 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0111 3 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0111 4 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0111 5 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0111 6 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 0111 7 these syscalls are not in a reserved range + + .short uftCutTrace-baseR ; 1000 0 CutTrace + .short uftNormalSyscall-baseR ; 1000 1 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1000 2 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1000 3 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1000 4 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1000 5 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1000 6 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1000 7 these syscalls are not in a reserved range + + .short uftNormalSyscall-baseR ; 1001 0 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1001 1 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1001 2 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1001 3 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1001 4 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1001 5 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1001 6 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1001 7 these syscalls are not in a reserved range + + .short uftNormalSyscall-baseR ; 1010 0 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1010 1 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1010 2 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1010 3 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1010 4 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1010 5 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1010 6 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1010 7 these syscalls are not in a reserved range + + .short uftNormalSyscall-baseR ; 1011 0 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1011 1 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1011 2 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1011 3 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1011 4 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1011 5 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1011 6 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1011 7 these syscalls are not in a reserved range + + .short uftNormalSyscall-baseR ; 1100 0 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1100 1 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1100 2 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1100 3 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1100 4 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1100 5 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1100 6 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1100 7 these syscalls are not in a reserved range + + .short uftNormalSyscall-baseR ; 1101 0 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1101 1 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1101 2 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1101 3 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1101 4 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1101 5 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1101 6 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1101 7 these syscalls are not in a reserved range + + .short uftNormalSyscall-baseR ; 1110 0 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1110 1 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1110 2 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1110 3 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1110 4 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1110 5 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1110 6 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1110 7 these syscalls are not in a reserved range + + .short uftNormalSyscall-baseR ; 1111 0 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1111 1 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1111 2 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1111 3 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1111 4 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1111 5 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1111 6 these syscalls are not in a reserved range + .short uftNormalSyscall-baseR ; 1111 7 these syscalls are not in a reserved range .align 2 ; prepare for code @@ -823,7 +930,7 @@ uftRFI: LEXT(uft_nop_if_32bit) b uftX64 ; patched to NOP if 32-bit processor - lwz r11,pfAvailable(r11) ; Get the feature flags +uftX32: lwz r11,pfAvailable(r11) ; Get the feature flags mfsprg r13,2 ; Restore R13 mtsprg 2,r11 ; Set the feature flags mfsprg r11,3 ; Restore R11 @@ -839,6 +946,277 @@ uftX64: mtspr hsprg0,r14 ; Save a register in a Hypervisor SPRG mfspr r14,hsprg0 ; Restore R14 rfid ; Back to our guy... +; +; Quickly cut a trace table entry for the CutTrace firmware call. +; +; All registers except R11 and R13 are unchanged. +; +; Note that this code cuts a trace table entry for the CutTrace call only. +; An identical entry is made during normal interrupt processing. Any entry +; format entry changes made must be done in both places. +; + + .align 5 + + .globl EXT(uft_cuttrace) +LEXT(uft_cuttrace) +uftCutTrace: + b uftct64 ; patched to NOP if 32-bit processor + + stw r20,tempr0(r11) ; Save some work registers + lwz r20,dgFlags(0) ; Get the flags + stw r21,tempr1(r11) ; Save some work registers + mfsrr1 r21 ; Get the SRR1 + rlwinm r20,r20,MSR_PR_BIT-enaUsrFCallb,MASK(MSR_PR) ; Shift the validity bit over to pr bit spot + stw r25,tempr2(r11) ; Save some work registers + orc r20,r20,r21 ; Get ~PR | FC + mfcr r25 ; Save the CR + stw r22,tempr3(r11) ; Save some work registers + lhz r22,PP_CPU_NUMBER(r11) ; Get the logical processor number + andi. r20,r20,MASK(MSR_PR) ; Set cr0_eq is we are in problem state and the validity bit is not set + stw r23,tempr4(r11) ; Save some work registers + lwz r23,traceMask(0) ; Get the trace mask + stw r24,tempr5(r11) ; Save some work registers + beq- ctbail32 ; Can not issue from user... + + + addi r24,r22,16 ; Get shift to move cpu mask to syscall mask + rlwnm r24,r23,r24,12,12 ; Shift cpu mask bit to rupt type mask + and. r24,r24,r23 ; See if both are on + +; +; We select a trace entry using a compare and swap on the next entry field. +; Since we do not lock the actual trace buffer, there is a potential that +; another processor could wrap an trash our entry. Who cares? +; + + li r23,trcWork ; Get the trace work area address + lwz r21,traceStart(0) ; Get the start of trace table + lwz r22,traceEnd(0) ; Get end of trace table + + beq-- ctdisa32 ; Leave because tracing is disabled... + +ctgte32: lwarx r20,0,r23 ; Get and reserve the next slot to allocate + addi r24,r20,LTR_size ; Point to the next trace entry + cmplw r24,r22 ; Do we need to wrap the trace table? + bne+ ctgte32s ; No wrap, we got us a trace entry... + + mr r24,r21 ; Wrap back to start + +ctgte32s: stwcx. r24,0,r23 ; Try to update the current pointer + bne- ctgte32 ; Collision, try again... + +#if ESPDEBUG + dcbf 0,r23 ; Force to memory + sync +#endif + + dcbz 0,r20 ; Clear and allocate first trace line + li r24,32 ; Offset to next line + +ctgte32tb: mftbu r21 ; Get the upper time now + mftb r22 ; Get the lower time now + mftbu r23 ; Get upper again + cmplw r21,r23 ; Has it ticked? + bne- ctgte32tb ; Yes, start again... + + dcbz r24,r20 ; Clean second line + +; +; Let us cut that trace entry now. +; +; Note that this code cuts a trace table entry for the CutTrace call only. +; An identical entry is made during normal interrupt processing. Any entry +; format entry changes made must be done in both places. +; + + lhz r24,PP_CPU_NUMBER(r11) ; Get the logical processor number + li r23,T_SYSTEM_CALL ; Get the system call id + mtctr r13 ; Restore the caller's CTR + sth r24,LTR_cpu(r20) ; Save processor number + li r24,64 ; Offset to third line + sth r23,LTR_excpt(r20) ; Set the exception code + dcbz r24,r20 ; Clean 3rd line + mfspr r23,dsisr ; Get the DSISR + stw r21,LTR_timeHi(r20) ; Save top of time stamp + li r24,96 ; Offset to fourth line + mflr r21 ; Get the LR + dcbz r24,r20 ; Clean 4th line + stw r22,LTR_timeLo(r20) ; Save bottom of time stamp + mfsrr0 r22 ; Get SRR0 + stw r25,LTR_cr(r20) ; Save CR + mfsrr1 r24 ; Get the SRR1 + stw r23,LTR_dsisr(r20) ; Save DSISR + stw r22,LTR_srr0+4(r20) ; Save SRR0 + mfdar r23 ; Get DAR + stw r24,LTR_srr1+4(r20) ; Save SRR1 + stw r23,LTR_dar+4(r20) ; Save DAR + stw r21,LTR_lr+4(r20) ; Save LR + + stw r13,LTR_ctr+4(r20) ; Save CTR + stw r0,LTR_r0+4(r20) ; Save register + stw r1,LTR_r1+4(r20) ; Save register + stw r2,LTR_r2+4(r20) ; Save register + stw r3,LTR_r3+4(r20) ; Save register + stw r4,LTR_r4+4(r20) ; Save register + stw r5,LTR_r5+4(r20) ; Save register + stw r6,LTR_r6+4(r20) ; Save register + +#if 0 + lwz r21,FPUowner(r11) ; (TEST/DEBUG) Get the current floating point owner + stw r21,LTR_rsvd0(r20) ; (TEST/DEBUG) Record the owner +#endif + +#if ESPDEBUG + addi r21,r20,32 ; Second line + addi r22,r20,64 ; Third line + dcbst 0,r20 ; Force to memory + dcbst 0,r21 ; Force to memory + addi r21,r22,32 ; Fourth line + dcbst 0,r22 ; Force to memory + dcbst 0,r21 ; Force to memory + sync ; Make sure it all goes +#endif + +ctdisa32: mtcrf 0x80,r25 ; Restore the used condition register field + lwz r20,tempr0(r11) ; Restore work register + lwz r21,tempr1(r11) ; Restore work register + lwz r25,tempr2(r11) ; Restore work register + mtctr r13 ; Restore the caller's CTR + lwz r22,tempr3(r11) ; Restore work register + lwz r23,tempr4(r11) ; Restore work register + lwz r24,tempr5(r11) ; Restore work register + b uftX32 ; Go restore the rest and go... + +ctbail32: mtcrf 0x80,r25 ; Restore the used condition register field + lwz r20,tempr0(r11) ; Restore work register + lwz r21,tempr1(r11) ; Restore work register + lwz r25,tempr2(r11) ; Restore work register + mtctr r13 ; Restore the caller's CTR + lwz r22,tempr3(r11) ; Restore work register + lwz r23,tempr4(r11) ; Restore work register + b uftNormalSyscall ; Go pass it on along... + +; +; This is the 64-bit version. +; + +uftct64: std r20,tempr0(r11) ; Save some work registers + lwz r20,dgFlags(0) ; Get the flags + std r21,tempr1(r11) ; Save some work registers + mfsrr1 r21 ; Get the SRR1 + rlwinm r20,r20,MSR_PR_BIT-enaUsrFCallb,MASK(MSR_PR) ; Shift the validity bit over to pr bit spot + std r25,tempr2(r11) ; Save some work registers + orc r20,r20,r21 ; Get ~PR | FC + mfcr r25 ; Save the CR + std r22,tempr3(r11) ; Save some work registers + lhz r22,PP_CPU_NUMBER(r11) ; Get the logical processor number + andi. r20,r20,MASK(MSR_PR) ; Set cr0_eq when we are in problem state and the validity bit is not set + std r23,tempr4(r11) ; Save some work registers + lwz r23,traceMask(0) ; Get the trace mask + std r24,tempr5(r11) ; Save some work registers + beq-- ctbail64 ; Can not issue from user... + + addi r24,r22,16 ; Get shift to move cpu mask to syscall mask + rlwnm r24,r23,r24,12,12 ; Shift cpu mask bit to rupt type mask + and. r24,r24,r23 ; See if both are on + +; +; We select a trace entry using a compare and swap on the next entry field. +; Since we do not lock the actual trace buffer, there is a potential that +; another processor could wrap an trash our entry. Who cares? +; + + li r23,trcWork ; Get the trace work area address + lwz r21,traceStart(0) ; Get the start of trace table + lwz r22,traceEnd(0) ; Get end of trace table + + beq-- ctdisa64 ; Leave because tracing is disabled... + +ctgte64: lwarx r20,0,r23 ; Get and reserve the next slot to allocate + addi r24,r20,LTR_size ; Point to the next trace entry + cmplw r24,r22 ; Do we need to wrap the trace table? + bne++ ctgte64s ; No wrap, we got us a trace entry... + + mr r24,r21 ; Wrap back to start + +ctgte64s: stwcx. r24,0,r23 ; Try to update the current pointer + bne-- ctgte64 ; Collision, try again... + +#if ESPDEBUG + dcbf 0,r23 ; Force to memory + sync +#endif + + dcbz128 0,r20 ; Zap the trace entry + + mftb r21 ; Get the time + +; +; Let us cut that trace entry now. +; +; Note that this code cuts a trace table entry for the CutTrace call only. +; An identical entry is made during normal interrupt processing. Any entry +; format entry changes made must be done in both places. +; + + lhz r24,PP_CPU_NUMBER(r11) ; Get the logical processor number + li r23,T_SYSTEM_CALL ; Get the system call id + sth r24,LTR_cpu(r20) ; Save processor number + sth r23,LTR_excpt(r20) ; Set the exception code + mfspr r23,dsisr ; Get the DSISR + std r21,LTR_timeHi(r20) ; Save top of time stamp + mflr r21 ; Get the LR + mfsrr0 r22 ; Get SRR0 + stw r25,LTR_cr(r20) ; Save CR + mfsrr1 r24 ; Get the SRR1 + stw r23,LTR_dsisr(r20) ; Save DSISR + std r22,LTR_srr0(r20) ; Save SRR0 + mfdar r23 ; Get DAR + std r24,LTR_srr1(r20) ; Save SRR1 + std r23,LTR_dar(r20) ; Save DAR + std r21,LTR_lr(r20) ; Save LR + + std r13,LTR_ctr(r20) ; Save CTR + std r0,LTR_r0(r20) ; Save register + std r1,LTR_r1(r20) ; Save register + std r2,LTR_r2(r20) ; Save register + std r3,LTR_r3(r20) ; Save register + std r4,LTR_r4(r20) ; Save register + std r5,LTR_r5(r20) ; Save register + std r6,LTR_r6(r20) ; Save register + +#if 0 + lwz r21,FPUowner(r11) ; (TEST/DEBUG) Get the current floating point owner + stw r21,LTR_rsvd0(r20) ; (TEST/DEBUG) Record the owner +#endif + +#if ESPDEBUG + dcbf 0,r20 ; Force to memory + sync ; Make sure it all goes +#endif + +ctdisa64: mtcrf 0x80,r25 ; Restore the used condition register field + ld r20,tempr0(r11) ; Restore work register + ld r21,tempr1(r11) ; Restore work register + ld r25,tempr2(r11) ; Restore work register + mtctr r13 ; Restore the caller's CTR + ld r22,tempr3(r11) ; Restore work register + ld r23,tempr4(r11) ; Restore work register + ld r24,tempr5(r11) ; Restore work register + b uftX64 ; Go restore the rest and go... + +ctbail64: mtcrf 0x80,r25 ; Restore the used condition register field + ld r20,tempr0(r11) ; Restore work register + ld r21,tempr1(r11) ; Restore work register + ld r25,tempr2(r11) ; Restore work register + mtctr r13 ; Restore the caller's CTR + ld r22,tempr3(r11) ; Restore work register + ld r23,tempr4(r11) ; Restore work register + li r11,T_SYSTEM_CALL|T_FAM ; Set system code call + b extEntry64 ; Go straight to the 64-bit code... + + ; Handle a system call that is not a UFT and which thus goes upstairs. @@ -1227,6 +1605,10 @@ gotTrcEnt: stwcx. r22,0,r23 ; Try to update the current pointer ; ; Let us cut that trace entry now. +; +; Note that this code cuts a trace table entry for everything but the CutTrace call. +; An identical entry is made during normal CutTrace processing. Any entry +; format changes made must be done in both places. ; lwz r16,ruptStamp(r2) ; Get top of time base @@ -1551,7 +1933,7 @@ trcselSF: lwarx r20,0,r23 ; Get and reserve the next slot to allocate addi r22,r20,LTR_size ; Point to the next trace entry cmplw r22,r26 ; Do we need to wrap the trace table? - bne+ gotTrcEntSF ; No wrap, we got us a trace entry... + bne++ gotTrcEntSF ; No wrap, we got us a trace entry... mr r22,r25 ; Wrap back to start @@ -1566,6 +1948,10 @@ gotTrcEntSF: ; ; Let us cut that trace entry now. +; +; Note that this code cuts a trace table entry for everything but the CutTrace call. +; An identical entry is made during normal CutTrace processing. Any entry +; format changes made must be done in both places. ; dcbz128 0,r20 ; Zap the trace entry @@ -1608,6 +1994,10 @@ gotTrcEntSF: std r13,LTR_save(r20) ; Save the savearea stw r17,LTR_dsisr(r20) ; Save the DSISR sth r11,LTR_excpt(r20) ; Save the exception type +#if 0 + lwz r17,FPUowner(r2) ; (TEST/DEBUG) Get the current floating point owner + stw r17,LTR_rsvd0(r20) ; (TEST/DEBUG) Record the owner +#endif #if ESPDEBUG dcbf 0,r20 ; Force to memory @@ -3272,8 +3662,16 @@ EXT(mckFlags): .long 0 ; 5028 user memory window virtual address .long 0 ; 502C user memory window virtual address .long 0 ; 5030 VMM boot-args forced feature flags - .long 0 ; 5034 reserved - .long 0 ; 5038 reserved + + .globl EXT(maxDec) +EXT(maxDec): + .long 0x7FFFFFFF ; 5034 maximum decrementer value + + + .globl EXT(pmsCtlp) +EXT(pmsCtlp): + .long 0 ; 5038 Pointer to power management stepper control + .long 0 ; 503C reserved .long 0 ; 5040 reserved .long 0 ; 5044 reserved