summaryrefslogtreecommitdiff
path: root/sys/arch/mvme88k
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/mvme88k')
-rw-r--r--sys/arch/mvme88k/include/m8820x.h16
-rw-r--r--sys/arch/mvme88k/mvme88k/m8820x.c1329
2 files changed, 63 insertions, 1282 deletions
diff --git a/sys/arch/mvme88k/include/m8820x.h b/sys/arch/mvme88k/include/m8820x.h
index 4b881800351..1a763f05f48 100644
--- a/sys/arch/mvme88k/include/m8820x.h
+++ b/sys/arch/mvme88k/include/m8820x.h
@@ -1,4 +1,6 @@
-/* $OpenBSD: m8820x.h,v 1.14 2004/08/02 08:35:00 miod Exp $ */
+#ifndef _MVME88K_M8820X_H_
+#define _MVME88K_M8820X_H_
+/* $OpenBSD: m8820x.h,v 1.15 2004/08/06 13:23:49 miod Exp $ */
/*
* Copyright (c) 2004, Miodrag Vallat.
*
@@ -49,7 +51,13 @@
* the rights to redistribute these changes.
*/
-#include <m88k/m8820x.h>
+/*
+ * Code features to enable
+ */
+
+#ifdef MVME188
+#define M88200_HAS_SPLIT_ADDRESS
+#endif
/*
* Address masks for MVME188 CMMU configs
@@ -59,3 +67,7 @@
#define CMMU_A12_MASK (1 << 12)
#define CMMU_A14_MASK (1 << 14)
#define CMMU_SRAM_MASK ((1 << 31) | (1 << 30))
+
+#include <m88k/m8820x.h>
+
+#endif /* _MVME88K_M8820X_H_ */
diff --git a/sys/arch/mvme88k/mvme88k/m8820x.c b/sys/arch/mvme88k/mvme88k/m8820x.c
index 8011a7e5abc..d9172b67905 100644
--- a/sys/arch/mvme88k/mvme88k/m8820x.c
+++ b/sys/arch/mvme88k/mvme88k/m8820x.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: m8820x.c,v 1.38 2004/08/04 15:54:38 miod Exp $ */
+/* $OpenBSD: m8820x.c,v 1.39 2004/08/06 13:23:49 miod Exp $ */
/*
* Copyright (c) 2004, Miodrag Vallat.
*
@@ -23,71 +23,15 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * Copyright (c) 2001 Steve Murphree, Jr.
- * Copyright (c) 1996 Nivas Madhur
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Nivas Madhur.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-/*
- * Mach Operating System
- * Copyright (c) 1993-1991 Carnegie Mellon University
- * Copyright (c) 1991 OMRON Corporation
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/simplelock.h>
#include <machine/asm_macro.h>
#include <machine/cpu_number.h>
+#ifdef DEBUG
#include <machine/locore.h>
+#endif
#include <machine/cmmu.h>
#include <machine/m8820x.h>
@@ -98,68 +42,7 @@
#include <machine/mvme188.h>
#endif
-#include <uvm/uvm_extern.h>
-
-#ifdef DDB
-#include <ddb/db_output.h> /* db_printf() */
-#endif
-
-/*
- * On some versions of the 88200, page size flushes don't work. I am using
- * sledge hammer approach till I find for sure which ones are bad XXX nivas
- */
-#define BROKEN_MMU_MASK
-
-u_int max_cmmus;
-
-void m8820x_cmmu_init(void);
-void m8820x_setup_board_config(void);
-void m8820x_cpu_configuration_print(int);
-void m8820x_cmmu_shutdown_now(void);
-void m8820x_cmmu_parity_enable(void);
-unsigned m8820x_cmmu_cpu_number(void);
-void m8820x_cmmu_set_sapr(unsigned, unsigned);
-void m8820x_cmmu_set_uapr(unsigned);
-void m8820x_cmmu_flush_tlb(unsigned, unsigned, vaddr_t, vsize_t);
-void m8820x_cmmu_flush_cache(int, paddr_t, psize_t);
-void m8820x_cmmu_flush_inst_cache(int, paddr_t, psize_t);
-void m8820x_cmmu_flush_data_cache(int, paddr_t, psize_t);
-void m8820x_dma_cachectl(vaddr_t, vsize_t, int);
-void m8820x_dma_cachectl_pa(paddr_t, psize_t, int);
-void m8820x_cmmu_dump_config(void);
-void m8820x_cmmu_show_translation(unsigned, unsigned, unsigned, int);
-void m8820x_show_apr(unsigned);
-
-/* This is the function table for the mc8820x CMMUs */
-struct cmmu_p cmmu8820x = {
- m8820x_cmmu_init,
- m8820x_setup_board_config,
- m8820x_cpu_configuration_print,
- m8820x_cmmu_shutdown_now,
- m8820x_cmmu_parity_enable,
- m8820x_cmmu_cpu_number,
- m8820x_cmmu_set_sapr,
- m8820x_cmmu_set_uapr,
- m8820x_cmmu_flush_tlb,
- m8820x_cmmu_flush_cache,
- m8820x_cmmu_flush_inst_cache,
- m8820x_cmmu_flush_data_cache,
- m8820x_dma_cachectl,
- m8820x_dma_cachectl_pa,
-#ifdef DDB
- m8820x_cmmu_dump_config,
- m8820x_cmmu_show_translation,
-#else
- NULL,
- NULL,
-#endif
-#ifdef DEBUG
- m8820x_show_apr,
-#else
- NULL,
-#endif
-};
-
+#ifdef MVME188
/*
* There are 6 possible MVME188 HYPERmodule configurations:
* - config 0: 4 CPUs, 8 CMMUs
@@ -167,69 +50,8 @@ struct cmmu_p cmmu8820x = {
* - config 2: 1 CPUs, 8 CMMUs
* - config 5: 2 CPUs, 4 CMMUs
* - config 6: 1 CPU, 4 CMMUs
- * - config A: 1 CPU, 2 CMMUs
+ * - config A: 1 CPU, 2 CMMUs (similar in operation to MVME187)
* which can exist either with MC88200 or MC88204 CMMUs.
- *
- * Systems with more than 2 CMMUs per CPU use programmable split schemes,
- * through PCNFA (for code CMMUs) and PCNFB (for data CMMUs) configuration
- * registers.
- *
- * The following schemes are available:
- * - split on A12 address bit (A14 for 88204)
- * - split on supervisor/user access
- * - split on SRAM/non-SRAM addresses, with either supervisor-only or all
- * access to SRAM.
- *
- * Configuration 6, with 4 CMMUs par CPU, also forces a split on A14 address
- * bit.
- *
- * Under OpenBSD, we will only split on A12 and A14 address bits, since we
- * do not want to waste CMMU resources on the SRAM, and user/supervisor
- * splits seem less efficient.
- *
- * The really nasty part of this choice is in the exception handling code,
- * when it needs to get error information from up to 4 CMMUs. See eh.S for
- * the gory details.
- */
-
-/*
- * CMMU kernel information
- */
-struct m8820x_cmmu {
- volatile u_int32_t *cmmu_regs; /* CMMU "base" area */
- unsigned int cmmu_cpu; /* cpu number it is attached to */
- unsigned int cmmu_type;
-#define NO_CMMU 0x00
-#define INST_CMMU 0x01
-#define DATA_CMMU 0x02
- vaddr_t cmmu_addr; /* address range */
- vaddr_t cmmu_addr_mask; /* address mask */
-};
-
-/*
- * Structure for accessing MMUS properly
- */
-
-#define MAX_CMMUS (2 * MAX_CPUS) /* maximum cmmus on the board */
-
-struct m8820x_cmmu m8820x_cmmu[MAX_CMMUS] = {
- /* address, cpu, mode, addr, mask */
- { NULL, -1, INST_CMMU, 0, 0 },
- { NULL, -1, DATA_CMMU, 0, 0 },
- { NULL, -1, INST_CMMU, 0, 0 },
- { NULL, -1, DATA_CMMU, 0, 0 },
- { NULL, -1, INST_CMMU, 0, 0 },
- { NULL, -1, DATA_CMMU, 0, 0 },
- { NULL, -1, INST_CMMU, 0, 0 },
- { NULL, -1, DATA_CMMU, 0, 0 }
-};
-
-unsigned int cmmu_shift;
-
-#ifdef MVME188
-/*
- * The following list describes the different MVME188 configurations
- * which are supported by this code.
*/
const struct board_config {
int ncpus;
@@ -254,45 +76,17 @@ const struct board_config {
};
#endif
-/* local prototypes */
-void m8820x_cmmu_set(int, unsigned, int, int, int, vaddr_t);
-void m8820x_cmmu_wait(int);
-void m8820x_cmmu_sync_cache(paddr_t, psize_t);
-void m8820x_cmmu_sync_inval_cache(paddr_t, psize_t);
-void m8820x_cmmu_inval_cache(paddr_t, psize_t);
-
-/* Flags passed to m8820x_cmmu_set() */
-#define MODE_VAL 0x01
-#define ADDR_VAL 0x02
-
-#ifdef DEBUG
-void
-m8820x_show_apr(unsigned value)
-{
- printf("table @ 0x%x000", PG_PFNUM(value));
- if (value & CACHE_WT)
- printf(", writethrough");
- if (value & CACHE_GLOBAL)
- printf(", global");
- if (value & CACHE_INH)
- printf(", cache inhibit");
- if (value & APR_V)
- printf(", valid");
- printf("\n");
-}
-#endif
-
/*
* This routine sets up the CPU/CMMU configuration.
*/
void
m8820x_setup_board_config()
{
- volatile unsigned *cr;
+ struct m8820x_cmmu *cmmu;
int num, cmmu_num;
int vme188_config;
#ifdef MVME188
- u_int32_t *volatile whoami;
+ u_int32_t whoami;
#endif
master_cpu = 0; /* temp to get things going */
@@ -303,21 +97,16 @@ m8820x_setup_board_config()
/* There is no WHOAMI reg on MVME187 - fake it... */
vme188_config = 0x0a;
m8820x_cmmu[0].cmmu_regs = (void *)SBC_CMMU_I;
- m8820x_cmmu[0].cmmu_cpu = 0;
m8820x_cmmu[1].cmmu_regs = (void *)SBC_CMMU_D;
- m8820x_cmmu[1].cmmu_cpu = 0;
- m8820x_cmmu[2].cmmu_regs = (void *)NULL;
- m8820x_cmmu[3].cmmu_regs = (void *)NULL;
- m8820x_cmmu[4].cmmu_regs = (void *)NULL;
- m8820x_cmmu[5].cmmu_regs = (void *)NULL;
- m8820x_cmmu[6].cmmu_regs = (void *)NULL;
- m8820x_cmmu[7].cmmu_regs = (void *)NULL;
+ max_cpus = 1;
+ max_cmmus = 2;
+ cmmu_shift = 1;
break;
#endif /* MVME187 */
#ifdef MVME188
case BRD_188:
- whoami = (u_int32_t *volatile)MVME188_WHOAMI;
- vme188_config = (*whoami & 0xf0) >> 4;
+ whoami = *(volatile u_int32_t *)MVME188_WHOAMI;
+ vme188_config = (whoami & 0xf0) >> 4;
m8820x_cmmu[0].cmmu_regs = (void *)VME_CMMU_I0;
m8820x_cmmu[1].cmmu_regs = (void *)VME_CMMU_D0;
m8820x_cmmu[2].cmmu_regs = (void *)VME_CMMU_I1;
@@ -326,17 +115,15 @@ m8820x_setup_board_config()
m8820x_cmmu[5].cmmu_regs = (void *)VME_CMMU_D2;
m8820x_cmmu[6].cmmu_regs = (void *)VME_CMMU_I3;
m8820x_cmmu[7].cmmu_regs = (void *)VME_CMMU_D3;
+ max_cpus = bd_config[vme188_config].ncpus;
+ max_cmmus = bd_config[vme188_config].ncmmus;
+ cmmu_shift = ff1(max_cmmus / max_cpus);
break;
#endif /* MVME188 */
}
- max_cpus = bd_config[vme188_config].ncpus;
- max_cmmus = bd_config[vme188_config].ncmmus;
-
- cmmu_shift = ff1(max_cmmus / max_cpus);
-
#ifdef MVME188
- if (bd_config[vme188_config].ncpus > 0) {
+ if (bd_config[vme188_config].ncpus != 0) {
/* 187 has a fixed configuration, no need to print it */
if (brdtyp == BRD_188) {
printf("MVME188 board configuration #%X "
@@ -349,12 +136,12 @@ m8820x_setup_board_config()
}
#endif
-#ifdef DIAGNOSTIC
+#ifdef DEBUG
/*
- * Probe for available MMUs
+ * Check CMMU type
*/
for (cmmu_num = 0; cmmu_num < max_cmmus; cmmu_num++) {
- cr = m8820x_cmmu[cmmu_num].cmmu_regs;
+ volatile unsigned *cr = m8820x_cmmu[cmmu_num].cmmu_regs;
if (badwordaddr((vaddr_t)cr) == 0) {
int type;
@@ -364,14 +151,12 @@ m8820x_setup_board_config()
"at CMMU address %p\n", cr);
continue; /* will probably die quickly */
}
- } else
- m8820x_cmmu[cmmu_num].cmmu_type = NO_CMMU;
+ }
}
#endif
/*
- * Now that we know which CMMUs are there, let's report on which
- * CPU/CMMU sets seem complete (hopefully all)
+ * Now that we know which CMMUs are there, report every association
*/
for (num = 0; num < max_cpus; num++) {
int type;
@@ -380,16 +165,29 @@ m8820x_setup_board_config()
type = CMMU_TYPE(m8820x_cmmu[num << cmmu_shift].
cmmu_regs[CMMU_IDR]);
- printf("CPU%d is attached with %d MC8820%c CMMUs\n",
+ printf("CPU%d is associated to %d MC8820%c CMMUs\n",
num, 1 << cmmu_shift, type == M88204_ID ? '4' : '0');
}
#ifdef MVME188
/*
- * Configure CPU/CMMU strategy into PCNFA and PCNFB board registers.
- * We should theoretically only set these on configurations 1, 2
- * and 6, since the other ones do not have P bus decoders.
+ * Systems with more than 2 CMMUs per CPU use programmable split
+ * schemes, through PCNFA (for code CMMUs) and PCNFB (for data CMMUs)
+ * configuration registers.
+ *
+ * The following schemes are available:
+ * - split on A12 address bit (A14 for 88204)
+ * - split on supervisor/user access
+ * - split on SRAM/non-SRAM addresses, with either supervisor-only or
+ * all access to SRAM.
+ *
+ * Configuration 6, with 4 CMMUs par CPU, also allows a split on A14
+ * address bit.
+ *
+ * Setup the default A12/A14 split here. We should theoretically only
+ * set the PCNFA and PCNFB on configurations 1, 2 and 6, since the
+ * other ones do not have P bus decoders.
* However, is it safe to write them anyways - the values will be
* discarded. Just don't do this on a 187...
*/
@@ -397,20 +195,12 @@ m8820x_setup_board_config()
*(volatile unsigned long *)MVME188_PCNFA = 0;
*(volatile unsigned long *)MVME188_PCNFB = 0;
}
-#endif
-
- /*
- * Calculate the CMMU<->CPU connections
- */
- for (cmmu_num = 0; cmmu_num < max_cmmus; cmmu_num++) {
- m8820x_cmmu[cmmu_num].cmmu_cpu =
- (cmmu_num * max_cpus) / max_cmmus;
- }
/*
* Now set up addressing limits
*/
- for (cmmu_num = 0; cmmu_num < max_cmmus; cmmu_num++) {
+ for (cmmu_num = 0, cmmu = m8820x_cmmu; cmmu_num < max_cmmus;
+ cmmu_num++, cmmu++) {
num = cmmu_num >> 1; /* CPU view of the CMMU */
switch (cmmu_shift) {
@@ -420,9 +210,8 @@ m8820x_setup_board_config()
* CMMU numbers 0 and 1 match on A14 set,
* 2 and 3 on A14 clear
*/
- m8820x_cmmu[cmmu_num].cmmu_addr |=
- (num < 2 ? CMMU_A14_MASK : 0);
- m8820x_cmmu[cmmu_num].cmmu_addr_mask |= CMMU_A14_MASK;
+ cmmu->cmmu_addr |= (num < 2 ? CMMU_A14_MASK : 0);
+ cmmu->cmmu_addr_mask |= CMMU_A14_MASK;
/* FALLTHROUGH */
case 2:
@@ -431,9 +220,8 @@ m8820x_setup_board_config()
* CMMU numbers 0 and 2 match on A12 set,
* 1 and 3 on A12 clear.
*/
- m8820x_cmmu[cmmu_num].cmmu_addr |=
- (num & 1 ? 0 : CMMU_A12_MASK);
- m8820x_cmmu[cmmu_num].cmmu_addr_mask |= CMMU_A12_MASK;
+ cmmu->cmmu_addr |= (num & 1 ? 0 : CMMU_A12_MASK);
+ cmmu->cmmu_addr_mask |= CMMU_A12_MASK;
break;
case 1:
@@ -441,8 +229,8 @@ m8820x_setup_board_config()
* We don't need to set up anything for the hardwired
* configurations.
*/
- m8820x_cmmu[cmmu_num].cmmu_addr = 0;
- m8820x_cmmu[cmmu_num].cmmu_addr_mask = 0;
+ cmmu->cmmu_addr = 0;
+ cmmu->cmmu_addr_mask = 0;
break;
}
@@ -450,321 +238,12 @@ m8820x_setup_board_config()
* If these CMMUs are 88204, these splitting address lines
* need to be shifted two bits.
*/
- if (CMMU_TYPE(m8820x_cmmu[cmmu_num].cmmu_regs[CMMU_IDR]) ==
- M88204_ID) {
- m8820x_cmmu[cmmu_num].cmmu_addr <<= 2;
- m8820x_cmmu[cmmu_num].cmmu_addr_mask <<= 2;
+ if (CMMU_TYPE(cmmu->cmmu_regs[CMMU_IDR]) == M88204_ID) {
+ cmmu->cmmu_addr <<= 2;
+ cmmu->cmmu_addr_mask <<= 2;
}
}
-}
-
-#ifdef DDB
-void
-m8820x_cmmu_dump_config()
-{
-#ifdef MVME188
- int cmmu_num;
-
-#ifdef MVME187
- if (brdtyp != BRD_188)
- return;
#endif
-
- db_printf("Current CPU/CMMU configuration:\n");
- for (cmmu_num = 0; cmmu_num < max_cmmus; cmmu_num++) {
- db_printf("CMMU #%d: %s CMMU for CPU %d:\n addr 0x%08lx mask 0x%08lx\n",
- cmmu_num,
- (m8820x_cmmu[cmmu_num].cmmu_type == INST_CMMU) ? "inst" : "data",
- m8820x_cmmu[cmmu_num].cmmu_cpu,
- m8820x_cmmu[cmmu_num].cmmu_addr,
- m8820x_cmmu[cmmu_num].cmmu_addr_mask);
- }
-#endif /* MVME188 */
-}
-#endif /* DDB */
-
-/*
- * This function is called by the MMU module and pokes values
- * into the CMMU's registers.
- */
-void
-m8820x_cmmu_set(int reg, unsigned val, int flags, int cpu, int mode,
- vaddr_t addr)
-{
- int mmu;
-
- /*
- * We scan all CMMUs to find the matching ones and store the
- * values there.
- */
- for (mmu = cpu << cmmu_shift;
- mmu < (cpu + 1) << cmmu_shift; mmu++) {
- if ((flags & MODE_VAL) != 0) {
- if (m8820x_cmmu[mmu].cmmu_type != mode)
- continue;
- }
-#ifdef MVME188
- if ((flags & ADDR_VAL) != 0) {
- if (m8820x_cmmu[mmu].cmmu_addr_mask != 0 &&
- (addr & m8820x_cmmu[mmu].cmmu_addr_mask) !=
- m8820x_cmmu[mmu].cmmu_addr)
- continue;
- }
-#endif
- m8820x_cmmu[mmu].cmmu_regs[reg] = val;
- }
-}
-
-/*
- * Force a read from the CMMU status register, thereby forcing execution to
- * stop until all pending CMMU operations are finished.
- * This is used by the various cache invalidation functions.
- */
-void
-m8820x_cmmu_wait(int cpu)
-{
- int mmu;
-
- /*
- * We scan all related CMMUs and read their status register.
- */
- for (mmu = cpu << cmmu_shift;
- mmu < (cpu + 1) << cmmu_shift; mmu++) {
-#ifdef DEBUG
- if (m8820x_cmmu[mmu].cmmu_regs[CMMU_SSR] & CMMU_SSR_BE) {
- panic("cache flush failed!");
- }
-#else
- /* force the read access, but do not issue this statement... */
- __asm__ __volatile__ ("|or r0, r0, %0" ::
- "r" (m8820x_cmmu[mmu].cmmu_regs[CMMU_SSR]));
-#endif
- }
-}
-
-const char *mmutypes[8] = {
- "Unknown (0)",
- "Unknown (1)",
- "Unknown (2)",
- "Unknown (3)",
- "Unknown (4)",
- "M88200 (16K)",
- "M88204 (64K)",
- "Unknown (7)"
-};
-
-/*
- * Should only be called after the calling cpus knows its cpu
- * number and master/slave status . Should be called first
- * by the master, before the slaves are started.
-*/
-void
-m8820x_cpu_configuration_print(int master)
-{
- int pid = read_processor_identification_register();
- int proctype = (pid & 0xff00) >> 8;
- int procvers = (pid & 0xe) >> 1;
- int mmu, cpu = cpu_number();
- struct simplelock print_lock;
-
- if (master)
- simple_lock_init(&print_lock);
-
- simple_lock(&print_lock);
-
- printf("cpu%d: ", cpu);
- if (proctype != 0) {
- printf("unknown model arch 0x%x rev 0x%x\n",
- proctype, procvers);
- simple_unlock(&print_lock);
- return;
- }
-
- printf("M88100 rev 0x%x", procvers);
-#if 0 /* not useful yet */
-#ifdef MVME188
- if (brdtyp == BRD_188)
- printf(", %s", master ? "master" : "slave");
-#endif
-#endif
- printf(", %d CMMU", 1 << cmmu_shift);
-
- for (mmu = cpu << cmmu_shift; mmu < (cpu + 1) << cmmu_shift;
- mmu++) {
- int idr = m8820x_cmmu[mmu].cmmu_regs[CMMU_IDR];
- int mmuid = CMMU_TYPE(idr);
-
- if (mmu % 2 == 0)
- printf("\ncpu%d: ", cpu);
- else
- printf(", ");
-
- if (mmutypes[mmuid][0] == 'U')
- printf("unknown model id 0x%x", mmuid);
- else
- printf("%s", mmutypes[mmuid]);
- printf(" rev 0x%x, %scache",
- CMMU_VERSION(idr),
- m8820x_cmmu[mmu].cmmu_type == INST_CMMU ? "I" : "D");
- }
- printf("\n");
-
-#ifndef ERRATA__XXX_USR
- {
- static int errata_warn = 0;
-
- if (proctype != 0 && procvers < 2) {
- if (!errata_warn++)
- printf("WARNING: M88100 bug workaround code "
- "not enabled.\nPlease recompile the kernel "
- "with option ERRATA__XXX_USR !\n");
- }
- }
-#endif
-
- simple_unlock(&print_lock);
-}
-
-/*
- * CMMU initialization routine
- */
-void
-m8820x_cmmu_init()
-{
- unsigned int line, cmmu_num;
- int cssp, cpu, type;
- u_int32_t apr;
- volatile unsigned *cr;
-
- for (cmmu_num = 0; cmmu_num < max_cmmus; cmmu_num++) {
- if (m8820x_cmmu[cmmu_num].cmmu_type != NO_CMMU) {
- cr = m8820x_cmmu[cmmu_num].cmmu_regs;
- type = CMMU_TYPE(cr[CMMU_IDR]);
-
- /*
- * Reset cache
- */
- for (cssp = type == M88204_ID ? 3 : 0;
- cssp >= 0; cssp--)
- for (line = 0; line <= 255; line++) {
- cr[CMMU_SAR] =
- line << MC88200_CACHE_SHIFT;
- cr[CMMU_CSSP(cssp)] =
- CMMU_CSSP_L5 | CMMU_CSSP_L4 |
- CMMU_CSSP_L3 | CMMU_CSSP_L2 |
- CMMU_CSSP_L1 | CMMU_CSSP_L0 |
- CMMU_CSSP_VV(3, CMMU_VV_INVALID) |
- CMMU_CSSP_VV(2, CMMU_VV_INVALID) |
- CMMU_CSSP_VV(1, CMMU_VV_INVALID) |
- CMMU_CSSP_VV(0, CMMU_VV_INVALID);
- }
-
- /*
- * Set the SCTR, SAPR, and UAPR to some known state
- */
- cr[CMMU_SCTR] &=
- ~(CMMU_SCTR_PE | CMMU_SCTR_SE | CMMU_SCTR_PR);
- cr[CMMU_SAPR] = cr[CMMU_UAPR] =
- ((0x00000 << PG_BITS) | CACHE_WT | CACHE_GLOBAL |
- CACHE_INH) & ~APR_V;
-
- cr[CMMU_BWP0] = cr[CMMU_BWP1] =
- cr[CMMU_BWP2] = cr[CMMU_BWP3] =
- cr[CMMU_BWP4] = cr[CMMU_BWP5] =
- cr[CMMU_BWP6] = cr[CMMU_BWP7] = 0;
- cr[CMMU_SCR] = CMMU_FLUSH_CACHE_INV_ALL;
- __asm__ __volatile__ ("|or r0, r0, %0" ::
- "r" (cr[CMMU_SSR]));
- cr[CMMU_SCR] = CMMU_FLUSH_SUPER_ALL;
- cr[CMMU_SCR] = CMMU_FLUSH_USER_ALL;
- }
- }
-
- /*
- * Enable snooping on MVME188 only.
- * Snooping is enabled for instruction cmmus as well so that
- * we can share breakpoints.
- */
-#ifdef MVME188
- if (brdtyp == BRD_188) {
- for (cpu = 0; cpu < max_cpus; cpu++) {
- if (cpu_sets[cpu] == 0)
- continue;
-
- m8820x_cmmu_set(CMMU_SCTR, CMMU_SCTR_SE, MODE_VAL, cpu,
- DATA_CMMU, 0);
- m8820x_cmmu_set(CMMU_SCTR, CMMU_SCTR_SE, MODE_VAL, cpu,
- INST_CMMU, 0);
-
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_SUPER_ALL,
- 0, cpu, 0, 0);
- m8820x_cmmu_wait(cpu);
- /* Icache gets flushed just below */
- }
- }
-#endif
-
- /*
- * Enable instruction cache.
- * Data cache can not be enabled at this point, because some device
- * addresses can never be cached, and the no-caching zones are not
- * set up yet.
- */
- for (cpu = 0; cpu < max_cpus; cpu++) {
- if (cpu_sets[cpu] == 0)
- continue;
-
- apr = ((0x00000 << PG_BITS) | CACHE_WT | CACHE_GLOBAL)
- & ~(CACHE_INH | APR_V);
-
- m8820x_cmmu_set(CMMU_SAPR, apr, MODE_VAL, cpu, INST_CMMU, 0);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_SUPER_ALL,
- 0, cpu, 0, 0);
- m8820x_cmmu_wait(cpu);
- }
-}
-
-/*
- * Just before poweroff or reset....
- */
-void
-m8820x_cmmu_shutdown_now()
-{
- unsigned cmmu_num;
- volatile unsigned *cr;
-
- CMMU_LOCK;
- for (cmmu_num = 0; cmmu_num < MAX_CMMUS; cmmu_num++)
- if (m8820x_cmmu[cmmu_num].cmmu_type != NO_CMMU) {
- cr = m8820x_cmmu[cmmu_num].cmmu_regs;
-
- cr[CMMU_SCTR] &=
- ~(CMMU_SCTR_PE | CMMU_SCTR_SE | CMMU_SCTR_PR);
- cr[CMMU_SAPR] = cr[CMMU_UAPR] =
- ((0x00000 << PG_BITS) | CACHE_INH) &
- ~(CACHE_WT | CACHE_GLOBAL | APR_V);
- }
- CMMU_UNLOCK;
-}
-
-/*
- * enable parity
- */
-void
-m8820x_cmmu_parity_enable()
-{
- unsigned cmmu_num;
- volatile unsigned *cr;
-
- CMMU_LOCK;
-
- for (cmmu_num = 0; cmmu_num < max_cmmus; cmmu_num++)
- if (m8820x_cmmu[cmmu_num].cmmu_type != NO_CMMU) {
- cr = m8820x_cmmu[cmmu_num].cmmu_regs;
- cr[CMMU_SCTR] |= CMMU_SCTR_PE;
- }
-
- CMMU_UNLOCK;
}
/*
@@ -812,713 +291,3 @@ m8820x_cmmu_cpu_number()
panic("can't figure out cpu number from whoami register %x", whoami);
#endif
}
-
-void
-m8820x_cmmu_set_sapr(unsigned cpu, unsigned ap)
-{
- CMMU_LOCK;
- m8820x_cmmu_set(CMMU_SAPR, ap, 0, cpu, 0, 0);
- CMMU_UNLOCK;
-}
-
-void
-m8820x_cmmu_set_uapr(unsigned ap)
-{
- int s = splhigh();
- int cpu = cpu_number();
-
- CMMU_LOCK;
- m8820x_cmmu_set(CMMU_UAPR, ap, 0, cpu, 0, 0);
- CMMU_UNLOCK;
- splx(s);
-}
-
-/*
- * Functions that invalidate TLB entries.
- */
-
-/*
- * flush any tlb
- */
-void
-m8820x_cmmu_flush_tlb(unsigned cpu, unsigned kernel, vaddr_t vaddr,
- vsize_t size)
-{
- int s = splhigh();
-
- CMMU_LOCK;
-
- /*
- * Since segment operations are horribly expensive, don't
- * do any here. Invalidations of up to three pages are performed
- * as page invalidations, otherwise the entire tlb is flushed.
- *
- * Note that this code relies upon size being a multiple of
- * a page and vaddr being page-aligned.
- */
- if (size == PAGE_SIZE) { /* most frequent situation */
- m8820x_cmmu_set(CMMU_SAR, vaddr,
- ADDR_VAL, cpu, 0, vaddr);
- m8820x_cmmu_set(CMMU_SCR,
- kernel ? CMMU_FLUSH_SUPER_PAGE : CMMU_FLUSH_USER_PAGE,
- ADDR_VAL, cpu, 0, vaddr);
- } else if (size > 3 * PAGE_SIZE) {
- m8820x_cmmu_set(CMMU_SCR,
- kernel ? CMMU_FLUSH_SUPER_ALL : CMMU_FLUSH_USER_ALL,
- 0, cpu, 0, 0);
- } else
- while (size != 0) {
- m8820x_cmmu_set(CMMU_SAR, vaddr,
- ADDR_VAL, cpu, 0, vaddr);
- m8820x_cmmu_set(CMMU_SCR,
- kernel ? CMMU_FLUSH_SUPER_PAGE : CMMU_FLUSH_USER_PAGE,
- ADDR_VAL, cpu, 0, vaddr);
-
- size -= PAGE_SIZE;
- vaddr += PAGE_SIZE;
- }
-
- CMMU_UNLOCK;
- splx(s);
-}
-
-/*
- * Functions that invalidate caches.
- *
- * Cache invalidates require physical addresses. Care must be exercised when
- * using segment invalidates. This implies that the starting physical address
- * plus the segment length should be invalidated. A typical mistake is to
- * extract the first physical page of a segment from a virtual address, and
- * then expecting to invalidate when the pages are not physically contiguous.
- *
- * 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).
- */
-
-/*
- * flush both Instruction and Data caches
- */
-void
-m8820x_cmmu_flush_cache(int cpu, paddr_t physaddr, psize_t size)
-{
- int s = splhigh();
- CMMU_LOCK;
-
-#if !defined(BROKEN_MMU_MASK)
- if (size > NBSG) {
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, 0,
- cpu, 0, 0);
- } else if (size <= MC88200_CACHE_LINE) {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr, ADDR_VAL,
- cpu, 0, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_LINE, ADDR_VAL,
- cpu, 0, (unsigned)physaddr);
- } else if (size <= NBPG) {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr, ADDR_VAL,
- cpu, 0, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_PAGE, ADDR_VAL,
- cpu, 0, (unsigned)physaddr);
- } else {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr, 0,
- cpu, 0, 0);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_SEGMENT, 0,
- cpu, 0, 0);
- }
-#else
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, 0, cpu, 0, 0);
-#endif /* !BROKEN_MMU_MASK */
-
- m8820x_cmmu_wait(cpu);
-
- CMMU_UNLOCK;
- splx(s);
-}
-
-/*
- * flush Instruction caches
- */
-void
-m8820x_cmmu_flush_inst_cache(int cpu, paddr_t physaddr, psize_t size)
-{
- int s = splhigh();
- CMMU_LOCK;
-
-#if !defined(BROKEN_MMU_MASK)
- if (size > NBSG) {
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, MODE_VAL,
- cpu, INST_CMMU, 0);
- } else if (size <= MC88200_CACHE_LINE) {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_LINE,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, (unsigned)physaddr);
- } else if (size <= NBPG) {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_PAGE,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, (unsigned)physaddr);
- } else {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL, cpu, INST_CMMU, 0);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_SEGMENT,
- MODE_VAL, cpu, INST_CMMU, 0);
- }
-#else
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, MODE_VAL,
- cpu, INST_CMMU, 0);
-#endif /* !BROKEN_MMU_MASK */
-
- m8820x_cmmu_wait(cpu);
-
- CMMU_UNLOCK;
- splx(s);
-}
-
-void
-m8820x_cmmu_flush_data_cache(int cpu, paddr_t physaddr, psize_t size)
-{
- int s = splhigh();
- CMMU_LOCK;
-
-#if !defined(BROKEN_MMU_MASK)
- if (size > NBSG) {
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, MODE_VAL,
- cpu, DATA_CMMU, 0);
- } else if (size <= MC88200_CACHE_LINE) {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_LINE,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, (unsigned)physaddr);
- } else if (size <= NBPG) {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_PAGE,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, (unsigned)physaddr);
- } else {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL, cpu, DATA_CMMU, 0);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_SEGMENT,
- MODE_VAL, cpu, DATA_CMMU, 0);
- }
-#else
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, MODE_VAL,
- cpu, DATA_CMMU, 0);
-#endif /* !BROKEN_MMU_MASK */
-
- m8820x_cmmu_wait(cpu);
-
- CMMU_UNLOCK;
- splx(s);
-}
-
-/*
- * sync dcache (and icache too)
- */
-void
-m8820x_cmmu_sync_cache(paddr_t physaddr, psize_t size)
-{
- int s = splhigh();
- int cpu = cpu_number();
-
- CMMU_LOCK;
-
-#if !defined(BROKEN_MMU_MASK)
- if (size > NBSG) {
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CB_ALL, MODE_VAL,
- cpu, DATA_CMMU, 0);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CB_ALL, MODE_VAL,
- cpu, INST_CMMU, 0);
- } else if (size <= MC88200_CACHE_LINE) {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_CB_LINE,
- MODE_VAL, cpu, INST_CMMU, 0);
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_CB_LINE,
- MODE_VAL, cpu, DATA_CMMU, 0);
- } else if (size <= NBPG) {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_CB_PAGE,
- MODE_VAL, cpu, INST_CMMU, 0);
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_CB_PAGE,
- MODE_VAL, cpu, DATA_CMMU, 0);
- } else {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_CB_SEGMENT,
- MODE_VAL, cpu, INST_CMMU, 0);
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_CB_SEGMENT,
- MODE_VAL, cpu, DATA_CMMU, 0);
- }
-#else
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CB_ALL, MODE_VAL,
- cpu, DATA_CMMU, 0);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CB_ALL, MODE_VAL,
- cpu, INST_CMMU, 0);
-#endif /* !BROKEN_MMU_MASK */
-
- m8820x_cmmu_wait(cpu);
-
- CMMU_UNLOCK;
- splx(s);
-}
-
-void
-m8820x_cmmu_sync_inval_cache(paddr_t physaddr, psize_t size)
-{
- int s = splhigh();
- int cpu = cpu_number();
-
- CMMU_LOCK;
-
-#if !defined(BROKEN_MMU_MASK)
- if (size > NBSG) {
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, MODE_VAL,
- cpu, DATA_CMMU, 0);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, MODE_VAL,
- cpu, INST_CMMU, 0);
- } else if (size <= MC88200_CACHE_LINE) {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_CBI_LINE,
- MODE_VAL, cpu, INST_CMMU, 0);
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_CBI_LINE,
- MODE_VAL, cpu, DATA_CMMU, 0);
- } else if (size <= NBPG) {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_CBI_PAGE,
- MODE_VAL, cpu, INST_CMMU, 0);
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_CBI_PAGE,
- MODE_VAL, cpu, DATA_CMMU, 0);
- } else {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_CBI_SEGMENT,
- MODE_VAL, cpu, INST_CMMU, 0);
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_CBI_SEGMENT,
- MODE_VAL, cpu, DATA_CMMU, 0);
- }
-#else
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, MODE_VAL,
- cpu, DATA_CMMU, 0);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_CBI_ALL, MODE_VAL,
- cpu, INST_CMMU, 0);
-#endif /* !BROKEN_MMU_MASK */
-
- m8820x_cmmu_wait(cpu);
-
- CMMU_UNLOCK;
- splx(s);
-}
-
-void
-m8820x_cmmu_inval_cache(paddr_t physaddr, psize_t size)
-{
- int s = splhigh();
- int cpu = cpu_number();
-
- CMMU_LOCK;
-
-#if !defined(BROKEN_MMU_MASK)
- if (size > NBSG) {
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_INV_ALL, MODE_VAL,
- cpu, DATA_CMMU, 0);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_INV_ALL, MODE_VAL,
- cpu, INST_CMMU, 0);
- } else if (size <= MC88200_CACHE_LINE) {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_INV_LINE,
- MODE_VAL, cpu, INST_CMMU, 0);
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_INV_LINE,
- MODE_VAL, cpu, DATA_CMMU, 0);
- } else if (size <= NBPG) {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_INV_PAGE,
- MODE_VAL, cpu, INST_CMMU, 0);
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_INV_PAGE,
- MODE_VAL, cpu, DATA_CMMU, 0);
- } else {
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, INST_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_INV_SEGMENT,
- MODE_VAL, cpu, INST_CMMU, 0);
- m8820x_cmmu_set(CMMU_SAR, (unsigned)physaddr,
- MODE_VAL | ADDR_VAL, cpu, DATA_CMMU, (unsigned)physaddr);
- m8820x_cmmu_set(CMMU_SAR, CMMU_FLUSH_CACHE_INV_SEGMENT,
- MODE_VAL, cpu, DATA_CMMU, 0);
- }
-#else
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_INV_ALL, MODE_VAL,
- cpu, DATA_CMMU, 0);
- m8820x_cmmu_set(CMMU_SCR, CMMU_FLUSH_CACHE_INV_ALL, MODE_VAL,
- cpu, INST_CMMU, 0);
-#endif /* !BROKEN_MMU_MASK */
-
- m8820x_cmmu_wait(cpu);
-
- CMMU_UNLOCK;
- splx(s);
-}
-
-void
-m8820x_dma_cachectl(vaddr_t va, vsize_t size, int op)
-{
- paddr_t pa;
-#if !defined(BROKEN_MMU_MASK)
- psize_t count;
-
- while (size != 0) {
- count = NBPG - (va & PGOFSET);
-
- if (size < count)
- count = size;
-
- if (pmap_extract(pmap_kernel(), va, &pa) != FALSE) {
- switch (op) {
- case DMA_CACHE_SYNC:
- m8820x_cmmu_sync_cache(pa, count);
- break;
- case DMA_CACHE_SYNC_INVAL:
- m8820x_cmmu_sync_inval_cache(pa, count);
- break;
- default:
- m8820x_cmmu_inval_cache(pa, count);
- break;
- }
- }
-
- va += count;
- size -= count;
- }
-#else
- /* XXX This assumes the space is also physically contiguous */
- if (pmap_extract(pmap_kernel(), va, &pa) != FALSE) {
- switch (op) {
- case DMA_CACHE_SYNC:
- m8820x_cmmu_sync_cache(pa, size);
- break;
- case DMA_CACHE_SYNC_INVAL:
- m8820x_cmmu_sync_inval_cache(pa, size);
- break;
- default:
- m8820x_cmmu_inval_cache(pa, size);
- break;
- }
- }
-#endif /* !BROKEN_MMU_MASK */
-}
-
-void
-m8820x_dma_cachectl_pa(paddr_t pa, psize_t size, int op)
-{
-#if !defined(BROKEN_MMU_MASK)
- psize_t count;
-
- while (size != 0) {
- count = NBPG - (va & PGOFSET);
-
- if (size < count)
- count = size;
-
- switch (op) {
- case DMA_CACHE_SYNC:
- m8820x_cmmu_sync_cache(pa, count);
- break;
- case DMA_CACHE_SYNC_INVAL:
- m8820x_cmmu_sync_inval_cache(pa, count);
- break;
- default:
- m8820x_cmmu_inval_cache(pa, count);
- break;
- }
-
- pa += count;
- size -= count;
- }
-#else
- switch (op) {
- case DMA_CACHE_SYNC:
- m8820x_cmmu_sync_cache(pa, size);
- break;
- case DMA_CACHE_SYNC_INVAL:
- m8820x_cmmu_sync_inval_cache(pa, size);
- break;
- default:
- m8820x_cmmu_inval_cache(pa, size);
- break;
- }
-#endif /* !BROKEN_MMU_MASK */
-}
-
-#ifdef DDB
-/*
- * Show (for debugging) how the current CPU translates the given ADDRESS
- * (as DATA).
- */
-void
-m8820x_cmmu_show_translation(unsigned address, unsigned supervisor_flag,
- unsigned verbose_flag, int unused __attribute__ ((unused)))
-{
- int cpu = cpu_number();
- vaddr_t va = address;
- int cmmu_num;
- u_int32_t value;
-
- /*
- * Find the correct data CMMU.
- */
- for (cmmu_num = cpu << cmmu_shift;
- cmmu_num < (cpu + 1) << cmmu_shift; cmmu_num++) {
- if (m8820x_cmmu[cmmu_num].cmmu_type != DATA_CMMU)
- continue;
- if (m8820x_cmmu[cmmu_num].cmmu_addr_mask == 0 ||
- (va & m8820x_cmmu[cmmu_num].cmmu_addr_mask) ==
- m8820x_cmmu[cmmu_num].cmmu_addr)
- break;
- }
- if (cmmu_num == (cpu + 1) << cmmu_shift) {
- db_printf("No matching cmmu for VA %08x\n", address);
- return;
- }
-
- if (verbose_flag != 0)
- db_printf("VA %08x is managed by CMMU#%d.\n",
- address, cmmu_num);
-
- /*
- * Perform some sanity checks.
- */
- if (verbose_flag == 0) {
- if ((m8820x_cmmu[cmmu_num].cmmu_regs[CMMU_SCTR] &
- CMMU_SCTR_SE) == 0)
- db_printf("WARNING: snooping not enabled for CMMU#%d.\n",
- cmmu_num);
- } else {
- int i;
-
- for (i = 0; i < max_cmmus; i++)
- if (m8820x_cmmu[i].cmmu_type != NO_CMMU &&
- (verbose_flag > 1 ||
- (m8820x_cmmu[i].cmmu_regs[CMMU_SCTR] &
- CMMU_SCTR_SE) == 0)) {
- db_printf("CMMU#%d (cpu %d %s) snooping %s\n",
- i, m8820x_cmmu[i].cmmu_cpu,
- m8820x_cmmu[i].cmmu_type ? "data" : "inst",
- (m8820x_cmmu[i].cmmu_regs[CMMU_SCTR] &
- CMMU_SCTR_SE) ? "on":"OFF");
- }
- }
-
- /*
- * Ask for a CMMU probe and report its result.
- */
- {
- volatile unsigned *cmmu_regs = m8820x_cmmu[cmmu_num].cmmu_regs;
- u_int32_t ssr;
-
- cmmu_regs[CMMU_SAR] = address;
- cmmu_regs[CMMU_SCR] =
- supervisor_flag ? CMMU_PROBE_SUPER : CMMU_PROBE_USER;
- ssr = cmmu_regs[CMMU_SSR];
-
- switch (verbose_flag) {
- case 2:
- db_printf("probe of 0x%08x returns ssr=0x%08x\n",
- address, ssr);
- /* FALLTHROUGH */
- case 1:
- if (ssr & CMMU_SSR_V)
- db_printf("PROBE of 0x%08x returns phys=0x%x",
- address, cmmu_regs[CMMU_SAR]);
- else
- db_printf("PROBE fault at 0x%x",
- cmmu_regs[CMMU_PFAR]);
- if (ssr & CMMU_SSR_CE)
- db_printf(", copyback err");
- if (ssr & CMMU_SSR_BE)
- db_printf(", bus err");
- if (ssr & CACHE_WT)
- db_printf(", writethrough");
- if (ssr & CMMU_SSR_SO)
- db_printf(", sup prot");
- if (ssr & CACHE_GLOBAL)
- db_printf(", global");
- if (ssr & CACHE_INH)
- db_printf(", cache inhibit");
- if (ssr & CMMU_SSR_M)
- db_printf(", modified");
- if (ssr & CMMU_SSR_U)
- db_printf(", used");
- if (ssr & CMMU_SSR_PROT)
- db_printf(", write prot");
- if (ssr & CMMU_SSR_BH)
- db_printf(", BATC");
- db_printf(".\n");
- break;
- }
- }
-
- /*
- * Interpret area descriptor.
- */
-
- if (supervisor_flag)
- value = m8820x_cmmu[cmmu_num].cmmu_regs[CMMU_SAPR];
- else
- value = m8820x_cmmu[cmmu_num].cmmu_regs[CMMU_UAPR];
-
- switch (verbose_flag) {
- case 2:
- db_printf("CMMU#%d", cmmu_num);
- db_printf(" %cAPR is 0x%08x\n",
- supervisor_flag ? 'S' : 'U', value);
- /* FALLTHROUGH */
- case 1:
- db_printf("CMMU#%d", cmmu_num);
- db_printf(" %cAPR: SegTbl: 0x%x000p",
- supervisor_flag ? 'S' : 'U', PG_PFNUM(value));
- if (value & CACHE_WT)
- db_printf(", WTHRU");
- if (value & CACHE_GLOBAL)
- db_printf(", GLOBAL");
- if (value & CACHE_INH)
- db_printf(", INHIBIT");
- if (value & APR_V)
- db_printf(", VALID");
- db_printf("\n");
- break;
- }
-
- if ((value & APR_V) == 0) {
- db_printf("VA 0x%08x -> apr 0x%08x not valid\n", va, value);
- return;
- }
-
- value &= PG_FRAME; /* now point to seg page */
-
- /*
- * Walk segment and page tables to find our page.
- */
- {
- sdt_entry_t sdt;
-
- if (verbose_flag)
- db_printf("will follow to entry %d of page at 0x%x...\n",
- SDTIDX(va), value);
- value |= SDTIDX(va) * sizeof(sdt_entry_t);
-
- if (badwordaddr((vaddr_t)value)) {
- db_printf("VA 0x%08x -> segment table @0x%08x not accessible\n",
- va, value);
- return;
- }
-
- sdt = *(sdt_entry_t *)value;
- switch (verbose_flag) {
- case 2:
- db_printf("SEG DESC @0x%x is 0x%08x\n", value, sdt);
- /* FALLTHROUGH */
- case 1:
- db_printf("SEG DESC @0x%x: PgTbl: 0x%x000",
- value, PG_PFNUM(sdt));
- if (sdt & CACHE_WT)
- db_printf(", WTHRU");
- if (sdt & SG_SO)
- db_printf(", S-PROT");
- if (sdt & CACHE_GLOBAL)
- db_printf(", GLOBAL");
- if (sdt & CACHE_INH)
- db_printf(", $INHIBIT");
- if (sdt & SG_PROT)
- db_printf(", W-PROT");
- if (sdt & SG_V)
- db_printf(", VALID");
- db_printf(".\n");
- break;
- }
-
- if ((sdt & SG_V) == 0) {
- db_printf("VA 0x%08x -> segment entry 0x%8x @0x%08x not valid\n",
- va, sdt, value);
- return;
- }
-
- value = ptoa(PG_PFNUM(sdt));
- }
-
- {
- pt_entry_t pte;
-
- if (verbose_flag)
- db_printf("will follow to entry %d of page at 0x%x...\n",
- PDTIDX(va), value);
- value |= PDTIDX(va) * sizeof(pt_entry_t);
-
- if (badwordaddr((vaddr_t)value)) {
- db_printf("VA 0x%08x -> page table entry @0x%08x not accessible\n",
- va, value);
- return;
- }
-
- pte = *(pt_entry_t *)value;
- switch (verbose_flag) {
- case 2:
- db_printf("PAGE DESC @0x%x is 0x%08x.\n", value, pte);
- /* FALLTHROUGH */
- case 1:
- db_printf("PAGE DESC @0x%x: page @%x000",
- value, PG_PFNUM(pte));
- if (pte & PG_W)
- db_printf(", WIRE");
- if (pte & CACHE_WT)
- db_printf(", WTHRU");
- if (pte & PG_SO)
- db_printf(", S-PROT");
- if (pte & CACHE_GLOBAL)
- db_printf(", GLOBAL");
- if (pte & CACHE_INH)
- db_printf(", $INHIBIT");
- if (pte & PG_M)
- db_printf(", MOD");
- if (pte & PG_U)
- db_printf(", USED");
- if (pte & PG_PROT)
- db_printf(", W-PROT");
- if (pte & PG_V)
- db_printf(", VALID");
- db_printf(".\n");
- break;
- }
-
- if ((pte & PG_V) == 0) {
- db_printf("VA 0x%08x -> page table entry 0x%08x @0x%08x not valid\n",
- va, pte, value);
- return;
- }
-
- value = ptoa(PG_PFNUM(pte)) | (va & PAGE_MASK);
- }
-
- db_printf("VA 0x%08x -> PA 0x%08x\n", va, value);
-}
-#endif /* DDB */