X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/91447636331957f3d9b5ca5b508f07c526b0074d..4a3eedf9ecc9bbe3f3a5c6ce5e53ad199d639d32:/osfmk/ppc/hw_exception.s?ds=inline diff --git a/osfmk/ppc/hw_exception.s b/osfmk/ppc/hw_exception.s index 51b344457..ab77e1774 100644 --- a/osfmk/ppc/hw_exception.s +++ b/osfmk/ppc/hw_exception.s @@ -1,23 +1,29 @@ /* - * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_OSREFERENCE_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. 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. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * 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 * 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@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * @OSF_COPYRIGHT@ @@ -50,6 +56,7 @@ #define VERIFYSAVE 0 #define FPVECDBG 0 +#define FPFLOOD 0 #define INSTRUMENT 0 /* @@ -154,9 +161,26 @@ tvecoff: stw r26,FM_BACKPTR(r1) ; Link back to the previous frame #endif /* DEBUG */ mr r30,r4 - lwz r3,SAVtime+4(r4) - addi r4,r13,SYSTEM_TIMER - bl EXT(timer_event) + lwz r3,SAVtime(r4) + lwz r4,SAVtime+4(r4) + addi r5,r13,SYSTEM_TIMER + bl EXT(thread_timer_event) + addi r5,r25,SYSTEM_STATE + bl EXT(state_event) + + lwz r7,ACT_TASK(r13) + lwz r8,TASK_VTIMERS(r7) + cmpwi r8,0 + beq++ 0f + + lwz r7,ACT_PER_PROC(r13) + li r4,AST_BSD + lwz r8,PP_PENDING_AST(r7) + or r8,r8,r4 + stw r8,PP_PENDING_AST(r7) + addi r3,r13,ACT_AST + bl EXT(hw_atomic_or) +0: /* call trap handler proper, with * ARG0 = type @@ -198,6 +222,10 @@ tvecoff: stw r26,FM_BACKPTR(r1) ; Link back to the previous frame .L_call_trap: +#if FPFLOOD + stfd f31,emfp31(r25) ; (TEST/DEBUG) +#endif + bl EXT(trap) lis r10,hi16(MASK(MSR_VEC)) ; Get the vector enable @@ -353,9 +381,26 @@ noassist: cmplwi r15,0x7000 ; Do we have a fast path trap? stw r0,ACT_MACT_KSP(r13) ; Mark stack as busy with 0 val stw r15,FM_BACKPTR(r1) ; Link stack frame backwards - lwz r3,SAVtime+4(r30) - addi r4,r13,SYSTEM_TIMER - bl EXT(timer_event) + lwz r3,SAVtime(r30) + lwz r4,SAVtime+4(r30) + addi r5,r13,SYSTEM_TIMER + bl EXT(thread_timer_event) + addi r5,r25,SYSTEM_STATE + bl EXT(state_event) + + lwz r7,ACT_TASK(r13) + lwz r8,TASK_VTIMERS(r7) + cmpwi r8,0 + beq++ 0f + + lwz r7,ACT_PER_PROC(r13) + li r4,AST_BSD + lwz r8,PP_PENDING_AST(r7) + or r8,r8,r4 + stw r8,PP_PENDING_AST(r7) + addi r3,r13,ACT_AST + bl EXT(hw_atomic_or) +0: #if DEBUG /* If debugging, we need two frames, the first being a dummy @@ -396,6 +441,11 @@ noassist: cmplwi r15,0x7000 ; Do we have a fast path trap? mr r4,r13 ; current activation addi r7,r7,1 ; Bump it stw r7,TASK_SYSCALLS_UNIX(r8) ; Save it + +#if FPFLOOD + stfd f31,emfp31(r25) ; (TEST/DEBUG) +#endif + bl EXT(unix_syscall) ; Check out unix... .L_call_server_syscall_exception: @@ -424,7 +474,7 @@ noassist: cmplwi r15,0x7000 ; Do we have a fast path trap? ; and the savearea/pcb as the first parameter. ; It is up to the callee to enable interruptions if ; they should be. We are in a state here where -; both interrupts and preemption is ok, but because we could +; both interrupts and preemption are ok, but because we could ; be calling diagnostic code we will not enable. ; ; Also, the callee is responsible for finding any parameters @@ -494,11 +544,11 @@ LEXT(ppcscret) */ ksystrace: - mr r4,r30 ; Pass in saved state + mr r4,r30 ; Pass in saved state bl EXT(syscall_trace) - cmplw r31,r29 ; Is this syscall in the table? - add r31,r27,r28 ; Point right to the syscall table entry + cmplw r31,r29 ; Is this syscall in the table? + add r31,r27,r28 ; Point right to the syscall table entry bge- .L_call_server_syscall_exception ; The syscall number is invalid @@ -510,20 +560,20 @@ ksystrace: .L_ksystrace_munge: cmplwi r0,0 ; do we have a munger to call? - mtctr r0 ; Set the function call address - addi r3,r30,saver3 ; Pointer to args from save area - addi r4,r1,FM_ARG0+ARG_SIZE ; Pointer for munged args + mtctr r0 ; Set the function call address + addi r3,r30,saver3 ; Pointer to args from save area + addi r4,r1,FM_ARG0+ARG_SIZE ; Pointer for munged args beq-- .L_ksystrace_trapcall ; just make the trap call - bctrl ; Call the munge function + bctrl ; Call the munge function .L_ksystrace_trapcall: - lwz r0,MACH_TRAP_FUNCTION(r31) ; Pick up the function address - mtctr r0 ; Set the function call address - addi r3,r1,FM_ARG0+ARG_SIZE ; Pointer to munged args + lwz r0,MACH_TRAP_FUNCTION(r31) ; Pick up the function address + mtctr r0 ; Set the function call address + addi r3,r1,FM_ARG0+ARG_SIZE ; Pointer to munged args bctrl - mr r4,r30 ; Pass in the savearea - bl EXT(syscall_trace_end) ; Trace the exit of the system call + mr r4,r30 ; Pass in the savearea + bl EXT(syscall_trace_end) ; Trace the exit of the system call b .L_mach_return @@ -543,27 +593,27 @@ ksystrace: ; Call a function that can print out our syscall info ; Note that we don t care about any volatiles yet ; - lwz r10,ACT_TASK(r13) ; Get our task + lwz r10,ACT_TASK(r13) ; Get our task lwz r0,saver0+4(r30) - lis r8,hi16(EXT(kdebug_enable)) ; Get top of kdebug_enable + lis r8,hi16(EXT(kdebug_enable)) ; Get top of kdebug_enable lis r28,hi16(EXT(mach_trap_table)) ; Get address of table ori r8,r8,lo16(EXT(kdebug_enable)) ; Get bottom of kdebug_enable - lwz r8,0(r8) ; Get kdebug_enable + lwz r8,0(r8) ; Get kdebug_enable lwz r7,TASK_SYSCALLS_MACH(r10) ; Get the current count neg r31,r0 ; Make this positive - mr r3,r31 ; save it - slwi r27,r3,4 ; multiply by 16 - slwi r3,r3,2 ; and the original by 4 + mr r3,r31 ; save it + slwi r27,r3,4 ; multiply by 16 + slwi r3,r3,2 ; and the original by 4 ori r28,r28,lo16(EXT(mach_trap_table)) ; Get address of table - add r27,r27,r3 ; for a total of 20x (5 words/entry) - addi r7,r7,1 ; Bump TASK_SYSCALLS_MACH count - cmplwi r8,0 ; Is kdebug_enable non-zero - stw r7,TASK_SYSCALLS_MACH(r10) ; Save count - bne-- ksystrace ; yes, tracing enabled + add r27,r27,r3 ; for a total of 20x (5 words/entry) + addi r7,r7,1 ; Bump TASK_SYSCALLS_MACH count + cmplwi r8,0 ; Is kdebug_enable non-zero + stw r7,TASK_SYSCALLS_MACH(r10) ; Save count + bne-- ksystrace ; yes, tracing enabled - cmplwi r31,MACH_TRAP_TABLE_COUNT ; Is this syscall in the table? - add r31,r27,r28 ; Point right to the syscall table entry + cmplwi r31,MACH_TRAP_TABLE_COUNT ; Is this syscall in the table? + add r31,r27,r28 ; Point right to the syscall table entry bge-- .L_call_server_syscall_exception ; The syscall number is invalid @@ -575,16 +625,21 @@ ksystrace: .L_kernel_syscall_munge: cmplwi r0,0 ; test for null munger - mtctr r0 ; Set the function call address + mtctr r0 ; Set the function call address addi r3,r30,saver3 ; Pointer to args from save area addi r4,r1,FM_ARG0+ARG_SIZE ; Pointer for munged args beq-- .L_kernel_syscall_trapcall ; null munger - skip to trap call bctrl ; Call the munge function .L_kernel_syscall_trapcall: - lwz r0,MACH_TRAP_FUNCTION(r31) ; Pick up the function address - mtctr r0 ; Set the function call address - addi r3,r1,FM_ARG0+ARG_SIZE ; Pointer to munged args + lwz r0,MACH_TRAP_FUNCTION(r31) ; Pick up the function address + mtctr r0 ; Set the function call address + addi r3,r1,FM_ARG0+ARG_SIZE ; Pointer to munged args + +#if FPFLOOD + stfd f31,emfp31(r25) ; (TEST/DEBUG) +#endif + bctrl @@ -596,12 +651,12 @@ ksystrace: */ .L_mach_return: - srawi r0,r3,31 ; properly extend the return code - cmpi cr0,r3,KERN_INVALID_ARGUMENT ; deal with invalid system calls - mr r31,r16 ; Move the current thread pointer - stw r0, saver3(r30) ; stash the high part of the return code - stw r3,saver3+4(r30) ; Stash the low part of the return code - beq- cr0,.L_mach_invalid_ret ; otherwise fall through into the normal return path + srawi r0,r3,31 ; properly extend the return code + cmpi cr0,r3,KERN_INVALID_ARGUMENT ; deal with invalid system calls + mr r31,r16 ; Move the current thread pointer + stw r0, saver3(r30) ; stash the high part of the return code + stw r3,saver3+4(r30) ; Stash the low part of the return code + beq-- cr0,.L_mach_invalid_ret ; otherwise fall through into the normal return path .L_mach_invalid_arg: @@ -666,12 +721,12 @@ scrnotkern: * we want to pass the error code back to the caller */ lwz r0,saver0+4(r30) ; reload the original syscall number - neg r28,r0 ; Make this positive - mr r4,r28 ; save a copy - slwi r27,r4,4 ; multiply by 16 - slwi r4,r4,2 ; and another 4 + neg r28,r0 ; Make this positive + mr r4,r28 ; save a copy + slwi r27,r4,4 ; multiply by 16 + slwi r4,r4,2 ; and another 4 lis r28,hi16(EXT(mach_trap_table)) ; Get address of table - add r27,r27,r4 ; for a total of 20x (5 words/entry) + add r27,r27,r4 ; for a total of 20x (5 words/entry) ori r28,r28,lo16(EXT(mach_trap_table)) ; Get address of table add r28,r27,r28 ; Point right to the syscall table entry lwz r27,MACH_TRAP_FUNCTION(r28) ; Pick up the function address @@ -934,25 +989,46 @@ ihbootnover: ; (TEST/DEBUG) mr r31,r3 mr r30,r4 - lwz r3,SAVtime+4(r4) - addi r4,r13,SYSTEM_TIMER - bl EXT(timer_event) + lwz r3,SAVtime(r4) + lwz r4,SAVtime+4(r4) + addi r5,r25,PP_PROCESSOR + lwz r5,KERNEL_TIMER(r5) + bl EXT(thread_timer_event) + addi r6,r25,PP_PROCESSOR + lwz r5,CURRENT_STATE(r6) + addi r7,r6,USER_STATE + cmplw r5,r7 + bne 0f + addi r5,r6,SYSTEM_STATE + bl EXT(state_event) +0: + + lwz r7,ACT_TASK(r13) + lwz r8,TASK_VTIMERS(r7) + cmpwi r8,0 + beq++ 0f + + lwz r7,ACT_PER_PROC(r13) + li r4,AST_BSD + lwz r8,PP_PENDING_AST(r7) + or r8,r8,r4 + stw r8,PP_PENDING_AST(r7) + addi r3,r13,ACT_AST + bl EXT(hw_atomic_or) +0: mr r3,r31 mr r4,r30 lwz r5,savedsisr(r30) ; Get the DSISR lwz r6,savedar+4(r30) ; Get the DAR - - bl EXT(interrupt) +#if FPFLOOD + stfd f31,emfp31(r25) ; (TEST/DEBUG) +#endif -/* interrupt() returns a pointer to the saved state in r3 - * - * Ok, back from C. Disable interrupts while we restore things - */ - .globl EXT(ihandler_ret) + bl EXT(interrupt) -LEXT(ihandler_ret) ; Marks our return point from debugger entry +/* interrupt() returns a pointer to the saved state in r3 */ lis r10,hi16(MASK(MSR_VEC)) ; Get the vector enable mfmsr r0 ; Get our MSR @@ -963,7 +1039,7 @@ LEXT(ihandler_ret) ; Marks our return point from debugger entry lwz r10,ACT_PER_PROC(r8) ; Get the per_proc block lwz r7,SAVflags(r3) ; Pick up the flags - lwz r9,SAVprev+4(r3) ; Get previous save area + lwz r9,SAVprev+4(r3) ; Get previous save area cmplwi cr1,r8,0 ; Are we still initializing? lwz r12,savesrr1+4(r3) ; Get the MSR we will load on return andis. r11,r7,hi16(SAVrststk) ; Is this the first on the stack? @@ -1159,7 +1235,10 @@ fpuhasdfrd: lwz r24,FPUsave(r26) ; (TEST/DEBUG) Get the first savearea mr. r23,r23 ; (TEST/DEBUG) Should be level 0 beq++ fpulvl0 ; (TEST/DEBUG) Yes... - BREAKPOINT_TRAP ; (TEST/DEBUG) + + lis r0,hi16(Choke) ; (TEST/DEBUG) Choke code + ori r0,r0,lo16(Choke) ; (TEST/DEBUG) and the rest + sc ; (TEST/DEBUG) System ABEND fpulvl0: mr. r24,r24 ; (TEST/DEBUG) Any context? beq fpunusrstt ; (TEST/DEBUG) No... @@ -1167,11 +1246,17 @@ fpulvl0: mr. r24,r24 ; (TEST/DEBUG) Any context? lwz r21,SAVprev+4(r24) ; (TEST/DEBUG) Get previous pointer mr. r23,r23 ; (TEST/DEBUG) Is this our user context? beq++ fpulvl0b ; (TEST/DEBUG) Yes... - BREAKPOINT_TRAP ; (TEST/DEBUG) + + lis r0,hi16(Choke) ; (TEST/DEBUG) Choke code + ori r0,r0,lo16(Choke) ; (TEST/DEBUG) and the rest + sc ; (TEST/DEBUG) System ABEND fpulvl0b: mr. r21,r21 ; (TEST/DEBUG) Is there a forward chain? beq++ fpunusrstt ; (TEST/DEBUG) Nope... - BREAKPOINT_TRAP ; (TEST/DEBUG) + + lis r0,hi16(Choke) ; (TEST/DEBUG) Choke code + ori r0,r0,lo16(Choke) ; (TEST/DEBUG) and the rest + sc ; (TEST/DEBUG) System ABEND fpunusrstt: ; (TEST/DEBUG) #endif @@ -1191,6 +1276,7 @@ fpunusrstt: ; (TEST/DEBUG) beq++ fpuena ; Nope... lwz r25,SAVlevel(r24) ; Get the level of savearea lwz r0,SAVprev+4(r24) ; Get the previous + cmplw r30,r25 ; Is savearea for the level we are launching? bne++ fpuena ; No, just go enable... @@ -1394,13 +1480,19 @@ segtb: mftbu r20 ; Get the upper time base mtdec r13 ; Set our value -chkifuser: addi r4,r28,SYSTEM_TIMER - mftb r3 +chkifuser: bl EXT(mach_absolute_time) + lwz r5,ACT_PER_PROC(r28) + addi r6,r5,PP_PROCESSOR + lwz r5,KERNEL_TIMER(r6) + lwz r29,CURRENT_STATE(r6) beq-- cr7,chkifuser1 ; Skip this if we are going to kernel... stw r18,umwSpace(r28) ; Half-invalidate to force MapUserAddressWindow to reload SRs - addi r4,r28,USER_TIMER + addi r5,r28,USER_TIMER + addi r29,r6,USER_STATE -chkifuser1: bl EXT(timer_event) +chkifuser1: bl EXT(thread_timer_event) + mr r5,r29 + bl EXT(state_event) chkenax: