📄 entry.s
字号:
dtlb_check_alias_20w: /* 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 depdi 0,63,23,t1 cmpb,*<>,n t0,t1,dtlb_fault /* forward */ ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot depd,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. */ extrd,u,*= va,41,1,r0 or,*tr %r23,%r0,pte /* If "from" use "from" page */ or,* %r26,%r0,pte /* else "to", use "to" page */ idtlbt pte,prot rfir nopnadtlb_miss_20w: extrd,u spc,63,7,t1 /* adjust va */ depd t1,31,7,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,nadtlb_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,nadtlb_emulate 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,nadtlb_emulate depdi 0,63,12,ptp /* clear prot bits */ /* Third level page table lookup */ shladd t0,3,ptp,ptp ldi _PAGE_ACCESSED,t1 ldd 0(ptp),pte bb,>=,n pte,_PAGE_PRESENT_BIT,nadtlb_check_flush_20w 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 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: mfctl %cr25,ptp /* Assume user space miss */ 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,dtlb_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,dtlb_check_alias_11 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,dtlb_check_alias_11 /* 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 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_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: mfctl %cr25,ptp /* Assume user space miss */ 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,nadtlb_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,nadtlb_emulate 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,nadtlb_check_flush_11 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,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: mfctl %cr25,ptp /* Assume user space miss */ 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,dtlb_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,dtlb_check_alias_20 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,dtlb_check_alias_20 /* 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 idtlbt */ 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 rfir nopdtlb_check_alias_20: /* 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 depd,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 */ idtlbt pte,prot rfir nopnadtlb_miss_20: mfctl %cr25,ptp /* Assume user space miss */ 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,nadtlb_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,nadtlb_emulate 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,nadtlb_check_flush_20 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 */ 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 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 */ b,l 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 b,l get_register,%r25 extrw,u %r9,10,5,%r8 /* Get base register # */ CMPIB=,n -1,%r1,nadtlb_fault /* have to use slow path */ b,l 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. */ extrd,u spc,63,7,t1 /* adjust va */ depd t1,31,7,va /* adjust va */ depdi 0,63,7,spc /* adjust space */ cmpib,*= 0,spc,itlb_miss_kernel_20w extrd,u va,33,9,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_20w: ldd,s t1(ptp),ptp extrd,u va,42,9,t0 /* get second-level index */ bb,>=,n ptp,_PAGE_PRESENT_BIT,itlb_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,itlb_fault depdi 0,63,12,ptp /* clear prot bits */ /* Third level page table lookup */ shladd t0,3,ptp,ptp ldi _PAGE_ACCESSED,t1 ldd 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 */ std 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 */ depdi 0,63,12,pte extrd,u pte,56,32,pte iitlbt pte,prot rfir nopitlb_miss_kernel_20w: b itlb_miss_common_20w mfctl %cr24,ptp /* Load kernel pgd */#elseitlb_miss_11: /* * 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_11 extru va,9,10,t1 /* Get pgd index */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -