Module Name:    src
Committed By:   uwe
Date:           Mon Aug  3 22:28:39 UTC 2020

Modified Files:
        src/sys/arch/sh3/sh3: mmu_sh4.c

Log Message:
sh4_tlb_invalidate_addr - refactor to avoid RUN_P2.

Introduce __sh4_tlb_assoc that performs the associative write.  Call
it from sh4_tlb_invalidate_addr.  In sh4_tlb_update do not call
sh4_tlb_invalidate_addr, call __sh4_tlb_assoc directly.  We need to do
the song and dance to block exceptions and set PTEH anyway for the new
value, so don't waste all that effort.


To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/sh3/sh3/mmu_sh4.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/sh3/sh3/mmu_sh4.c
diff -u src/sys/arch/sh3/sh3/mmu_sh4.c:1.17 src/sys/arch/sh3/sh3/mmu_sh4.c:1.18
--- src/sys/arch/sh3/sh3/mmu_sh4.c:1.17	Mon Aug  3 19:24:28 2020
+++ src/sys/arch/sh3/sh3/mmu_sh4.c	Mon Aug  3 22:28:39 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: mmu_sh4.c,v 1.17 2020/08/03 19:24:28 uwe Exp $	*/
+/*	$NetBSD: mmu_sh4.c,v 1.18 2020/08/03 22:28:39 uwe Exp $	*/
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mmu_sh4.c,v 1.17 2020/08/03 19:24:28 uwe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mmu_sh4.c,v 1.18 2020/08/03 22:28:39 uwe Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -39,6 +39,8 @@ __KERNEL_RCSID(0, "$NetBSD: mmu_sh4.c,v 
 #include <sh3/mmu.h>
 #include <sh3/mmu_sh4.h>
 
+static __noinline void __sh4_tlb_assoc(uint32_t);
+
 #define	SH4_MMU_HAZARD	__asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;")
 
 /* Must be inlined because we "call" it while running on P2 */
@@ -77,30 +79,43 @@ sh4_mmu_start(void)
 	SH4_MMU_HAZARD;
 }
 
+
+/*
+ * Perform associative write to UTLB.  Must be called via its P2
+ * address.  Note, the ASID match is against PTEH, not "va".  The
+ * caller is responsible for saving/setting/restoring PTEH.
+ */
+static __noinline void
+__sh4_tlb_assoc(uint32_t va)
+{
+
+	_reg_write_4(SH4_UTLB_AA | SH4_UTLB_A, va);
+	PAD_P1_SWITCH;
+}
+
+
 void
 sh4_tlb_invalidate_addr(int asid, vaddr_t va)
 {
-	uint32_t pteh;
-	int sr;
+	void (*tlb_assoc_p2)(uint32_t);
+	uint32_t opteh;
+	uint32_t sr;
+
+	tlb_assoc_p2 = SH3_P2SEG_FUNC(__sh4_tlb_assoc);
 
 	va &= SH4_UTLB_AA_VPN_MASK;
+
 	sr = _cpu_exception_suspend();
+	opteh = _reg_read_4(SH4_PTEH); /* save current ASID */
 
-	/* Save current ASID */
-	pteh = _reg_read_4(SH4_PTEH);
-	/* Set ASID for associative write */
-	_reg_write_4(SH4_PTEH, asid);
-
-	/* Associative write(UTLB/ITLB). not required ITLB invalidate. */
-	RUN_P2;
-	_reg_write_4(SH4_UTLB_AA | SH4_UTLB_A, va); /* Clear D, V */
-	RUN_P1;
-	/* Restore ASID */
-	_reg_write_4(SH4_PTEH, pteh);
+	_reg_write_4(SH4_PTEH, asid); /* set ASID for associative write */
+	(*tlb_assoc_p2)(va); /* invalidate { va, ASID } entry if exists */
 
+	_reg_write_4(SH4_PTEH, opteh); /* restore ASID */
 	_cpu_set_sr(sr);
 }
 
+
 void
 sh4_tlb_invalidate_asid(int asid)
 {
@@ -151,36 +166,37 @@ sh4_tlb_invalidate_all(void)
 void
 sh4_tlb_update(int asid, vaddr_t va, uint32_t pte)
 {
-	uint32_t oasid;
-	uint32_t ptel;
-	int sr;
+	void (*tlb_assoc_p2)(uint32_t);
+	uint32_t opteh, ptel;
+	uint32_t sr;
 
 	KDASSERT(asid < 0x100);
 	KDASSERT(va != 0);
 	KDASSERT((pte & ~PGOFSET) != 0);
 
-	sr = _cpu_exception_suspend();
-	/* Save old ASID */
-	oasid = _reg_read_4(SH4_PTEH) & SH4_PTEH_ASID_MASK;
+	tlb_assoc_p2 = SH3_P2SEG_FUNC(__sh4_tlb_assoc);
 
-	/* Invalidate old entry (if any) */
-	sh4_tlb_invalidate_addr(asid, va);
+	sr = _cpu_exception_suspend();
+	opteh = _reg_read_4(SH4_PTEH); /* save old ASID */
 
-	_reg_write_4(SH4_PTEH, asid);
-	/* Load new entry */
+	/*
+	 * Invalidate { va, ASID } entry if exists.  Only ASID is
+	 * matched in PTEH, but set the va part too for ldtlb below.
+	 */
 	_reg_write_4(SH4_PTEH, (va & ~PGOFSET) | asid);
+	(*tlb_assoc_p2)(va & SH4_UTLB_AA_VPN_MASK);
+
+	/* Load new entry (PTEH is already set) */
 	ptel = pte & PG_HW_BITS;
+	_reg_write_4(SH4_PTEL, ptel);
 	if (pte & _PG_PCMCIA) {
 		_reg_write_4(SH4_PTEA,
 		    (pte >> _PG_PCMCIA_SHIFT) & SH4_PTEA_SA_MASK);
 	} else {
 		_reg_write_4(SH4_PTEA, 0);
 	}
-	_reg_write_4(SH4_PTEL, ptel);
 	__asm volatile("ldtlb; nop");
 
-	/* Restore old ASID */
-	if (asid != oasid)
-		_reg_write_4(SH4_PTEH, oasid);
+	_reg_write_4(SH4_PTEH, opteh); /* restore old ASID */
 	_cpu_set_sr(sr);
 }

Reply via email to