?? entry.s
字號:
depdi 7,11,3,prot /* Set for user space (1 rsvd for read) */ extrd,u,*= pte,_PAGE_GATEWAY_BIT+32,1,r0 depdi 0,11,2,prot /* If Gateway, Set PL2 to 0 */ /* Get rid of prot bits and convert to page addr for idtlbt */ depdi 0,63,12,pte extrd,u pte,56,32,pte idtlbt %r16,%r17 rfir nop#elsedbit_trap_11: mfctl %cr25,ptp /* Assume user space trap */ or,<> %r0,spc,%r0 /* If it is user space, nullify */ mfctl %cr24,ptp /* Load kernel pgd instead */ extru va,9,10,t1 /* Get pgd index */ mfsp %sr7,t0 /* Get current space */ or,= %r0,t0,%r0 /* If kernel, nullify following test */ comb,<>,n t0,spc,dbit_fault /* forward */ /* First level page table lookup */ ldwx,s t1(ptp),ptp extru va,19,10,t0 /* get second-level index */ bb,>=,n ptp,_PAGE_PRESENT_BIT,dbit_fault depi 0,31,12,ptp /* clear prot bits */ /* Second level page table lookup */ sh2addl t0,ptp,ptp ldi (_PAGE_ACCESSED|_PAGE_DIRTY),t1 ldw 0(ptp),pte bb,>=,n pte,_PAGE_PRESENT_BIT,dbit_fault /* Set Accessed and Dirty bits in the pte */ or t1,pte,pte stw pte,0(ptp) /* write back pte */ copy spc,prot /* init prot with faulting space */ dep pte,8,7,prot extru,= pte,_PAGE_NO_CACHE_BIT,1,r0 depi 1,12,1,prot extru,= pte,_PAGE_USER_BIT,1,r0 depi 7,11,3,prot /* Set for user space (1 rsvd for read) */ extru,= pte,_PAGE_GATEWAY_BIT,1,r0 depi 0,11,2,prot /* If Gateway, Set PL2 to 0 */ /* Get rid of prot bits and convert to page addr for idtlba */ depi 0,31,12,pte extru pte,24,25,pte mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ mtsp spc,%sr1 idtlba pte,(%sr1,va) idtlbp prot,(%sr1,va) mtsp t0, %sr1 /* Restore sr1 */ rfir nopdbit_trap_20: mfctl %cr25,ptp /* Assume user space trap */ or,<> %r0,spc,%r0 /* If it is user space, nullify */ mfctl %cr24,ptp /* Load kernel pgd instead */ extru va,9,10,t1 /* Get pgd index */ mfsp %sr7,t0 /* Get current space */ or,= %r0,t0,%r0 /* If kernel, nullify following test */ comb,<>,n t0,spc,dbit_fault /* forward */ /* First level page table lookup */ ldwx,s t1(ptp),ptp extru va,19,10,t0 /* get second-level index */ bb,>=,n ptp,_PAGE_PRESENT_BIT,dbit_fault depi 0,31,12,ptp /* clear prot bits */ /* Second level page table lookup */ sh2addl t0,ptp,ptp ldi (_PAGE_ACCESSED|_PAGE_DIRTY),t1 ldw 0(ptp),pte bb,>=,n pte,_PAGE_PRESENT_BIT,dbit_fault /* Set Accessed and Dirty bits in the pte */ or t1,pte,pte stw pte,0(ptp) /* write back pte */ copy spc,prot /* init prot with faulting space */ .level 2.0 depd pte,8,7,prot extrd,u,*= pte,_PAGE_NO_CACHE_BIT+32,1,r0 depdi 1,12,1,prot extrd,u,*= pte,_PAGE_USER_BIT+32,1,r0 depdi 7,11,3,prot /* Set for user space (1 rsvd for read) */ extrd,u,*= pte,_PAGE_GATEWAY_BIT+32,1,r0 depdi 0,11,2,prot /* If Gateway, Set PL2 to 0 */ /* Get rid of prot bits and convert to page addr for idtlbt */ depdi 0,63,12,pte extrd,u pte,56,25,pte idtlbt %r16,%r17 .level 1.1 rfir nop#endif .import handle_interruption,codekernel_bad_space: b tlb_fault ldi 31,%r1 /* Use an unused code */dbit_fault: b tlb_fault ldi 20,%r1itlb_fault: b tlb_fault ldi 6,%r1dtlb_fault: ldi 15,%r1 /* Fall Through */tlb_fault: mtctl %r1,%cr29 mtctl %r29,%cr31 get_stack save_specials %r29 /* Note this saves a trashed r1 */ SAVE_CR (%cr20, PT_ISR(%r29)) SAVE_CR (%cr21, PT_IOR(%r29)) virt_map rfir STREG %r1,PT_GR1(%r29) /* save good value after rfir */ save_general %r29 ldo PT_FR0(%r29), %r25 save_fp %r25 loadgp copy %r29, %r25 bl handle_interruption, %r2 copy %r29, %r16 b intr_return nop /* Register saving semantics for system calls: %r1 clobbered by system call macro in userspace %r2 saved in PT_REGS by gateway page %r3 - %r18 preserved by C code (saved by signal code) %r19 - %r20 saved in PT_REGS by gateway page %r21 - %r22 non-standard syscall args stored in kernel stack by gateway page %r23 - %r26 arg3-arg0, saved in PT_REGS by gateway page %r27 - %r30 saved in PT_REGS by gateway page %r31 syscall return pointer */ /* Floating point registers (FIXME: what do we do with these?) %fr0 - %fr3 status/exception, not preserved %fr4 - %fr7 arguments %fr8 - %fr11 not preserved by C code %fr12 - %fr21 preserved by C code %fr22 - %fr31 not preserved by C code */ .macro reg_save regs STREG %r3, PT_GR3(\regs) STREG %r4, PT_GR4(\regs) STREG %r5, PT_GR5(\regs) STREG %r6, PT_GR6(\regs) STREG %r7, PT_GR7(\regs) STREG %r8, PT_GR8(\regs) STREG %r9, PT_GR9(\regs) STREG %r10,PT_GR10(\regs) STREG %r11,PT_GR11(\regs) STREG %r12,PT_GR12(\regs) STREG %r13,PT_GR13(\regs) STREG %r14,PT_GR14(\regs) STREG %r15,PT_GR15(\regs) STREG %r16,PT_GR16(\regs) STREG %r17,PT_GR17(\regs) STREG %r18,PT_GR18(\regs) .endm .macro reg_restore regs LDREG PT_GR3(\regs), %r3 LDREG PT_GR4(\regs), %r4 LDREG PT_GR5(\regs), %r5 LDREG PT_GR6(\regs), %r6 LDREG PT_GR7(\regs), %r7 LDREG PT_GR8(\regs), %r8 LDREG PT_GR9(\regs), %r9 LDREG PT_GR10(\regs),%r10 LDREG PT_GR11(\regs),%r11 LDREG PT_GR12(\regs),%r12 LDREG PT_GR13(\regs),%r13 LDREG PT_GR14(\regs),%r14 LDREG PT_GR15(\regs),%r15 LDREG PT_GR16(\regs),%r16 LDREG PT_GR17(\regs),%r17 LDREG PT_GR18(\regs),%r18 .endm .export sys_fork_wrappersys_fork_wrapper: ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get pt regs */ reg_save %r1 STREG %r2,-RP_OFFSET(%r30) ldo FRAME_SIZE(%r30),%r30 /* These are call-clobbered registers and therefore also syscall-clobbered (we hope). */ STREG %r2,PT_GR19(%r1) /* save for child */ STREG %r30,PT_GR20(%r1) ldil L%child_return, %r3 ldo R%child_return(%r3), %r3 LDIL_FIXUP(%r3) STREG %r3,PT_GR21(%r1) /* save for child */ LDREG PT_GR30(%r1),%r25 copy %r1,%r24 bl sys_clone,%r2 ldi SIGCHLD,%r26 LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2wrapper_exit: ldo -FRAME_SIZE(%r30),%r30 /* get the stackframe */ ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get pt regs */ reg_restore %r1 bv %r0(%r2) nop /* Set the return value for the child */child_return: LDREG TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2 b wrapper_exit copy %r0,%r28 .export sys_clone_wrappersys_clone_wrapper: ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get pt regs */ reg_save %r1 STREG %r2,-RP_OFFSET(%r30) ldo FRAME_SIZE(%r30),%r30 STREG %r30,PT_GR20(%r1) ldil L%child_return,%r3 ldo R%child_return(%r3),%r3 LDIL_FIXUP(%r3) bl sys_clone,%r2 STREG %r3,PT_GR21(%r1) /* save for child */ b wrapper_exit LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2 .export sys_vfork_wrappersys_vfork_wrapper: ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get pt regs */ reg_save %r1 STREG %r2,-RP_OFFSET(%r30) ldo FRAME_SIZE(%r30),%r30 STREG %r30,PT_GR20(%r1) ldil L%child_return,%r3 ldo R%child_return(%r3),%r3 LDIL_FIXUP(%r3) STREG %r3,PT_GR21(%r1) /* save for child */ bl sys_vfork,%r2 copy %r1,%r26 b wrapper_exit LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2 .macro execve_wrapper execve ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get pt regs */ /* * Do we need to save/restore r3-r18 here? * I don't think so. why would new thread need old * threads registers? */ /* %arg0 - %arg3 are already saved for us. */ STREG %r2,-RP_OFFSET(%r30) ldo FRAME_SIZE(%r30),%r30 bl \execve,%r2 copy %r1,%arg0 ldo -FRAME_SIZE(%r30),%r30 LDREG -RP_OFFSET(%r30),%r2 /* If exec succeeded we need to load the args */ ldo -1024(%r0),%r1 comb,>>= %r28,%r1,error_\execve copy %r2,%r19error_\execve: bv %r0(%r19) nop .endm .export sys_execve_wrapper .import sys_execvesys_execve_wrapper: execve_wrapper sys_execve#ifdef __LP64__ .export sys32_execve_wrapper .import sys32_execvesys32_execve_wrapper: execve_wrapper sys32_execve#endif .export sys_rt_sigreturn_wrappersys_rt_sigreturn_wrapper: ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30), %r26 /* Don't save regs, we are going to restore them from sigcontext. */ STREG %r2, -RP_OFFSET(%r30) bl sys_rt_sigreturn,%r2 ldo FRAME_SIZE(%r30), %r30 ldo -FRAME_SIZE(%r30), %r30 LDREG -RP_OFFSET(%r30), %r2 /* FIXME: I think we need to restore a few more things here. */ ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get pt regs */ reg_restore %r1 /* If the signal was received while the process was blocked on a * syscall, then r2 will take us to syscall_exit; otherwise r2 will * take us to syscall_exit_rfi and on to intr_return. */ bv %r0(%r2) LDREG PT_GR28(%r1),%r28 /* reload original r28 for syscall_exit */ .export sys_sigaltstack_wrappersys_sigaltstack_wrapper: /* Get the user stack pointer */ LDREG -TASK_SZ_ALGN-FRAME_SIZE+TASK_PT_GR30(%r30), %r24 STREG %r2, -RP_OFFSET(%r30) bl do_sigaltstack,%r2 ldo FRAME_SIZE(%r30), %r30 ldo -FRAME_SIZE(%r30), %r30 LDREG -RP_OFFSET(%r30), %r2 bv %r0(%r2) nop .export sys_rt_sigsuspend_wrappersys_rt_sigsuspend_wrapper: ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30), %r24 reg_save %r24 STREG %r2, -RP_OFFSET(%r30) bl sys_rt_sigsuspend,%r2 ldo FRAME_SIZE(%r30), %r30 ldo -FRAME_SIZE(%r30), %r30 LDREG -RP_OFFSET(%r30), %r2 ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 reg_restore %r1 bv %r0(%r2) nop .export syscall_exitsyscall_exit: /* NOTE: HP-UX syscalls also come through here after hpux_syscall_exit fixes up return values. */ /* NOTE: Not all syscalls exit this way. rt_sigreturn will exit * via syscall_exit_rfi if the signal was received while the process * was running. All traced processes will probably exit via * syscall_exit_rfi in the future. */ /* save return value now */ STREG %r28,TASK_PT_GR28-TASK_SZ_ALGN-FRAME_SIZE(%r30)syscall_check_bh:/* #ifdef NOTNOW */ /* Check for software interrupts */ .import irq_stat,data ldil L%irq_stat,%r19 ldo R%irq_stat(%r19),%r19 LDIL_FIXUP(%r19)#ifdef CONFIG_SMP /* sched.h: int processor */ ldw TASK_PROCESSOR-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r20 /* get cpu # */#if (IRQSTAT_SZ == 32) dep %r20,26,27,%r20 /* shift left 5 bits */#else#error IRQSTAT_SZ changed, fix dep#endif /* IRQSTAT_SZ */ add %r19,%r20,%r19#endif /* CONFIG_SMP */ ldw IRQSTAT_SI_ACTIVE(%r19),%r20 /* hardirq.h: unsigned int */ ldw IRQSTAT_SI_MASK(%r19),%r19 /* hardirq.h: unsigned int */ and %r19,%r20,%r20 comib,<>,n 0,%r20,syscall_do_softirq /* forward *//* #endif */syscall_check_resched: /* check for reschedule */ LDREG TASK_NEED_RESCHED-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r19 /* long */ comib,<>,n 0,%r19,syscall_do_resched /* forward */syscall_check_sig: ldo -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ /* check for pending signals */ ldw TASK_SIGPENDING(%r1),%r19 comib,<>,n 0,%r19,syscall_do_signal /* forward */syscall_restore: /* disable interrupts while dicking with the kernel stack, */ /* or life can become unpleasant */ rsm PSW_SM_I, %r20 LDREG TASK_PTRACE(%r1), %r19 /* Are we being ptraced? */ bb,<,n %r19,31,syscall_restore_rfi LDREG TASK_PT_GR20(%r1),%r19 mtctl %r19, %cr27 LDREG TASK_PT_GR2(%r1),%r2 /* restore user rp */ LDREG TASK_PT_GR21(%r1),%r21 LDREG TASK_PT_GR22(%r1),%r22 LDREG TASK_PT_GR23(%r1),%r23 LDREG TASK_PT_GR24(%r1),%r24 LDREG TASK_PT_GR25(%r1),%r25 LDREG TASK_PT_GR26(%r1),%r26 LDREG TASK_PT_GR27(%r1),%r27 /* restore user dp */ LDREG TASK_PT_GR28(%r1),%r28 /* syscall return value */ LDREG TASK_PT_GR29(%r1),%r29 LDREG TASK_PT_GR30(%r1),%r30 /* restore user sp */ LDREG TASK_PT_GR31(%r1),%r31 /* restore syscall rp */ ldo TASK_PT_FR31(%r1),%r19 /* reload fpregs */ rest_fp %r19 LDREG TASK_PT_SAR(%r1),%r19 /* restore SAR */ mtsar %r19 LDREG TASK_PT_GR19(%r1),%r19 mtctl %r1,%cr30 /* intrhandler okay. */ mfsp %sr3,%r1 /* Get users space id */ mtsp %r1,%sr4 /* Restore sr4 */ mtsp %r1,%sr5 /* Restore sr5 */ mtsp %r1,%sr6 /* Restore sr6 */ depi 3,31,2,%r31 /* ensure return to user mode. */ mtsm %r20 /* restore irq state */ mfctl %cr27,%r20 /* * Due to a dependency in the tlb miss handlers on sr7, it * is essential that sr7 get set in the delay slot. */#ifdef __LP64__ /* Note the be (and mtsp) is executed in narrow mode. This is OK * for 32 bit processes, but won't work once we support 64 bit * processes. */ rsm PSW_SM_W, %r0 be 0(%sr3,%r31) /* return to user space */ mtsp %r1,%sr7 /* Restore sr7 */#else be 0(%sr3,%r31) /* return to user space */ mtsp %r1,%sr7 /* Restore sr7 */#endif /* We have to return via an RFI, so that PSW T and R bits can be set * appropriately. * This sets up pt_regs so we can return via intr_restore, which is not * the most efficient way of doing things, but it works. */syscall_restore_rfi: ldo -1(%r0),%r2 /* Set recovery cntr to -1 */ mtctl %r2,%cr0 /* for immediate trap */ copy %r0,%r2 /* Create a reasonable PSW */ /* XXX W bit??? */ depi -1,13,1,%r2 depi -1,28,1,%r2 depi -1,30,1,%r2 depi -1,31,1,%r2 bb,<,n %r19,15,set_rbit /* PT_SINGLESTEP */ bb,>=,n %r19,14,set_nobit /* PT_BLOCKSTEP, see ptrace.c */set_tbit: depi -1,7,1,%r2 b,n set_nobitset_rbit: depi -1,27,1,%r2set_nobit: STREG %r2,TASK_PT_PSW(%r1) STREG %r1,TASK_PT_CR30(%r1) mfsp %sr0,%r2 STREG %r2,TASK_PT_SR0(%r1) mfsp %sr1,%r2 STREG %r2,TASK_PT_SR1(%r1) mfsp %sr2,%r2 STREG %r2,TASK_PT_SR2(%r1) mfsp %sr3,%r2 STREG %r2,TASK_PT_SR3(%r1) STREG %r2,TASK_PT_SR4(%r1) STREG %r2,TASK_PT_SR5(%r1) STREG %r2,TASK_PT_SR6(%r1) STREG %r2,TASK_PT_SR7(%r1) STREG %r2,TASK_PT_IASQ0(%r1) STREG %r2,TASK_PT_IASQ1(%r1) LDREG TASK_PT_GR31(%r1),%r2 depi 3,31,2,%r2 /* ensure return to user mode. */ STREG %r2,TASK_PT_IAOQ0(%r1) ldo 4(%r2),%r2 STREG %r2,TASK_PT_IAOQ1(%r1) ldo TASK_REGS(%r1),%r25 reg_save %r25 /* Save r3 to r18 */ copy %r25,%r16 b intr_restore nop .import do_softirq,codesyscall_do_softirq: bl do_softirq,%r2 nop b syscall_check_resched ssm PSW_SM_I, %r0 /* do_softirq returns with I bit off */ .import schedule,codesyscall_do_resched: bl schedule,%r2 nop b syscall_check_bh /* if resched, we start over again */ nop .import do_signal,codesyscall_do_signal: /* Save callee-save registers (for sigcontext). FIXME: After this point the process structure should be consistent with all the relevant state of the process before the syscall. We need to verify this. */ ldo TASK_REGS(%r1), %r25 /* struct pt_regs *regs */ reg_save %r25 ldi 1, %r24 /* unsigned long in_syscall */ bl do_signal,%r2 copy %r0, %r26 /* sigset_t *oldset = NULL */ ldo -TASK_SZ_ALGN-FRAME_SIZE(%r30), %r1 /* reload task ptr */ ldo TASK_REGS(%r1), %r20 /* reload pt_regs */ reg_restore %r20 b,n syscall_restore#ifdef __LP64__unimplemented_64bitirq: ssm PSW_SM_Q+PSW_SM_I, %r0 /* indicate that we had an interrupt */ ldi 0x77, %r28 ldi 0x77, %r29 /* save interrupt registers in GRs for diagnosis */ mfctl %cr17, %r17 mfctl %cr18, %r18 mfctl %cr19, %r19 mfctl %cr20, %r20 mfctl %cr21, %r21 mfctl %cr22, %r22 b,n . nop#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -