diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2006-04-09 12:11:12 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2006-04-09 12:11:12 +0000 |
commit | 0857e379c68e7fe815a8708f47cf629409c544dd (patch) | |
tree | 878d5f51a913fabeb40bfda7407c707c5446dc85 /sys | |
parent | 8687f73385de2fab544ff98f2f75958f8898c626 (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')
-rw-r--r-- | sys/arch/m88k/m88k/m8820x_machdep.c | 207 |
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; } |