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);
}