summaryrefslogtreecommitdiff
path: root/sys/arch/m88k
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-04-09 12:11:12 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-04-09 12:11:12 +0000
commit0857e379c68e7fe815a8708f47cf629409c544dd (patch)
tree878d5f51a913fabeb40bfda7407c707c5446dc85 /sys/arch/m88k
parent8687f73385de2fab544ff98f2f75958f8898c626 (diff)
On MVME188 systems with more than two CMMUs par CPU, do not honor the
address split scheme when operating on caches, as this does not work (probably for some snooping needs?); TLB operations are still honoring the split and are not affected.
Diffstat (limited to 'sys/arch/m88k')
-rw-r--r--sys/arch/m88k/m88k/m8820x_machdep.c207
1 files changed, 97 insertions, 110 deletions
diff --git a/sys/arch/m88k/m88k/m8820x_machdep.c b/sys/arch/m88k/m88k/m8820x_machdep.c
index 1dd0dd3516a..2eb16f17514 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.19 2005/12/21 22:15:24 miod Exp $ */
+/* $OpenBSD: m8820x_machdep.c,v 1.20 2006/04/09 12:11:11 miod Exp $ */
/*
* Copyright (c) 2004, Miodrag Vallat.
*
@@ -153,7 +153,8 @@ u_int max_cmmus;
u_int cmmu_shift;
/* local prototypes */
-void m8820x_cmmu_set(int, u_int, int, int, int, vaddr_t);
+void m8820x_cmmu_set_reg(int, u_int, int, int, int);
+void m8820x_cmmu_set_cmd(u_int, int, int, int, vaddr_t);
void m8820x_cmmu_wait(int);
int m8820x_cmmu_sync_cache(paddr_t, psize_t);
int m8820x_cmmu_sync_inval_cache(paddr_t, psize_t);
@@ -164,11 +165,33 @@ int m8820x_cmmu_inval_cache(paddr_t, psize_t);
#define ADDR_VAL 0x02
/*
- * This function is called by the MMU module and pokes values
- * into the CMMU's registers.
+ * Helper functions to poke values into the appropriate CMMU registers.
*/
+
void
-m8820x_cmmu_set(int reg, u_int val, int flags, int cpu, int mode, vaddr_t addr)
+m8820x_cmmu_set_reg(int reg, u_int val, int flags, int cpu, int mode)
+{
+ struct m8820x_cmmu *cmmu;
+ int mmu, cnt;
+
+ mmu = cpu << cmmu_shift;
+ cmmu = m8820x_cmmu + mmu;
+
+ /*
+ * We scan all CMMUs to find the matching ones and store the
+ * values there.
+ */
+ for (cnt = 1 << cmmu_shift; cnt != 0; cnt--, mmu++, cmmu++) {
+ if ((flags & MODE_VAL) != 0) {
+ if (CMMU_MODE(mmu) != mode)
+ continue;
+ }
+ cmmu->cmmu_regs[reg] = val;
+ }
+}
+
+void
+m8820x_cmmu_set_cmd(u_int cmd, int flags, int cpu, int mode, vaddr_t addr)
{
struct m8820x_cmmu *cmmu;
int mmu, cnt;
@@ -186,13 +209,13 @@ m8820x_cmmu_set(int reg, u_int val, int flags, int cpu, int mode, vaddr_t addr)
continue;
}
#ifdef M88200_HAS_SPLIT_ADDRESS
- if ((flags & ADDR_VAL) != 0) {
- if (cmmu->cmmu_addr_mask != 0 &&
- (addr & cmmu->cmmu_addr_mask) != cmmu->cmmu_addr)
+ if ((flags & ADDR_VAL) != 0 && cmmu->cmmu_addr_mask != 0) {
+ if ((addr & cmmu->cmmu_addr_mask) != cmmu->cmmu_addr)
continue;
}
#endif
- cmmu->cmmu_regs[reg] = val;
+ cmmu->cmmu_regs[CMMU_SAR] = addr;
+ cmmu->cmmu_regs[CMMU_SCR] = cmd;
}
}
@@ -409,7 +432,7 @@ m8820x_initialize_cpu(cpuid_t cpu)
* Data cache will be enabled later.
*/
apr &= ~CACHE_INH;
- m8820x_cmmu_set(CMMU_SAPR, apr, MODE_VAL, cpu, INST_CMMU, 0);
+ m8820x_cmmu_set_reg(CMMU_SAPR, apr, MODE_VAL, cpu, INST_CMMU);
}
/*
@@ -437,7 +460,7 @@ void
m8820x_set_sapr(cpuid_t cpu, apr_t ap)
{
CMMU_LOCK;
- m8820x_cmmu_set(CMMU_SAPR, ap, 0, cpu, 0, 0);
+ m8820x_cmmu_set_reg(CMMU_SAPR, ap, 0, cpu, 0);
CMMU_UNLOCK;
}
@@ -448,7 +471,7 @@ m8820x_set_uapr(apr_t ap)
int cpu = cpu_number();
CMMU_LOCK;
- m8820x_cmmu_set(CMMU_UAPR, ap, 0, cpu, 0, 0);
+ m8820x_cmmu_set_reg(CMMU_UAPR, ap, 0, cpu, 0);
CMMU_UNLOCK;
splx(s);
}
@@ -476,28 +499,25 @@ m8820x_flush_tlb(cpuid_t cpu, unsigned kernel, vaddr_t vaddr, u_int count)
*/
switch (count) {
default:
- m8820x_cmmu_set(CMMU_SCR,
+ m8820x_cmmu_set_reg(CMMU_SCR,
kernel ? CMMU_FLUSH_SUPER_ALL : CMMU_FLUSH_USER_ALL,
- 0, cpu, 0, 0);
+ 0, cpu, 0);
break;
case 3:
- m8820x_cmmu_set(CMMU_SAR, vaddr, ADDR_VAL, cpu, 0, vaddr);
- m8820x_cmmu_set(CMMU_SCR,
+ m8820x_cmmu_set_cmd(
kernel ? CMMU_FLUSH_SUPER_PAGE : CMMU_FLUSH_USER_PAGE,
ADDR_VAL, cpu, 0, vaddr);
vaddr += PAGE_SIZE;
/* FALLTHROUGH */
case 2:
- m8820x_cmmu_set(CMMU_SAR, vaddr, ADDR_VAL, cpu, 0, vaddr);
- m8820x_cmmu_set(CMMU_SCR,
+ m8820x_cmmu_set_cmd(
kernel ? CMMU_FLUSH_SUPER_PAGE : CMMU_FLUSH_USER_PAGE,
ADDR_VAL, cpu, 0, vaddr);
vaddr += PAGE_SIZE;
/* FALLTHROUGH */
case 1: /* most frequent situation */
case 0:
- m8820x_cmmu_set(CMMU_SAR, vaddr, ADDR_VAL, cpu, 0, vaddr);
- m8820x_cmmu_set(CMMU_SCR,
+ m8820x_cmmu_set_cmd(
kernel ? CMMU_FLUSH_SUPER_PAGE : CMMU_FLUSH_USER_PAGE,
ADDR_VAL, cpu, 0, vaddr);
break;
@@ -519,6 +539,9 @@ m8820x_flush_tlb(cpuid_t cpu, unsigned kernel, vaddr_t vaddr, u_int count)
* We don't push Instruction Caches prior to invalidate because they are not
* snooped and never modified (I guess it doesn't matter then which form
* of the command we use then).
+ *
+ * XXX On systems with more than two CMMUs per CPU, we do not honor the
+ * address split - this does not work...
*/
/*
@@ -531,23 +554,17 @@ m8820x_flush_cache(cpuid_t cpu, paddr_t physaddr, psize_t size)
CMMU_LOCK;
if (size > NBSG) {
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, 0,
- cpu, 0, 0);
+ m8820x_cmmu_set_reg(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, 0,
+ cpu, 0);
} else if (size <= MC88200_CACHE_LINE) {
- m8820x_cmmu_set(CMMU_SAR, physaddr, ADDR_VAL,
- cpu, 0, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_LINE, ADDR_VAL,
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CBI_LINE, 0 /* ADDR_VAL */,
cpu, 0, physaddr);
} else if (size <= PAGE_SIZE) {
- m8820x_cmmu_set(CMMU_SAR, physaddr, ADDR_VAL,
- cpu, 0, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_PAGE, ADDR_VAL,
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CBI_PAGE, 0 /* ADDR_VAL */,
cpu, 0, physaddr);
} else {
- m8820x_cmmu_set(CMMU_SAR, physaddr, 0,
- cpu, 0, 0);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_SEGMENT, 0,
- cpu, 0, 0);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CBI_SEGMENT, 0,
+ cpu, 0, physaddr);
}
m8820x_cmmu_wait(cpu);
@@ -566,23 +583,17 @@ m8820x_flush_inst_cache(cpuid_t cpu, paddr_t physaddr, psize_t size)
CMMU_LOCK;
if (size > NBSG) {
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, MODE_VAL,
- cpu, INST_CMMU, 0);
+ m8820x_cmmu_set_reg(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL,
+ MODE_VAL, cpu, INST_CMMU);
} else if (size <= MC88200_CACHE_LINE) {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_LINE,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CBI_LINE,
+ MODE_VAL /* | ADDR_VAL */, cpu, INST_CMMU, physaddr);
} else if (size <= PAGE_SIZE) {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_PAGE,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CBI_PAGE,
+ MODE_VAL /* | ADDR_VAL */, cpu, INST_CMMU, physaddr);
} else {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- MODE_VAL, cpu, INST_CMMU, 0);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_SEGMENT,
- MODE_VAL, cpu, INST_CMMU, 0);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CBI_SEGMENT,
+ MODE_VAL, cpu, INST_CMMU, physaddr);
}
m8820x_cmmu_wait(cpu);
@@ -598,23 +609,17 @@ m8820x_flush_data_cache(cpuid_t cpu, paddr_t physaddr, psize_t size)
CMMU_LOCK;
if (size > NBSG) {
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, MODE_VAL,
- cpu, DATA_CMMU, 0);
+ m8820x_cmmu_set_reg(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL,
+ MODE_VAL, cpu, DATA_CMMU);
} else if (size <= MC88200_CACHE_LINE) {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_LINE,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CBI_LINE,
+ MODE_VAL /* | ADDR_VAL */, cpu, DATA_CMMU, physaddr);
} else if (size <= PAGE_SIZE) {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_PAGE,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CBI_PAGE,
+ MODE_VAL /* | ADDR_VAL */, cpu, DATA_CMMU, physaddr);
} else {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- MODE_VAL, cpu, DATA_CMMU, 0);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_SEGMENT,
- MODE_VAL, cpu, DATA_CMMU, 0);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CBI_SEGMENT,
+ MODE_VAL, cpu, DATA_CMMU, physaddr);
}
m8820x_cmmu_wait(cpu);
@@ -636,26 +641,20 @@ m8820x_cmmu_sync_cache(paddr_t physaddr, psize_t size)
CMMU_LOCK;
if (size > NBSG) {
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CB_ALL, MODE_VAL,
- cpu, DATA_CMMU, 0);
+ m8820x_cmmu_set_reg(CMMU_SCR, CMMU_FLUSH_CACHE_CB_ALL,
+ MODE_VAL, cpu, DATA_CMMU);
rc = 1;
} else if (size <= MC88200_CACHE_LINE) {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CB_LINE,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CB_LINE,
+ MODE_VAL /* | ADDR_VAL */, cpu, DATA_CMMU, physaddr);
rc = 0;
} else if (size <= PAGE_SIZE) {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CB_PAGE,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CB_PAGE,
+ MODE_VAL /* | ADDR_VAL */, cpu, DATA_CMMU, physaddr);
rc = 0;
} else {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CB_SEGMENT,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CB_SEGMENT,
+ MODE_VAL, cpu, DATA_CMMU, physaddr);
rc = 0;
}
@@ -676,34 +675,28 @@ m8820x_cmmu_sync_inval_cache(paddr_t physaddr, psize_t size)
CMMU_LOCK;
if (size > NBSG) {
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_INV_ALL, MODE_VAL,
- cpu, INST_CMMU, 0);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, MODE_VAL,
- cpu, DATA_CMMU, 0);
+ m8820x_cmmu_set_reg(CMMU_SCR, CMMU_FLUSH_CACHE_INV_ALL,
+ MODE_VAL, cpu, INST_CMMU);
+ m8820x_cmmu_set_reg(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL,
+ MODE_VAL, cpu, DATA_CMMU);
rc = 1;
} else if (size <= MC88200_CACHE_LINE) {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- ADDR_VAL, cpu, 0, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_INV_LINE,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_LINE,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_INV_LINE,
+ MODE_VAL /* | ADDR_VAL */, cpu, INST_CMMU, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CBI_LINE,
+ MODE_VAL /* | ADDR_VAL */, cpu, DATA_CMMU, physaddr);
rc = 0;
} else if (size <= PAGE_SIZE) {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- ADDR_VAL, cpu, 0, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_INV_PAGE,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_PAGE,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_INV_PAGE,
+ MODE_VAL /* | ADDR_VAL */, cpu, INST_CMMU, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CBI_PAGE,
+ MODE_VAL /* | ADDR_VAL */, cpu, DATA_CMMU, physaddr);
rc = 0;
} else {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- ADDR_VAL, cpu, 0, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_INV_SEGMENT,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_SEGMENT,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_INV_SEGMENT,
+ MODE_VAL, cpu, INST_CMMU, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_CBI_SEGMENT,
+ MODE_VAL, cpu, DATA_CMMU, physaddr);
rc = 0;
}
@@ -724,26 +717,20 @@ m8820x_cmmu_inval_cache(paddr_t physaddr, psize_t size)
CMMU_LOCK;
if (size > NBSG) {
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_INV_ALL, 0,
- cpu, 0, 0);
+ m8820x_cmmu_set_reg(CMMU_SCR, CMMU_FLUSH_CACHE_INV_ALL, 0,
+ cpu, 0);
rc = 1;
} else if (size <= MC88200_CACHE_LINE) {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- ADDR_VAL, cpu, 0, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_INV_LINE,
- ADDR_VAL, cpu, 0, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_INV_LINE,
+ 0 /* ADDR_VAL */, cpu, 0, physaddr);
rc = 0;
} else if (size <= PAGE_SIZE) {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- ADDR_VAL, cpu, 0, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_INV_PAGE,
- ADDR_VAL, cpu, 0, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_INV_PAGE,
+ 0 /* ADDR_VAL */, cpu, 0, physaddr);
rc = 0;
} else {
- m8820x_cmmu_set(CMMU_SAR, physaddr,
- ADDR_VAL, cpu, 0, physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_INV_SEGMENT,
- ADDR_VAL, cpu, 0, physaddr);
+ m8820x_cmmu_set_cmd(CMMU_FLUSH_CACHE_INV_SEGMENT,
+ 0, cpu, 0, physaddr);
rc = 0;
}