diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2010-04-18 22:04:40 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2010-04-18 22:04:40 +0000 |
commit | a438e324e70ca6e94ae333db346240ab09a6c153 (patch) | |
tree | bb39d26c835f463cab516422f6881bd8ac88006e /sys/arch | |
parent | 23aedc2af582c445ff84e97ff328d37e54d80eba (diff) |
Work in progress support for AViiON models 4600 and 530.
Also features support for {awkw,bast}ard 6:1 CMMU:CPU configurations (4I2D).
Tested on model 4605, which runs up to cpu_initclocks(), which is not written
for this system family yet. No regression on model 4300.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/aviion/aviion/av400_machdep.c | 23 | ||||
-rw-r--r-- | sys/arch/aviion/aviion/av530_machdep.c | 583 | ||||
-rw-r--r-- | sys/arch/aviion/aviion/eh.S | 52 | ||||
-rw-r--r-- | sys/arch/aviion/aviion/m8820x.c | 59 | ||||
-rw-r--r-- | sys/arch/aviion/conf/GENERIC | 4 | ||||
-rw-r--r-- | sys/arch/aviion/dev/vme.c | 67 | ||||
-rw-r--r-- | sys/arch/aviion/include/av400.h | 10 | ||||
-rw-r--r-- | sys/arch/aviion/include/av530.h | 191 | ||||
-rw-r--r-- | sys/arch/aviion/include/board.h | 6 | ||||
-rw-r--r-- | sys/arch/m88k/include/m8820x.h | 6 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/m8820x_machdep.c | 57 |
11 files changed, 974 insertions, 84 deletions
diff --git a/sys/arch/aviion/aviion/av400_machdep.c b/sys/arch/aviion/aviion/av400_machdep.c index 3948ae39039..8b4502c7bc7 100644 --- a/sys/arch/aviion/aviion/av400_machdep.c +++ b/sys/arch/aviion/aviion/av400_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: av400_machdep.c,v 1.14 2009/02/16 22:54:59 miod Exp $ */ +/* $OpenBSD: av400_machdep.c,v 1.15 2010/04/18 22:04:37 miod Exp $ */ /* * Copyright (c) 2006, 2007, Miodrag Vallat. * @@ -159,7 +159,7 @@ #include <aviion/dev/sysconvar.h> #include <aviion/dev/vmevar.h> -u_int safe_level(u_int mask, u_int curlevel); +u_int av400_safe_level(u_int, u_int); const pmap_table_entry av400_ptable[] = { @@ -183,7 +183,16 @@ const struct board board_av400 = { av400_setipl, av400_raiseipl, av400_intsrc, - av400_ptable + + av400_ptable, + + AV400_VME16_BASE, + AV400_VME16_START, AV400_VME16_END, + AV400_VME24_BASE, + AV400_VME24_START, AV400_VME24_END, + AV400_VME32_BASE, + AV400_VME32_START1, AV400_VME32_END1, + AV400_VME32_START2, AV400_VME32_END2 }; /* @@ -199,7 +208,7 @@ const struct board board_av400 = { * Note that, on the AV400 design, the interrupt enable registers are * write-only and read back as 0xffffffff. */ -u_int32_t int_mask_reg[] = { 0, 0, 0, 0 }; +static u_int32_t int_mask_reg[] = { 0, 0, 0, 0 }; u_int av400_curspl[] = { IPL_HIGH, IPL_HIGH, IPL_HIGH, IPL_HIGH }; @@ -275,7 +284,7 @@ av400_bootstrap() * while keeping ``mask'' masked. */ u_int -safe_level(u_int mask, u_int curlevel) +av400_safe_level(u_int mask, u_int curlevel) { int i; @@ -380,7 +389,7 @@ av400_intsrc(int i) /* * Provide the interrupt source for a given interrupt status bit. */ -const u_int obio_vec[32] = { +static const u_int obio_vec[32] = { 0, /* SWI0 */ 0, /* SWI1 */ 0, @@ -461,7 +470,7 @@ av400_intr(struct trapframe *eframe) * priority. */ do { - level = safe_level(cur_mask, old_spl); + level = av400_safe_level(cur_mask, old_spl); av400_setipl(level); if (unmasked == 0) { diff --git a/sys/arch/aviion/aviion/av530_machdep.c b/sys/arch/aviion/aviion/av530_machdep.c new file mode 100644 index 00000000000..f965852693c --- /dev/null +++ b/sys/arch/aviion/aviion/av530_machdep.c @@ -0,0 +1,583 @@ +/* $OpenBSD: av530_machdep.c,v 1.1 2010/04/18 22:04:37 miod Exp $ */ +/* + * Copyright (c) 2006, 2007, 2010 Miodrag Vallat. + * + * 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. + * + * 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. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/errno.h> + +#include <uvm/uvm_extern.h> + +#include <machine/asm_macro.h> +#include <machine/board.h> +#include <machine/bus.h> +#include <machine/cmmu.h> +#include <machine/cpu.h> +#include <machine/trap.h> + +#include <machine/m88100.h> +#include <machine/m8820x.h> +#include <machine/avcommon.h> +#include <machine/av530.h> +#include <machine/prom.h> + +#include <aviion/dev/sysconvar.h> +#include <aviion/dev/vmevar.h> + +u_int av530_safe_level(u_int, u_int, u_int); + +const pmap_table_entry +av530_ptable[] = { + { AV530_PROM, AV530_PROM, AV530_PROM_SIZE, + UVM_PROT_RW, CACHE_INH }, +#if 0 /* mapped by the hardcoded BATC entries */ + { AV530_UTILITY,AV530_UTILITY, AV530_UTILITY_SIZE, + UVM_PROT_RW, CACHE_INHIBIT }, +#endif + { 0, 0, (vsize_t)-1, 0, 0 } +}; + +const struct board board_av530 = { + "530/4600 series", + av530_bootstrap, + av530_memsize, + av530_startup, + av530_intr, + NULL, /* XXX need PIT clock code */ + av530_getipl, + av530_setipl, + av530_raiseipl, + av530_intsrc, + + av530_ptable, + + AV530_VME16_BASE, + AV530_VME16_START, AV530_VME16_END, + AV530_VME24_BASE, + AV530_VME24_START, AV530_VME24_END, + AV530_VME32_BASE, + AV530_VME32_START1, AV530_VME32_END1, + AV530_VME32_START2, AV530_VME32_END2 +}; + +/* + * The MVME188 interrupt arbiter has 25 orthogonal interrupt sources. + * On the AViiON 530 machines, there are even more interrupt sources in use, + * requiring the use of two arbiters. + * We fold this model in the 8-level spl model this port uses, enforcing + * priorities manually with the interrupt masks. + */ + +/* + * Copy of the interrupt enable registers for each CPU. + * Note that, on the AV530 design, the interrupt enable registers are + * write-only and read back as 0xffffffff. + */ +static u_int32_t int_mask_reg[] = { 0, 0, 0, 0 }; +static u_int32_t ext_int_mask_reg[] = { 0, 0, 0, 0 }; + +u_int av530_curspl[] = { IPL_HIGH, IPL_HIGH, IPL_HIGH, IPL_HIGH }; + +#ifdef MULTIPROCESSOR +/* + * Interrupts allowed on secondary processors. + */ +#define SLAVE_MASK 0 /* IRQ_SWI0 | IRQ_SWI1 */ +#define SLAVE_EXMASK 0 +#endif + +/* + * Figure out how much memory is available, by asking the PROM. + */ +vaddr_t +av530_memsize() +{ + vaddr_t memsize0, memsize1; + + memsize0 = scm_memsize(0); + memsize1 = scm_memsize(1); + + /* + * What we got is the ``top of memory'', i.e. the largest addressable + * word address, ending in 0xffc. Round up to a multiple of a page. + */ + memsize0 = round_page(memsize0); + memsize1 = round_page(memsize1); + + physmem = atop(memsize0); + return (memsize1); +} + +void +av530_startup() +{ +} + +int32_t cpuid, sysid; + +void +av530_bootstrap() +{ + extern struct cmmu_p cmmu8820x; + extern u_char hostaddr[6]; + uint32_t whoami; + + /* + * Set up CMMU addresses. We need to access the WHOAMI register + * early since addresses differ between the 6:1 and 2:1 designs. + */ + cmmu = &cmmu8820x; + whoami = (*(volatile u_int32_t *)AV_WHOAMI & 0xf0) >> 4; + switch (whoami) { + default: /* 2:1 systems */ + m8820x_cmmu[0].cmmu_regs = (void *)AV530_CMMU_I0; + m8820x_cmmu[1].cmmu_regs = (void *)AV530_CMMU_D0; + m8820x_cmmu[2].cmmu_regs = (void *)AV530_CMMU_I1; + m8820x_cmmu[3].cmmu_regs = (void *)AV530_CMMU_D1; + break; + case 3: + case 7: /* 6:1 systems */ + m8820x_cmmu[0].cmmu_regs = (void *)AV530_CMMU6_I0; + m8820x_cmmu[1].cmmu_regs = (void *)AV530_CMMU6_D0; + m8820x_cmmu[2].cmmu_regs = (void *)AV530_CMMU6_I1; + m8820x_cmmu[3].cmmu_regs = (void *)AV530_CMMU6_D1; + m8820x_cmmu[4].cmmu_regs = (void *)AV530_CMMU6_I2; + m8820x_cmmu[6].cmmu_regs = (void *)AV530_CMMU6_I3; + + m8820x_cmmu[8].cmmu_regs = (void *)AV530_CMMU6_I4; + m8820x_cmmu[9].cmmu_regs = (void *)AV530_CMMU6_D2; + m8820x_cmmu[10].cmmu_regs = (void *)AV530_CMMU6_I5; + m8820x_cmmu[11].cmmu_regs = (void *)AV530_CMMU6_D3; + m8820x_cmmu[12].cmmu_regs = (void *)AV530_CMMU6_I6; + m8820x_cmmu[14].cmmu_regs = (void *)AV530_CMMU6_I7; + break; + } + + /* clear and disable all interrupts */ + *(volatile u_int32_t *)AV_IENALL = 0; + *(volatile u_int32_t *)AV_EXIENALL = 0; + + /* + * Get all the information we'll need later from the PROM, while + * we can still use it. + */ + scm_getenaddr(hostaddr); + cpuid = scm_cpuid(); + sysid = scm_sysid(); +} + +/* + * Return the next ipl >= ``curlevel'' at which we can reenable interrupts + * while keeping ``mask'' masked. + */ +u_int +av530_safe_level(u_int mask, u_int exmask, u_int curlevel) +{ + int i; + + for (i = curlevel; i < NIPLS; i++) + if ((int_mask_val[i] & mask) == 0 && + (ext_int_mask_val[i] & exmask) == 0) + return i; + + return (NIPLS - 1); +} + +u_int +av530_getipl(void) +{ + return av530_curspl[cpu_number()]; +} + +u_int +av530_setipl(u_int level) +{ + u_int32_t mask, exmask, curspl, psr; + u_int cpu = cpu_number(); + + psr = get_psr(); + set_psr(psr | PSR_IND); + curspl = av530_curspl[cpu]; + + mask = int_mask_val[level]; + exmask = ext_int_mask_val[level]; +#ifdef MULTIPROCESSOR + if (cpu != master_cpu) { + mask &= SLAVE_MASK; + exmask &= SLAVE_EXMASK; + } +#endif + + av530_curspl[cpu] = level; + *(u_int32_t *)AV_IEN(cpu) = int_mask_reg[cpu] = mask; + *(u_int32_t *)AV_EXIEN(cpu) = ext_int_mask_reg[cpu] = exmask; + /* + * We do not flush the pipeline here, because interrupts are disabled, + * and set_psr() will synchronize the pipeline. + */ + set_psr(psr); + + return curspl; +} + +u_int +av530_raiseipl(u_int level) +{ + u_int32_t mask, exmask, curspl, psr; + u_int cpu = cpu_number(); + + psr = get_psr(); + set_psr(psr | PSR_IND); + curspl = av530_curspl[cpu]; + if (curspl < level) { + mask = int_mask_val[level]; + exmask = ext_int_mask_val[level]; +#ifdef MULTIPROCESSOR + if (cpu != master_cpu) { + mask &= SLAVE_MASK; + exmask &= SLAVE_EXMASK; + } +#endif + + av530_curspl[cpu] = level; + *(u_int32_t *)AV_IEN(cpu) = int_mask_reg[cpu] = mask; + *(u_int32_t *)AV_EXIEN(cpu) = ext_int_mask_reg[cpu] = exmask; + } + /* + * We do not flush the pipeline here, because interrupts are disabled, + * and set_psr() will synchronize the pipeline. + */ + set_psr(psr); + + return curspl; +} + +/* + * Provide the interrupt masks for a given logical interrupt source. + */ +u_int64_t +av530_intsrc(int i) +{ + static const u_int32_t intsrc[] = { + 0, + IRQ_ABORT, + IRQ_ACF, + IRQ_SF, + 0, /* XXX no clock */ + IRQ_DI, + 0, + 0, + 0, + 0, + 0, + IRQ_VME1, + IRQ_VME2, + IRQ_VME3, + IRQ_VME4, + IRQ_VME5, + IRQ_VME6, + IRQ_VME7 + }, ext_intsrc[] = { + 0, + 0, + 0, + 0, + 0, + 0, + EXIRQ_DUART2, + EXIRQ_LAN0, + EXIRQ_LAN1, + EXIRQ_SCSI0, + EXIRQ_SCSI1, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + }; + uint64_t isrc; + + isrc = ext_intsrc[i]; + isrc = (isrc << 32) | intsrc[i]; + return isrc; +} + +/* + * Provide the interrupt source for a given interrupt status bit. + */ +static const u_int obio_vec[32] = { + 0, /* SWI0 */ + 0, /* SWI1 */ + 0, /* SWI2 */ + 0, /* SWI3 */ + INTSRC_VME, /* VME1 */ + 0, + INTSRC_VME, /* VME2 */ + 0, /* SIGLPI */ + 0, /* LMI */ + 0, + INTSRC_VME, /* VME3 */ + 0, + INTSRC_VME, /* VME4 */ + 0, + INTSRC_VME, /* VME5 */ + 0, + 0, /* HPI */ + INTSRC_DUART1, /* DI */ + 0, /* MEM */ + INTSRC_VME, /* VME6 */ + INTSRC_SYSFAIL, /* SF */ + 0, + 0, /* KBD */ + INTSRC_VME, /* VME7 */ + 0, /* SWI4 */ + 0, /* SWI5 */ + 0, /* SWI6 */ + 0, /* SWI7 */ + 0, /* DTI */ + 0, /* ARBTO */ + INTSRC_ACFAIL, /* ACF */ + INTSRC_ABORT /* ABORT */ +}; +static const u_int obio_exvec[32] = { + 0, + 0, + 0, + 0, + 0, + 0, /* PDMA */ + 0, /* IOEXP2 */ + 0, + 0, /* IOEXP1 */ + 0, + 0, + 0, + 0, /* VDMA */ + INTSRC_DUART2, /* DUART2 */ + 0, /* ZBUF */ + 0, /* VIDEO */ + INTSRC_SCSI2, /* SCSI1 */ + INTSRC_SCSI1, /* SCSI0 */ + INTSRC_ETHERNET2, /* LAN1 */ + INTSRC_ETHERNET1, /* LAN0 */ + 0, /* SCC */ + 0, /* DMA0C */ + 0, /* DMA1C */ + 0, /* DMA2C */ + 0, /* DMA3C */ + 0, /* DMA4C */ + 0, + 0, /* PIT0OF */ + 0, /* PIT1OF */ + 0, /* PIT2OF */ + 0, /* PIT3OF */ + 0 /* RTCOF */ +}; + +/* + * Device interrupt handler for AV530 + */ + +#define VME_VECTOR_MASK 0x1ff /* mask into VIACK register */ +#define VME_BERR_MASK 0x100 /* timeout during VME IACK cycle */ + +void +av530_intr(struct trapframe *eframe) +{ + int cpu = cpu_number(); + u_int32_t cur_mask, ign_mask; + u_int32_t cur_exmask, ign_exmask; + u_int level, old_spl; + struct intrhand *intr; + intrhand_t *list; + int ret, intbit; + vaddr_t ivec; + u_int intsrc, vec; + int unmasked = 0; + int warn; +#ifdef DIAGNOSTIC + static int problems = 0; +#endif + + cur_mask = ISR_GET_CURRENT_MASK(cpu); + cur_exmask = EXISR_GET_CURRENT_MASK(cpu); + ign_mask = 0; + ign_exmask = 0; + old_spl = eframe->tf_mask; + + if (cur_mask == 0 && cur_exmask == 0) { + /* + * Spurious interrupts - may be caused by debug output clearing + * DUART interrupts. + */ + flush_pipeline(); + goto out; + } + + uvmexp.intrs++; + + /* + * We want to service all interrupts marked in the IST register + * They are all valid because the mask would have prevented them + * from being generated otherwise. We will service them in order of + * priority. + */ + for (;;) { + cur_mask = ISR_GET_CURRENT_MASK(cpu); + cur_exmask = EXISR_GET_CURRENT_MASK(cpu); + if ((cur_mask & ~ign_mask) == 0 && + (cur_exmask & ~ign_exmask) == 0) + break; + + level = av530_safe_level(cur_mask, cur_exmask, old_spl); + av530_setipl(level); + + if (unmasked == 0) { + set_psr(get_psr() & ~PSR_IND); + unmasked = 1; + } + + /* find the first bit set in the current mask */ + warn = 0; + if (cur_mask != 0) { + intbit = ff1(cur_mask); + intsrc = obio_vec[intbit]; + + if (intsrc == 0) + panic("%s: unexpected interrupt source" + " (bit %d), level %d, mask 0x%b", + __func__, intbit, level, + cur_mask, IST_STRING); + } else { + intbit = ff1(cur_exmask); + intsrc = obio_exvec[intbit]; + + if (intsrc == 0) + panic("%s: unexpected extended interrupt source" + " (bit %d), level %d, mask 0x%b", + __func__, intbit, level, + cur_exmask, EXIST_STRING); + } + + if (intsrc == INTSRC_VME) { + ivec = AV530_VIRQLV + (level << 2); + vec = *(volatile u_int32_t *)ivec & VME_VECTOR_MASK; + if (vec & VME_BERR_MASK) { + /* no need to dump exmask for vme intr */ + printf("%s: timeout getting VME " + "interrupt vector, " + "level %d, mask 0x%b\n", + __func__, level, + cur_mask, IST_STRING); + ign_mask |= 1 << intbit; + continue; + } + list = &vmeintr_handlers[vec]; + } else { + list = &sysconintr_handlers[intsrc]; + } + + if (SLIST_EMPTY(list)) { + warn = 1; + } else { + /* + * Walk through all interrupt handlers in the chain + * for the given vector, calling each handler in turn, + * until some handler returns a value != 0. + */ + ret = 0; + SLIST_FOREACH(intr, list, ih_link) { + if (ISSET(intr->ih_flags, INTR_WANTFRAME)) + ret = (*intr->ih_fn)((void *)eframe); + else + ret = (*intr->ih_fn)(intr->ih_arg); + if (ret != 0) { + intr->ih_count.ec_count++; + break; + } + } + if (ret == 0) + warn = 2; + } + + if (warn != 0) { + if (cur_mask != 0) + ign_mask |= 1 << intbit; + else + ign_exmask |= 1 << intbit; + + if (intsrc == INTSRC_VME) + printf("%s: %s VME interrupt, " + "level %d, vec 0x%x, mask 0x%b\n", + __func__, + warn == 1 ? "spurious" : "unclaimed", + level, vec, cur_mask, IST_STRING); + else { + if (cur_mask != 0) + printf("%s: %s interrupt, " + "level %d, bit %d, mask 0x%b\n", + __func__, + warn == 1 ? + "spurious" : "unclaimed", + level, intbit, + cur_mask, IST_STRING); + else + printf("%s: %s extended interrupt, " + "level %d, bit %d, mask 0x%b\n", + __func__, + warn == 1 ? + "spurious" : "unclaimed", + level, intbit, + cur_exmask, EXIST_STRING); + } + } + } + +#ifdef DIAGNOSTIC + if (ign_mask != 0 || ign_exmask != 0) { + if (++problems >= 10) + panic("%s: broken interrupt behaviour", __func__); + } else + problems = 0; +#endif + +out: + /* + * process any remaining data access exceptions before + * returning to assembler + */ + if (eframe->tf_dmt0 & DMT_VALID) + m88100_trap(T_DATAFLT, eframe); + + /* + * Disable interrupts before returning to assembler, the spl will + * be restored later. + */ + set_psr(get_psr() | PSR_IND); +} diff --git a/sys/arch/aviion/aviion/eh.S b/sys/arch/aviion/aviion/eh.S index 630cc79fbcd..99b0de93575 100644 --- a/sys/arch/aviion/aviion/eh.S +++ b/sys/arch/aviion/aviion/eh.S @@ -1,6 +1,6 @@ -/* $OpenBSD: eh.S,v 1.5 2007/12/21 23:56:53 miod Exp $ */ +/* $OpenBSD: eh.S,v 1.6 2010/04/18 22:04:37 miod Exp $ */ /* - * Copyright (c) 2006, Miodrag Vallat + * Copyright (c) 2006, 2010 Miodrag Vallat * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -36,7 +36,7 @@ #include <m88k/m88k/eh_common.S> -ENTRY(pfsr_av400_double) +ENTRY(pfsr_double) /* * 4 CMMUs per CPU. Almost as simple as the 2 CMMUs per CPU * situation... @@ -68,7 +68,7 @@ ENTRY(pfsr_av400_double) br.n _ASM_LABEL(pfsr_done) st TMP3, r31, EF_DPFSR -ENTRY(pfsr_av400_straight) +ENTRY(pfsr_straight) /* * We have the simple 2 CMMUs per CPU mapping. Pick our couple; * no need to reset fault status registers in this case. @@ -80,3 +80,47 @@ ENTRY(pfsr_av400_straight) ld TMP3, TMP2, r0 br.n _ASM_LABEL(pfsr_done) st TMP3, r31, EF_DPFSR + +ENTRY(pfsr_six) + /* + * 6 CMMU (2D4I) per CPU. + * This is the worst situation. We handle the data CMMU first, + * using the cpu_info pointers; and then the instruction CMMU, + * relying upon them being set up every 0x1000 bytes in the + * address space. + */ + ld TMP2, TMP, CI_PFSR_D0 + ld TMP3, TMP2, r0 + extu TMP3, TMP3, 3<16> + bcnd ne0, TMP3, 1f + st r0, TMP2, r0 + ld TMP2, TMP, CI_PFSR_D1 +1: + ld TMP3, TMP2, r0 + st r0, TMP2, r0 + st TMP3, r31, EF_DPFSR + + ld TMP2, TMP, CI_PFSR_I0 + ld TMP3, TMP2, r0 + extu TMP3, TMP3, 3<16> + bcnd ne0, TMP3, 2f + st r0, TMP2, r0 + + addu TMP2, TMP2, 0x1000 /* I1 */ + ld TMP3, TMP2, r0 + extu TMP3, TMP3, 3<16> + bcnd ne0, TMP3, 2f + st r0, TMP2, r0 + + addu TMP2, TMP2, 0x1000 /* I2 */ + ld TMP3, TMP2, r0 + extu TMP3, TMP3, 3<16> + bcnd ne0, TMP3, 2f + st r0, TMP2, r0 + + addu TMP2, TMP2, 0x1000 /* I3 */ +2: + ld TMP3, TMP2, r0 + st r0, TMP2, r0 + br.n _ASM_LABEL(pfsr_done) + st TMP3, r31, EF_IPFSR diff --git a/sys/arch/aviion/aviion/m8820x.c b/sys/arch/aviion/aviion/m8820x.c index 79b6392a3fe..f0b6277d075 100644 --- a/sys/arch/aviion/aviion/m8820x.c +++ b/sys/arch/aviion/aviion/m8820x.c @@ -1,6 +1,6 @@ -/* $OpenBSD: m8820x.c,v 1.6 2009/04/19 17:56:12 miod Exp $ */ +/* $OpenBSD: m8820x.c,v 1.7 2010/04/18 22:04:37 miod Exp $ */ /* - * Copyright (c) 2004, 2006, Miodrag Vallat. + * Copyright (c) 2004, 2006, 2010 Miodrag Vallat. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -36,8 +36,9 @@ #include <machine/m8820x.h> #include <machine/prom.h> -extern u_int32_t pfsr_av400_straight[]; -extern u_int32_t pfsr_av400_double[]; +extern u_int32_t pfsr_straight[]; +extern u_int32_t pfsr_double[]; +extern u_int32_t pfsr_six[]; /* * This routine sets up the CPU/CMMU configuration. @@ -48,7 +49,7 @@ m8820x_setup_board_config() extern u_int32_t pfsr_save[]; struct m8820x_cmmu *cmmu; struct scm_cpuconfig scc; - int type, cpu_num, cmmu_num; + int type, cpu_num, cpu_cmmu_num, cmmu_num, cmmu_per_cpu; volatile u_int *cr; u_int32_t whoami; u_int32_t *m8820x_pfsr; @@ -57,6 +58,9 @@ m8820x_setup_board_config() * First, find if any CPU0 CMMU is a 88204. If so, we can * issue the CPUCONFIG system call to get the configuration * details. + * NOTE that this relies upon [0] and [1] to always have + * valid CMMU addresses - thankfully this is always the case + * on model 530 regardless of the CMMU configuration. */ if (badaddr((vaddr_t)m8820x_cmmu[0].cmmu_regs, 4) != 0 || badaddr((vaddr_t)m8820x_cmmu[1].cmmu_regs, 4) != 0) { @@ -110,8 +114,11 @@ hardprobe: * slots we can ignore, and keep using badaddr() to cope * with unpopulated slots. */ - cmmu = m8820x_cmmu + 7; - for (max_cmmus = 7; max_cmmus != 0; max_cmmus--, cmmu--) { + cmmu = m8820x_cmmu + MAX_CMMUS - 1; + for (max_cmmus = MAX_CMMUS - 1; max_cmmus != 0; + max_cmmus--, cmmu--) { + if (cmmu->cmmu_regs == NULL) + continue; if (badaddr((vaddr_t)cmmu->cmmu_regs, 4) == 0) break; } @@ -122,8 +129,8 @@ hardprobe: /* * Deduce our configuration from the WHOAMI register. */ - whoami = *(volatile u_int32_t *)AV_WHOAMI; - switch ((whoami & 0xf0) >> 4) { + whoami = (*(volatile u_int32_t *)AV_WHOAMI & 0xf0) >> 4; + switch (whoami) { case 0: /* 4 CPUs, 8 CMMUs */ scc.cpucount = 4; break; @@ -135,10 +142,16 @@ hardprobe: break; case 3: /* 2 CPUs, 12 CMMUs */ case 7: /* 1 CPU, 6 CMMU */ - printf("MAYDAY, 6:1 CMMU configuration (whoami %x)" - " but no CPUCONFIG information\n", whoami); - scm_halt(); - /* NOTREACHED */ + /* + * + */ + ncpusfound = whoami == 7 ? 1 : 2; + cmmu_per_cpu = 6; + cmmu_shift = 3; + max_cmmus = ncpusfound << cmmu_shift; + scc.isplit = scc.dsplit = 0; /* XXX unknown */ + m8820x_pfsr = pfsr_six; + goto done; break; default: printf("unrecognized CMMU configuration, whoami %x\n", @@ -171,13 +184,15 @@ knowledge: ncpusfound = scc.cpucount; if (scc.igang == 1) { cmmu_shift = 1; - m8820x_pfsr = pfsr_av400_straight; + m8820x_pfsr = pfsr_straight; } else { cmmu_shift = 2; - m8820x_pfsr = pfsr_av400_double; + m8820x_pfsr = pfsr_double; } - max_cmmus = ncpusfound << scc.igang; + max_cmmus = ncpusfound << cmmu_shift; + cmmu_per_cpu = 1 << cmmu_shift; +done: /* * Now that we know which CMMUs are there, report every association */ @@ -189,7 +204,7 @@ knowledge: cmmu_regs[CMMU_IDR]); printf("CPU%d is associated to %d MC8820%c CMMUs\n", - cpu_num, 1 << cmmu_shift, + cpu_num, cmmu_per_cpu, type == M88204_ID ? '4' : '0'); } } @@ -201,15 +216,17 @@ knowledge: if (cmmu_shift > 1) { for (cmmu_num = 0, cmmu = m8820x_cmmu; cmmu_num < max_cmmus; cmmu_num++, cmmu++) { - cpu_num = cmmu_num >> 1; /* CPU view of the CMMU */ + cpu_cmmu_num = cmmu_num >> 1; /* CPU view of the CMMU */ - if (cmmu_num & 1) { + if (CMMU_MODE(cmmu_num) == INST_CMMU) { /* I0, I1 */ - cmmu->cmmu_addr = cpu_num < 2 ? 0 : scc.isplit; + cmmu->cmmu_addr = + cpu_cmmu_num < 2 ? 0 : scc.isplit; cmmu->cmmu_addr_mask = scc.isplit; } else { /* D0, D1 */ - cmmu->cmmu_addr = cpu_num < 2 ? 0 : scc.dsplit; + cmmu->cmmu_addr = + cpu_cmmu_num < 2 ? 0 : scc.dsplit; cmmu->cmmu_addr_mask = scc.dsplit; } } diff --git a/sys/arch/aviion/conf/GENERIC b/sys/arch/aviion/conf/GENERIC index 65faae30a96..5b0ba40d1ab 100644 --- a/sys/arch/aviion/conf/GENERIC +++ b/sys/arch/aviion/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.2 2006/05/20 12:06:51 miod Exp $ +# $OpenBSD: GENERIC,v 1.3 2010/04/18 22:04:39 miod Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -19,7 +19,7 @@ option M88100 # Supported models option AV400 # 100, 200, 300, 400, 3000, 4000, 4300 -#option AV530 # 4600, 530 +option AV530 # 4600, 530 #option AV5000 # 5000, 6000 #option AV6280 # 6280, 8000-8 diff --git a/sys/arch/aviion/dev/vme.c b/sys/arch/aviion/dev/vme.c index 456e2e7b9cb..faad62acef2 100644 --- a/sys/arch/aviion/dev/vme.c +++ b/sys/arch/aviion/dev/vme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vme.c,v 1.4 2007/12/19 22:05:06 miod Exp $ */ +/* $OpenBSD: vme.c,v 1.5 2010/04/18 22:04:39 miod Exp $ */ /* * Copyright (c) 2006, 2007, Miodrag Vallat. * @@ -46,7 +46,6 @@ #include <aviion/dev/vmevar.h> #include <machine/avcommon.h> -#include <machine/av400.h> /* XXX */ struct vmesoftc { struct device sc_dev; @@ -139,13 +138,13 @@ vmeattach(struct device *parent, struct device *self, void *aux) * Display VME ranges. */ printf("%s: A32 %08x-%08x\n", self->dv_xname, - AV400_VME32_START1, AV400_VME32_END1); + platform->vme32_start1, platform->vme32_end1); printf("%s: A32 %08x-%08x\n", self->dv_xname, - AV400_VME32_START2, AV400_VME32_END2); + platform->vme32_start2, platform->vme32_end2); printf("%s: A24 %08x-%08x\n", self->dv_xname, - AV400_VME24_START, AV400_VME24_END); + platform->vme24_start, platform->vme24_end); printf("%s: A16 %08x-%08x\n", self->dv_xname, - AV400_VME16_START, AV400_VME16_END); + platform->vme16_start, platform->vme16_end); /* scan for child devices */ config_search(vmescan, self, aux); @@ -341,16 +340,24 @@ vmeintr_disestablish(u_int vec, struct intrhand *ih) * bus_space specific functions */ +#define ISVMEA32(addr) \ + (((addr) >= platform->vme32_start1 && (addr) <= platform->vme32_end1) || \ + ((addr) >= platform->vme32_start2 && (addr) <= platform->vme32_end2)) +#define ISVMEA24(addr) \ + ((addr) >= platform->vme24_start && (addr) <= platform->vme24_end) +#define ISVMEA16(addr) \ + ((addr) >= platform->vme16_start && (addr) <= platform->vme16_end) + int vme16_map(bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *ret) { struct vmesoftc *sc = (void *)vme_cd.cd_devs[0]; - if (AV400_ISVMEA16(addr) && AV400_ISVMEA16(addr + size - 1)) - return (vme_map(sc->sc_ext_a16, addr + AV400_VME16_BASE, addr, - size, flags, ret)); - else - return (EINVAL); + if (ISVMEA16(addr) && ISVMEA16(addr + size - 1)) + return vme_map(sc->sc_ext_a16, addr + platform->vme16_base, + addr, size, flags, ret); + + return EINVAL; } int @@ -358,11 +365,11 @@ vme24_map(bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *ret) { struct vmesoftc *sc = (void *)vme_cd.cd_devs[0]; - if (AV400_ISVMEA24(addr) && AV400_ISVMEA24(addr + size - 1)) - return (vme_map(sc->sc_ext_a24, addr + AV400_VME24_BASE, addr, - size, flags, ret)); - else - return (EINVAL); + if (ISVMEA24(addr) && ISVMEA24(addr + size - 1)) + return vme_map(sc->sc_ext_a24, addr + platform->vme24_base, + addr, size, flags, ret); + + return EINVAL; } int @@ -370,11 +377,11 @@ vme32_map(bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *ret) { struct vmesoftc *sc = (void *)vme_cd.cd_devs[0]; - if (AV400_ISVMEA32(addr) && AV400_ISVMEA32(addr + size - 1)) - return (vme_map(sc->sc_ext_a32, addr + AV400_VME32_BASE, addr, - size, flags, ret)); - else - return (EINVAL); + if (ISVMEA32(addr) && ISVMEA32(addr + size - 1)) + return vme_map(sc->sc_ext_a32, addr + platform->vme32_base, + addr, size, flags, ret); + + return EINVAL; } int @@ -431,7 +438,7 @@ vme16_unmap(bus_space_handle_t handle, bus_size_t size) if (pmap_extract(pmap_kernel(), (vaddr_t)handle, &pa) == FALSE) return; - pa -= AV400_VME16_BASE; + pa -= platform->vme16_base; return (vme_unmap(sc->sc_ext_a16, pa, (vaddr_t)handle, size)); } @@ -444,7 +451,7 @@ vme24_unmap(bus_space_handle_t handle, bus_size_t size) if (pmap_extract(pmap_kernel(), (vaddr_t)handle, &pa) == FALSE) return; - pa -= AV400_VME24_BASE; + pa -= platform->vme24_base; return (vme_unmap(sc->sc_ext_a24, pa, (vaddr_t)handle, size)); } @@ -457,7 +464,7 @@ vme32_unmap(bus_space_handle_t handle, bus_size_t size) if (pmap_extract(pmap_kernel(), (vaddr_t)handle, &pa) == FALSE) return; - pa -= AV400_VME32_BASE; + pa -= platform->vme32_base; return (vme_unmap(sc->sc_ext_a32, pa, (vaddr_t)handle, size)); } @@ -643,19 +650,19 @@ vmemmap(dev_t dev, off_t off, int prot) switch (awidth) { case VME_A32: - if (!AV400_ISVMEA32(pa)) + if (!ISVMEA32(pa)) return (-1); - pa += AV400_VME32_BASE; + pa += platform->vme32_base; break; case VME_A24: - if (!AV400_ISVMEA24(pa)) + if (!ISVMEA24(pa)) return (-1); - pa += AV400_VME24_BASE; + pa += platform->vme24_base; break; case VME_A16: - if (!AV400_ISVMEA16(pa)) + if (!ISVMEA16(pa)) return (-1); - pa += AV400_VME16_BASE; + pa += platform->vme16_base; break; } diff --git a/sys/arch/aviion/include/av400.h b/sys/arch/aviion/include/av400.h index 5e3e6c6adb6..c7a38af64e3 100644 --- a/sys/arch/aviion/include/av400.h +++ b/sys/arch/aviion/include/av400.h @@ -1,4 +1,4 @@ -/* $OpenBSD: av400.h,v 1.5 2007/12/19 22:05:06 miod Exp $ */ +/* $OpenBSD: av400.h,v 1.6 2010/04/18 22:04:39 miod Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * All rights reserved. @@ -69,14 +69,6 @@ #define AV400_VME16_START 0x00000000 #define AV400_VME16_END 0x0000ffff -#define AV400_ISVMEA32(addr) \ - (((addr) >= AV400_VME32_START1 && (addr) < AV400_VME32_END1 + 1U) || \ - ((addr) >= AV400_VME32_START2 && (addr) < AV400_VME32_END2 + 1U)) -#define AV400_ISVMEA24(addr) \ - ((addr) >= AV400_VME24_START && (addr) < AV400_VME24_END + 1U) -#define AV400_ISVMEA16(addr) \ - ((addr) >= AV400_VME16_START /* && (addr) <= AV400_VME16_END */) - /* * AV400 declarations for hardware level device registers and such. */ diff --git a/sys/arch/aviion/include/av530.h b/sys/arch/aviion/include/av530.h new file mode 100644 index 00000000000..d5bb22b5827 --- /dev/null +++ b/sys/arch/aviion/include/av530.h @@ -0,0 +1,191 @@ +/* $OpenBSD: av530.h,v 1.1 2010/04/18 22:04:39 miod Exp $ */ +/* + * Copyright (c) 2006, 2010 Miodrag Vallat + * + * 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. + * + * 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. + */ + +#ifndef __MACHINE_AV530_H__ +#define __MACHINE_AV530_H__ + +#define AV530_PROM 0xffc00000 +#define AV530_PROM_SIZE 0x00080000 +#define AV530_UTILITY 0xfff00000 +#define AV530_UTILITY_SIZE 0x00100000 + +/* + * AV530 VME mappings + */ + +#define AV530_VME32_BASE 0x00000000 +#define AV530_VME32_START1 0x40000000 +#define AV530_VME32_END1 0x7fffffff +#define AV530_VME32_START2 0x90000000 +#define AV530_VME32_END2 0xfdffffff +#define AV530_VME24_BASE 0xfe000000 +#define AV530_VME24_START 0x00000000 +#define AV530_VME24_END 0x00ffffff +#define AV530_VME16_BASE 0xffff0000 +#define AV530_VME16_START 0x00000000 +#define AV530_VME16_END 0x0000ffff + +/* + * AV530 declarations for hardware level device registers and such. + */ + +#define AV530_SETSWI 0xfff84080 /* generate soft interrupt */ +#define AV530_CLRSWI 0xfff84084 /* reset soft interrupt */ + +#define AV530_VIRQLV 0xfff85000 +#define AV530_VIACK1V 0xfff85004 +#define AV530_VIACK2V 0xfff85008 +#define AV530_VIACK3V 0xfff8500c +#define AV530_VIACK4V 0xfff85010 +#define AV530_VIACK5V 0xfff85014 +#define AV530_VIACK6V 0xfff85018 +#define AV530_VIACK7V 0xfff8501c +#define AV530_VIRQV 0xfff85020 + +/* + * IEN and IST register bits + * See ``Programming System Control and I/O Registers: AViiON 4600 and + * 530 series'', section 3 (Interrupts). + */ + +#define IRQ_RESERVED 0x0020aa00 /* all reserved bits */ +#define IRQ_ABORT 0x80000000 /* 31 - Abort */ +#define IRQ_ACF 0x40000000 /* 30 - AC Fail */ +#define IRQ_ARBTO 0x20000000 /* 29 - VME Arbiter Timeout */ +#define IRQ_DTI 0x10000000 /* 28 - DUART Timer Interrupt */ +#define IRQ_SWI7 0x08000000 /* 27 - SW Interrupt level 7 */ +#define IRQ_SWI6 0x04000000 /* 26 - SW Interrupt level 6 */ +#define IRQ_SWI5 0x02000000 /* 25 - SW Interrupt level 5 */ +#define IRQ_SWI4 0x01000000 /* 24 - SW Interrupt level 4 */ +#define IRQ_VME7 0x00800000 /* 23 - VMEBus level 7 */ +#define IRQ_KBD 0x00400000 /* 22 - Keyboard */ +#define IRQ_SF 0x00100000 /* 20 - System Failure */ +#define IRQ_VME6 0x00080000 /* 19 - VMEBus level 6 */ +#define IRQ_MEM 0x00040000 /* 18 - Memory Error */ +#define IRQ_DI 0x00020000 /* 17 - DUART */ +#define IRQ_SIGHPI 0x00010000 /* 16 - SIGHPI */ +#define IRQ_VME5 0x00004000 /* 14 - VMEBus level 5 */ +#define IRQ_VME4 0x00001000 /* 12 - VMEBus level 4 */ +#define IRQ_VME3 0x00000400 /* 10 - VMEBus level 3 */ +#define IRQ_LMI 0x00000100 /* 08 - Location Monitor */ +#define IRQ_SIGLPI 0x00000080 /* 07 - SIGLPI */ +#define IRQ_VME2 0x00000040 /* 06 - VMEBus level 2 */ +#define IRQ_VME1 0x00000010 /* 04 - VMEBus level 1 */ +#define IRQ_SWI3 0x00000008 /* 03 - SW Interrupt level 3 */ +#define IRQ_SWI2 0x00000004 /* 02 - SW Interrupt level 2 */ +#define IRQ_SWI1 0x00000002 /* 01 - SW Interrupt level 1 */ +#define IRQ_SWI0 0x00000001 /* 00 - SW Interrupt level 0 */ + +#define IST_STRING "\20" \ + "\40ABRT\37ACF\36ARBTO\35DTI\34SWI7\33SWI6\32SWI5\31SWI4" \ + "\30IRQ7\27KBD\25SF\24IRQ6\23MEM\22DI\21SIGHPI" \ + "\17IRQ5\15IRQ4\13IRQ3\11LMI" \ + "\10SIGLPI\7IRQ2\5IRQ1\4SWI3\3SWI2\2SWI1\1SWI0" + +/* + * Extended interrupts + */ + +#define AV_EXIEN_BASE 0xfff8e000 +#define AV_EXIEN0 0xfff8e004 +#define AV_EXIEN1 0xfff8e008 +#define AV_EXIEN2 0xfff8e010 +#define AV_EXIEN3 0xfff8e020 +#define AV_EXIENALL 0xfff8e03c +#define AV_EXIEN(cpu) (AV_EXIEN_BASE + (4 << (cpu))) + +#define AV_EXIST 0xfff8e040 + +#define EXISR_GET_CURRENT_MASK(cpu) \ + (*(volatile u_int *)AV_EXIST & ext_int_mask_reg[cpu]) + +/* + * EXIEN and EXIST register bits + * See ``Programming System control and I/O registers for the 4600 and 530 + * series'', section 3 (Interrupts). + */ + +#define EXIRQ_RESERVED 0x04000e9f /* all reserved bits */ +#define EXIRQ_RTCOF 0x80000000 /* 31 - RTC Overflow */ +#define EXIRQ_PIT3OF 0x40000000 /* 30 - PIT 3 Overflow */ +#define EXIRQ_PIT2OF 0x20000000 /* 29 - PIT 2 Overflow */ +#define EXIRQ_PIT1OF 0x10000000 /* 28 - PIT 1 Overflow */ +#define EXIRQ_PIT0OF 0x08000000 /* 27 - PIT 0 Overflow */ +#define EXIRQ_DMA4C 0x02000000 /* 25 - DMA4 Channel Complete */ +#define EXIRQ_DMA3C 0x01000000 /* 24 - DMA3 Channel Complete */ +#define EXIRQ_DMA2C 0x00800000 /* 23 - DMA2 Channel Complete */ +#define EXIRQ_DMA1C 0x00400000 /* 22 - DMA1 Channel Complete */ +#define EXIRQ_DMA0C 0x00200000 /* 21 - DMA0 Channel Complete */ +#define EXIRQ_SCC 0x00100000 /* 20 - SCC */ +#define EXIRQ_LAN0 0x00080000 /* 19 - Ethernet 0 */ +#define EXIRQ_LAN1 0x00040000 /* 18 - Ethernet 1 */ +#define EXIRQ_SCSI0 0x00020000 /* 17 - SCSI0 */ +#define EXIRQ_SCSI1 0x00010000 /* 16 - SCSI1 */ +#define EXIRQ_VIDEO 0x00008000 /* 15 - Video */ +#define EXIRQ_ZBUF 0x00004000 /* 14 - Z Buffer */ +#define EXIRQ_DUART2 0x00002000 /* 13 - DUART2 */ +#define EXIRQ_VDMA 0x00001000 /* 12 - VDMA */ +#define EXIRQ_IOEXP1 0x00000100 /* 8 - IO Expansion 1 */ +#define EXIRQ_IOEXP2 0x00000040 /* 6 - IO Expansion 2 */ +#define EXIRQ_PDMA 0x00000020 /* 5 - Parallel Printer DMA */ + +#define EXIST_STRING "\20" \ + "\40RTCOF\37PIT3OF\36PIT2OF\35PIT1OF\34PIT0OF\32DMA4\31DMA3" \ + "\30DMA2\27DMA1\26DMA0\25SCC\24LAN0\23LAN1\22SCSI0\21SCSI1" \ + "\20VIDEO\17ZBUF\16DUART2\15VDMA\11IOEXP1" \ + "\7IOEXP2\6PDMA" + +#define AV530_SRST 0xfff83100 /* software reset */ +#define SRST_KBD 0x08 +#define SRST_DUART2 0x02 +#define SRST_DUART1 0x01 +#define AV530_IOBRDID0 0xfffcf000 +#define AV530_IOBRDID1 0xfffcf004 +#define AV530_CONFIG 0xfff8fffc + +/* + * CMMU addresses + */ + +#define AV530_CMMU_D0 0xfff00000 +#define AV530_CMMU_I0 0xfff01000 +#define AV530_CMMU_D1 0xfff02000 +#define AV530_CMMU_I1 0xfff03000 + +#define AV530_CMMU6_D0 0xfff00000 +#define AV530_CMMU6_D1 0xfff01000 +#define AV530_CMMU6_I0 0xfff04000 +#define AV530_CMMU6_I1 0xfff05000 +#define AV530_CMMU6_I2 0xfff06000 +#define AV530_CMMU6_I3 0xfff07000 +#define AV530_CMMU6_D2 0xfff08000 +#define AV530_CMMU6_D3 0xfff09000 +#define AV530_CMMU6_I4 0xfff0c000 +#define AV530_CMMU6_I5 0xfff0d000 +#define AV530_CMMU6_I6 0xfff0e000 +#define AV530_CMMU6_I7 0xfff0f000 + +#endif /* __MACHINE_AV530_H__ */ diff --git a/sys/arch/aviion/include/board.h b/sys/arch/aviion/include/board.h index 21258eadb04..a9975f6ca31 100644 --- a/sys/arch/aviion/include/board.h +++ b/sys/arch/aviion/include/board.h @@ -1,4 +1,4 @@ -/* $OpenBSD: board.h,v 1.4 2009/02/16 22:55:03 miod Exp $ */ +/* $OpenBSD: board.h,v 1.5 2010/04/18 22:04:39 miod Exp $ */ /* * Copyright (c) 2006, 2007, Miodrag Vallat * @@ -46,6 +46,10 @@ struct board { u_int64_t (*intsrc)(int); pmap_table_t ptable; + + vaddr_t vme16_base, vme16_start, vme16_end; + vaddr_t vme24_base, vme24_start, vme24_end; + vaddr_t vme32_base, vme32_start1, vme32_end1, vme32_start2, vme32_end2; }; #define md_interrupt_func(f) platform->intr(f) diff --git a/sys/arch/m88k/include/m8820x.h b/sys/arch/m88k/include/m8820x.h index d83ea886484..efb1f28a70e 100644 --- a/sys/arch/m88k/include/m8820x.h +++ b/sys/arch/m88k/include/m8820x.h @@ -1,4 +1,4 @@ -/* $OpenBSD: m8820x.h,v 1.7 2006/05/06 16:59:26 miod Exp $ */ +/* $OpenBSD: m8820x.h,v 1.8 2010/04/18 22:04:39 miod Exp $ */ /* * Copyright (c) 2004, Miodrag Vallat. * @@ -198,7 +198,11 @@ struct m8820x_cmmu { #define DATA_CMMU 0x01 /* odd number */ #define CMMU_MODE(num) ((num) & 1) +#ifdef M88200_HAS_ASYMMETRICAL_ASSOCIATION +#define MAX_CMMUS 16 /* maximum cmmus on the board */ +#else #define MAX_CMMUS 8 /* maximum cmmus on the board */ +#endif extern struct m8820x_cmmu m8820x_cmmu[MAX_CMMUS]; extern u_int cmmu_shift; extern u_int max_cmmus; diff --git a/sys/arch/m88k/m88k/m8820x_machdep.c b/sys/arch/m88k/m88k/m8820x_machdep.c index 776ef59544f..178382b02ad 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.38 2009/04/19 17:56:13 miod Exp $ */ +/* $OpenBSD: m8820x_machdep.c,v 1.39 2010/04/18 22:04:39 miod Exp $ */ /* * Copyright (c) 2004, 2007, Miodrag Vallat. * @@ -179,6 +179,10 @@ m8820x_cmmu_set_reg(int reg, u_int val, int flags, int cpu, int mode) * values there. */ for (cnt = 1 << cmmu_shift; cnt != 0; cnt--, mmu++, cmmu++) { +#ifdef M88200_HAS_ASYMMETRICAL_ASSOCIATION + if (cmmu->cmmu_regs == NULL) + continue; +#endif if ((flags & MODE_VAL) != 0) { if (CMMU_MODE(mmu) != mode) continue; @@ -201,6 +205,10 @@ m8820x_cmmu_set_cmd(u_int cmd, int flags, int cpu, int mode, vaddr_t addr) * values there. */ for (cnt = 1 << cmmu_shift; cnt != 0; cnt--, mmu++, cmmu++) { +#ifdef M88200_HAS_ASYMMETRICAL_ASSOCIATION + if (cmmu->cmmu_regs == NULL) + continue; +#endif if ((flags & MODE_VAL) != 0) { if (CMMU_MODE(mmu) != mode) continue; @@ -234,6 +242,10 @@ m8820x_cmmu_wait(int cpu) * We scan all related CMMUs and read their status register. */ for (cnt = 1 << cmmu_shift; cnt != 0; cnt--, mmu++, cmmu++) { +#ifdef M88200_HAS_ASYMMETRICAL_ASSOCIATION + if (cmmu->cmmu_regs == NULL) + continue; +#endif #ifdef DEBUG if (cmmu->cmmu_regs[CMMU_SSR] & CMMU_SSR_BE) { panic("cache flush failed!"); @@ -258,7 +270,7 @@ m8820x_cpu_configuration_print(int main) int pid = get_cpu_pid(); int proctype = (pid & PID_ARN) >> ARN_SHIFT; int procvers = (pid & PID_VN) >> VN_SHIFT; - int mmu, cnt, cpu = cpu_number(); + int reported, nmmu, mmu, cnt, cpu = cpu_number(); #ifdef M88200_HAS_SPLIT_ADDRESS int aline, abit, amask; #endif @@ -275,15 +287,31 @@ m8820x_cpu_configuration_print(int main) if (main == 0) printf(", secondary"); #endif - printf(", %d CMMU", 1 << cmmu_shift); + nmmu = 1 << cmmu_shift; +#ifdef M88200_HAS_ASYMMETRICAL_ASSOCIATION + mmu = cpu << cmmu_shift; + cmmu = m8820x_cmmu + mmu; + for (cnt = 1 << cmmu_shift; cnt != 0; cnt--, mmu++, cmmu++) + if (cmmu->cmmu_regs == NULL) + nmmu--; +#endif + printf(", %d CMMU", nmmu); mmu = cpu << cmmu_shift; cmmu = m8820x_cmmu + mmu; + reported = 0; for (cnt = 1 << cmmu_shift; cnt != 0; cnt--, mmu++, cmmu++) { - int idr = cmmu->cmmu_regs[CMMU_IDR]; - int mmuid = CMMU_TYPE(idr); + int idr, mmuid; + +#ifdef M88200_HAS_ASYMMETRICAL_ASSOCIATION + if (cmmu->cmmu_regs == NULL) + continue; +#endif - if (mmu % 2 == 0) + idr = cmmu->cmmu_regs[CMMU_IDR]; + mmuid = CMMU_TYPE(idr); + + if (reported++ % 2 == 0) printf("\ncpu%d: ", cpu); else printf(", "); @@ -320,6 +348,9 @@ m8820x_cpu_configuration_print(int main) abit); amask ^= 1 << abit; } + } else if (cmmu_shift != 1) { + /* unknown split scheme */ + printf(" split"); } else #endif printf(" full"); @@ -382,8 +413,8 @@ m8820x_initialize_cpu(cpuid_t cpu) ci = &m88k_cpus[cpu]; switch (cmmu_shift) { default: - /* exception code does not use ci_pfsr_* fields */ - break; + /* exception code may not use ci_pfsr fields, compute anyway */ + /* FALLTHROUGH */ case 2: ci->ci_pfsr_d1 = (u_int)cmmu[3].cmmu_regs + CMMU_PFSR * 4; ci->ci_pfsr_i1 = (u_int)cmmu[2].cmmu_regs + CMMU_PFSR * 4; @@ -395,6 +426,10 @@ m8820x_initialize_cpu(cpuid_t cpu) } for (cnt = 1 << cmmu_shift; cnt != 0; cnt--, cmmu++) { +#ifdef M88200_HAS_ASYMMETRICAL_ASSOCIATION + if (cmmu->cmmu_regs == NULL) + continue; +#endif type = CMMU_TYPE(cmmu->cmmu_regs[CMMU_IDR]); /* @@ -462,6 +497,10 @@ m8820x_shutdown() cmmu = m8820x_cmmu; for (cmmu_num = 0; cmmu_num < max_cmmus; cmmu_num++, cmmu++) { +#ifdef M88200_HAS_ASYMMETRICAL_ASSOCIATION + if (cmmu->cmmu_regs == NULL) + continue; +#endif cmmu->cmmu_regs[CMMU_SAPR] = cmmu->cmmu_regs[CMMU_UAPR] = ((0x00000 << PG_BITS) | CACHE_INH) & ~(CACHE_WT | CACHE_GLOBAL | APR_V); @@ -555,7 +594,7 @@ m8820x_flush_tlb(cpuid_t cpu, unsigned kernel, vaddr_t vaddr, u_int count) * 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... + * address split - this does not seem to work... */ #define trunc_cache_line(a) ((a) & ~(MC88200_CACHE_LINE - 1)) |