📄 entry.s
字号:
ldo R%intr_check_sig(%r2), %r2 /* * Note for all tlb miss handlers: * * cr24 contains a pointer to the kernel address space * page directory. * * cr25 contains a pointer to the current user address * space page directory. * * sr3 will contain the space id of the user address space * of the current running thread while that thread is * running in the kernel. */ /* * register number allocations. Note that these are all * in the shadowed registers */ t0 = r1 /* temporary register 0 */ va = r8 /* virtual address for which the trap occured */ t1 = r9 /* temporary register 1 */ pte = r16 /* pte/phys page # */ prot = r17 /* prot bits */ spc = r24 /* space for which the trap occured */ ptp = r25 /* page directory/page table pointer */#ifdef __LP64__dtlb_miss_20w: space_adjust spc,va,t0 get_pgd spc,ptp space_check spc,t0,dtlb_fault L3_ptep ptp,pte,t0,va,dtlb_check_alias_20w update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot idtlbt pte,prot rfir nopdtlb_check_alias_20w: do_alias spc,t0,t1,va,pte,prot,dtlb_fault idtlbt pte,prot rfir nopnadtlb_miss_20w: space_adjust spc,va,t0 get_pgd spc,ptp space_check spc,t0,nadtlb_fault L3_ptep ptp,pte,t0,va,nadtlb_check_flush_20w update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot idtlbt pte,prot rfir nopnadtlb_check_flush_20w: bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate /* Insert a "flush only" translation */ depdi,z 7,7,3,prot depdi 1,10,1,prot /* 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 rfir nop#elsedtlb_miss_11: get_pgd spc,ptp space_check spc,t0,dtlb_fault L2_ptep ptp,pte,t0,va,dtlb_check_alias_11 update_ptep ptp,pte,t0,t1 make_insert_tlb_11 spc,pte,prot 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 nopdtlb_check_alias_11: /* Check to see if fault is in the temporary alias region */ cmpib,<>,n 0,spc,dtlb_fault /* forward */ ldil L%(TMPALIAS_MAP_START),t0 copy va,t1 depwi 0,31,23,t1 cmpb,<>,n t0,t1,dtlb_fault /* forward */ ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot depw,z prot,8,7,prot /* * OK, it is in the temp alias region, check whether "from" or "to". * Check "subtle" note in pacache.S re: r23/r26. */ extrw,u,= va,9,1,r0 or,tr %r23,%r0,pte /* If "from" use "from" page */ or %r26,%r0,pte /* else "to", use "to" page */ idtlba pte,(va) idtlbp prot,(va) rfir nopnadtlb_miss_11: get_pgd spc,ptp space_check spc,t0,nadtlb_fault L2_ptep ptp,pte,t0,va,nadtlb_check_flush_11 update_ptep ptp,pte,t0,t1 make_insert_tlb_11 spc,pte,prot 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 nopnadtlb_check_flush_11: bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate /* Insert a "flush only" translation */ zdepi 7,7,3,prot depi 1,10,1,prot /* 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 nopdtlb_miss_20: space_adjust spc,va,t0 get_pgd spc,ptp space_check spc,t0,dtlb_fault L2_ptep ptp,pte,t0,va,dtlb_check_alias_20 update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot f_extend pte,t0 idtlbt pte,prot rfir nopdtlb_check_alias_20: do_alias spc,t0,t1,va,pte,prot,dtlb_fault idtlbt pte,prot rfir nopnadtlb_miss_20: get_pgd spc,ptp space_check spc,t0,nadtlb_fault L2_ptep ptp,pte,t0,va,nadtlb_check_flush_20 update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot f_extend pte,t0 idtlbt pte,prot rfir nopnadtlb_check_flush_20: bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate /* Insert a "flush only" translation */ depdi,z 7,7,3,prot depdi 1,10,1,prot /* Get rid of prot bits and convert to page addr for idtlbt */ depdi 0,63,12,pte extrd,u pte,56,32,pte idtlbt pte,prot rfir nop#endifnadtlb_emulate: /* * Non access misses can be caused by fdc,fic,pdc,lpa,probe and * probei instructions. We don't want to fault for these * instructions (not only does it not make sense, it can cause * deadlocks, since some flushes are done with the mmap * semaphore held). If the translation doesn't exist, we can't * insert a translation, so have to emulate the side effects * of the instruction. Since we don't insert a translation * we can get a lot of faults during a flush loop, so it makes * sense to try to do it here with minimum overhead. We only * emulate fdc,fic & pdc instructions whose base and index * registers are not shadowed. We defer everything else to the * "slow" path. */ mfctl %cr19,%r9 /* Get iir */ ldi 0x280,%r16 and %r9,%r16,%r17 cmpb,<>,n %r16,%r17,nadtlb_fault /* Not fdc,fic,pdc */ bb,>=,n %r9,26,nadtlb_nullify /* m bit not set, just nullify */ BL get_register,%r25 extrw,u %r9,15,5,%r8 /* Get index register # */ CMPIB=,n -1,%r1,nadtlb_fault /* have to use slow path */ copy %r1,%r24 BL get_register,%r25 extrw,u %r9,10,5,%r8 /* Get base register # */ CMPIB=,n -1,%r1,nadtlb_fault /* have to use slow path */ BL set_register,%r25 add,l %r1,%r24,%r1 /* doesn't affect c/b bits */nadtlb_nullify: mfctl %cr22,%r8 /* Get ipsw */ ldil L%PSW_N,%r9 or %r8,%r9,%r8 /* Set PSW_N */ mtctl %r8,%cr22 rfir nop#ifdef __LP64__itlb_miss_20w: /* * I miss is a little different, since we allow users to fault * on the gateway page which is in the kernel address space. */ space_adjust spc,va,t0 get_pgd spc,ptp space_check spc,t0,itlb_fault L3_ptep ptp,pte,t0,va,itlb_fault update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot iitlbt pte,prot rfir nop#elseitlb_miss_11: get_pgd spc,ptp space_check spc,t0,itlb_fault L2_ptep ptp,pte,t0,va,itlb_fault update_ptep ptp,pte,t0,t1 make_insert_tlb_11 spc,pte,prot 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_20: get_pgd spc,ptp space_check spc,t0,itlb_fault L2_ptep ptp,pte,t0,va,itlb_fault update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot f_extend pte,t0 iitlbt pte,prot rfir nop#endif#ifdef __LP64__dbit_trap_20w: space_adjust spc,va,t0 get_pgd spc,ptp space_check spc,t0,dbit_fault L3_ptep ptp,pte,t0,va,dbit_fault#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 update_dirty ptp,pte,t1 make_insert_tlb spc,pte,prot 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: get_pgd spc,ptp space_check spc,t0,dbit_fault L2_ptep ptp,pte,t0,va,dbit_fault#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 update_dirty ptp,pte,t1 make_insert_tlb_11 spc,pte,prot 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: get_pgd spc,ptp space_check spc,t0,dbit_fault L2_ptep ptp,pte,t0,va,dbit_fault#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 update_dirty ptp,pte,t1 make_insert_tlb spc,pte,prot f_extend pte,t1 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: LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 ldo TASK_REGS(%r1),%r1 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 */ LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 ldo TASK_REGS(%r1),%r1 /* get pt regs */ LDREG PT_CR27(%r1), %r3 mtctl %r3, %cr27 reg_restore %r1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -