patch-2.1.115 linux/arch/sparc64/kernel/dtlb_prot.S
Next file: linux/arch/sparc64/kernel/ebus.c
Previous file: linux/arch/sparc64/kernel/dtlb_miss.S
Back to the patch index
Back to the overall index
- Lines: 114
- Date:
Tue Aug 4 16:03:35 1998
- Orig file:
v2.1.114/linux/arch/sparc64/kernel/dtlb_prot.S
- Orig date:
Thu Apr 23 20:21:31 1998
diff -u --recursive --new-file v2.1.114/linux/arch/sparc64/kernel/dtlb_prot.S linux/arch/sparc64/kernel/dtlb_prot.S
@@ -1,56 +1,62 @@
-/* $Id: dtlb_prot.S,v 1.15 1998/01/14 17:14:46 jj Exp $
- * dtlb_prot.S: Data TLB protection code, this is included directly
- * into the trap table.
+/* $Id: dtlb_prot.S,v 1.17 1998/05/25 16:59:11 davem Exp $
+ * dtlb_prot.S: DTLB protection trap strategy.
+ * This is included directly into the trap table.
*
- * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1996,1998 David S. Miller (davem@dm.cobaltmicro.com)
+ * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz)
*/
- /* We know kernel never takes protection trap,
- * this makes this routine a lot easier than it
- * would be otherwise.
- */
-
-#define MODIFIED_BITS (_PAGE_WRITE | _PAGE_W | _PAGE_MODIFIED | _PAGE_ACCESSED)
-
- /* ICACHE line 1 */
- /*0x00*/ ldxa [%g0] ASI_DMMU, %g1 ! Get TAG_TARGET
- /*0x04*/ srlx %g1, 10, %g3 ! Position PGD offset
- /*0x08*/ and %g1, 0xffe, %g4 ! Mask PMD offset
- /*0x0c*/ and %g3, 0xffc, %g3 ! Mask PGD offset
- /*0x10*/ add %g4, %g4, %g4 ! Position PMD offset
- /*0x14*/ lduwa [%g7 + %g3] ASI_PHYS_USE_EC, %g5 ! Load PGD
- /*0x18*/ lduwa [%g5 + %g4] ASI_PHYS_USE_EC, %g4 ! Load PMD
- /*0x1c*/ ldxa [%g0] ASI_DMMU_TSB_8KB_PTR, %g1 ! For PTE offset
-
- /* ICACHE line 2 */
- /*0x20*/ srlx %g1, 1, %g1 ! PTE offset
- /*0x24*/ ldxa [%g4 + %g1] ASI_PHYS_USE_EC, %g3 ! Load PTE
- /*0x28*/ andcc %g3, _PAGE_WRITE, %g0 ! Writable?
- /*0x2c*/ be,pt %xcc, sparc64_dtlb_prot_catch ! Nope...
- /*0x30*/ or %g3, (MODIFIED_BITS), %g3 ! Yes it is
- /*0x34*/ mov TLB_TAG_ACCESS, %g5 ! Get the page
- /*0x38*/ add %g1, %g4, %g1 ! to get a tmpreg
- /*0x3c*/ ldxa [%g5] ASI_DMMU, %g4 ! From MMU
-
- /* ICACHE line 3 */
- /*0x40*/ mov TLB_SFSR, %g5 ! read SFSR
- /*0x44*/ srlx %g4, 13, %g4 ! Prepare...
- /*0x48*/ ldxa [%g5] ASI_DMMU, %g5 ! from DMMU for
- /*0x4c*/ sllx %g4, 13, %g4 ! ...and mask page
- /*0x50*/ and %g5, 0x10, %g5 ! context bit
- /*0x54*/ or %g4, %g5, %g4 ! for prot trap
-1:/*0x58*/ stxa %g0, [%g4] ASI_DMMU_DEMAP ! TLB flush page
- /*0x5c*/ membar #Sync ! Synchronize
-
- /* ICACHE line 4 */
- /*0x60*/ stxa %g3, [%g1] ASI_PHYS_USE_EC ! Update sw PTE
- /*0x64*/ stxa %g3, [%g0] ASI_DTLB_DATA_IN ! TLB load
- /*0x68*/ retry ! Trap return
- /*0x6c*/ nop
- /*0x70*/ nop
- /*0x74*/ nop
- /*0x78*/ nop
- /*0x7c*/ nop
+#define TAG_CONTEXT_BITS 0x3ff
+#define VPTE_SHIFT (PAGE_SHIFT - 3)
+#define MODIFIED_BITS (_PAGE_WRITE | _PAGE_W | _PAGE_MODIFIED | _PAGE_ACCESSED)
+/* Ways we can get here:
+ *
+ * [TL == 0] 1) User stores to readonly pages.
+ * [TL == 0] 2) Nucleus stores to user readonly pages.
+ * [TL > 0] 3) Nucleus stores to user readonly stack frame.
+ */
+
+/* PROT ** ICACHE line 1: User DTLB protection trap */
+ ldxa [%g1] ASI_DMMU, %g6 ! Primary or Secondary ctx?
+ and %g6, 0x10, %g6 ! Get pri/sec ctx bit
+ stxa %g0, [%g1] ASI_DMMU ! Clear SFSR FaultValid bit
+ membar #Sync ! Synchronize ASI stores
+ ldxa [%g1 + %g1] ASI_DMMU, %g4 ! Load TAG_ACCESS
+ andn %g4, TAG_CONTEXT_BITS, %g4 ! Clear CTX bits
+ stxa %g0, [%g4 + %g6] ASI_DMMU_DEMAP ! Perform TLB flush of page
+ membar #Sync ! Synchronize ASI stores
+
+/* PROT ** ICACHE line 2: Further normal processing */
+ srax %g4, VPTE_SHIFT, %g6 ! Compute VPTE offset
+ ldxa [%g3 + %g6] ASI_S, %g5 ! Load PTE entry
+ andcc %g5, _PAGE_WRITE, %g0 ! Writable page?
+ be,pt %xcc, 1f ! Nope, real fault
+ or %g5, (MODIFIED_BITS), %g5 ! Mark as writable/modified
+ stxa %g5, [%g3 + %g6] ASI_S ! Update PTE entry
+ stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Load PTE into TLB
+ retry ! Trap return
+
+/* PROT ** ICACHE line 3: Real user faults */
+1: rdpr %pstate, %g5 ! Move into alternate globals
+ wrpr %g5, PSTATE_AG|PSTATE_MG, %pstate
+ rdpr %tl, %g4 ! Need to do a winfixup?
+ cmp %g4, 1 ! Trap level >1?
+ mov TLB_TAG_ACCESS, %g4 ! Prepare reload of vaddr
+ bgu,pn %xcc, winfix_trampoline ! Yes, perform winfixup
+ ldxa [%g4] ASI_DMMU, %g5 ! Put tagaccess in %g5
+ sethi %hi(1f), %g7 ! Nope, normal fault
+
+/* PROT ** ICACHE line 4: More real fault processing */
+ ba,pt %xcc, etrap ! Save state
+1: or %g7, %lo(1b), %g7 ! ...
+ ba,pt %xcc, sparc64_realfault_continue! Now call the fault handler
+ mov 1, %o2 ! Indicate this was a write
+ nop
+ nop
+ nop
+ nop
+
+#undef TAG_CONTEXT_BITS
+#undef VPTE_SHIFT
#undef MODIFIED_BITS
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov