From 67ca76fd68c94a5ecc0189003c489a99c1b5ff31 Mon Sep 17 00:00:00 2001 From: eeh Date: Thu, 31 Aug 2000 20:14:55 +0000 Subject: [PATCH] Use casx instead of stx to change entries in the page table trees. --- sys/arch/sparc64/sparc64/locore.s | 164 +++++++++++++++++++++++++++--- 1 file changed, 150 insertions(+), 14 deletions(-) diff --git a/sys/arch/sparc64/sparc64/locore.s b/sys/arch/sparc64/sparc64/locore.s index 1c422842c064..10eeea506472 100644 --- a/sys/arch/sparc64/sparc64/locore.s +++ b/sys/arch/sparc64/sparc64/locore.s @@ -1,4 +1,4 @@ -/* $NetBSD: locore.s,v 1.94 2000/08/23 21:35:57 eeh Exp $ */ +/* $NetBSD: locore.s,v 1.95 2000/08/31 20:14:55 eeh Exp $ */ /* * Copyright (c) 1996-1999 Eduardo Horvath * Copyright (c) 1996 Paul Kranenburg @@ -2173,12 +2173,13 @@ dmmu_write_fault: brz,pn %g4, winfix ! NULL entry? check somewhere else add %g5, %g4, %g6 DLFLUSH(%g6,%g5) +1: ldxa [%g6] ASI_PHYS_CACHED, %g4 DLFLUSH2(%g5) brgez,pn %g4, winfix ! Entry invalid? Punt btst TTE_REAL_W|TTE_W, %g4 ! Is it a ref fault? bz,pn %xcc, winfix ! No -- really fault - or %g4, TTE_MODIFY|TTE_ACCESS|TTE_W, %g4 ! Update the modified bit + or %g4, TTE_MODIFY|TTE_ACCESS|TTE_W, %g7 ! Update the modified bit #ifdef DEBUG /* Make sure we don't try to replace a kernel translation */ @@ -2198,7 +2199,10 @@ dmmu_write_fault: ldxa [%g0] ASI_DMMU_8KPTR, %g2 ! Load DMMU 8K TSB pointer ldxa [%g0] ASI_DMMU, %g1 ! Hard coded for unified 8K TSB Load DMMU tag target register - stxa %g4, [%g6] ASI_PHYS_CACHED ! and write it out + casxa [%g6] ASI_PHYS_CACHED, %g4, %g7 ! and write it out + cmp %g4, %g7 + bne,pn %xcc, 1b + or %g4, TTE_MODIFY|TTE_ACCESS|TTE_W, %g4 ! Update the modified bit DLFLUSH(%g6, %g6) stx %g1, [%g2] ! Update TSB entry tag stx %g4, [%g2+8] ! Update TSB entry data @@ -2322,11 +2326,15 @@ Ludata_miss: brz,pn %g4, winfix ! NULL entry? check somewhere else add %g5, %g4, %g6 DLFLUSH(%g6,%g5) +1: ldxa [%g6] ASI_PHYS_CACHED, %g4 DLFLUSH2(%g5) brgez,pn %g4, winfix ! Entry invalid? Punt - bset TTE_ACCESS, %g4 ! Update the modified bit - stxa %g4, [%g6] ASI_PHYS_CACHED ! and write it out + or %g4, TTE_ACCESS, %g7 ! Update the modified bit + casxa [%g6] ASI_PHYS_CACHED, %g4, %g7 ! and write it out + cmp %g4, %g7 + bne,pn %xcc, 1b + or %g4, TTE_ACCESS, %g4 ! Update the modified bit DLFLUSH(%g6, %g5) stx %g1, [%g2] ! Update TSB entry tag stx %g4, [%g2+8] ! Update TSB entry data @@ -3266,11 +3274,15 @@ Lutext_miss: brz,pn %g4, textfault ! NULL entry? check somewhere else add %g5, %g4, %g6 DLFLUSH(%g6,%g5) +1: ldxa [%g6] ASI_PHYS_CACHED, %g4 DLFLUSH2(%g5) brgez,pn %g4, textfault - bset TTE_ACCESS, %g4 ! Update accessed bit - stxa %g4, [%g6] ASI_PHYS_CACHED ! and store it + or %g4, TTE_ACCESS, %g7 ! Update accessed bit + casxa [%g6] ASI_PHYS_CACHED, %g4, %g7 ! and store it + cmp %g4, %g7 + bne,pn %xcc, 1b + or %g4, TTE_ACCESS, %g7 ! Update accessed bit DLFLUSH(%g6,%g5) stx %g1, [%g2] ! Update TSB entry tag stx %g4, [%g2+8] ! Update TSB entry data @@ -8486,7 +8498,11 @@ ENTRY(probeget) ! %o0 = addr, %o1 = asi, %o4 = (1,2,4) sethi %hi(CPCB), %o2 LDPTR [%o2 + %lo(CPCB)], %o2 ! cpcb->pcb_onfault = Lfserr; +#ifdef _LP64 + set _C_LABEL(Lfsbail), %o5 +#else set _C_LABEL(Lfsprobe), %o5 +#endif STPTR %o5, [%o2 + PCB_ONFAULT] or %o0, 0x9, %o3 ! if (PHYS_ASI(asi)) { sub %o3, 0x1d, %o3 @@ -9341,11 +9357,13 @@ ENTRY(pseg_get) /* * In 32-bit mode: * - * extern void pseg_set(struct pmap* %o0, vaddr_t addr %o1, int64_t tte %o2:%o3, paddr_t spare %o4:%o5); + * extern void pseg_set(struct pmap* %o0, vaddr_t addr %o1, int64_t tte %o2:%o3, + * paddr_t spare %o4:%o5); * * In 64-bit mode: * - * extern void pseg_set(struct pmap* %o0, vaddr_t addr %o1, int64_t tte %o2, paddr_t spare %o3); + * extern void pseg_set(struct pmap* %o0, vaddr_t addr %o1, int64_t tte %o2, + * paddr_t spare %o3); * * Set a pseg entry to a particular TTE value. Returns 0 on success, 1 if it needs to fill * a pseg, and -1 if the address is in the virtual hole. (NB: nobody in pmap checks for the @@ -9403,6 +9421,7 @@ ENTRY(pseg_set) and %o5, STMASK, %o5 sll %o5, 3, %o5 add %o4, %o5, %o4 +2: DLFLUSH(%o4,%g1) ldxa [%o4] ASI_PHYS_CACHED, %o5 ! Load page directory pointer DLFLUSH2(%g1) @@ -9410,9 +9429,10 @@ ENTRY(pseg_set) brnz,a,pt %o5, 0f ! Null pointer? mov %o5, %o4 brz,pn %o3, 1f ! Have a spare? - nop - stxa %o3, [%o4] ASI_PHYS_CACHED - DLFLUSH(%o4, %o4) + mov %o3, %o5 + casxa [%o4] ASI_PHYS_CACHED, %g0, %o5 + brnz,pn %o5, 2b ! Something changed? + DLFLUSH(%o4, %o5) mov %o3, %o4 clr %o3 ! Mark spare as used 0: @@ -9420,6 +9440,7 @@ ENTRY(pseg_set) and %o5, PDMASK, %o5 sll %o5, 3, %o5 add %o4, %o5, %o4 +2: DLFLUSH(%o4,%g1) ldxa [%o4] ASI_PHYS_CACHED, %o5 ! Load table directory pointer DLFLUSH2(%g1) @@ -9427,8 +9448,9 @@ ENTRY(pseg_set) brnz,a,pt %o5, 0f ! Null pointer? mov %o5, %o4 brz,pn %o3, 1f ! Have a spare? - nop - stxa %o3, [%o4] ASI_PHYS_CACHED + mov %o3, %o5 + casxa [%o4] ASI_PHYS_CACHED, %g0, %o5 + brnz,pn %o5, 2b ! Something changed? DLFLUSH(%o4, %o4) mov %o3, %o4 clr %o3 ! Mark spare as used @@ -9457,6 +9479,120 @@ ENTRY(pseg_set) retl mov 1, %o0 +/* + * In 32-bit mode: + * + * extern void pseg_find(struct pmap* %o0, vaddr_t addr %o1, + * paddr_t spare %o2:%o3); + * + * In 64-bit mode: + * + * extern void pseg_find(struct pmap* %o0, vaddr_t addr %o1, paddr_t spare %o2); + * + * Get the paddr for a particular TTE entry. Returns the TTE's PA on success, + * 1 if it needs to fill a pseg, and -1 if the address is in the virtual hole. + * (NB: nobody in pmap checks for the virtual hole, so the system will hang.) + * Allocate a page, pass the phys addr in as the spare, and try again. + * If spare is not NULL it is assumed to be the address of a zeroed physical + * page that can be used to generate a directory table or page table if needed. + * + */ +ENTRY(pseg_find) +#ifndef _LP64 + btst 1, %sp ! 64-bit mode? + bnz,pt %icc, 0f + sllx %o2, 32, %o2 ! Shift to high 32-bits + sll %o3, 0, %o3 ! Zero extend + sll %o1, 0, %o1 + or %o2, %o3, %o2 +0: +#endif +#ifdef NOT_DEBUG + !! Trap any changes to pmap_kernel below 0xf0000000 + set _C_LABEL(kernel_pmap_), %o5 + cmp %o0, %o5 + bne 0f + sethi %hi(0xf0000000), %o5 + cmp %o1, %o5 + tlu 1 +0: +#endif + !! + !! However we managed to get here we now have: + !! + !! %o0 = *pmap + !! %o1 = addr + !! %o2 = spare + !! + srax %o1, HOLESHIFT, %o4 ! Check for valid address + brz,pt %o4, 0f ! Should be zero or -1 + inc %o4 ! Make -1 -> 0 + brz,pt %o4, 0f + nop +#ifdef DEBUG + ta 1 ! Break into debugger +#endif + mov -1, %o0 ! Error -- in hole! + retl + mov -1, %o1 +0: + ldx [%o0 + PM_PHYS], %o4 ! pmap->pm_segs + srlx %o1, STSHIFT, %o5 + and %o5, STMASK, %o5 + sll %o5, 3, %o5 + add %o4, %o5, %o4 +2: + DLFLUSH(%o4,%o3) + ldxa [%o4] ASI_PHYS_CACHED, %o5 ! Load page directory pointer + DLFLUSH2(%o3) + + brnz,a,pt %o5, 0f ! Null pointer? + mov %o5, %o4 + brz,pn %o2, 1f ! Have a spare? + mov %o2, %o5 + casxa [%o4] ASI_PHYS_CACHED, %g0, %o5 + brnz,pn %o5, 2b ! Something changed? + DLFLUSH(%o4, %o5) + mov %o2, %o4 + clr %o2 ! Mark spare as used +0: + srlx %o1, PDSHIFT, %o5 + and %o5, PDMASK, %o5 + sll %o5, 3, %o5 + add %o4, %o5, %o4 +2: + DLFLUSH(%o4,%o3) + ldxa [%o4] ASI_PHYS_CACHED, %o5 ! Load table directory pointer + DLFLUSH2(%o3) + + brnz,a,pt %o5, 0f ! Null pointer? + mov %o5, %o4 + brz,pn %o2, 1f ! Have a spare? + mov %o2, %o5 + casxa [%o4] ASI_PHYS_CACHED, %g0, %o5 + brnz,pn %o5, 2b ! Something changed? + DLFLUSH(%o4, %o4) + mov %o2, %o4 + clr %o2 ! Mark spare as used +0: + srlx %o1, PTSHIFT, %o5 ! Convert to ptab offset + btst 1, %sp + and %o5, PTMASK, %o5 + sll %o5, 3, %o5 + bz,pn %icc, 0f ! 64-bit mode? + add %o5, %o4, %o0 + retl + clr %o0 +0: + srl %o0, 0, %o1 + retl ! No, generate a %o0:%o1 double + srlx %o0, 32, %o0 + +1: + retl + mov 1, %o0 + + /* * copywords(src, dst, nbytes) *