summaryrefslogtreecommitdiff
path: root/sys/arch/m88k
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2013-11-16 18:45:21 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2013-11-16 18:45:21 +0000
commit431731812874189793edce7ce2b5f568e44fc441 (patch)
tree058097d595daf7e32527caa82bd09f6d039eab6a /sys/arch/m88k
parent240cdcbabc5239b94c9488aacdae734862dff715 (diff)
Allow initial device mappings (from pmap_table) to be backed up by BATC.
Use this on luna88k to map the bitmap planes of the frame buffer used by the driver. 10% speedup under X.
Diffstat (limited to 'sys/arch/m88k')
-rw-r--r--sys/arch/m88k/include/cmmu.h10
-rw-r--r--sys/arch/m88k/include/mmu.h30
-rw-r--r--sys/arch/m88k/include/pmap_table.h3
-rw-r--r--sys/arch/m88k/m88k/m8820x_machdep.c25
-rw-r--r--sys/arch/m88k/m88k/pmap.c176
5 files changed, 193 insertions, 51 deletions
diff --git a/sys/arch/m88k/include/cmmu.h b/sys/arch/m88k/include/cmmu.h
index c0b41465b4f..65a2aa2b19c 100644
--- a/sys/arch/m88k/include/cmmu.h
+++ b/sys/arch/m88k/include/cmmu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmmu.h,v 1.31 2013/11/02 23:10:30 miod Exp $ */
+/* $OpenBSD: cmmu.h,v 1.32 2013/11/16 18:45:20 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1993-1992 Carnegie Mellon University
@@ -33,6 +33,8 @@
*/
#if defined(_KERNEL) && !defined(_LOCORE)
+#include <machine/mmu.h>
+
/* machine dependent cmmu function pointer structure */
struct cmmu_p {
cpuid_t (*init)(void);
@@ -107,6 +109,12 @@ extern __cpu_simple_lock_t cmmu_cpu_lock;
#define DMA_CACHE_SYNC_INVAL 0x01
#define DMA_CACHE_SYNC 0x02
+/*
+ * Current BATC values.
+ */
+
+extern batc_t global_dbatc[BATC_MAX], global_ibatc[BATC_MAX];
+
#endif /* _KERNEL && !_LOCORE */
#endif /* _M88K_CMMU_H_ */
diff --git a/sys/arch/m88k/include/mmu.h b/sys/arch/m88k/include/mmu.h
index fddbed446c1..14cdb63a5e4 100644
--- a/sys/arch/m88k/include/mmu.h
+++ b/sys/arch/m88k/include/mmu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mmu.h,v 1.14 2013/11/02 23:10:30 miod Exp $ */
+/* $OpenBSD: mmu.h,v 1.15 2013/11/16 18:45:20 miod Exp $ */
/*
* This file bears almost no resemblance to the original m68k file,
@@ -76,7 +76,7 @@
* Area descriptors
*/
-typedef u_int32_t apr_t;
+typedef uint32_t apr_t;
#define APR_V 0x00000001 /* valid bit */
@@ -87,21 +87,10 @@ typedef u_int32_t apr_t;
#define PATC_ENTRIES 56
/*
- * BATC entries
- */
-
-#define BATC_V 0x00000001
-#define BATC_PROT 0x00000002
-#define BATC_INH 0x00000004
-#define BATC_GLOBAL 0x00000008
-#define BATC_WT 0x00000010
-#define BATC_SO 0x00000020
-
-/*
* Segment table entries
*/
-typedef u_int32_t sdt_entry_t;
+typedef uint32_t sdt_entry_t;
#define SG_V 0x00000001
#define SG_NV 0x00000000
@@ -118,7 +107,7 @@ typedef u_int32_t sdt_entry_t;
* Page table entries
*/
-typedef u_int32_t pt_entry_t;
+typedef uint32_t pt_entry_t;
#define PG_V 0x00000001
#define PG_NV 0x00000000
@@ -165,9 +154,18 @@ typedef u_int32_t pt_entry_t;
#define PDTIDX(va) (((va) & PDT_MASK) >> PDT_SHIFT)
/*
- * Parameters and macros for BATC
+ * BATC entries
*/
+#define BATC_V 0x00000001
+#define BATC_PROT 0x00000002
+#define BATC_INH 0x00000004
+#define BATC_GLOBAL 0x00000008
+#define BATC_WT 0x00000010
+#define BATC_SO 0x00000020
+
+typedef uint32_t batc_t;
+
/* 8820x fixed size BATC */
#define BATC_BLKSHIFT 19
#define BATC_BLKBYTES (1 << BATC_BLKSHIFT)
diff --git a/sys/arch/m88k/include/pmap_table.h b/sys/arch/m88k/include/pmap_table.h
index b44097ae7b2..b3a987d4633 100644
--- a/sys/arch/m88k/include/pmap_table.h
+++ b/sys/arch/m88k/include/pmap_table.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap_table.h,v 1.4 2011/03/23 16:54:35 pirofti Exp $ */
+/* $OpenBSD: pmap_table.h,v 1.5 2013/11/16 18:45:20 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1992 Carnegie Mellon University
@@ -38,6 +38,7 @@ struct pmap_table {
psize_t size;
vm_prot_t prot;
unsigned int cacheability;
+ boolean_t may_use_batc;
};
const struct pmap_table *pmap_table_build(void);
diff --git a/sys/arch/m88k/m88k/m8820x_machdep.c b/sys/arch/m88k/m88k/m8820x_machdep.c
index 90cf25c5480..32bec51eae8 100644
--- a/sys/arch/m88k/m88k/m8820x_machdep.c
+++ b/sys/arch/m88k/m88k/m8820x_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: m8820x_machdep.c,v 1.60 2013/11/03 09:42:55 miod Exp $ */
+/* $OpenBSD: m8820x_machdep.c,v 1.61 2013/11/16 18:45:20 miod Exp $ */
/*
* Copyright (c) 2004, 2007, 2010, 2011, 2013, Miodrag Vallat.
*
@@ -173,8 +173,10 @@ void m8820x_cmmu_inv_locked(int, paddr_t, psize_t);
void m8820x_enable_other_cmmu_cache(void);
#endif
-void m8820x_dbatc_set(cpuid_t, uint, uint32_t);
-void m8820x_ibatc_set(cpuid_t, uint, uint32_t);
+static inline
+void m8820x_dbatc_set(cpuid_t, uint, batc_t);
+static inline
+void m8820x_ibatc_set(cpuid_t, uint, batc_t);
/* Flags passed to m8820x_cmmu_set_*() */
#define MODE_VAL 0x01
@@ -345,14 +347,16 @@ m8820x_cmmu_wait(int cpu)
* BATC routines
*/
+static inline
void
-m8820x_dbatc_set(cpuid_t cpu, uint batcno, uint32_t batc)
+m8820x_dbatc_set(cpuid_t cpu, uint batcno, batc_t batc)
{
m8820x_cmmu_set_reg_if_mode(CMMU_BWP(batcno), batc, cpu, DATA_CMMU);
}
+static inline
void
-m8820x_ibatc_set(cpuid_t cpu, uint batcno, uint32_t batc)
+m8820x_ibatc_set(cpuid_t cpu, uint batcno, batc_t batc)
{
m8820x_cmmu_set_reg_if_mode(CMMU_BWP(batcno), batc, cpu, INST_CMMU);
}
@@ -362,7 +366,7 @@ m8820x_batc_setup(cpuid_t cpu, apr_t cmode)
{
paddr_t s_text, e_text, s_data, e_data, e_rodata;
uint batcno;
- uint32_t batc, proto;
+ batc_t batc, proto;
extern caddr_t kernelstart;
extern caddr_t etext;
extern caddr_t erodata;
@@ -392,7 +396,7 @@ m8820x_batc_setup(cpuid_t cpu, apr_t cmode)
#ifdef DEBUG
printf("cpu%d ibat%d %p(%08x)\n", cpu, batcno, s_text, batc);
#endif
- m8820x_ibatc_set(cpu, batcno, batc);
+ global_ibatc[batcno] = batc;
s_text += BATC_BLKBYTES;
if (++batcno == BATC_MAX)
break;
@@ -415,11 +419,16 @@ m8820x_batc_setup(cpuid_t cpu, apr_t cmode)
#ifdef DEBUG
printf("cpu%d dbat%d %p(%08x)\n", cpu, batcno, s_data, batc);
#endif
- m8820x_dbatc_set(cpu, batcno, batc);
+ global_dbatc[batcno] = batc;
s_data += BATC_BLKBYTES;
if (++batcno == BATC_MAX)
break;
}
+
+ for (batcno = 0; batcno < BATC_MAX; batcno++) {
+ m8820x_dbatc_set(cpu, batcno, global_dbatc[batcno]);
+ m8820x_ibatc_set(cpu, batcno, global_ibatc[batcno]);
+ }
}
/*
diff --git a/sys/arch/m88k/m88k/pmap.c b/sys/arch/m88k/m88k/pmap.c
index a9a73e87ebb..dde3272a098 100644
--- a/sys/arch/m88k/m88k/pmap.c
+++ b/sys/arch/m88k/m88k/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.74 2013/11/03 09:42:55 miod Exp $ */
+/* $OpenBSD: pmap.c,v 1.75 2013/11/16 18:45:20 miod Exp $ */
/*
* Copyright (c) 2001-2004, 2010, Miodrag Vallat.
@@ -148,13 +148,20 @@ paddr_t s_firmware;
psize_t l_firmware;
/*
+ * Current BATC values.
+ */
+
+batc_t global_dbatc[BATC_MAX];
+batc_t global_ibatc[BATC_MAX];
+
+/*
* Internal routines
*/
void pmap_changebit(struct vm_page *, int, int);
void pmap_clean_page(paddr_t);
pt_entry_t *pmap_expand(pmap_t, vaddr_t, int);
pt_entry_t *pmap_expand_kmap(vaddr_t, int);
-void pmap_map(paddr_t, psize_t, vm_prot_t, u_int);
+void pmap_map(paddr_t, psize_t, vm_prot_t, u_int, boolean_t);
pt_entry_t *pmap_pte(pmap_t, vaddr_t);
void pmap_remove_page(struct vm_page *);
void pmap_remove_pte(pmap_t, vaddr_t, pt_entry_t *,
@@ -242,29 +249,91 @@ int
pmap_translation_info(pmap_t pmap, vaddr_t va, paddr_t *pap, uint32_t *ti)
{
pt_entry_t *pte;
+ vaddr_t var;
+ uint batcno;
int s;
int rv;
/*
* Check for a BATC translation first.
- * Even though we do not use BATC yet, 88100-based designs (with
- * 8820x CMMUs) have two hardwired BATC entries which map the
- * upper 1MB (so-called `utility space') 1:1 in supervisor space.
+ * We only use BATC for supervisor mappings (i.e. pmap_kernel()).
*/
+
+ if (pmap == pmap_kernel()) {
+ /*
+ * 88100-based designs (with 8820x CMMUs) have two hardwired
+ * BATC entries which map the upper 1MB (so-called
+ * `utility space') 1:1 in supervisor space.
+ */
#ifdef M88100
- if (CPU_IS88100 && pmap == pmap_kernel()) {
- if (va >= BATC9_VA) {
- *pap = va;
- *ti = BATC9 & CACHE_MASK;
- return PTI_BATC;
+ if (CPU_IS88100) {
+ if (va >= BATC9_VA) {
+ *pap = va;
+ *ti = 0;
+ if (BATC9 & BATC_INH)
+ *ti |= CACHE_INH;
+ if (BATC9 & BATC_GLOBAL)
+ *ti |= CACHE_GLOBAL;
+ if (BATC9 & BATC_WT)
+ *ti |= CACHE_WT;
+ return PTI_BATC;
+ }
+ if (va >= BATC8_VA) {
+ *pap = va;
+ *ti = 0;
+ if (BATC8 & BATC_INH)
+ *ti |= CACHE_INH;
+ if (BATC8 & BATC_GLOBAL)
+ *ti |= CACHE_GLOBAL;
+ if (BATC8 & BATC_WT)
+ *ti |= CACHE_WT;
+ return PTI_BATC;
+ }
}
- if (va >= BATC8_VA) {
- *pap = va;
- *ti = BATC8 & CACHE_MASK;
- return PTI_BATC;
+#endif
+
+ /*
+ * Now try all DBATC entries.
+ * Note that pmap_translation_info() might be invoked (via
+ * pmap_extract() ) for instruction faults; we *rely* upon
+ * the fact that all executable mappings covered by IBATC
+ * will be:
+ * - read-only, with no RO->RW upgrade allowed
+ * - dual mapped by ptes, so that pmap_extract() can still
+ * return a meaningful result.
+ * Should this ever change, some kernel interfaces will need
+ * to be made aware of (and carry on to callees) whether the
+ * address should be resolved as an instruction or data
+ * address.
+ */
+ var = trunc_batc(va);
+ for (batcno = 0; batcno < BATC_MAX; batcno++) {
+ vaddr_t batcva;
+ paddr_t batcpa;
+ batc_t batc;
+
+ batc = global_dbatc[batcno];
+ if ((batc & BATC_V) == 0)
+ continue;
+
+ batcva = (batc << (BATC_BLKSHIFT - BATC_VSHIFT)) &
+ ~BATC_BLKMASK;
+ if (batcva == var) {
+ batcpa = (batc <<
+ (BATC_BLKSHIFT - BATC_PSHIFT)) &
+ ~BATC_BLKMASK;
+ *pap = batcpa + (va - var);
+ *ti = 0;
+ if (batc & BATC_INH)
+ *ti |= CACHE_INH;
+ if (batc & BATC_GLOBAL)
+ *ti |= CACHE_GLOBAL;
+ if (batc & BATC_WT)
+ *ti |= CACHE_WT;
+ return PTI_BATC;
+ }
}
}
-#endif
/*
* Check for a regular PTE translation.
@@ -500,11 +569,19 @@ pmap_steal_memory(vsize_t size, vaddr_t *vstartp, vaddr_t *vendp)
* [INTERNAL]
* Setup a wired mapping in pmap_kernel(). Similar to pmap_kenter_pa(),
* but allows explicit cacheability control.
+ * This is only used at bootstrap time. Mappings may also be backed up
+ * by a BATC entry if requested and possible; but note that the BATC
+ * entries set up here may be overwritten by cmmu_batc_setup() later on
+ * (which is harmless since we are creating proper ptes anyway).
*/
void
-pmap_map(paddr_t pa, psize_t sz, vm_prot_t prot, u_int cmode)
+pmap_map(paddr_t pa, psize_t sz, vm_prot_t prot, u_int cmode,
+ boolean_t may_use_batc)
{
pt_entry_t *pte, npte;
+ batc_t batc;
+ uint npg, batcno;
+ paddr_t curpa;
DPRINTF(CD_MAP, ("pmap_map(%p, %p, %x, %x)\n",
pa, sz, prot, cmode));
@@ -514,23 +591,71 @@ pmap_map(paddr_t pa, psize_t sz, vm_prot_t prot, u_int cmode)
pa, pa + sz);
#endif
+ sz = round_page(pa + sz) - trunc_page(pa);
+ pa = trunc_page(pa);
+
npte = m88k_protection(prot) | cmode | PG_W | PG_V;
#ifdef M88110
if (CPU_IS88110 && m88k_protection(prot) != PG_RO)
npte |= PG_M;
#endif
- sz = atop(round_page(pa + sz) - trunc_page(pa));
- pa = trunc_page(pa);
- while (sz-- != 0) {
- if ((pte = pmap_pte(pmap_kernel(), pa)) == NULL)
- pte = pmap_expand_kmap(pa, 0);
+ npg = atop(sz);
+ curpa = pa;
+ while (npg-- != 0) {
+ if ((pte = pmap_pte(pmap_kernel(), curpa)) == NULL)
+ pte = pmap_expand_kmap(curpa, 0);
- *pte = npte | pa;
- pa += PAGE_SIZE;
+ *pte = npte | curpa;
+ curpa += PAGE_SIZE;
pmap_kernel()->pm_stats.resident_count++;
pmap_kernel()->pm_stats.wired_count++;
}
+
+ if (may_use_batc) {
+ sz = round_batc(pa + sz) - trunc_batc(pa);
+ pa = trunc_batc(pa);
+
+ batc = BATC_SO | BATC_V;
+ if ((prot & VM_PROT_WRITE) == 0)
+ batc |= BATC_PROT;
+ if (cmode & CACHE_INH)
+ batc |= BATC_INH;
+ if (cmode & CACHE_WT)
+ batc |= BATC_WT;
+ batc |= BATC_GLOBAL; /* XXX 88110 SP */
+
+ for (; sz != 0; sz -= BATC_BLKBYTES, pa += BATC_BLKBYTES) {
+ /* check if an existing BATC covers this area */
+ for (batcno = 0; batcno < BATC_MAX; batcno++) {
+ if ((global_dbatc[batcno] & BATC_V) == 0)
+ continue;
+ curpa = (global_dbatc[batcno] <<
+ (BATC_BLKSHIFT - BATC_PSHIFT)) &
+ ~BATC_BLKMASK;
+ if (curpa == pa)
+ break;
+ }
+
+ /*
+ * If there is a BATC covering this range, reuse it.
+ * We assume all BATC-possible mappings will use the
+ * same protection and cacheability settings.
+ */
+ if (batcno != BATC_MAX)
+ continue;
+
+ /* create a new DBATC if possible */
+ for (batcno = BATC_MAX; batcno != 0; batcno--) {
+ if (global_dbatc[batcno - 1] & BATC_V)
+ continue;
+ global_dbatc[batcno - 1] = batc |
+ ((pa >> BATC_BLKSHIFT) << BATC_PSHIFT) |
+ ((pa >> BATC_BLKSHIFT) << BATC_VSHIFT);
+ break;
+ }
+ }
+ }
}
/*
@@ -666,13 +791,14 @@ pmap_bootstrap(paddr_t s_rom, paddr_t e_rom)
if (e_rom != s_rom) {
s_firmware = s_rom;
l_firmware = e_rom - s_rom;
- pmap_map(s_firmware, l_firmware, UVM_PROT_RW, CACHE_INH);
+ pmap_map(s_firmware, l_firmware, UVM_PROT_RW, CACHE_INH, FALSE);
}
for (ptable = pmap_table_build(); ptable->size != (vsize_t)-1; ptable++)
if (ptable->size != 0)
pmap_map(ptable->start, ptable->size,
- ptable->prot, ptable->cacheability);
+ ptable->prot, ptable->cacheability,
+ ptable->may_use_batc);
/*
* Adjust cache settings according to the hardware we are running on.