summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-03-04 19:39:06 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-03-04 19:39:06 +0000
commit116be10bad8d35ab75adc174ebc567fab484e9ca (patch)
treeeb056fdfac207df16fd57a4b2dd146a933330c81 /sys
parentce7eb9bc42780d9563daa8f7713629c83fdb6d98 (diff)
Since 88110 processors can not flush individual TLB entries, instead of
flushing the whole TLB block every time a pte is modified, store a bitmask of pending flushes and do them at pmap_update() time. 88100 behaviour is unchanged.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/m88k/include/cpu.h5
-rw-r--r--sys/arch/m88k/include/pmap.h6
-rw-r--r--sys/arch/m88k/m88k/pmap.c76
3 files changed, 71 insertions, 16 deletions
diff --git a/sys/arch/m88k/include/cpu.h b/sys/arch/m88k/include/cpu.h
index 90dec8e0e56..1f6a8d82b98 100644
--- a/sys/arch/m88k/include/cpu.h
+++ b/sys/arch/m88k/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.44 2009/02/21 18:37:47 miod Exp $ */
+/* $OpenBSD: cpu.h,v 1.45 2009/03/04 19:39:02 miod Exp $ */
/*
* Copyright (c) 1996 Nivas Madhur
* Copyright (c) 1992, 1993
@@ -115,6 +115,8 @@ struct cpu_info {
u_int ci_cpudep3;
u_int ci_cpudep4;
u_int ci_cpudep5;
+ u_int ci_cpudep6;
+ u_int ci_cpudep7;
/* 88100 fields */
#define ci_pfsr_i0 ci_cpudep0 /* instruction... */
@@ -129,6 +131,7 @@ struct cpu_info {
#define ci_h_epsr ci_cpudep3 /* for hardclock */
#define ci_s_sxip ci_cpudep4 /* and softclock */
#define ci_s_epsr ci_cpudep5
+#define ci_pmap_ipi ci_cpudep6 /* delayed pmap tlb ipi */
struct schedstate_percpu
ci_schedstate; /* scheduling state */
diff --git a/sys/arch/m88k/include/pmap.h b/sys/arch/m88k/include/pmap.h
index 3e6eef03375..bafd1b2f303 100644
--- a/sys/arch/m88k/include/pmap.h
+++ b/sys/arch/m88k/include/pmap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.h,v 1.12 2007/12/25 00:48:51 miod Exp $ */
+/* $OpenBSD: pmap.h,v 1.13 2009/03/04 19:39:02 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1991 Carnegie Mellon University
@@ -57,7 +57,9 @@ extern caddr_t vmmap;
#define pmap_phys_address(frame) ((paddr_t)(ptoa(frame)))
#define pmap_copy(dp,sp,d,l,s) do { /* nothing */ } while (0)
-#define pmap_update(pmap) do { /* nothing (yet) */ } while (0)
+#if !defined(M88110)
+#define pmap_update(pmap) do { /* nothing */ } while (0)
+#endif
#define pmap_clear_modify(pg) pmap_unsetbit(pg, PG_M)
#define pmap_clear_reference(pg) pmap_unsetbit(pg, PG_U)
diff --git a/sys/arch/m88k/m88k/pmap.c b/sys/arch/m88k/m88k/pmap.c
index beb668556a5..bb5e67bc9d3 100644
--- a/sys/arch/m88k/m88k/pmap.c
+++ b/sys/arch/m88k/m88k/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.45 2008/06/14 10:55:20 mk Exp $ */
+/* $OpenBSD: pmap.c,v 1.46 2009/03/04 19:39:05 miod Exp $ */
/*
* Copyright (c) 2001-2004, Miodrag Vallat
* Copyright (c) 1998-2001 Steve Murphree, Jr.
@@ -160,7 +160,7 @@ vaddr_t kmapva = 0;
/*
* Internal routines
*/
-static void flush_atc_entry(pmap_t, vaddr_t);
+void flush_atc_entry(pmap_t, vaddr_t);
pt_entry_t *pmap_expand_kmap(vaddr_t, vm_prot_t, int);
void pmap_remove_pte(pmap_t, vaddr_t, pt_entry_t *, boolean_t);
void pmap_remove_range(pmap_t, vaddr_t, vaddr_t);
@@ -195,32 +195,82 @@ boolean_t pmap_testbit(struct vm_page *, int);
* pmap affected pmap
* va virtual address that should be flushed
*/
-static
-#ifndef MULTIPROCESSOR
-__inline__
-#endif
void
flush_atc_entry(pmap_t pmap, vaddr_t va)
{
-#ifdef MULTIPROCESSOR
u_int32_t users;
- int cpu;
boolean_t kernel;
if ((users = pmap->pm_cpus) == 0)
return;
kernel = pmap == kernel_pmap;
- while ((cpu = ff1(users)) != 32) {
- cmmu_flush_tlb(cpu, kernel, va, 1);
- users ^= 1 << cpu;
+
+#ifdef MULTIPROCESSOR
+ /*
+ * On 88100, we take action immediately.
+ */
+ if (CPU_IS88100) {
+ int cpu;
+
+ while ((cpu = ff1(users)) != 32) {
+ cmmu_flush_tlb(cpu, kernel, va, 1);
+ users ^= 1 << cpu;
+ }
+ }
+
+ /*
+ * On 88110, we only remember which tlb need to be invalidated,
+ * and wait for pmap_update() to do it.
+ */
+ if (CPU_IS88110) {
+ struct cpu_info *ci;
+ CPU_INFO_ITERATOR cpu;
+
+ CPU_INFO_FOREACH(cpu, ci) {
+ if (ISSET(users, 1 << ci->ci_cpuid))
+ ci->ci_pmap_ipi |= kernel ?
+ CI_IPI_TLB_FLUSH_KERNEL :
+ CI_IPI_TLB_FLUSH_USER;
+ }
}
#else /* MULTIPROCESSOR */
- if (pmap->pm_cpus != 0)
- cmmu_flush_tlb(cpu_number(), pmap == kernel_pmap, va, 1);
+ if (CPU_IS88100)
+ cmmu_flush_tlb(cpu_number(), kernel, va, 1);
+ if (CPU_IS88110)
+ curcpu()->ci_pmap_ipi |= kernel ?
+ CI_IPI_TLB_FLUSH_KERNEL : CI_IPI_TLB_FLUSH_USER;
#endif /* MULTIPROCESSOR */
}
+#ifdef M88110
+void
+pmap_update(pmap_t pm)
+{
+ /*
+ * Time to perform all necessary TLB invalidations.
+ */
+ if (CPU_IS88110) {
+ u_int ipi;
+#ifdef MULTIPROCESSOR
+ struct cpu_info *ci;
+ CPU_INFO_ITERATOR cpu;
+
+ CPU_INFO_FOREACH(cpu, ci)
+#else
+ struct cpu_info *ci = curcpu();
+#endif
+ /* CPU_INFO_FOREACH(cpu, ci) */ {
+ ipi = atomic_clear_int(&ci->ci_pmap_ipi);
+ if (ipi & CI_IPI_TLB_FLUSH_KERNEL)
+ cmmu_flush_tlb(ci->ci_cpuid, TRUE, 0 ,0);
+ if (ipi & CI_IPI_TLB_FLUSH_USER)
+ cmmu_flush_tlb(ci->ci_cpuid, FALSE, 0 ,0);
+ }
+ }
+}
+#endif
+
/*
* Routine: PMAP_PTE
*