📄 entry.s
字号:
mfctl %cr25,ptp /* load user pgd */ mfsp %sr7,t0 /* Get current space */ or,= %r0,t0,%r0 /* If kernel, nullify following test */ cmpb,<>,n t0,spc,itlb_fault /* forward */ /* First level page table lookup */itlb_miss_common_11: ldwx,s t1(ptp),ptp extru va,19,10,t0 /* get second-level index */ bb,>=,n ptp,_PAGE_PRESENT_BIT,itlb_fault depi 0,31,12,ptp /* clear prot bits */ /* Second level page table lookup */ sh2addl t0,ptp,ptp ldi _PAGE_ACCESSED,t1 ldw 0(ptp),pte bb,>=,n pte,_PAGE_PRESENT_BIT,itlb_fault /* Check whether the "accessed" bit was set, otherwise do so */ or t1,pte,t0 /* t0 has R bit set */ and,<> t1,pte,%r0 /* test and nullify if already set */ stw t0,0(ptp) /* write back pte */ zdep spc,30,15,prot /* create prot id from space */ dep pte,8,7,prot /* add in prot bits from pte */ 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 iitlba */ 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 iitlba pte,(%sr1,va) iitlbp prot,(%sr1,va) mtsp t0, %sr1 /* Restore sr1 */ rfir nopitlb_miss_kernel_11: b itlb_miss_common_11 mfctl %cr24,ptp /* Load kernel pgd */itlb_miss_20: /* * I miss is a little different, since we allow users to fault * on the gateway page which is in the kernel address space. */ cmpib,= 0,spc,itlb_miss_kernel_20 extru va,9,10,t1 /* Get pgd index */ mfctl %cr25,ptp /* load user pgd */ mfsp %sr7,t0 /* Get current space */ or,= %r0,t0,%r0 /* If kernel, nullify following test */ cmpb,<>,n t0,spc,itlb_fault /* forward */ /* First level page table lookup */itlb_miss_common_20: ldwx,s t1(ptp),ptp extru va,19,10,t0 /* get second-level index */ bb,>=,n ptp,_PAGE_PRESENT_BIT,itlb_fault depi 0,31,12,ptp /* clear prot bits */ /* Second level page table lookup */ sh2addl t0,ptp,ptp ldi _PAGE_ACCESSED,t1 ldw 0(ptp),pte bb,>=,n pte,_PAGE_PRESENT_BIT,itlb_fault /* Check whether the "accessed" bit was set, otherwise do so */ or t1,pte,t0 /* t0 has R bit set */ and,<> t1,pte,%r0 /* test and nullify if already set */ stw t0,0(ptp) /* write back pte */ space_to_prot spc prot /* create prot id from space */ depd pte,8,7,prot /* add in prot bits from pte */ 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 iitlbt */ extrd,s pte,35,4,t1 depdi 0,63,12,pte /* clear lower 12 bits */ addi,= 1,t1,0 extrd,u,*tr pte,56,25,pte extrd,s pte,56,25,pte /* bit 31:8 >> 8 */ iitlbt pte,prot rfir nopitlb_miss_kernel_20: b itlb_miss_common_20 mfctl %cr24,ptp /* Load kernel pgd */#endif#ifdef __LP64__dbit_trap_20w: extrd,u spc,63,7,t1 /* adjust va */ depd t1,31,7,va /* adjust va */ depdi 0,1,2,va /* adjust va */ depdi 0,63,7,spc /* adjust space */ mfctl %cr25,ptp /* Assume user space miss */ or,*<> %r0,spc,%r0 /* If it is user space, nullify */ mfctl %cr24,ptp /* Load kernel pgd instead */ extrd,u va,33,9,t1 /* Get pgd index */ mfsp %sr7,t0 /* Get current space */ or,*= %r0,t0,%r0 /* If kernel, nullify following test */ cmpb,*<>,n t0,spc,dbit_fault /* forward */ /* First level page table lookup */ ldd,s t1(ptp),ptp extrd,u va,42,9,t0 /* get second-level index */ bb,>=,n ptp,_PAGE_PRESENT_BIT,dbit_fault depdi 0,63,12,ptp /* clear prot bits */ /* Second level page table lookup */ ldd,s t0(ptp),ptp extrd,u va,51,9,t0 /* get third-level index */ bb,>=,n ptp,_PAGE_PRESENT_BIT,dbit_fault depdi 0,63,12,ptp /* clear prot bits */ /* Third level page table lookup */ shladd t0,3,ptp,ptp#ifdef CONFIG_SMP CMPIB=,n 0,spc,dbit_nolock_20w ldil L%PA(pa_dbit_lock),t0 ldo R%PA(pa_dbit_lock)(t0),t0dbit_spin_20w: ldcw 0(t0),t1 cmpib,= 0,t1,dbit_spin_20w nopdbit_nolock_20w:#endif ldi (_PAGE_ACCESSED|_PAGE_DIRTY),t1 ldd 0(ptp),pte bb,>=,n pte,_PAGE_PRESENT_BIT,dbit_fault /* Set Accessed and Dirty bits in the pte */ or t1,pte,pte std pte,0(ptp) /* write back pte */ space_to_prot spc prot /* create prot id from space */ depd pte,8,7,prot /* add in prot bits from pte */ 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,52,pte idtlbt pte,prot#ifdef CONFIG_SMP CMPIB=,n 0,spc,dbit_nounlock_20w ldi 1,t1 stw t1,0(t0)dbit_nounlock_20w:#endif 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 */ cmpb,<>,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#ifdef CONFIG_SMP CMPIB=,n 0,spc,dbit_nolock_11 ldil L%PA(pa_dbit_lock),t0 ldo R%PA(pa_dbit_lock)(t0),t0dbit_spin_11: ldcw 0(t0),t1 cmpib,= 0,t1,dbit_spin_11 nopdbit_nolock_11:#endif 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 */ zdep spc,30,15,prot /* create prot id from space */ dep pte,8,7,prot /* add in prot bits from pte */ 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,t1 /* Save sr1 so we can use it in tlb inserts */ mtsp spc,%sr1 idtlba pte,(%sr1,va) idtlbp prot,(%sr1,va) mtsp t1, %sr1 /* Restore sr1 */#ifdef CONFIG_SMP CMPIB=,n 0,spc,dbit_nounlock_11 ldi 1,t1 stw t1,0(t0)dbit_nounlock_11:#endif 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 */ cmpb,<>,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#ifdef CONFIG_SMP CMPIB=,n 0,spc,dbit_nolock_20 ldil L%PA(pa_dbit_lock),t0 ldo R%PA(pa_dbit_lock)(t0),t0dbit_spin_20: ldcw 0(t0),t1 cmpib,= 0,t1,dbit_spin_20 nopdbit_nolock_20:#endif 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 */ space_to_prot spc prot /* create prot id from space */ depd pte,8,7,prot /* add in prot bits from pte */ 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 */ extrd,s pte,35,4,t1 depdi 0,63,12,pte /* clear lower 12 bits */ addi,= 1,t1,0 extrd,u,*tr pte,56,25,pte extrd,s pte,56,25,pte /* bit 31:8 >> 8 */ idtlbt pte,prot#ifdef CONFIG_SMP CMPIB=,n 0,spc,dbit_nounlock_20 ldi 1,t1 stw t1,0(t0)dbit_nounlock_20:#endif rfir nop#endif .import handle_interruption,codekernel_bad_space: b intr_save ldi 31,%r8 /* Use an unused code */dbit_fault: b intr_save ldi 20,%r8itlb_fault: b intr_save ldi 6,%r8nadtlb_fault: b intr_save ldi 17,%r8dtlb_fault: b intr_save ldi 15,%r8 /* 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_wrapper .export child_returnsys_fork_wrapper: ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get pt regs */ reg_save %r1 mfctl %cr27, %r3 STREG %r3, PT_CR27(%r1) STREG %r2,-RP_OFFSET(%r30) ldo FRAME_SIZE(%r30),%r30#ifdef __LP64__ ldo -16(%r30),%r29 /* Reference param save area */#endif /* These are call-clobbered registers and therefore also syscall-clobbered (we hope). */ STREG %r2,PT_GR19(%r1) /* save for child */ STREG %r30,PT_GR21(%r1) 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 */ LDREG PT_CR27(%r1), %r3 mtctl %r3, %cr27 reg_restore %r1 /* strace expects syscall # to be preserved in r20 */ ldi __NR_fork,%r20 bv %r0(%r2) STREG %r20,PT_GR20(%r1) /* Set the return value for the child */child_return: bl schedule_tail, %r2 nop LDREG TASK_PT_GR19-TASK_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%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 mfctl %cr27, %r3 STREG %r3, PT_CR27(%r1) STREG %r2,-RP_OFFSET(%r30) ldo FRAME_SIZE(%r30),%r30#ifdef __LP64__ ldo -16(%r30),%r29 /* Reference param save area */#endif STREG %r2,PT_GR19(%r1) /* save for child */ STREG %r30,PT_GR21(%r1) bl sys_clone,%r2 copy %r1,%r24 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 mfctl %cr27, %r3 STREG %r3, PT_CR27(%r1) STREG %r2,-RP_OFFSET(%r30) ldo FRAME_SIZE(%r30),%r30#ifdef __LP64__ ldo -16(%r30),%r29 /* Reference param save area */#endif STREG %r2,PT_GR19(%r1) /* save for child */ STREG %r30,PT_GR21(%r1) bl sys_vfork,%r2 copy %r1,%r26
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -