Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sh3/sh3 sh4_tlb_invalidate_addr - refactor to avoid...
details: https://anonhg.NetBSD.org/src/rev/5fceb40fa71a
branches: trunk
changeset: 936989:5fceb40fa71a
user: uwe <uwe%NetBSD.org@localhost>
date: Mon Aug 03 22:28:39 2020 +0000
description:
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.
diffstat:
sys/arch/sh3/sh3/mmu_sh4.c | 74 +++++++++++++++++++++++++++------------------
1 files changed, 45 insertions(+), 29 deletions(-)
diffs (136 lines):
diff -r fe4bf4e8338c -r 5fceb40fa71a sys/arch/sh3/sh3/mmu_sh4.c
--- a/sys/arch/sh3/sh3/mmu_sh4.c Mon Aug 03 21:53:25 2020 +0000
+++ b/sys/arch/sh3/sh3/mmu_sh4.c Mon Aug 03 22:28:39 2020 +0000
@@ -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 @@
#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_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();
-
- /* Save current ASID */
- pteh = _reg_read_4(SH4_PTEH);
- /* Set ASID for associative write */
- _reg_write_4(SH4_PTEH, asid);
+ opteh = _reg_read_4(SH4_PTEH); /* save current 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 @@
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);
+ tlb_assoc_p2 = SH3_P2SEG_FUNC(__sh4_tlb_assoc);
+
sr = _cpu_exception_suspend();
- /* Save old ASID */
- oasid = _reg_read_4(SH4_PTEH) & SH4_PTEH_ASID_MASK;
+ opteh = _reg_read_4(SH4_PTEH); /* save old ASID */
- /* Invalidate old entry (if any) */
- sh4_tlb_invalidate_addr(asid, va);
+ /*
+ * 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);
- _reg_write_4(SH4_PTEH, asid);
- /* Load new entry */
- _reg_write_4(SH4_PTEH, (va & ~PGOFSET) | asid);
+ /* 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);
}
Home |
Main Index |
Thread Index |
Old Index