Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc64/sparc64 sun4v: Add handling of trap 0x06c @...
details: https://anonhg.NetBSD.org/src/rev/201c35dada1d
branches: trunk
changeset: 353058:201c35dada1d
user: palle <palle%NetBSD.org@localhost>
date: Tue Apr 18 20:02:50 2017 +0000
description:
sun4v: Add handling of trap 0x06c @ trap level 1 - based on code from OpenBSD, but slightly adapted to NetBSD. verified using qemu
diffstat:
sys/arch/sparc64/sparc64/locore.s | 263 ++++++++++++++++++++++++++++++++++++-
1 files changed, 256 insertions(+), 7 deletions(-)
diffs (truncated from 313 to 300 lines):
diff -r 2c2a6c35dbbb -r 201c35dada1d sys/arch/sparc64/sparc64/locore.s
--- a/sys/arch/sparc64/sparc64/locore.s Tue Apr 18 19:41:27 2017 +0000
+++ b/sys/arch/sparc64/sparc64/locore.s Tue Apr 18 20:02:50 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.s,v 1.409 2017/02/19 18:25:45 palle Exp $ */
+/* $NetBSD: locore.s,v 1.410 2017/04/18 20:02:50 palle Exp $ */
/*
* Copyright (c) 2006-2010 Matthew R. Green
@@ -1102,7 +1102,7 @@
HARDINT4V(14) ! 0x04e = level 14 interrupt
HARDINT4V(15) ! 0x04f = level 15 interrupt
sun4v_trap_entry 28 ! 0x050-0x06b
- VTRAP(T_FDMMU_PROT, sun4v_tl0_dtsb_prot) ! 0x6c
+ VTRAP(T_FDMMU_PROT, sun4v_tl0_dtsb_prot) ! 0x06c
sun4v_trap_entry 15 ! 0x06d-0x07b
VTRAP(T_CPU_MONDO, sun4v_cpu_mondo) ! 0x07c = cpu mondo
VTRAP(T_DEV_MONDO, sun4v_dev_mondo) ! 0x07d = dev mondo
@@ -1149,7 +1149,9 @@
CLEANWIN1 ! 0x24-0x27 = clean window
sun4v_trap_entry 9 ! 0x028-0x030
VTRAP(T_DATA_MMU_MISS, sun4v_dtsb_miss) ! 0x031 = data MMU miss
- sun4v_trap_entry 78 ! 0x032-0x07f
+ sun4v_trap_entry 58 ! 0x032-0x06b
+ VTRAP(T_FDMMU_PROT, sun4v_tl1_dtsb_prot) ! 0x06c
+ sun4v_trap_entry 19 ! 0x06d-0x07f
SPILL64(uspill8_sun4vt1,ASI_AIUS) ! 0x080 spill_0_normal -- save user windows
SPILL32(uspill4_sun4vt1,ASI_AIUS) ! 0x084 spill_1_normal
SPILLBOTH(uspill8_sun4vt1,uspill4_sun4vt1,ASI_AIUS) ! 0x088 spill_2_normal
@@ -2952,8 +2954,7 @@
1:
LDPTRA [%g6] ASI_PHYS_CACHED, %g4 ! Fetch TTE
brgez,pn %g4, sun4v_datatrap ! Entry invalid? Punt
- or %g4, SUN4V_TLB_MODIFY|SUN4V_TLB_ACCESS|SUN4V_TLB_W, %g7
- ! Update the modified bit
+ or %g4, SUN4V_TLB_MODIFY|SUN4V_TLB_ACCESS|SUN4V_TLB_W, %g7 ! Update the modified bit
# btst SUN4V_TLB_REAL_W|SUN4V_TLB_W, %g4 ! Is it a ref fault?
mov 1, %g2
@@ -2965,8 +2966,7 @@
casxa [%g6] ASI_PHYS_CACHED, %g4, %g7 ! and write it out
cmp %g4, %g7
bne,pn %xcc, 1b
- or %g4, SUN4V_TLB_MODIFY|SUN4V_TLB_ACCESS|SUN4V_TLB_W, %g4
- ! Update the modified bit
+ or %g4, SUN4V_TLB_MODIFY|SUN4V_TLB_ACCESS|SUN4V_TLB_W, %g4 ! Update the modified bit
2:
GET_TSB_DMMU %g2
@@ -3146,6 +3146,253 @@
nop
NOTREACHED
+sun4v_tl1_dtsb_prot:
+ GET_MMFSA %g1 ! MMU Fault status area
+ add %g1, 0x48, %g3
+ LDPTRA [%g3] ASI_PHYS_CACHED, %g3 ! Data fault address
+ add %g1, 0x50, %g6
+ LDPTRA [%g6] ASI_PHYS_CACHED, %g6 ! Data fault context
+
+ GET_CTXBUSY %g4
+ sllx %g6, 3, %g6 ! Make it into an offset into ctxbusy
+ LDPTR [%g4 + %g6], %g4 ! Load up our page table.
+
+ srax %g3, HOLESHIFT, %g5 ! Check for valid address
+ brz,pt %g5, 0f ! Should be zero or -1
+ inc %g5 ! Make -1 -> 0
+ brnz,pn %g5, sun4v_tl1_ptbl_miss ! Error! In hole!
+0:
+ srlx %g3, STSHIFT, %g6
+ and %g6, STMASK, %g6 ! Index into pm_segs
+ sll %g6, 3, %g6
+ add %g4, %g6, %g4
+ LDPTRA [%g4] ASI_PHYS_CACHED, %g4 ! Load page directory pointer
+
+ srlx %g3, PDSHIFT, %g6
+ and %g6, PDMASK, %g6
+ sll %g6, 3, %g6
+ brz,pn %g4, sun4v_tl1_ptbl_miss ! NULL entry? check somewhere else
+ add %g4, %g6, %g4
+ LDPTRA [%g4] ASI_PHYS_CACHED, %g4 ! Load page table pointer
+
+ srlx %g3, PTSHIFT, %g6 ! Convert to ptab offset
+ and %g6, PTMASK, %g6
+ sll %g6, 3, %g6
+ brz,pn %g4, sun4v_tl1_ptbl_miss ! NULL entry? check somewhere else
+ add %g4, %g6, %g6
+1:
+ LDPTRA [%g6] ASI_PHYS_CACHED, %g4 ! Fetch TTE
+ brgez,pn %g4, sun4v_tl1_ptbl_miss ! Entry invalid? Punt
+ or %g4, SUN4V_TLB_MODIFY|SUN4V_TLB_ACCESS|SUN4V_TLB_W, %g7 ! Update the modified bit
+
+# btst SUN4V_TLB_REAL_W|SUN4V_TLB_W, %g4 ! Is it a ref fault?
+ mov 1, %g2
+ sllx %g2, 61, %g2
+ or %g2, SUN4V_TLB_W, %g2
+ btst %g2, %g4
+ bz,pn %xcc, sun4v_tl1_ptbl_miss ! No -- really fault
+ nop
+ casxa [%g6] ASI_PHYS_CACHED, %g4, %g7 ! and write it out
+ cmp %g4, %g7
+ bne,pn %xcc, 1b
+ or %g4, SUN4V_TLB_MODIFY|SUN4V_TLB_ACCESS|SUN4V_TLB_W, %g4 ! Update the modified bit
+2:
+ GET_TSB_DMMU %g2
+
+ mov %g1, %g7 ! save MMFSA
+
+ /* Construct TSB tag word. */
+ add %g1, 0x50, %g6
+ LDPTRA [%g6] ASI_PHYS_CACHED, %g6 ! Data fault context
+ mov %g3, %g1 ! Data fault address
+ srlx %g1, 22, %g1 ! 63..22 of virt addr
+ sllx %g6, 48, %g6 ! context_id in 63..48
+ or %g1, %g6, %g1 ! construct TTE tag
+
+ srlx %g3, PTSHIFT, %g3
+ sethi %hi(_C_LABEL(tsbsize)), %g5
+ mov 512, %g6
+ ld [%g5 + %lo(_C_LABEL(tsbsize))], %g5
+ sllx %g6, %g5, %g5 ! %g5 = 512 << tsbsize = TSBENTS
+ sub %g5, 1, %g5 ! TSBENTS -> offset
+ and %g3, %g5, %g3 ! mask out TTE index
+ sllx %g3, 4, %g3 ! TTE size is 16 bytes
+ add %g2, %g3, %g2 ! location of TTE in ci_tsb_dmmu
+
+ membar #StoreStore
+
+ STPTR %g4, [%g2 + 8] ! store TTE data
+ STPTR %g1, [%g2] ! store TTE tag
+
+ mov %o0, %g1
+ mov %o1, %g2
+ mov %o2, %g3
+
+ add %g7, 0x48, %o0
+ ldxa [%o0] ASI_PHYS_CACHED, %o0 ! Data fault address
+ add %g7, 0x50, %o1
+ ldxa [%o1] ASI_PHYS_CACHED, %o1 ! Data fault context
+ mov MAP_DTLB, %o2
+ ta ST_MMU_UNMAP_ADDR
+
+ mov %g1, %o0
+ mov %g2, %o1
+ mov %g3, %o2
+
+ retry
+ NOTREACHED
+
+sun4v_tl1_ptbl_miss:
+ rdpr %tpc, %g1
+
+ set rft_user_fault_start, %g2
+ cmp %g1, %g2
+ blu,pt %xcc, 1f
+ set rft_user_fault_end, %g2
+ cmp %g1, %g2
+ bgeu,pt %xcc, 1f
+ nop
+
+ /* Fixup %cwp. */
+ rdpr %cwp, %g1
+ inc %g1
+ wrpr %g1, %cwp
+
+ rdpr %tt, %g1
+ wrpr 1, %tl
+ wrpr %g1, %tt
+ rdpr %cwp, %g1
+ set TSTATE_KERN, %g2
+ wrpr %g1, %g2, %tstate
+ set return_from_trap, %g1
+ wrpr %g1, %tpc
+ add %g1, 4, %g1
+ wrpr %g1, %tnpc
+ wrpr %g0, 1, %gl
+
+ ba,pt %xcc, sun4v_datatrap
+ wrpr WSTATE_KERN, %wstate
+
+1:
+ rdpr %tstate, %g3
+ rdpr %tt, %g4
+
+ rdpr %tl, %g1
+ dec %g1
+ wrpr %g1, %tl
+ rdpr %tt, %g2
+ inc %g1
+ wrpr %g1, %tl
+
+ wrpr %g0, %g3, %tstate
+ wrpr %g0, %g4, %tt
+
+ andn %g2, 0x00f, %g3
+ cmp %g3, 0x080
+ be,pn %icc, flush_normals
+ nop
+ cmp %g3, 0x0a0
+ be,pn %icc, flush_others
+ nop
+ cmp %g3, 0x0c0
+ be,pn %icc, ufill_trap
+ nop
+
+ Debugger()
+ NOTREACHED
+
+flush_others:
+ set pcbspill_others, %g1
+ wrpr %g1, %tnpc
+ done
+ NOTREACHED
+
+flush_normals:
+ufill_trap:
+
+ /*
+ * Rearrange our trap state such that it appears as if we got
+ * this trap directly from user mode. Then process it at TL = 1.
+ * We'll take the spill/fill trap again once we return to user mode.
+ */
+ rdpr %tt, %g1
+ rdpr %tstate, %g3
+ wrpr %g0, 1, %tl
+ wrpr %g0, %g1, %tt
+ rdpr %tstate, %g2
+ wrpr %g0, 2, %tl
+ and %g2, TSTATE_CWP, %g2
+ andn %g3, TSTATE_CWP, %g3
+ wrpr %g2, %g3, %tstate
+ set sun4v_datatrap, %g4
+ wrpr %g0, %g4, %tnpc
+ done
+
+/*
+ * Spill user windows into the PCB.
+ */
+pcbspill_normals:
+ ba,pt %xcc, pcbspill
+ wrpr 0x80, %tt
+
+pcbspill_others:
+ wrpr 0xa0, %tt
+
+pcbspill:
+ set CPUINFO_VA, %g6
+ ldx [%g6 + CI_CPCB], %g6
+
+ GET_CTXBUSY %g1
+
+ ldx [%g1], %g1 ! kernel pmap is ctx 0
+
+ srlx %g6, STSHIFT, %g7
+ and %g7, STMASK, %g7
+ sll %g7, 3, %g7 ! byte offset into ctxbusy
+ add %g7, %g1, %g1
+ ldxa [%g1] ASI_PHYS_CACHED, %g1 ! Load pointer to directory
+
+ srlx %g6, PDSHIFT, %g7 ! Do page directory
+ and %g7, PDMASK, %g7
+ sll %g7, 3, %g7
+ brz,pn %g1, pcbspill_fail
+ add %g7, %g1, %g1
+ ldxa [%g1] ASI_PHYS_CACHED, %g1
+ srlx %g6, PTSHIFT, %g7 ! Convert to ptab offset
+ and %g7, PTMASK, %g7
+ brz %g1, pcbspill_fail
+ sll %g7, 3, %g7
+ add %g1, %g7, %g7
+ ldxa [%g7] ASI_PHYS_CACHED, %g7 ! This one is not
+ brgez %g7, pcbspill_fail
+ srlx %g7, PGSHIFT, %g7 ! Isolate PA part
+ sll %g6, 32-PGSHIFT, %g6 ! And offset
+ sllx %g7, PGSHIFT+8, %g7 ! There are 8 bits to the left of the PA in the TTE
+ srl %g6, 32-PGSHIFT, %g6
+ srax %g7, 8, %g7
+ or %g7, %g6, %g6 ! Then combine them to form PA
+
+ wr %g0, ASI_PHYS_CACHED, %asi ! Use ASI_PHYS_CACHED to prevent possible page faults
+
+ lduba [%g6 + PCB_NSAVED] %asi, %g7
+ sllx %g7, 7, %g5
+ add %g6, %g5, %g5
+ SPILL stxa, %g5 + PCB_RW, 8, %asi
+ saved
+
+ sllx %g7, 3, %g5
+ add %g6, %g5, %g5
+
+ inc %g7
+ stba %g7, [%g6 + PCB_NSAVED] %asi
+
+ retry
+ NOTREACHED
+
+pcbspill_fail:
+ Debugger()
+ NOTREACHED
+
Home |
Main Index |
Thread Index |
Old Index