- mr r4,r30
- bl EXT(syscall_trace)
- lwz r0,saver0(r30) ; Get the system call selector */
- neg r31,r0 ; Make system call number positive and put in r31
- lis r29,hi16(EXT(mach_trap_count)) ; High part of valid trap number
- ori r29,r29,lo16(EXT(mach_trap_count)) ; Low part of valid trap number
- lis r28,hi16(EXT(mach_trap_table)) ; High part of trap table
- lwz r29,0(r29) ; Get the first invalid system call number
- ori r28,r28,lo16(EXT(mach_trap_table)) ; Low part of trap table
-
- cmplw r31,r29 ; See if we have a valid system call number
- slwi r31,r31,MACH_TRAP_OFFSET_POW2 ; Get offset into table
-
- bge- .L_call_server_syscall_exception ; System call number of bogus
-
- add r31,r31,r28 ; Point to the system call entry
- lis r28,hi16(EXT(kern_invalid)) ; Get the high invalid routine address
- lwz r0,MACH_TRAP_FUNCTION(r31) ; Grab the system call routine address
- ori r28,r28,lo16(EXT(kern_invalid)) ; Get the low part of the invalid routine address
- lwz r29,MACH_TRAP_ARGC(r31) ; Get the number of arguments in the call
- cmplw r0,r28 ; Is this an invalid entry?
- beq- .L_call_server_syscall_exception ; Yes, it is invalid...
-
-/* get arg count. If argc > 8 then not all args were in regs,
- * so we must perform copyin.
- */
- cmpwi cr0,r29,8 ; Do we have more than 8 arguments?
- ble+ .L_syscall_got_args ; Nope, no copy in needed...
-
-/* argc > 8 - perform a copyin */
-/* if the syscall came from kernel space, we can just copy */
-
- lwz r0,savesrr1(r30) ; Pick up exception time MSR
- andi. r0,r0,MASK(MSR_PR) ; Check the priv bit
- bne+ .L_syscall_arg_copyin ; We are not priviliged...
-
-/* we came from a privilaged task, just do a copy */
-/* get user's stack pointer */
-
- lwz r28,saver1(r30) ; Get the stack pointer
-
- subi r29,r29,8 ; Get the number of arguments to copy
-
- addi r28,r28,COPYIN_ARG0_OFFSET-4 ; Point to source - 4
- addi r27,r1,FM_ARG0-4 ; Point to sink - 4
-
-.L_syscall_copy_word_loop:
- addic. r29,r29,-1 ; Count down the number of arguments left
- lwz r0,4(r28) ; Pick up the argument from the stack
- addi r28,r28,4 ; Point to the next source
- stw r0,4(r27) ; Store the argument
- addi r27,r27,4 ; Point to the next sink
- bne+ .L_syscall_copy_word_loop ; Move all arguments...
- b .L_syscall_got_args ; Go call it now...
-
-
-/* we came from a user task, pay the price of a real copyin */
-/* set recovery point */
-
- .align 5
-
-.L_syscall_arg_copyin:
- lwz r8,ACT_VMMAP(r13) ; Get the vm_map for this activation
- lis r28,hi16(.L_syscall_copyin_recover)
- lwz r8,VMMAP_PMAP(r8) ; Get the pmap
- ori r28,r28,lo16(.L_syscall_copyin_recover)
- addi r8,r8,PMAP_SEGS ; Point to the pmap SR slots
- stw r28,THREAD_RECOVER(r16) ; R16 still holds thread ptr
-
-/* We can manipulate the COPYIN segment register quite easily
- * here, but we've also got to make sure we don't go over a
- * segment boundary - hence some mess.
- * Registers from 12-29 are free for our use.
- */
-
-
- lwz r28,saver1(r30) ; Get the stack pointer
- subi r29,r29,8 ; Get the number of arguments to copy
- addi r28,r28,COPYIN_ARG0_OFFSET ; Set source in user land
-
-/* set up SR_COPYIN to allow us to copy, we may need to loop
- * around if we change segments. We know that this previously
- * pointed to user space, so the sid doesn't need setting.
- */
-
- rlwinm r7,r28,6,26,29 ; Get index to the segment slot
-
-.L_syscall_copyin_seg_loop:
- lwzx r10,r8,r7 ; Get the source SR value
- rlwinm r26,r28,0,4,31 ; Clear the segment number from source address
- mtsr SR_COPYIN,r10 ; Set the copyin SR
- isync
-
- oris r26,r26,(SR_COPYIN_NUM << (28-16)) ; Insert the copyin segment number into source address
-
- addi r27,r1,FM_ARG0-4 ; Point to area - 4 where we will store the arguments
-
-.L_syscall_copyin_word_loop:
- lwz r0,0(r26) ; MAY CAUSE PAGE FAULT!
- subi r29,r29,1 ; Decrement count
- addi r26,r26,4 ; Bump input
- stw r0,4(r27) ; Save the copied in word
- mr. r29,r29 ; Are they all moved?
- addi r27,r27,4 ; Bump output
- beq+ .L_syscall_copyin_done ; Escape if we are done...
-
- rlwinm. r0,r26,0,4,29 ; Did we just step into a new segment?
- addi r28,r28,4 ; Bump up user state address also
- bne+ .L_syscall_copyin_word_loop ; We are still on the same segment...
-
- addi r7,r7,4 ; Bump to next slot
- b .L_syscall_copyin_seg_loop ; On new segment! remap
-
-/* Don't bother restoring SR_COPYIN, we can leave it trashed */
-/* clear thread recovery as we're done touching user data */
-
- .align 5
-
-.L_syscall_copyin_done:
- li r0,0
- stw r0,THREAD_RECOVER(r16) ; R16 still holds thread ptr
-
-.L_syscall_got_args:
- lwz r0,MACH_TRAP_FUNCTION(r31) ; Get function address
- lwz r8,ACT_TASK(r13) ; Get our task
- lis r10,hi16(EXT(c_syscalls_mach)) ; Get top half of counter address
- lwz r7,TASK_SYSCALLS_MACH(r8) ; Get the current count
- lwz r3,saver3(r30) ; Restore r3
- addi r7,r7,1 ; Bump it
- ori r10,r10,lo16(EXT(c_syscalls_mach)) ; Get low half of counter address
- stw r7,TASK_SYSCALLS_MACH(r8) ; Save it
- lwz r4,saver4(r30) ; Restore r4
- lwz r9,0(r10) ; Get counter
- mtctr r0 ; Set function address
- lwz r5,saver5(r30) ; Restore r5
- lwz r6,saver6(r30) ; Restore r6
- addi r9,r9,1 ; Add 1
- lwz r7,saver7(r30) ; Restore r7
- lwz r8,saver8(r30) ; Restore r8
- stw r9,0(r10) ; Save it back
- lwz r9,saver9(r30) ; Restore r9
- lwz r10,saver10(r30) ; Restore r10
-
-
-;
-; Note that all arguments from the system call are passed into the function
-;
-
- bctrl ; Perform the actual syscall
+ 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 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 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
+ 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
+
+ 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
+
+ lwz r0,savesrr1(r30) ; Get the saved srr1
+ rlwinm. r0,r0,0,MSR_SF_BIT,MSR_SF_BIT ; Test for 64 bit caller
+ lwz r0,MACH_TRAP_ARG_MUNGE32(r31) ; Pick up the 32 bit munge function address
+ beq-- .L_kernel_syscall_munge
+ lwz r0,MACH_TRAP_ARG_MUNGE64(r31) ; Pick up the 64 bit munge function address
+
+.L_kernel_syscall_munge:
+ cmplwi r0,0 ; test for null munger
+ 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
+
+#if FPFLOOD
+ stfd f31,emfp31(r25) ; (TEST/DEBUG)
+#endif