diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-03-04 19:39:06 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-03-04 19:39:06 +0000 |
commit | 116be10bad8d35ab75adc174ebc567fab484e9ca (patch) | |
tree | eb056fdfac207df16fd57a4b2dd146a933330c81 /sys | |
parent | ce7eb9bc42780d9563daa8f7713629c83fdb6d98 (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.h | 5 | ||||
-rw-r--r-- | sys/arch/m88k/include/pmap.h | 6 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/pmap.c | 76 |
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 * |