- cmp cr0, r31, r29
- bge- cr0, .L_call_server_syscall_exception
-
- addis r29, 0, HIGH_CADDR(EXT(mach_trap_table))
- addi r29, r29, LOW_ADDR(EXT(mach_trap_table))
-
- /* multiply the trap number to get offset into table */
- slwi r31, r31, MACH_TRAP_OFFSET_POW2
-
- /* r31 now holds offset into table of our trap entry,
- * add on the table base, and it then holds pointer to entry
- */
- add r31, r31, r29
-
- /* If the function is kern_invalid, prepare to send an exception.
- This is messy, but parallels the x86. We need it for task_by_pid,
- at least. */
- lis r29, HIGH_CADDR(EXT(kern_invalid))
- addi r29, r29, LOW_ADDR(EXT(kern_invalid))
- lwz r0, MACH_TRAP_FUNCTION(r31)
- cmp cr0, r0, r29
- beq- .L_call_server_syscall_exception
-
- /* get arg count. If argc > 8 then not all args were in regs,
- * so we must perform copyin.
- */
- lwz r29, MACH_TRAP_ARGC(r31)
- cmpwi cr0, r29, 8
- ble+ .L_syscall_got_args
-
-/* 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're 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 */
-
-.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
-
-/* Make r27 point to address-4 of where we will store copied args */
- addi r27,r1,FM_ARG0-4
-
-.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 */
-
-.L_syscall_copyin_done:
- li r0,0
- stw r0,THREAD_RECOVER(r16) /* R16 still holds thread ptr */
-
-.L_syscall_got_args:
- 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 */
- 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 */
-
- lwz r0,MACH_TRAP_FUNCTION(r31)
-
-/* calling this function, all the callee-saved registers are
- * still valid except for r30 and r31 which are in the PCB
- * r30 holds pointer to saved state (ie. pcb)
- * r31 is scrap
- */
- mtctr r0
- bctrl /* perform the actual syscall */
+.L_kernel_syscall:
+;
+; 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 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