diff options
Diffstat (limited to 'sys/arch/aviion')
-rw-r--r-- | sys/arch/aviion/aviion/av400_machdep.c | 103 | ||||
-rw-r--r-- | sys/arch/aviion/aviion/av530_machdep.c | 137 | ||||
-rw-r--r-- | sys/arch/aviion/aviion/cio_clock.c | 166 | ||||
-rw-r--r-- | sys/arch/aviion/aviion/machdep.c | 4 | ||||
-rw-r--r-- | sys/arch/aviion/aviion/rtc_clock.c | 123 | ||||
-rw-r--r-- | sys/arch/aviion/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/arch/aviion/conf/files.aviion | 5 | ||||
-rw-r--r-- | sys/arch/aviion/dev/mainbus.c | 4 | ||||
-rw-r--r-- | sys/arch/aviion/dev/nvram.c | 54 | ||||
-rw-r--r-- | sys/arch/aviion/dev/oosiop_syscon.c | 29 | ||||
-rw-r--r-- | sys/arch/aviion/dev/syscon.c | 6 | ||||
-rw-r--r-- | sys/arch/aviion/dev/sysconvar.h | 4 | ||||
-rw-r--r-- | sys/arch/aviion/dev/vme.c | 524 | ||||
-rw-r--r-- | sys/arch/aviion/dev/vmevar.h | 30 | ||||
-rw-r--r-- | sys/arch/aviion/include/_types.h | 5 | ||||
-rw-r--r-- | sys/arch/aviion/include/av400.h | 59 | ||||
-rw-r--r-- | sys/arch/aviion/include/av530.h | 162 | ||||
-rw-r--r-- | sys/arch/aviion/include/avcommon.h | 59 | ||||
-rw-r--r-- | sys/arch/aviion/include/board.h | 40 |
19 files changed, 919 insertions, 598 deletions
diff --git a/sys/arch/aviion/aviion/av400_machdep.c b/sys/arch/aviion/aviion/av400_machdep.c index 8b4502c7bc7..85493f1add1 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.15 2010/04/18 22:04:37 miod Exp $ */ +/* $OpenBSD: av400_machdep.c,v 1.16 2010/04/21 19:33:45 miod Exp $ */ /* * Copyright (c) 2006, 2007, Miodrag Vallat. * @@ -167,11 +167,23 @@ av400_ptable[] = { UVM_PROT_RW, CACHE_INH }, #if 0 /* mapped by the hardcoded BATC entries */ { AV400_UTILITY,AV400_UTILITY, AV400_UTILITY_SIZE, - UVM_PROT_RW, CACHE_INHIBIT }, + UVM_PROT_RW, CACHE_INH }, #endif { 0, 0, (vsize_t)-1, 0, 0 } }; +const struct vme_range vme_av400[] = { + { VME_A16, + AV400_VME16_START, AV400_VME16_END, AV400_VME16_BASE }, + { VME_A24, + AV400_VME24_START, AV400_VME24_END, AV400_VME24_BASE }, + { VME_A32, + AV400_VME32_START1, AV400_VME32_END1, AV400_VME32_BASE }, + { VME_A32, + AV400_VME32_START2, AV400_VME32_END2, AV400_VME32_BASE }, + { 0 } +}; + const struct board board_av400 = { "100/200/300/400/3000/4000/4300 series", av400_bootstrap, @@ -185,14 +197,7 @@ const struct board board_av400 = { av400_intsrc, 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 + vme_av400 }; /* @@ -208,7 +213,7 @@ const struct board board_av400 = { * Note that, on the AV400 design, the interrupt enable registers are * write-only and read back as 0xffffffff. */ -static u_int32_t int_mask_reg[] = { 0, 0, 0, 0 }; +u_int32_t av400_int_mask_reg[] = { 0, 0, 0, 0 }; u_int av400_curspl[] = { IPL_HIGH, IPL_HIGH, IPL_HIGH, IPL_HIGH }; @@ -216,7 +221,7 @@ u_int av400_curspl[] = { IPL_HIGH, IPL_HIGH, IPL_HIGH, IPL_HIGH }; /* * Interrupts allowed on secondary processors. */ -#define SLAVE_MASK 0 /* IRQ_SWI0 | IRQ_SWI1 */ +#define SLAVE_MASK 0 /* AV400_IRQ_SWI0 | AV400_IRQ_SWI1 */ #endif /* @@ -246,8 +251,6 @@ av400_startup() { } -int32_t cpuid, sysid; - void av400_bootstrap() { @@ -318,7 +321,7 @@ av400_setipl(u_int level) #endif av400_curspl[cpu] = level; - *(u_int32_t *)AV_IEN(cpu) = int_mask_reg[cpu] = mask; + *(u_int32_t *)AV_IEN(cpu) = av400_int_mask_reg[cpu] = mask; /* * We do not flush the pipeline here, because interrupts are disabled, * and set_psr() will synchronize the pipeline. @@ -345,7 +348,7 @@ av400_raiseipl(u_int level) #endif av400_curspl[cpu] = level; - *(u_int32_t *)AV_IEN(cpu) = int_mask_reg[cpu] = mask; + *(u_int32_t *)AV_IEN(cpu) = av400_int_mask_reg[cpu] = mask; } /* * We do not flush the pipeline here, because interrupts are disabled, @@ -364,23 +367,23 @@ av400_intsrc(int i) { static const u_int32_t intsrc[] = { 0, - IRQ_ABORT, - IRQ_ACF, - IRQ_SF, - IRQ_CIOI, - IRQ_DI1, - IRQ_DI2, - IRQ_ECI, + AV400_IRQ_ABORT, + AV400_IRQ_ACF, + AV400_IRQ_SF, + AV400_IRQ_CIOI, + AV400_IRQ_DI1, + AV400_IRQ_DI2, + AV400_IRQ_ECI, 0, - IRQ_SCI, + AV400_IRQ_SCI, 0, - IRQ_VME1, - IRQ_VME2, - IRQ_VME3, - IRQ_VME4, - IRQ_VME5, - IRQ_VME6, - IRQ_VME7 + AV400_IRQ_VME1, + AV400_IRQ_VME2, + AV400_IRQ_VME3, + AV400_IRQ_VME4, + AV400_IRQ_VME5, + AV400_IRQ_VME6, + AV400_IRQ_VME7 }; return ((u_int64_t)intsrc[i]); @@ -389,31 +392,31 @@ av400_intsrc(int i) /* * Provide the interrupt source for a given interrupt status bit. */ -static const u_int obio_vec[32] = { +static const u_int av400_obio_vec[32] = { 0, /* SWI0 */ 0, /* SWI1 */ 0, 0, - INTSRC_VME, /* VME1 */ + INTSRC_VME(1), /* VME1 */ INTSRC_SCSI1, /* SCI */ - INTSRC_VME, /* VME2 */ + INTSRC_VME(2), /* VME2 */ 0, 0, 0, /* DVB */ - INTSRC_VME, /* VME3 */ + INTSRC_VME(3), /* VME3 */ 0, /* DWP */ - INTSRC_VME, /* VME4 */ + INTSRC_VME(4), /* VME4 */ 0, /* DTC */ - INTSRC_VME, /* VME5 */ + INTSRC_VME(5), /* VME5 */ INTSRC_ETHERNET1, /* ECI */ INTSRC_DUART2, /* DI2 */ INTSRC_DUART1, /* DI1 */ 0, /* PPI */ - INTSRC_VME, /* VME6 */ + INTSRC_VME(6), /* VME6 */ INTSRC_SYSFAIL, /* SF */ - INTSRC_CIO, /* CIOI */ + INTSRC_CLOCK, /* CIOI */ 0, /* KBD */ - INTSRC_VME, /* VME7 */ + INTSRC_VME(7), /* VME7 */ 0, /* PAR */ 0, /* VID */ 0, /* ZBUF */ @@ -431,6 +434,9 @@ static const u_int obio_vec[32] = { #define VME_VECTOR_MASK 0x1ff /* mask into VIACK register */ #define VME_BERR_MASK 0x100 /* timeout during VME IACK cycle */ +#define ISR_GET_CURRENT_MASK(cpu) \ + (*(volatile u_int *)AV_IST & av400_int_mask_reg[cpu]) + void av400_intr(struct trapframe *eframe) { @@ -481,14 +487,16 @@ av400_intr(struct trapframe *eframe) /* find the first bit set in the current mask */ warn = 0; intbit = ff1(cur_mask); - intsrc = obio_vec[intbit]; + intsrc = av400_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); + __func__, intbit, level, + cur_mask, AV400_IST_STRING); - if (intsrc == INTSRC_VME) { + if (IS_VME_INTSRC(intsrc)) { + level = VME_INTSRC_LEVEL(intsrc); ivec = AV400_VIRQLV + (level << 2); vec = *(volatile u_int32_t *)ivec & VME_VECTOR_MASK; if (vec & VME_BERR_MASK) { @@ -496,7 +504,7 @@ av400_intr(struct trapframe *eframe) "interrupt vector, " "level %d, mask 0x%b\n", __func__, level, - cur_mask, IST_STRING); + cur_mask, AV400_IST_STRING); ign_mask |= 1 << intbit; continue; } @@ -531,18 +539,19 @@ av400_intr(struct trapframe *eframe) if (warn != 0) { ign_mask |= 1 << intbit; - if (intsrc == INTSRC_VME) + if (IS_VME_INTSRC(intsrc)) 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); + level, vec, + cur_mask, AV400_IST_STRING); else printf("%s: %s interrupt, " "level %d, bit %d, mask 0x%b\n", __func__, warn == 1 ? "spurious" : "unclaimed", - level, intbit, cur_mask, IST_STRING); + level, intbit, cur_mask, AV400_IST_STRING); } } while (((cur_mask = ISR_GET_CURRENT_MASK(cpu)) & ~ign_mask) != 0); diff --git a/sys/arch/aviion/aviion/av530_machdep.c b/sys/arch/aviion/aviion/av530_machdep.c index f965852693c..fd0e138da20 100644 --- a/sys/arch/aviion/aviion/av530_machdep.c +++ b/sys/arch/aviion/aviion/av530_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: av530_machdep.c,v 1.1 2010/04/18 22:04:37 miod Exp $ */ +/* $OpenBSD: av530_machdep.c,v 1.2 2010/04/21 19:33:45 miod Exp $ */ /* * Copyright (c) 2006, 2007, 2010 Miodrag Vallat. * @@ -50,38 +50,42 @@ u_int av530_safe_level(u_int, u_int, u_int); -const pmap_table_entry -av530_ptable[] = { +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 }, + UVM_PROT_RW, CACHE_INH }, #endif { 0, 0, (vsize_t)-1, 0, 0 } }; +const struct vme_range vme_av530[] = { + { VME_A16, + AV530_VME16_START, AV530_VME16_END, AV530_VME16_BASE }, + { VME_A24, + AV530_VME24_START, AV530_VME24_END, AV530_VME24_BASE }, + { VME_A32, + AV530_VME32_START1, AV530_VME32_END1, AV530_VME32_BASE }, + { VME_A32, + AV530_VME32_START2, AV530_VME32_END2, AV530_VME32_BASE }, + { 0 } +}; + const struct board board_av530 = { "530/4600 series", av530_bootstrap, av530_memsize, av530_startup, av530_intr, - NULL, /* XXX need PIT clock code */ + rtc_init_clocks, 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 + vme_av530 }; /* @@ -94,11 +98,9 @@ const struct board board_av530 = { /* * 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_int32_t av530_int_mask_reg[] = { 0, 0, 0, 0 }; +u_int32_t av530_ext_int_mask_reg[] = { 0, 0, 0, 0 }; u_int av530_curspl[] = { IPL_HIGH, IPL_HIGH, IPL_HIGH, IPL_HIGH }; @@ -106,7 +108,7 @@ u_int av530_curspl[] = { IPL_HIGH, IPL_HIGH, IPL_HIGH, IPL_HIGH }; /* * Interrupts allowed on secondary processors. */ -#define SLAVE_MASK 0 /* IRQ_SWI0 | IRQ_SWI1 */ +#define SLAVE_MASK 0 /* AV530_IRQ_SWI0 | AV530_IRQ_SWI1 */ #define SLAVE_EXMASK 0 #endif @@ -137,13 +139,13 @@ av530_startup() { } -int32_t cpuid, sysid; - void av530_bootstrap() { extern struct cmmu_p cmmu8820x; +#if 0 extern u_char hostaddr[6]; +#endif uint32_t whoami; /* @@ -185,14 +187,16 @@ av530_bootstrap() * Get all the information we'll need later from the PROM, while * we can still use it. */ +#if 0 scm_getenaddr(hostaddr); +#endif cpuid = scm_cpuid(); sysid = scm_sysid(); } /* * Return the next ipl >= ``curlevel'' at which we can reenable interrupts - * while keeping ``mask'' masked. + * while keeping ``mask'' and ``exmask'' masked. */ u_int av530_safe_level(u_int mask, u_int exmask, u_int curlevel) @@ -233,8 +237,8 @@ av530_setipl(u_int level) #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; + *(u_int32_t *)AV_IEN(cpu) = av530_int_mask_reg[cpu] = mask; + *(u_int32_t *)AV_EXIEN(cpu) = av530_ext_int_mask_reg[cpu] = exmask; /* * We do not flush the pipeline here, because interrupts are disabled, * and set_psr() will synchronize the pipeline. @@ -264,8 +268,9 @@ av530_raiseipl(u_int level) #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; + *(u_int32_t *)AV_IEN(cpu) = av530_int_mask_reg[cpu] = mask; + *(u_int32_t *)AV_EXIEN(cpu) = + av530_ext_int_mask_reg[cpu] = exmask; } /* * We do not flush the pipeline here, because interrupts are disabled, @@ -284,35 +289,35 @@ av530_intsrc(int i) { static const u_int32_t intsrc[] = { 0, - IRQ_ABORT, - IRQ_ACF, - IRQ_SF, - 0, /* XXX no clock */ - IRQ_DI, + AV530_IRQ_ABORT, + AV530_IRQ_ACF, + AV530_IRQ_SF, 0, + AV530_IRQ_DI, 0, 0, 0, 0, - IRQ_VME1, - IRQ_VME2, - IRQ_VME3, - IRQ_VME4, - IRQ_VME5, - IRQ_VME6, - IRQ_VME7 - }, ext_intsrc[] = { 0, + AV530_IRQ_VME1, + AV530_IRQ_VME2, + AV530_IRQ_VME3, + AV530_IRQ_VME4, + AV530_IRQ_VME5, + AV530_IRQ_VME6, + AV530_IRQ_VME7 + }, ext_intsrc[] = { 0, 0, 0, 0, + AV530_EXIRQ_PIT0OF, 0, - EXIRQ_DUART2, - EXIRQ_LAN0, - EXIRQ_LAN1, - EXIRQ_SCSI0, - EXIRQ_SCSI1, + AV530_EXIRQ_DUART2, + AV530_EXIRQ_LAN0, + AV530_EXIRQ_LAN1, + AV530_EXIRQ_SCSI0, + AV530_EXIRQ_SCSI1, 0, 0, 0, @@ -331,31 +336,31 @@ av530_intsrc(int i) /* * Provide the interrupt source for a given interrupt status bit. */ -static const u_int obio_vec[32] = { +static const u_int av530_obio_vec[32] = { 0, /* SWI0 */ 0, /* SWI1 */ 0, /* SWI2 */ 0, /* SWI3 */ - INTSRC_VME, /* VME1 */ + INTSRC_VME(1), /* VME1 */ 0, - INTSRC_VME, /* VME2 */ + INTSRC_VME(2), /* VME2 */ 0, /* SIGLPI */ 0, /* LMI */ 0, - INTSRC_VME, /* VME3 */ + INTSRC_VME(3), /* VME3 */ 0, - INTSRC_VME, /* VME4 */ + INTSRC_VME(4), /* VME4 */ 0, - INTSRC_VME, /* VME5 */ + INTSRC_VME(5), /* VME5 */ 0, 0, /* HPI */ INTSRC_DUART1, /* DI */ 0, /* MEM */ - INTSRC_VME, /* VME6 */ + INTSRC_VME(6), /* VME6 */ INTSRC_SYSFAIL, /* SF */ 0, 0, /* KBD */ - INTSRC_VME, /* VME7 */ + INTSRC_VME(7), /* VME7 */ 0, /* SWI4 */ 0, /* SWI5 */ 0, /* SWI6 */ @@ -365,7 +370,7 @@ static const u_int obio_vec[32] = { INTSRC_ACFAIL, /* ACF */ INTSRC_ABORT /* ABORT */ }; -static const u_int obio_exvec[32] = { +static const u_int av530_obio_exvec[32] = { 0, 0, 0, @@ -393,7 +398,7 @@ static const u_int obio_exvec[32] = { 0, /* DMA3C */ 0, /* DMA4C */ 0, - 0, /* PIT0OF */ + INTSRC_CLOCK, /* PIT0OF */ 0, /* PIT1OF */ 0, /* PIT2OF */ 0, /* PIT3OF */ @@ -407,6 +412,11 @@ static const u_int obio_exvec[32] = { #define VME_VECTOR_MASK 0x1ff /* mask into VIACK register */ #define VME_BERR_MASK 0x100 /* timeout during VME IACK cycle */ +#define ISR_GET_CURRENT_MASK(cpu) \ + (*(volatile u_int *)AV_IST & av530_int_mask_reg[cpu]) +#define EXISR_GET_CURRENT_MASK(cpu) \ + (*(volatile u_int *)AV_EXIST & av530_ext_int_mask_reg[cpu]) + void av530_intr(struct trapframe *eframe) { @@ -467,25 +477,26 @@ av530_intr(struct trapframe *eframe) warn = 0; if (cur_mask != 0) { intbit = ff1(cur_mask); - intsrc = obio_vec[intbit]; + intsrc = av530_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); + cur_mask, AV530_IST_STRING); } else { intbit = ff1(cur_exmask); - intsrc = obio_exvec[intbit]; + intsrc = av530_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); + cur_exmask, AV530_EXIST_STRING); } - if (intsrc == INTSRC_VME) { + if (IS_VME_INTSRC(intsrc)) { + level = VME_INTSRC_LEVEL(intsrc); ivec = AV530_VIRQLV + (level << 2); vec = *(volatile u_int32_t *)ivec & VME_VECTOR_MASK; if (vec & VME_BERR_MASK) { @@ -494,7 +505,7 @@ av530_intr(struct trapframe *eframe) "interrupt vector, " "level %d, mask 0x%b\n", __func__, level, - cur_mask, IST_STRING); + cur_mask, AV530_IST_STRING); ign_mask |= 1 << intbit; continue; } @@ -532,12 +543,12 @@ av530_intr(struct trapframe *eframe) else ign_exmask |= 1 << intbit; - if (intsrc == INTSRC_VME) + if (IS_VME_INTSRC(intsrc)) 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); + level, vec, cur_mask, AV530_IST_STRING); else { if (cur_mask != 0) printf("%s: %s interrupt, " @@ -546,7 +557,7 @@ av530_intr(struct trapframe *eframe) warn == 1 ? "spurious" : "unclaimed", level, intbit, - cur_mask, IST_STRING); + cur_mask, AV530_IST_STRING); else printf("%s: %s extended interrupt, " "level %d, bit %d, mask 0x%b\n", @@ -554,7 +565,7 @@ av530_intr(struct trapframe *eframe) warn == 1 ? "spurious" : "unclaimed", level, intbit, - cur_exmask, EXIST_STRING); + cur_exmask, AV530_EXIST_STRING); } } } diff --git a/sys/arch/aviion/aviion/cio_clock.c b/sys/arch/aviion/aviion/cio_clock.c index 38fa20edb6a..7d405cefdc6 100644 --- a/sys/arch/aviion/aviion/cio_clock.c +++ b/sys/arch/aviion/aviion/cio_clock.c @@ -1,6 +1,6 @@ -/* $OpenBSD: cio_clock.c,v 1.1 2007/12/19 22:05:04 miod Exp $ */ +/* $OpenBSD: cio_clock.c,v 1.2 2010/04/21 19:33:45 miod Exp $ */ /* - * Copyright (c) 2006, 2007, Miodrag Vallat. + * Copyright (c) 2006, 2007, 2009 Miodrag Vallat. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -138,22 +138,16 @@ #include <sys/systm.h> #include <sys/kernel.h> #include <sys/errno.h> +#include <sys/mutex.h> +#include <sys/timetc.h> #include <uvm/uvm_extern.h> -#include <machine/asm_macro.h> #include <machine/board.h> -#include <machine/cmmu.h> -#include <machine/cpu.h> -#include <machine/reg.h> -#include <machine/trap.h> - -#include <machine/m88100.h> -#include <machine/m8820x.h> #include <machine/avcommon.h> -#include <machine/prom.h> #include <aviion/dev/sysconvar.h> +#include <dev/ic/z8536reg.h> /* * Z8536 (CIO) Clock routines @@ -163,29 +157,27 @@ void cio_clock_init(u_int); u_int read_cio(int); void write_cio(int, u_int); -struct intrhand clock_ih; +struct intrhand cio_clock_ih; int cio_clockintr(void *); int cio_calibrateintr(void *); +u_int cio_get_timecount(struct timecounter *); volatile int cio_calibrate_phase = 0; extern u_int aviion_delay_const; -struct simplelock cio_clock_lock; +uint32_t cio_step; +uint32_t cio_refcnt; +uint32_t cio_lastcnt; -#define CIO_LOCK simple_lock(&acio_clock_lock) -#define CIO_UNLOCK simple_unlock(&cio_clock__lock) +struct mutex cio_mutex = MUTEX_INITIALIZER(IPL_CLOCK); -/* - * Statistics clock interval and variance, in usec. Variance must be a - * power of two. Since this gives us an even number, not an odd number, - * we discard one case and compensate. That is, a variance of 4096 would - * give us offsets in [0..4095]. Instead, we take offsets in [1..4095]. - * This is symmetric about the point 2048, or statvar/2, and thus averages - * to that value (assuming uniform random numbers). - */ -int statvar = 8192; -int statmin; /* statclock interval - 1/2*variance */ +struct timecounter cio_timecounter = { + .tc_get_timecount = cio_get_timecount, + .tc_counter_mask = 0xffffffff, + .tc_name = "cio", + .tc_quality = 0 +}; /* * Notes on the AV400 clock usage: @@ -211,8 +203,6 @@ cio_init_clocks(void) psr = get_psr(); set_psr(psr | PSR_IND); - simple_lock_init(&cio_clock_lock); - #ifdef DIAGNOSTIC if (1000000 % hz) { printf("cannot get %d Hz clock; using 100 Hz\n", hz); @@ -223,16 +213,16 @@ cio_init_clocks(void) cio_clock_init(tick); - stathz = 0; + profhz = stathz = 0; /* * Calibrate delay const. */ - clock_ih.ih_fn = cio_calibrateintr; - clock_ih.ih_arg = 0; - clock_ih.ih_flags = INTR_WANTFRAME; - clock_ih.ih_ipl = IPL_CLOCK; - sysconintr_establish(INTSRC_CIO, &clock_ih, "clock"); + cio_clock_ih.ih_fn = cio_calibrateintr; + cio_clock_ih.ih_arg = 0; + cio_clock_ih.ih_flags = INTR_WANTFRAME; + cio_clock_ih.ih_ipl = IPL_CLOCK; + sysconintr_establish(INTSRC_CLOCK, &cio_clock_ih, "clock"); aviion_delay_const = 1; set_psr(psr); @@ -250,22 +240,21 @@ cio_init_clocks(void) set_psr(psr | PSR_IND); - sysconintr_disestablish(INTSRC_CIO, &clock_ih); - clock_ih.ih_fn = cio_clockintr; - sysconintr_establish(INTSRC_CIO, &clock_ih, "clock"); + sysconintr_disestablish(INTSRC_CLOCK, &cio_clock_ih); + cio_clock_ih.ih_fn = cio_clockintr; + sysconintr_establish(INTSRC_CLOCK, &cio_clock_ih, "clock"); set_psr(psr); + + tc_init(&cio_timecounter); } int cio_calibrateintr(void *eframe) { - CIO_LOCK; - write_cio(CIO_CSR1, CIO_GCB | CIO_CIP); /* Ack the interrupt */ - - /* restart counter */ - write_cio(CIO_CSR1, CIO_GCB | CIO_TCB | CIO_IE); - CIO_UNLOCK; + /* no need to grab the mutex, only one processor is running for now */ + /* ack the interrupt */ + write_cio(ZCIO_CT1CS, ZCIO_CTCS_GCB | ZCIO_CTCS_C_IP); cio_calibrate_phase++; @@ -275,12 +264,11 @@ cio_calibrateintr(void *eframe) int cio_clockintr(void *eframe) { - CIO_LOCK; - write_cio(CIO_CSR1, CIO_GCB | CIO_CIP); /* Ack the interrupt */ - - /* restart counter */ - write_cio(CIO_CSR1, CIO_GCB | CIO_TCB | CIO_IE); - CIO_UNLOCK; + mtx_enter(&cio_mutex); + /* ack the interrupt */ + write_cio(ZCIO_CT1CS, ZCIO_CTCS_GCB | ZCIO_CTCS_C_IP); + cio_refcnt += cio_step; + mtx_leave(&cio_mutex); hardclock(eframe); @@ -291,35 +279,25 @@ cio_clockintr(void *eframe) void write_cio(int reg, u_int val) { - int s; volatile int i; volatile u_int32_t * cio_ctrl = (volatile u_int32_t *)CIO_CTRL; - s = splclock(); - CIO_LOCK; - i = *cio_ctrl; /* goto state 1 */ *cio_ctrl = 0; /* take CIO out of RESET */ i = *cio_ctrl; /* reset CIO state machine */ *cio_ctrl = (reg & 0xff); /* select register */ *cio_ctrl = (val & 0xff); /* write the value */ - - CIO_UNLOCK; - splx(s); } /* Read CIO register */ u_int read_cio(int reg) { - int c, s; + int c; volatile int i; volatile u_int32_t * cio_ctrl = (volatile u_int32_t *)CIO_CTRL; - s = splclock(); - CIO_LOCK; - /* select register */ *cio_ctrl = (reg & 0xff); /* delay for a short time to allow 8536 to settle */ @@ -327,8 +305,6 @@ read_cio(int reg) ; /* read the value */ c = *cio_ctrl; - CIO_UNLOCK; - splx(s); return (c & 0xff); } @@ -341,33 +317,71 @@ cio_clock_init(u_int period) { volatile int i; - CIO_LOCK; - /* Start by forcing chip into known state */ - read_cio(CIO_MICR); - write_cio(CIO_MICR, CIO_MICR_RESET); /* Reset the CTC */ + read_cio(ZCIO_MIC); + write_cio(ZCIO_MIC, ZCIO_MIC_RESET); /* Reset the CTC */ for (i = 0; i < 1000; i++) /* Loop to delay */ ; /* Clear reset and start init seq. */ - write_cio(CIO_MICR, 0x00); + write_cio(ZCIO_MIC, 0x00); /* Wait for chip to come ready */ - while ((read_cio(CIO_MICR) & CIO_MICR_RJA) == 0) + while ((read_cio(ZCIO_MIC) & ZCIO_MIC_RJA) == 0) ; /* Initialize the 8536 for real */ - write_cio(CIO_MICR, - CIO_MICR_MIE /* | CIO_MICR_NV */ | CIO_MICR_RJA | CIO_MICR_DLC); - write_cio(CIO_CTMS1, CIO_CTMS_CSC); /* Continuous count */ - write_cio(CIO_PDCB, 0xff); /* set port B to input */ + write_cio(ZCIO_MIC, + ZCIO_MIC_MIE /* | ZCIO_MIC_NV */ | ZCIO_MIC_RJA | ZCIO_MIC_DLC); + write_cio(ZCIO_CT1MD, ZCIO_CTMD_CSC); /* Continuous count */ + write_cio(ZCIO_PBDIR, 0xff); /* set port B to input */ period <<= 1; /* CT#1 runs at PCLK/2, hence 2MHz */ - write_cio(CIO_CT1MSB, period >> 8); - write_cio(CIO_CT1LSB, period); + write_cio(ZCIO_CT1TCM, period >> 8); + write_cio(ZCIO_CT1TCL, period); /* enable counter #1 */ - write_cio(CIO_MCCR, CIO_MCCR_CT1E | CIO_MCCR_PBE); - write_cio(CIO_CSR1, CIO_GCB | CIO_TCB | CIO_IE); + write_cio(ZCIO_MCC, ZCIO_MCC_CT1E | ZCIO_MCC_PBE); + write_cio(ZCIO_CT1CS, ZCIO_CTCS_GCB | ZCIO_CTCS_TCB | ZCIO_CTCS_S_IE); + + cio_step = period; + cio_timecounter.tc_frequency = (uint64_t)cio_step * hz; +} + +u_int +cio_get_timecount(struct timecounter *tc) +{ + u_int cmsb, clsb, counter, curcnt; + + /* + * The CIO counter is free running, but by setting the + * RCC bit in its control register, we can read a frozen + * value of the counter. + * The counter will automatically unfreeze after reading + * its LSB. + */ + + mtx_enter(&cio_mutex); + write_cio(ZCIO_CT1CS, ZCIO_CTCS_GCB | ZCIO_CTCS_RCC); + cmsb = read_cio(ZCIO_CT1CCM); + clsb = read_cio(ZCIO_CT1CCL); + curcnt = cio_refcnt; + + counter = (cmsb << 8) | clsb; +#if 0 /* this will never happen unless the period itself is 65536 */ + if (counter == 0) + counter = 65536; +#endif + + /* + * The counter counts down from its initialization value to 1. + */ + counter = cio_step - counter; + + curcnt += counter; + if (curcnt < cio_lastcnt) + curcnt += cio_step; - CIO_UNLOCK; + cio_lastcnt = curcnt; + mtx_leave(&cio_mutex); + return curcnt; } diff --git a/sys/arch/aviion/aviion/machdep.c b/sys/arch/aviion/aviion/machdep.c index 344476bc6e2..1ad3b855ae7 100644 --- a/sys/arch/aviion/aviion/machdep.c +++ b/sys/arch/aviion/aviion/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.34 2010/04/18 18:37:37 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.35 2010/04/21 19:33:45 miod Exp $ */ /* * Copyright (c) 2007 Miodrag Vallat. * @@ -162,6 +162,8 @@ const char *prom_bootargs; /* set in locore.S */ char bootargs[256]; /* local copy */ u_int bootdev, bootunit, bootpart; /* set in locore.S */ +int32_t cpuid, sysid; + int cputyp; /* set in locore.S */ int avtyp; const struct board *platform; diff --git a/sys/arch/aviion/aviion/rtc_clock.c b/sys/arch/aviion/aviion/rtc_clock.c new file mode 100644 index 00000000000..696ad7861a4 --- /dev/null +++ b/sys/arch/aviion/aviion/rtc_clock.c @@ -0,0 +1,123 @@ +/* $OpenBSD: rtc_clock.c,v 1.1 2010/04/21 19:33:45 miod Exp $ */ + +/* + * Copyright (c) 2010 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Clock routines using a freerunning RTC counter (models 530/4600) + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/timetc.h> + +#include <machine/board.h> +#include <machine/avcommon.h> +#include <machine/av530.h> + +#include <aviion/dev/sysconvar.h> + +extern u_int aviion_delay_const; + +struct intrhand rtc_clock_ih; + +int rtc_clockintr(void *); +u_int rtc_get_timecount(struct timecounter *); + +struct timecounter rtc_timecounter = { + .tc_get_timecount = rtc_get_timecount, + .tc_counter_mask = 0xffffffff, + .tc_name = "rtc", + .tc_quality = 0 +}; + +uint32_t pit_step; + +void +rtc_init_clocks() +{ + uint rtc_speed, pit_interval; + +#ifdef DIAGNOSTIC + if (1000000 % hz) { + printf("cannot get %d Hz clock; using 100 Hz\n", hz); + hz = 100; + } +#endif + tick = 1000000 / hz; + + profhz = stathz = 0; + + /* + * According to the documentation, systems of this family run + * at 33MHz; however other sources seem to imply model 530 + * runs at 25Mhz only. + * If this turns out to be the case, proper calibration of the + * system clock will be necessary. + */ + aviion_delay_const = 33; + rtc_speed = 33333333 / 2; /* apparently RTC runs at half CPUCLK */ + + /* + * RTC is free running; we can get a periodic interrupt at any + * multiple of 0x100 RTC ticks. We use PIT0 for this purpose. + * Therefore to get a proper system clock, we need an interrupt + * every (rtc_speed / hz) ticks, rounded down. + * With hz being 100, this won't be an exact 100Hz clock, but the + * timecounter code will make sure time is kept accurately. + */ + + /* disable and reset all counters */ + *(volatile uint32_t *)AV530_PIT_CMD_ALL = AV530_PIT_RESET; + /* setup countdown interrupt threshold */ + pit_interval = rtc_speed / hz; + pit_step = 0xffffff00 & (-pit_interval); + *(volatile uint32_t *)AV530_PIT0_CNT = pit_step; + /* start timer */ + *(volatile uint32_t *)AV530_PIT0_CS = AV530_PIT_CTEN; + + rtc_clock_ih.ih_fn = rtc_clockintr; + rtc_clock_ih.ih_arg = 0; + rtc_clock_ih.ih_flags = INTR_WANTFRAME; + rtc_clock_ih.ih_ipl = IPL_CLOCK; + sysconintr_establish(INTSRC_CLOCK, &rtc_clock_ih, "clock"); + + rtc_timecounter.tc_frequency = rtc_speed; + tc_init(&rtc_timecounter); +} + +int +rtc_clockintr(void *frame) +{ + /* + * Not only does the PIT stop upon overflow (requiring us to + * rearm it after acknowledging the interrupt), but also the + * comparison value is lost and needs to be setup again. + */ + *(volatile uint32_t *)AV530_PIT0_CS = AV530_PIT_IACK | AV530_PIT_RESET; + *(volatile uint32_t *)AV530_PIT0_CNT = pit_step; + *(volatile uint32_t *)AV530_PIT0_CS = AV530_PIT_CTEN; + hardclock(frame); + + return 1; +} + +u_int +rtc_get_timecount(struct timecounter *tc) +{ + return *(volatile uint32_t *)AV530_RTC_CNT; +} diff --git a/sys/arch/aviion/conf/GENERIC b/sys/arch/aviion/conf/GENERIC index ced7d0af819..ed0fd8bcad5 100644 --- a/sys/arch/aviion/conf/GENERIC +++ b/sys/arch/aviion/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.4 2010/04/20 22:53:23 miod Exp $ +# $OpenBSD: GENERIC,v 1.5 2010/04/21 19:33:47 miod Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -61,6 +61,7 @@ le0 at syscon? offset 0x8c000 ipl 1 # on-board ethernet dart1 at syscon? offset 0x82040 ipl 3 #ssi0 at syscon? offset 0x8d000 ipl 3 oosiop0 at syscon? offset 0xb0000 ipl 2 +oosiop1 at syscon? offset 0xb0080 ipl 2 #ile0 at syscon? offset 0xb00c0 ipl 1 #ile1 at syscon? offset 0xb0140 ipl 1 diff --git a/sys/arch/aviion/conf/files.aviion b/sys/arch/aviion/conf/files.aviion index c7e5bdce58d..9829595bbc7 100644 --- a/sys/arch/aviion/conf/files.aviion +++ b/sys/arch/aviion/conf/files.aviion @@ -1,4 +1,4 @@ -# $OpenBSD: files.aviion,v 1.6 2010/04/20 22:53:23 miod Exp $ +# $OpenBSD: files.aviion,v 1.7 2010/04/21 19:33:47 miod Exp $ # maxpartitions 16 @@ -72,9 +72,10 @@ file arch/aviion/aviion/av400_machdep.c av400 file arch/aviion/aviion/av530_machdep.c av530 file arch/aviion/aviion/av5000_machdep.c av5000 file arch/aviion/aviion/av6280_machdep.c av6280 -file arch/aviion/aviion/cio_clock.c av400 | av530 | +file arch/aviion/aviion/cio_clock.c av400 | av5000 | av6280 file arch/aviion/aviion/m8820x.c m88100 file arch/aviion/aviion/mem.c file arch/aviion/aviion/pmap_table.c file arch/aviion/aviion/prom.c +file arch/aviion/aviion/rtc_clock.c av530 diff --git a/sys/arch/aviion/dev/mainbus.c b/sys/arch/aviion/dev/mainbus.c index 403ee92812f..8d034f1c597 100644 --- a/sys/arch/aviion/dev/mainbus.c +++ b/sys/arch/aviion/dev/mainbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mainbus.c,v 1.3 2010/04/20 22:53:24 miod Exp $ */ +/* $OpenBSD: mainbus.c,v 1.4 2010/04/21 19:33:47 miod Exp $ */ /* * Copyright (c) 1998 Steve Murphree, Jr. * Copyright (c) 2004, Miodrag Vallat. @@ -36,6 +36,7 @@ #include <uvm/uvm_extern.h> #include <machine/autoconf.h> +#include <machine/board.h> #include <machine/bus.h> #include <machine/cmmu.h> #include <machine/cpu.h> @@ -128,7 +129,6 @@ void mainbus_attach(struct device *parent, struct device *self, void *args) { extern char cpu_model[]; - extern int32_t cpuid, sysid; printf(": %s, cpuid 0x%x", cpu_model, cpuid); if (sysid != -1) diff --git a/sys/arch/aviion/dev/nvram.c b/sys/arch/aviion/dev/nvram.c index 767e189d2f1..7a9f8f17469 100644 --- a/sys/arch/aviion/dev/nvram.c +++ b/sys/arch/aviion/dev/nvram.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nvram.c,v 1.5 2007/12/20 05:19:35 miod Exp $ */ +/* $OpenBSD: nvram.c,v 1.6 2010/04/21 19:33:47 miod Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -33,6 +33,7 @@ #include <sys/proc.h> #include <sys/ioctl.h> #include <sys/uio.h> +#include <sys/timetc.h> #include <machine/autoconf.h> #include <machine/conf.h> @@ -118,38 +119,6 @@ nvramattach(parent, self, args) printf(": MK48T0%d\n", sc->sc_len / 1024); } -/* - * Return the best possible estimate of the time in the timeval - * to which tvp points. We do this by returning the current time - * plus the amount of time since the last clock interrupt (clock.c:clkread). - * - * Check that this time is no less than any previously-reported time, - * which could happen around the time of a clock adjustment. Just for fun, - * we guarantee that the time will be greater than the value obtained by a - * previous call. - */ -void -microtime(tvp) - struct timeval *tvp; -{ - int s = splhigh(); - static struct timeval lasttime; - - *tvp = time; - while (tvp->tv_usec >= 1000000) { - tvp->tv_sec++; - tvp->tv_usec -= 1000000; - } - if (tvp->tv_sec == lasttime.tv_sec && - tvp->tv_usec <= lasttime.tv_usec && - (tvp->tv_usec = lasttime.tv_usec + 1) >= 1000000) { - tvp->tv_sec++; - tvp->tv_usec -= 1000000; - } - lasttime = *tvp; - splx(s); -} - #define LEAPYEAR(y) (((y) & 3) == 0) /* @@ -212,7 +181,7 @@ void timetochip(c) struct chiptime *c; { - int t, t2, t3, now = time.tv_sec; + int t, t2, t3, now = time_second; /* January 1 1970 was a Thursday (4 in unix wdays) */ /* compute the days since the epoch */ @@ -268,6 +237,9 @@ inittodr(base) struct nvramsoftc *sc = (struct nvramsoftc *) nvram_cd.cd_devs[0]; int sec, min, hour, day, mon, year; int badbase = 0, waszero = base == 0; + struct timespec ts; + + ts.tv_sec = ts.tv_nsec = 0; if (base < 36 * SECYR) { /* this code did not exist until 2006 */ /* @@ -302,7 +274,7 @@ inittodr(base) bus_space_read_4(sc->sc_iot, sc->sc_ioh, sc->sc_regs + (CLK_CSR << 2)) & ~CLK_READ); - if ((time.tv_sec = chiptotime(sec, min, hour, day, mon, year)) == 0) { + if ((ts.tv_sec = chiptotime(sec, min, hour, day, mon, year)) == 0) { printf("WARNING: bad date in nvram"); #ifdef DEBUG printf("\nday = %d, mon = %d, year = %d, hour = %d, min = %d, sec = %d", @@ -313,20 +285,22 @@ inittodr(base) * Believe the time in the file system for lack of * anything better, resetting the clock. */ - time.tv_sec = base; + ts.tv_sec = base; if (!badbase) resettodr(); } else { - int deltat = time.tv_sec - base; + int deltat = ts.tv_sec - base; if (deltat < 0) deltat = -deltat; if (waszero || deltat < 2 * SECDAY) - return; + goto done; printf("WARNING: clock %s %d days", - time.tv_sec < base ? "lost" : "gained", deltat / SECDAY); + ts.tv_sec < base ? "lost" : "gained", deltat / SECDAY); } printf(" -- CHECK AND RESET THE DATE!\n"); +done: + tc_setclock(&ts); } /* @@ -341,7 +315,7 @@ resettodr() struct nvramsoftc *sc = (struct nvramsoftc *) nvram_cd.cd_devs[0]; struct chiptime c; - if (!time.tv_sec || sc == NULL) + if (time_second == 0 || sc == NULL) return; timetochip(&c); diff --git a/sys/arch/aviion/dev/oosiop_syscon.c b/sys/arch/aviion/dev/oosiop_syscon.c index d0647999cdb..d82bbb99b5b 100644 --- a/sys/arch/aviion/dev/oosiop_syscon.c +++ b/sys/arch/aviion/dev/oosiop_syscon.c @@ -1,4 +1,4 @@ -/* $OpenBSD: oosiop_syscon.c,v 1.1 2010/04/20 22:53:24 miod Exp $ */ +/* $OpenBSD: oosiop_syscon.c,v 1.2 2010/04/21 19:33:47 miod Exp $ */ /* * Copyright (c) 2010 Miodrag Vallat. @@ -27,6 +27,7 @@ #include <machine/autoconf.h> #include <machine/board.h> #include <machine/bus.h> +#include <machine/av530.h> #include <aviion/dev/sysconvar.h> @@ -49,11 +50,29 @@ const struct cfattach oosiop_syscon_ca = { int oosiop_syscon_match(struct device *parent, void *match, void *aux) { + struct confargs *ca = aux; + paddr_t fuse; + if (avtyp != AV_530) return 0; - /* XXX check IOFUSE register */ - return 1; + switch (ca->ca_paddr) { + case AV530_SCSI1: + fuse = AV530_IOFUSE0; + break; + case AV530_SCSI2: + fuse = AV530_IOFUSE1; + break; + default: + return 0; + } + + /* check IOFUSE register */ + if (badaddr(fuse, 1) != 0) + return 0; + + /* check fuse status */ + return ISSET(*(volatile uint8_t *)fuse, AV530_IOFUSE_SCSI); } void @@ -63,6 +82,7 @@ oosiop_syscon_attach(struct device *parent, struct device *self, void *aux) struct oosiop_softc *sc = (struct oosiop_softc *)self; struct confargs *ca = aux; bus_space_handle_t ioh; + int intsrc; if (bus_space_map(ca->ca_iot, ca->ca_paddr, OOSIOP_NREGS, 0, &ioh) != 0) { @@ -88,5 +108,6 @@ oosiop_syscon_attach(struct device *parent, struct device *self, void *aux) ssc->sc_ih.ih_arg = sc; ssc->sc_ih.ih_flags = 0; ssc->sc_ih.ih_ipl = ca->ca_ipl; - sysconintr_establish(INTSRC_SCSI1, &ssc->sc_ih, self->dv_xname); + intsrc = ca->ca_paddr == AV530_SCSI1 ? INTSRC_SCSI1 : INTSRC_SCSI2; + sysconintr_establish(intsrc, &ssc->sc_ih, self->dv_xname); } diff --git a/sys/arch/aviion/dev/syscon.c b/sys/arch/aviion/dev/syscon.c index 85d0c0e9376..9c6c8920efe 100644 --- a/sys/arch/aviion/dev/syscon.c +++ b/sys/arch/aviion/dev/syscon.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syscon.c,v 1.4 2007/12/19 22:05:06 miod Exp $ */ +/* $OpenBSD: syscon.c,v 1.5 2010/04/21 19:33:47 miod Exp $ */ /* * Copyright (c) 2007 Miodrag Vallat. * @@ -95,7 +95,7 @@ sysconattach(struct device *parent, struct device *self, void *args) /* * Set up interrupt handlers. */ - for (i = 0; i < INTSRC_VME; i++) + for (i = 0; i < NINTSRC_SYSCON; i++) SLIST_INIT(&sysconintr_handlers[i]); /* @@ -163,7 +163,7 @@ syscon_print(void *args, const char *pnp) * Interrupt related code */ -intrhand_t sysconintr_handlers[INTSRC_VME]; +intrhand_t sysconintr_handlers[NINTSRC_SYSCON]; int sysconintr_establish(u_int intsrc, struct intrhand *ih, const char *name) diff --git a/sys/arch/aviion/dev/sysconvar.h b/sys/arch/aviion/dev/sysconvar.h index f9d09534d3a..b9883b31bfe 100644 --- a/sys/arch/aviion/dev/sysconvar.h +++ b/sys/arch/aviion/dev/sysconvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sysconvar.h,v 1.1 2007/12/19 22:05:06 miod Exp $ */ +/* $OpenBSD: sysconvar.h,v 1.2 2010/04/21 19:33:47 miod Exp $ */ /* * Copyright (c) 2007 Miodrag Vallat. @@ -17,7 +17,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -extern intrhand_t sysconintr_handlers[INTSRC_VME]; +extern intrhand_t sysconintr_handlers[NINTSRC_SYSCON]; int sysconintr_establish(u_int, struct intrhand *, const char *); void sysconintr_disestablish(u_int, struct intrhand *); diff --git a/sys/arch/aviion/dev/vme.c b/sys/arch/aviion/dev/vme.c index f07c6fb8f2d..784b841664c 100644 --- a/sys/arch/aviion/dev/vme.c +++ b/sys/arch/aviion/dev/vme.c @@ -1,6 +1,6 @@ -/* $OpenBSD: vme.c,v 1.6 2010/04/20 22:53:24 miod Exp $ */ +/* $OpenBSD: vme.c,v 1.7 2010/04/21 19:33:47 miod Exp $ */ /* - * Copyright (c) 2006, 2007, Miodrag Vallat. + * 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 @@ -24,10 +24,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/* - * XXX TODO: Finish /dev/vme{a16,a24,a32}{d8,d16,d32} interface. - */ - #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -47,25 +43,33 @@ #include <machine/avcommon.h> -struct vmesoftc { +struct vme_softc { struct device sc_dev; struct extent *sc_ext_a16; struct extent *sc_ext_a24; struct extent *sc_ext_a32; + + const struct vme_range *sc_ranges; }; int vmematch(struct device *, void *, void *); void vmeattach(struct device *, struct device *, void *); -struct cfattach vme_ca = { - sizeof(struct vmesoftc), vmematch, vmeattach +const struct cfattach vme_ca = { + sizeof(struct vme_softc), vmematch, vmeattach }; struct cfdriver vme_cd = { NULL, "vme", DV_DULL }; +/* minor device number encoding */ +#define AWIDTH_FIELD(minor) (minor & 0x0f) +#define AWIDTH(w) ((w) << 3) +#define DWIDTH_FIELD(minor) ((minor & 0xf0) >> 4) +#define DWIDTH(w) ((w) << 3) + uint16_t vme_d8_read_2(bus_space_tag_t, bus_space_handle_t, bus_size_t); void vme_d8_read_raw_2(bus_space_tag_t, bus_space_handle_t, bus_addr_t, uint8_t *, bus_size_t); @@ -102,28 +106,33 @@ int vme_subregion(bus_space_tag_t, bus_space_handle_t, bus_size_t, bus_size_t, bus_space_handle_t *); void * vme_vaddr(bus_space_tag_t, bus_space_handle_t); -int vme_map(struct extent *, paddr_t, bus_addr_t, bus_size_t, int, - bus_space_handle_t *); -void vme_unmap(struct extent *, vme_addr_t, vaddr_t, bus_size_t); +int vme_map(struct vme_softc *, struct extent *, u_int, + bus_addr_t, bus_size_t, int, vaddr_t *); +int vme_map_r(const struct vme_range *, paddr_t, psize_t, int, vm_prot_t, + vaddr_t *); +void vme_unmap(struct vme_softc *, struct extent *, u_int, + vaddr_t, paddr_t, bus_size_t); int vmeprint(void *, const char *); int vmescan(struct device *, void *, void *); +int vmerw(struct vme_softc *, int, int, struct uio *, int); + int vmematch(struct device *parent, void *vcf, void *aux) { /* XXX no VME on AV100/AV200/AV300, though */ - return (vme_cd.cd_ndevs == 0); + return (platform->vme_ranges != NULL && vme_cd.cd_ndevs == 0); } void vmeattach(struct device *parent, struct device *self, void *aux) { - struct vmesoftc *sc = (struct vmesoftc *)self; + struct vme_softc *sc = (struct vme_softc *)self; + const struct vme_range *r; + const char *fmt; u_int32_t ucsr; int i; - printf("\n"); - /* * Set up interrupt handlers. */ @@ -135,10 +144,16 @@ vmeattach(struct device *parent, struct device *self, void *aux) */ sc->sc_ext_a16 = extent_create("vme a16", 0, 1 << (16 - PAGE_SHIFT), M_DEVBUF, NULL, 0, EX_NOWAIT); + if (sc->sc_ext_a16 == NULL) + goto out1; sc->sc_ext_a24 = extent_create("vme a24", 0, 1 << (24 - PAGE_SHIFT), M_DEVBUF, NULL, 0, EX_NOWAIT); + if (sc->sc_ext_a24 == NULL) + goto out2; sc->sc_ext_a32 = extent_create("vme a32", 0, 1 << (32 - PAGE_SHIFT), M_DEVBUF, NULL, 0, EX_NOWAIT); + if (sc->sc_ext_a32 == NULL) + goto out3; /* * Force a reasonable timeout for VME data transfers. @@ -160,20 +175,38 @@ vmeattach(struct device *parent, struct device *self, void *aux) */ *(volatile u_int32_t *)AV_EXTAM = 0x0d; + sc->sc_ranges = platform->vme_ranges; + printf("\n"); + /* * Display VME ranges. */ - printf("%s: A32 %08x-%08x\n", self->dv_xname, - platform->vme32_start1, platform->vme32_end1); - printf("%s: A32 %08x-%08x\n", self->dv_xname, - platform->vme32_start2, platform->vme32_end2); - printf("%s: A24 %08x-%08x\n", self->dv_xname, - platform->vme24_start, platform->vme24_end); - printf("%s: A16 %08x-%08x\n", self->dv_xname, - platform->vme16_start, platform->vme16_end); + for (r = sc->sc_ranges; r->vr_width != 0; r++) { + switch (r->vr_width) { + default: + case VME_A32: + fmt = "%s: A32 %08x-%08x\n"; + break; + case VME_A24: + fmt = "%s: A24 %06x-%06x\n"; + break; + case VME_A16: + fmt = "%s: A16 %04x-%04x\n"; + break; + } + printf(fmt, self->dv_xname, r->vr_start, r->vr_end); + } /* scan for child devices */ config_search(vmescan, self, aux); + return; + +out3: + extent_destroy(sc->sc_ext_a24); +out2: + extent_destroy(sc->sc_ext_a16); +out1: + printf(": can't allocate memory\n", self->dv_xname); } int @@ -189,10 +222,10 @@ vmescan(struct device *parent, void *vcf, void *aux) vaa.vaa_ipl = (u_int)cf->cf_loc[3]; if ((*cf->cf_attach->ca_match)(parent, cf, &vaa) == 0) - return (0); + return 0; config_attach(parent, cf, &vaa, vmeprint); - return (1); + return 1; } int @@ -209,7 +242,7 @@ vmeprint(void *aux, const char *pnp) if (vaa->vaa_ipl != (u_int)-1) printf(" ipl %u", vaa->vaa_ipl); - return (UNCONF); + return UNCONF; } /* @@ -242,7 +275,7 @@ vmeintr_allocate(u_int count, int flags, int ipl, u_int *array) } } if (ISSET(flags, VMEINTR_EXCLUSIVE)) - return (EPERM); + return EPERM; /* * Try to find a range of count contiguous vectors, @@ -263,10 +296,10 @@ vmeintr_allocate(u_int count, int flags, int ipl, u_int *array) if (v == 0) { for (v = 0; v < count; v++) *array++ = vec++; - return (0); + return 0; } } - return (EPERM); + return EPERM; } /* @@ -276,7 +309,7 @@ vmeintr_allocate(u_int count, int flags, int ipl, u_int *array) if (SLIST_EMPTY(&vmeintr_handlers[vec])) { *array++ = vec; if (--count == 0) - return (0); + return 0; } } @@ -288,14 +321,14 @@ vmeintr_allocate(u_int count, int flags, int ipl, u_int *array) if (ih->ih_ipl == ipl && !ISSET(ih->ih_flags, INTR_EXCLUSIVE)) { *array++ = vec; if (--count == 0) - return (0); + return 0; } } /* * There are not enough vectors to share. */ - return (EPERM); + return EPERM; } int @@ -313,14 +346,14 @@ vmeintr_establish(u_int vec, struct intrhand *ih, const char *name) " it uses ipl %d\n", __func__, ih->ih_ipl, vec, intr->ih_ipl); #endif - return (EINVAL); + return EINVAL; } if (ISSET(intr->ih_flags, INTR_EXCLUSIVE) || ISSET(ih->ih_flags, INTR_EXCLUSIVE)) { #ifdef DIAGNOSTIC printf("%s: can't share vector %x\n", __func__, vec); #endif - return (EINVAL); + return EINVAL; } } @@ -331,9 +364,9 @@ vmeintr_establish(u_int vec, struct intrhand *ih, const char *name) /* * Enable VME interrupt source for this level. */ - intsrc_enable(INTSRC_VME + (ih->ih_ipl - 1), ih->ih_ipl); + intsrc_enable(INTSRC_VME(ih->ih_ipl), ih->ih_ipl); - return (0); + return 0; } void @@ -359,90 +392,119 @@ vmeintr_disestablish(u_int vec, struct intrhand *ih) break; } if (vec == NVMEINTR) - intsrc_disable(INTSRC_VME + (ih->ih_ipl - 1)); + intsrc_disable(INTSRC_VME(ih->ih_ipl)); } /* * 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 vme_a16_map(bus_space_tag_t tag, 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 (ISVMEA16(addr) && ISVMEA16(addr + size - 1)) - return vme_map(sc->sc_ext_a16, addr + platform->vme16_base, - addr, size, flags, ret); + struct vme_softc *sc = (void *)vme_cd.cd_devs[0]; + vaddr_t va; + int rc; - return EINVAL; + rc = vme_map(sc, sc->sc_ext_a16, VME_A16, addr, size, flags, &va); + *ret = (bus_space_handle_t)va; + return rc; } int vme_a24_map(bus_space_tag_t tag, 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 (ISVMEA24(addr) && ISVMEA24(addr + size - 1)) - return vme_map(sc->sc_ext_a24, addr + platform->vme24_base, - addr, size, flags, ret); + struct vme_softc *sc = (void *)vme_cd.cd_devs[0]; + vaddr_t va; + int rc; - return EINVAL; + rc = vme_map(sc, sc->sc_ext_a24, VME_A24, addr, size, flags, &va); + *ret = (bus_space_handle_t)va; + return rc; } int vme_a32_map(bus_space_tag_t tag, 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 (ISVMEA32(addr) && ISVMEA32(addr + size - 1)) - return vme_map(sc->sc_ext_a32, addr + platform->vme32_base, - addr, size, flags, ret); + struct vme_softc *sc = (void *)vme_cd.cd_devs[0]; + vaddr_t va; + int rc; - return EINVAL; + rc = vme_map(sc, sc->sc_ext_a32, VME_A32, addr, size, flags, &va); + *ret = (bus_space_handle_t)va; + return rc; } int -vme_map(struct extent *ext, paddr_t paddr, bus_addr_t addr, bus_size_t size, - int flags, bus_space_handle_t *ret) +vme_map(struct vme_softc *sc, struct extent *ext, u_int awidth, + bus_addr_t addr, bus_size_t size, int flags, vaddr_t *rva) { + const struct vme_range *r; int rc; paddr_t pa; - psize_t len; - vaddr_t ova, va; - u_int pg; + psize_t offs, len; - pa = trunc_page(paddr); - len = round_page(paddr + size) - pa; + /* + * Since we need to map VME address ranges on demand, we will allocate + * with a page granularity. + */ + pa = trunc_page(addr); + offs = addr - pa; + len = round_page(addr + size) - pa; + + /* + * Check that the mapping fits within the available address ranges. + */ + for (r = sc->sc_ranges; r->vr_width != 0; r++) { + if (r->vr_width == awidth && + r->vr_start <= addr && r->vr_end >= addr + size - 1) + break; + } + if (r->vr_width == 0) + return EINVAL; + /* + * Register this range in the per-width extent. + */ if (ext != NULL) { - rc = extent_alloc_region(ext, atop(addr), atop(len), + rc = extent_alloc_region(ext, atop(pa), atop(len), EX_NOWAIT | EX_MALLOCOK); if (rc != 0) - return (rc); + return rc; } - ova = va = uvm_km_valloc(kernel_map, len); - if (va == NULL) { - rc = ENOMEM; - goto fail; + /* + * Allocate virtual memory for the range and map it. + */ + rc = vme_map_r(r, pa, len, flags, UVM_PROT_RW, rva); + if (rc != 0) { + if (ext != NULL) + (void)extent_free(ext, atop(pa), atop(len), + EX_NOWAIT | EX_MALLOCOK); + return rc; } - *ret = (bus_space_handle_t)va; + *rva += offs; + return 0; +} +int +vme_map_r(const struct vme_range *r, paddr_t pa, psize_t len, int flags, + vm_prot_t prot, vaddr_t *rva) +{ + vaddr_t ova, va; + u_int pg; + + ova = va = uvm_km_valloc(kernel_map, len); + if (va == NULL) + return ENOMEM; + + pa += r->vr_base; for (pg = atop(len); pg != 0; pg--) { - pmap_kenter_pa(va, pa, UVM_PROT_RW); + pmap_kenter_pa(va, pa, prot); va += PAGE_SIZE; pa += PAGE_SIZE; } @@ -450,69 +512,96 @@ vme_map(struct extent *ext, paddr_t paddr, bus_addr_t addr, bus_size_t size, pmap_cache_ctrl(pmap_kernel(), ova, ova + len, CACHE_GLOBAL); pmap_update(pmap_kernel()); - return (0); + *rva = ova; -fail: - if (ext != NULL) - extent_free(ext, atop(addr), atop(len), EX_NOWAIT | EX_MALLOCOK); - return (rc); + return 0; } void vme_a16_unmap(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t size) { - struct vmesoftc *sc = (void *)vme_cd.cd_devs[0]; + struct vme_softc *sc = (void *)vme_cd.cd_devs[0]; + vaddr_t va = (vaddr_t)handle; paddr_t pa; - if (pmap_extract(pmap_kernel(), (vaddr_t)handle, &pa) == FALSE) + if (pmap_extract(pmap_kernel(), va, &pa) == FALSE) return; - pa -= platform->vme16_base; - return (vme_unmap(sc->sc_ext_a16, pa, (vaddr_t)handle, size)); + return vme_unmap(sc, sc->sc_ext_a16, VME_A16, va, pa, size); } void vme_a24_unmap(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t size) { - struct vmesoftc *sc = (void *)vme_cd.cd_devs[0]; + struct vme_softc *sc = (void *)vme_cd.cd_devs[0]; + vaddr_t va = (vaddr_t)handle; paddr_t pa; - if (pmap_extract(pmap_kernel(), (vaddr_t)handle, &pa) == FALSE) + if (pmap_extract(pmap_kernel(), va, &pa) == FALSE) return; - pa -= platform->vme24_base; - return (vme_unmap(sc->sc_ext_a24, pa, (vaddr_t)handle, size)); + return vme_unmap(sc, sc->sc_ext_a24, VME_A24, va, pa, size); } void vme_a32_unmap(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t size) { - struct vmesoftc *sc = (void *)vme_cd.cd_devs[0]; + struct vme_softc *sc = (void *)vme_cd.cd_devs[0]; + vaddr_t va = (vaddr_t)handle; paddr_t pa; - if (pmap_extract(pmap_kernel(), (vaddr_t)handle, &pa) == FALSE) + if (pmap_extract(pmap_kernel(), va, &pa) == FALSE) return; - pa -= platform->vme32_base; - return (vme_unmap(sc->sc_ext_a32, pa, (vaddr_t)handle, size)); + return vme_unmap(sc, sc->sc_ext_a32, VME_A32, va, pa, size); } void -vme_unmap(struct extent *ext, vme_addr_t addr, vaddr_t vaddr, bus_size_t size) +vme_unmap(struct vme_softc *sc, struct extent *ext, u_int awidth, + vaddr_t vaddr, paddr_t paddr, bus_size_t size) { + const struct vme_range *r; vaddr_t va; - vsize_t len; + paddr_t pa, addr; + psize_t len; va = trunc_page(vaddr); - len = round_page(vaddr + size) - va; + pa = trunc_page(paddr); + len = round_page(paddr + size) - pa; + /* + * Retrieve the address range this mapping comes from. + */ + for (r = sc->sc_ranges; r->vr_width != 0; r++) { + if (r->vr_width != awidth) + continue; + addr = paddr - r->vr_base; + if (r->vr_width == awidth && + r->vr_start <= addr && r->vr_end >= addr + size - 1) + break; + } + if (r->vr_width == 0) { +#ifdef DIAGNOSTIC + printf("%s: non-sensical A%d mapping at va %p pa %p\n", + __func__, AWIDTH(awidth), vaddr, paddr); +#endif + return; + } + + /* + * Undo the mapping. + */ pmap_kremove(va, len); pmap_update(pmap_kernel()); uvm_km_free(kernel_map, va, len); - if (ext != NULL) - extent_free(ext, atop(addr), atop(len), - EX_NOWAIT | EX_MALLOCOK); + /* + * Unregister mapping. + */ + if (ext != NULL) { + pa -= r->vr_base; + extent_free(ext, atop(pa), atop(len), EX_NOWAIT | EX_MALLOCOK); + } } int @@ -520,29 +609,30 @@ vme_subregion(bus_space_tag_t tag, bus_space_handle_t handle, bus_addr_t offset, bus_size_t size, bus_space_handle_t *ret) { /* since vme_map produces linear mappings, this is safe */ + /* XXX does not check range overflow */ *ret = handle + offset; - return (0); + return 0; } void * vme_vaddr(bus_space_tag_t tag, bus_space_handle_t handle) { - return ((void *)handle); + return (void *)handle; } /* - * D8 routines + * D8 access routines */ uint16_t -vme_d8_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) +vme_d8_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) { volatile uint8_t *addr = (volatile uint8_t *)(h + o); return ((uint16_t)addr[0] << 8) | ((uint16_t)addr[1]); } uint32_t -vme_d8_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) +vme_d8_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) { volatile uint8_t *addr = (volatile uint8_t *)(h + o); return ((uint32_t)addr[0] << 24) | ((uint32_t)addr[1] << 16) | @@ -550,7 +640,7 @@ vme_d8_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) } void -vme_d8_space_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, +vme_d8_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, uint16_t v) { volatile uint8_t *addr = (volatile uint8_t *)(h + o); @@ -559,7 +649,7 @@ vme_d8_space_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, } void -vme_d8_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, +vme_d8_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, uint32_t v) { volatile uint8_t *addr = (volatile uint8_t *)(h + o); @@ -570,61 +660,61 @@ vme_d8_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, } void -vme_d8_space_read_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, +vme_d8_read_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, uint8_t *buf, bus_size_t len) { len >>= 1; while (len-- != 0) { - *(uint16_t *)buf = vme_d8_space_read_2(t, h, o); + *(uint16_t *)buf = vme_d8_read_2(t, h, o); buf += 2; } } void -vme_d8_space_write_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, +vme_d8_write_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, const uint8_t *buf, bus_size_t len) { len >>= 1; while (len-- != 0) { - vme_d8_space_write_2(t, h, o, *(uint16_t *)buf); + vme_d8_write_2(t, h, o, *(uint16_t *)buf); buf += 2; } } void -vme_d8_space_read_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, +vme_d8_read_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, uint8_t *buf, bus_size_t len) { len >>= 2; while (len-- != 0) { - *(uint32_t *)buf = vme_d8_space_read_4(t, h, o); + *(uint32_t *)buf = vme_d8_read_4(t, h, o); buf += 4; } } void -vme_d8_space_write_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, +vme_d8_write_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, const uint8_t *buf, bus_size_t len) { len >>= 2; while (len-- != 0) { - vme_d8_space_write_4(t, h, o, *(uint32_t *)buf); + vme_d8_write_4(t, h, o, *(uint32_t *)buf); buf += 4; } } /* - * D16 routines + * D16 access routines */ uint32_t -vme_d16_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) +vme_d16_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) { volatile uint16_t *addr = (volatile uint16_t *)(h + o); return ((uint32_t)addr[0] << 16) | ((uint32_t)addr[1]); } void -vme_d16_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, +vme_d16_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, uint32_t v) { volatile uint16_t *addr = (volatile uint16_t *)(h + o); @@ -633,31 +723,29 @@ vme_d16_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, } void -vme_d16_space_read_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, +vme_d16_read_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, uint8_t *buf, bus_size_t len) { len >>= 2; while (len-- != 0) { - *(uint32_t *)buf = vme_d16_space_read_4(t, h, o); + *(uint32_t *)buf = vme_d16_read_4(t, h, o); buf += 4; } } void -vme_d16_space_write_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, +vme_d16_write_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, const uint8_t *buf, bus_size_t len) { len >>= 2; while (len-- != 0) { - vme_d16_space_write_4(t, h, o, *(uint32_t *)buf); + vme_d16_write_4(t, h, o, *(uint32_t *)buf); buf += 4; } } /* * Get a bus_space_tag for the requested address and data access modes. - * - * On aviion, we do not honour the dspace yet. */ int vmebus_get_bst(struct device *vsc, u_int aspace, u_int dspace, @@ -671,7 +759,7 @@ vmebus_get_bst(struct device *vsc, u_int aspace, u_int dspace, case VME_D8: break; default: - return (EINVAL); + return EINVAL; } switch (aspace) { @@ -680,13 +768,13 @@ vmebus_get_bst(struct device *vsc, u_int aspace, u_int dspace, case VME_A16: break; default: - return (EINVAL); + return EINVAL; } tag = (struct aviion_bus_space_tag *)malloc(sizeof *tag, M_DEVBUF, M_NOWAIT); if (tag == NULL) - return (ENOMEM); + return ENOMEM; switch (aspace) { default: @@ -710,6 +798,7 @@ vmebus_get_bst(struct device *vsc, u_int aspace, u_int dspace, tag->_space_write_1 = generic_space_write_1; switch (dspace) { + default: case VME_D32: tag->_space_read_2 = generic_space_read_2; tag->_space_write_2 = generic_space_write_2; @@ -723,27 +812,27 @@ vmebus_get_bst(struct device *vsc, u_int aspace, u_int dspace, case VME_D16: tag->_space_read_2 = generic_space_read_2; tag->_space_write_2 = generic_space_write_2; - tag->_space_read_4 = vme_d16_space_read_4; - tag->_space_write_4 = vme_d16_space_write_4; + tag->_space_read_4 = vme_d16_read_4; + tag->_space_write_4 = vme_d16_write_4; tag->_space_read_raw_2 = generic_space_read_raw_2; tag->_space_write_raw_2 = generic_space_write_raw_2; - tag->_space_read_raw_4 = vme_d16_space_read_raw_4; - tag->_space_write_raw_4 = vme_d16_space_write_raw_4; + tag->_space_read_raw_4 = vme_d16_read_raw_4; + tag->_space_write_raw_4 = vme_d16_write_raw_4; break; case VME_D8: - tag->_space_read_2 = vme_d8_space_read_2; - tag->_space_write_2 = vme_d8_space_write_2; - tag->_space_read_4 = vme_d8_space_read_4; - tag->_space_write_4 = vme_d8_space_write_4; - tag->_space_read_raw_2 = vme_d8_space_read_raw_2; - tag->_space_write_raw_2 = vme_d8_space_write_raw_2; - tag->_space_read_raw_4 = vme_d8_space_read_raw_4; - tag->_space_write_raw_4 = vme_d8_space_write_raw_4; + tag->_space_read_2 = vme_d8_read_2; + tag->_space_write_2 = vme_d8_write_2; + tag->_space_read_4 = vme_d8_read_4; + tag->_space_write_4 = vme_d8_write_4; + tag->_space_read_raw_2 = vme_d8_read_raw_2; + tag->_space_write_raw_2 = vme_d8_write_raw_2; + tag->_space_read_raw_4 = vme_d8_read_raw_4; + tag->_space_write_raw_4 = vme_d8_write_raw_4; break; } *bst = tag; - return (0); + return 0; } void @@ -756,17 +845,17 @@ vmebus_release_bst(struct device *vsc, bus_space_tag_t b) * /dev/vme* access routines */ -/* minor device number encoding */ -#define AWIDTH_FIELD(minor) (minor & 0x0f) -#define AWIDTH(w) ((w) << 3) -#define DWIDTH_FIELD(minor) ((minor & 0xf0) >> 4) -#define DWIDTH(w) ((w) << 3) - int vmeopen(dev_t dev, int flags, int type, struct proc *p) { - if (vme_cd.cd_ndevs == 0 || vme_cd.cd_devs[0] == NULL) - return (ENODEV); + struct vme_softc *sc; + + if (minor(dev) >= vme_cd.cd_ndevs || + (sc = vme_cd.cd_devs[minor(dev)]) == NULL) + return ENODEV; + + if (sc->sc_ranges == NULL) /* failed attach */ + return ENODEV; switch (AWIDTH_FIELD(minor(dev))) { case VME_A32: @@ -774,7 +863,7 @@ vmeopen(dev_t dev, int flags, int type, struct proc *p) case VME_A16: break; default: - return (ENODEV); + return ENODEV; } switch (DWIDTH_FIELD(minor(dev))) { @@ -783,28 +872,106 @@ vmeopen(dev_t dev, int flags, int type, struct proc *p) case VME_D8: break; default: - return (ENODEV); + return ENODEV; } - return (0); + return 0; } int vmeclose(dev_t dev, int flags, int type, struct proc *p) { - return (0); + return 0; } int vmeread(dev_t dev, struct uio *uio, int flags) { - return (EIO); + struct vme_softc *sc; + int awidth, dwidth; + + sc = vme_cd.cd_devs[minor(dev)]; + awidth = AWIDTH_FIELD(minor(dev)); + dwidth = DWIDTH_FIELD(minor(dev)); + + return vmerw(sc, awidth, dwidth, uio, flags); } int vmewrite(dev_t dev, struct uio *uio, int flags) { - return (EIO); + struct vme_softc *sc; + int awidth, dwidth; + + sc = vme_cd.cd_devs[minor(dev)]; + awidth = AWIDTH_FIELD(minor(dev)); + dwidth = DWIDTH_FIELD(minor(dev)); + + return vmerw(sc, awidth, dwidth, uio, flags); +} + +int +vmerw(struct vme_softc *sc, int awidth, int dwidth, struct uio *uio, int flags) +{ + const struct vme_range *r; + struct iovec *iov; + psize_t delta, len; + vaddr_t vmepg; + int rc = 0; + + while (uio->uio_resid > 0) { + iov = uio->uio_iov; + if (iov->iov_len == 0) { + uio->uio_iov++; + uio->uio_iovcnt--; + if (uio->uio_iovcnt < 0) + panic("bogus uio %p", uio); + continue; + } + + /* + * Figure out which range we will be working on; + * if we hit the end of a range we'll report EFAULT. + */ + for (r = sc->sc_ranges; r->vr_width != 0; r++) { + if (r->vr_width != awidth) + continue; + if ((off_t)r->vr_start <= uio->uio_offset && + (off_t)r->vr_end >= uio->uio_offset) + break; + } + if (r->vr_width == 0) { + rc = EFAULT; /* outside any valid range */ + break; + } + + delta = uio->uio_offset & PAGE_MASK; + len = min(uio->uio_resid, PAGE_SIZE - delta); + /* len = min(len, (off_t)r->vr_end - uio->uio_offset); */ + + rc = vme_map_r(r, trunc_page(uio->uio_offset), PAGE_SIZE, 0, + uio->uio_rw == UIO_READ ? UVM_PROT_R : UVM_PROT_RW, &vmepg); + if (rc != 0) + break; + + /* XXX wrap this because of dwidth */ + rc = uiomove((caddr_t)vmepg + delta, len, uio); + + /* inline vme_unmap */ + pmap_kremove(vmepg, PAGE_SIZE); + pmap_update(pmap_kernel()); + uvm_km_free(kernel_map, vmepg, PAGE_SIZE); + + if (rc != 0) + break; + + iov->iov_base += len; + iov->iov_len -= len; + uio->uio_offset += len; + uio->uio_resid -= len; + } + + return rc; } int @@ -812,44 +979,35 @@ vmeioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { switch (cmd) { default: - return (ENOTTY); + return ENOTTY; } } paddr_t vmemmap(dev_t dev, off_t off, int prot) { + struct vme_softc *sc; + const struct vme_range *r; int awidth; - paddr_t pa; - - if ((off & PAGE_MASK) != 0) - return (-1); + sc = vme_cd.cd_devs[minor(dev)]; awidth = AWIDTH_FIELD(minor(dev)); - /* check offset range */ - if (off < 0 || off >= (1ULL << AWIDTH(awidth))) - return (-1); - - pa = (paddr_t)off; + if ((off & PAGE_MASK) != 0) + return -1; - switch (awidth) { - case VME_A32: - if (!ISVMEA32(pa)) - return (-1); - pa += platform->vme32_base; - break; - case VME_A24: - if (!ISVMEA24(pa)) - return (-1); - pa += platform->vme24_base; - break; - case VME_A16: - if (!ISVMEA16(pa)) - return (-1); - pa += platform->vme16_base; - break; + /* + * Figure out which range we will be working on. + */ + for (r = sc->sc_ranges; r->vr_width != 0; r++) { + if (r->vr_width != awidth) + continue; + if ((off_t)r->vr_start <= off && + (off_t)r->vr_end >= off) + break; } + if (r->vr_width == 0) + return -1; - return (atop(pa)); + return atop(r->vr_base + (paddr_t)off); } diff --git a/sys/arch/aviion/dev/vmevar.h b/sys/arch/aviion/dev/vmevar.h index 9098585ce8c..3d30a2d5b00 100644 --- a/sys/arch/aviion/dev/vmevar.h +++ b/sys/arch/aviion/dev/vmevar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vmevar.h,v 1.3 2007/12/19 22:05:06 miod Exp $ */ +/* $OpenBSD: vmevar.h,v 1.4 2010/04/21 19:33:47 miod Exp $ */ /* * Copyright (c) 2006, 2007, Miodrag Vallat * @@ -30,6 +30,28 @@ typedef u_int32_t vme_addr_t; /* + * VME address and data widths + */ + +#define VME_A32 0x04 /* 100..000 */ +#define VME_A24 0x03 /* 011..000 */ +#define VME_A16 0x02 /* 010..000 */ +#define VME_D32 0x04 /* 100..000 */ +#define VME_D16 0x02 /* 010..000 */ +#define VME_D8 0x01 /* 001..000 */ + +/* + * VME address range + */ + +struct vme_range { + u_int vr_width; + vme_addr_t vr_start; + vme_addr_t vr_end; + paddr_t vr_base; +}; + +/* * Attachment information for VME devices. * * Drivers are supposed to do their interrupt vector allocation @@ -71,12 +93,6 @@ int vmeintr_establish(u_int, struct intrhand *, const char *); * when bus accesses are no longer necessary. */ int vmebus_get_bst(struct device *, u_int, u_int, bus_space_tag_t *); -#define VME_A32 0x04 /* 100..000 */ -#define VME_A24 0x03 /* 011..000 */ -#define VME_A16 0x02 /* 010..000 */ -#define VME_D32 0x04 /* 100..000 */ -#define VME_D16 0x02 /* 010..000 */ -#define VME_D8 0x01 /* 001..000 */ void vmebus_release_bst(struct device *, bus_space_tag_t); #endif /* _AVIION_VME_H_ */ diff --git a/sys/arch/aviion/include/_types.h b/sys/arch/aviion/include/_types.h index 2daea26703b..f532a0ac698 100644 --- a/sys/arch/aviion/include/_types.h +++ b/sys/arch/aviion/include/_types.h @@ -1,4 +1,7 @@ -/* $OpenBSD: _types.h,v 1.2 2007/05/15 01:56:46 deraadt Exp $ */ +/* $OpenBSD: _types.h,v 1.3 2010/04/21 19:33:47 miod Exp $ */ /* public domain */ #include <m88k/_types.h> + +/* Feature test macros */ +#define __HAVE_TIMECOUNTER diff --git a/sys/arch/aviion/include/av400.h b/sys/arch/aviion/include/av400.h index c7a38af64e3..919cb1a51fc 100644 --- a/sys/arch/aviion/include/av400.h +++ b/sys/arch/aviion/include/av400.h @@ -1,4 +1,4 @@ -/* $OpenBSD: av400.h,v 1.6 2010/04/18 22:04:39 miod Exp $ */ +/* $OpenBSD: av400.h,v 1.7 2010/04/21 19:33:47 miod Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * All rights reserved. @@ -85,7 +85,6 @@ #define AV400_VIACK6V 0xfff85018 #define AV400_VIACK7V 0xfff8501c #define AV400_VIRQV 0xfff85020 -#define AV400_IVEC 0x40 /* vector returned upon AV400 int */ /* * IEN and IST register bits @@ -93,35 +92,35 @@ * 400, 3000 and 4000 series'', section 3 (Interrupts). */ -#define IRQ_RESERVED 0x1800018c /* 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_ZBUF 0x04000000 /* 26 - Z Buffer */ -#define IRQ_VID 0x02000000 /* 25 - Video */ -#define IRQ_PAR 0x01000000 /* 24 - Parity Error */ -#define IRQ_VME7 0x00800000 /* 23 - VMEBus level 7 */ -#define IRQ_KBD 0x00400000 /* 22 - Keyboard */ -#define IRQ_CIOI 0x00200000 /* 21 - CIO */ -#define IRQ_SF 0x00100000 /* 20 - System Failure */ -#define IRQ_VME6 0x00080000 /* 19 - VMEBus level 6 */ -#define IRQ_PPI 0x00040000 /* 18 - Parallel Port */ -#define IRQ_DI1 0x00020000 /* 17 - DUART1 */ -#define IRQ_DI2 0x00010000 /* 16 - DUART2 */ -#define IRQ_ECI 0x00008000 /* 15 - Ethernet Controller */ -#define IRQ_VME5 0x00004000 /* 14 - VMEBus level 5 */ -#define IRQ_DTC 0x00002000 /* 13 - DMA Terminal Count */ -#define IRQ_VME4 0x00001000 /* 12 - VMEBus level 4 */ -#define IRQ_DWP 0x00000800 /* 11 - DMA Write Protect */ -#define IRQ_VME3 0x00000400 /* 10 - VMEBus level 3 */ -#define IRQ_DVB 0x00000200 /* 09 - DMA Valid Bit */ -#define IRQ_VME2 0x00000040 /* 06 - VMEBus level 2 */ -#define IRQ_SCI 0x00000020 /* 05 - SCSI Controller */ -#define IRQ_VME1 0x00000010 /* 04 - VMEBus level 1 */ -#define IRQ_SWI1 0x00000002 /* 01 - SW Interrupt level 1 */ -#define IRQ_SWI0 0x00000001 /* 00 - SW Interrupt level 0 */ +#define AV400_IRQ_RESERVED 0x1800018c /* all reserved bits */ +#define AV400_IRQ_ABORT 0x80000000 /* 31 - Abort */ +#define AV400_IRQ_ACF 0x40000000 /* 30 - AC Fail */ +#define AV400_IRQ_ARBTO 0x20000000 /* 29 - VME Arbiter Timeout */ +#define AV400_IRQ_ZBUF 0x04000000 /* 26 - Z Buffer */ +#define AV400_IRQ_VID 0x02000000 /* 25 - Video */ +#define AV400_IRQ_PAR 0x01000000 /* 24 - Parity Error */ +#define AV400_IRQ_VME7 0x00800000 /* 23 - VMEBus level 7 */ +#define AV400_IRQ_KBD 0x00400000 /* 22 - Keyboard */ +#define AV400_IRQ_CIOI 0x00200000 /* 21 - CIO */ +#define AV400_IRQ_SF 0x00100000 /* 20 - System Failure */ +#define AV400_IRQ_VME6 0x00080000 /* 19 - VMEBus level 6 */ +#define AV400_IRQ_PPI 0x00040000 /* 18 - Parallel Port */ +#define AV400_IRQ_DI1 0x00020000 /* 17 - DUART1 */ +#define AV400_IRQ_DI2 0x00010000 /* 16 - DUART2 */ +#define AV400_IRQ_ECI 0x00008000 /* 15 - Ethernet Controller */ +#define AV400_IRQ_VME5 0x00004000 /* 14 - VMEBus level 5 */ +#define AV400_IRQ_DTC 0x00002000 /* 13 - DMA Terminal Count */ +#define AV400_IRQ_VME4 0x00001000 /* 12 - VMEBus level 4 */ +#define AV400_IRQ_DWP 0x00000800 /* 11 - DMA Write Protect */ +#define AV400_IRQ_VME3 0x00000400 /* 10 - VMEBus level 3 */ +#define AV400_IRQ_DVB 0x00000200 /* 09 - DMA Valid Bit */ +#define AV400_IRQ_VME2 0x00000040 /* 06 - VMEBus level 2 */ +#define AV400_IRQ_SCI 0x00000020 /* 05 - SCSI Controller */ +#define AV400_IRQ_VME1 0x00000010 /* 04 - VMEBus level 1 */ +#define AV400_IRQ_SWI1 0x00000002 /* 01 - SW Interrupt level 1 */ +#define AV400_IRQ_SWI0 0x00000001 /* 00 - SW Interrupt level 0 */ -#define IST_STRING "\20" \ +#define AV400_IST_STRING "\20" \ "\40ABRT\37ACF\36ARBTO\33ZBUF\32VID\31PAR" \ "\30IRQ7\27KBD\26CIOI\25SF\24IRQ6\23PPI\22DI1\21DI2" \ "\20ECI\17IRQ5\16DTC\15IRQ4\14DWP\13IRQ3\12DVB" \ diff --git a/sys/arch/aviion/include/av530.h b/sys/arch/aviion/include/av530.h index d5bb22b5827..73965e000b9 100644 --- a/sys/arch/aviion/include/av530.h +++ b/sys/arch/aviion/include/av530.h @@ -1,4 +1,4 @@ -/* $OpenBSD: av530.h,v 1.1 2010/04/18 22:04:39 miod Exp $ */ +/* $OpenBSD: av530.h,v 1.2 2010/04/21 19:33:47 miod Exp $ */ /* * Copyright (c) 2006, 2010 Miodrag Vallat * @@ -71,35 +71,35 @@ * 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" \ +#define AV530_IRQ_RESERVED 0x0020aa00 /* all reserved bits */ +#define AV530_IRQ_ABORT 0x80000000 /* 31 - Abort */ +#define AV530_IRQ_ACF 0x40000000 /* 30 - AC Fail */ +#define AV530_IRQ_ARBTO 0x20000000 /* 29 - VME Arbiter Timeout */ +#define AV530_IRQ_DTI 0x10000000 /* 28 - DUART Timer Interrupt */ +#define AV530_IRQ_SWI7 0x08000000 /* 27 - SW Interrupt level 7 */ +#define AV530_IRQ_SWI6 0x04000000 /* 26 - SW Interrupt level 6 */ +#define AV530_IRQ_SWI5 0x02000000 /* 25 - SW Interrupt level 5 */ +#define AV530_IRQ_SWI4 0x01000000 /* 24 - SW Interrupt level 4 */ +#define AV530_IRQ_VME7 0x00800000 /* 23 - VMEBus level 7 */ +#define AV530_IRQ_KBD 0x00400000 /* 22 - Keyboard */ +#define AV530_IRQ_SF 0x00100000 /* 20 - System Failure */ +#define AV530_IRQ_VME6 0x00080000 /* 19 - VMEBus level 6 */ +#define AV530_IRQ_MEM 0x00040000 /* 18 - Memory Error */ +#define AV530_IRQ_DI 0x00020000 /* 17 - DUART */ +#define AV530_IRQ_SIGHPI 0x00010000 /* 16 - SIGHPI */ +#define AV530_IRQ_VME5 0x00004000 /* 14 - VMEBus level 5 */ +#define AV530_IRQ_VME4 0x00001000 /* 12 - VMEBus level 4 */ +#define AV530_IRQ_VME3 0x00000400 /* 10 - VMEBus level 3 */ +#define AV530_IRQ_LMI 0x00000100 /* 08 - Location Monitor */ +#define AV530_IRQ_SIGLPI 0x00000080 /* 07 - SIGLPI */ +#define AV530_IRQ_VME2 0x00000040 /* 06 - VMEBus level 2 */ +#define AV530_IRQ_VME1 0x00000010 /* 04 - VMEBus level 1 */ +#define AV530_IRQ_SWI3 0x00000008 /* 03 - SW Interrupt level 3 */ +#define AV530_IRQ_SWI2 0x00000004 /* 02 - SW Interrupt level 2 */ +#define AV530_IRQ_SWI1 0x00000002 /* 01 - SW Interrupt level 1 */ +#define AV530_IRQ_SWI0 0x00000001 /* 00 - SW Interrupt level 0 */ + +#define AV530_IST_STRING "\20" \ "\40ABRT\37ACF\36ARBTO\35DTI\34SWI7\33SWI6\32SWI5\31SWI4" \ "\30IRQ7\27KBD\25SF\24IRQ6\23MEM\22DI\21SIGHPI" \ "\17IRQ5\15IRQ4\13IRQ3\11LMI" \ @@ -119,53 +119,91 @@ #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). + * See ``Programming System Control and I/O Registers: AViiON 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" \ +#define AV530_EXIRQ_RESERVED 0x04000e9f /* all reserved bits */ +#define AV530_EXIRQ_RTCOF 0x80000000 /* 31 - RTC Overflow */ +#define AV530_EXIRQ_PIT3OF 0x40000000 /* 30 - PIT 3 Overflow */ +#define AV530_EXIRQ_PIT2OF 0x20000000 /* 29 - PIT 2 Overflow */ +#define AV530_EXIRQ_PIT1OF 0x10000000 /* 28 - PIT 1 Overflow */ +#define AV530_EXIRQ_PIT0OF 0x08000000 /* 27 - PIT 0 Overflow */ +#define AV530_EXIRQ_DMA4C 0x02000000 /* 25 - DMA4 Channel Complete */ +#define AV530_EXIRQ_DMA3C 0x01000000 /* 24 - DMA3 Channel Complete */ +#define AV530_EXIRQ_DMA2C 0x00800000 /* 23 - DMA2 Channel Complete */ +#define AV530_EXIRQ_DMA1C 0x00400000 /* 22 - DMA1 Channel Complete */ +#define AV530_EXIRQ_DMA0C 0x00200000 /* 21 - DMA0 Channel Complete */ +#define AV530_EXIRQ_SCC 0x00100000 /* 20 - SCC */ +#define AV530_EXIRQ_LAN0 0x00080000 /* 19 - Ethernet 0 */ +#define AV530_EXIRQ_LAN1 0x00040000 /* 18 - Ethernet 1 */ +#define AV530_EXIRQ_SCSI0 0x00020000 /* 17 - SCSI0 */ +#define AV530_EXIRQ_SCSI1 0x00010000 /* 16 - SCSI1 */ +#define AV530_EXIRQ_VIDEO 0x00008000 /* 15 - Video */ +#define AV530_EXIRQ_ZBUF 0x00004000 /* 14 - Z Buffer */ +#define AV530_EXIRQ_DUART2 0x00002000 /* 13 - DUART2 */ +#define AV530_EXIRQ_VDMA 0x00001000 /* 12 - VDMA */ +#define AV530_EXIRQ_IOEXP1 0x00000100 /* 8 - IO Expansion 1 */ +#define AV530_EXIRQ_IOEXP2 0x00000040 /* 6 - IO Expansion 2 */ +#define AV530_EXIRQ_PDMA 0x00000020 /* 5 - Parallel Printer DMA */ + +#define AV530_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" +/* + * Miscellaneous registers + */ + #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_IOBRDID0 0xfffcf000 /* byte access */ +#define AV530_IOBRDID1 0xfffcf004 /* byte access */ #define AV530_CONFIG 0xfff8fffc +#define AV530_IOFUSE0 0xfffb0040 /* byte access */ +#define AV530_IOFUSE1 0xfffb00c0 /* byte access */ +#define AV530_IOFUSE_LAN 0x02 +#define AV530_IOFUSE_SCSI 0x01 + +/* + * PIT and RTC + */ + +#define AV530_PIT0_CNT 0xfff8f004 +#define AV530_PIT1_CNT 0xfff8f008 +#define AV530_PIT2_CNT 0xfff8f010 +#define AV530_PIT3_CNT 0xfff8f020 +#define AV530_PIT0_CS 0xfff8f044 +#define AV530_PIT1_CS 0xfff8f048 +#define AV530_PIT2_CS 0xfff8f050 +#define AV530_PIT3_CS 0xfff8f060 +#define AV530_PIT_CMD_ALL 0xfff8f07c +#define AV530_PIT_CTEN 0x00000008 +#define AV530_PIT_TEST 0x00000004 +#define AV530_PIT_IACK 0x00000002 +#define AV530_PIT_RESET 0x00000001 + +#define AV530_RTC_CNT 0xfff8f084 +#define AV530_RTC_CS 0xfff8f088 +#define AV530_RTC_IACK 0x00000002 +#define AV530_RTC_RESET 0x00000001 + +/* + * Onboard device addresses + */ + +#define AV530_SCSI1 0xfffb0000 +#define AV530_SCSI2 0xfffb0080 +#define AV530_LAN1 0xfffb00c0 +#define AV530_LAN2 0xfffb0140 + /* * CMMU addresses */ diff --git a/sys/arch/aviion/include/avcommon.h b/sys/arch/aviion/include/avcommon.h index f2a7f5b4e41..d2f31566634 100644 --- a/sys/arch/aviion/include/avcommon.h +++ b/sys/arch/aviion/include/avcommon.h @@ -1,4 +1,4 @@ -/* $OpenBSD: avcommon.h,v 1.4 2007/12/19 22:05:06 miod Exp $ */ +/* $OpenBSD: avcommon.h,v 1.5 2010/04/21 19:33:47 miod Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * All rights reserved. @@ -62,9 +62,6 @@ #define AV_IST 0xfff84040 /* interrupt status register */ -#define ISR_GET_CURRENT_MASK(cpu) \ - (*(volatile u_int *)AV_IST & int_mask_reg[cpu]) - #define AV_ISTATE 0xfff84088 /* HW interrupt status */ #define AV_CLRINT 0xfff8408c /* reset HW interrupt */ @@ -122,65 +119,13 @@ #define VTO128US 0x10 /* 128 usec */ #define VTODISABLE 0x18 /* disabled */ -/* these are the various Z8536 CIO counter/timer registers */ +/* Z8536 counter/timer register (not found on all models) */ #define CIO_BASE 0xfff83000 #define CIO_PORTC 0xfff83000 #define CIO_PORTB 0xfff83004 #define CIO_PORTA 0xfff83008 #define CIO_CTRL 0xfff8300c -#define CIO_MICR 0x00 /* Master interrupt control register */ -#define CIO_MICR_MIE 0x80 -#define CIO_MICR_DLC 0x40 -#define CIO_MICR_NV 0x20 -#define CIO_MICR_PAVIS 0x10 -#define CIO_MICR_PBVIS 0x08 -#define CIO_MICR_CTVIS 0x04 -#define CIO_MICR_RJA 0x02 -#define CIO_MICR_RESET 0x01 - -#define CIO_MCCR 0x01 /* Master config control register */ -#define CIO_MCCR_PBE 0x80 -#define CIO_MCCR_CT1E 0x40 -#define CIO_MCCR_CT2E 0x20 -#define CIO_MCCR_CT3E 0x10 -#define CIO_MCCR_PLC 0x08 -#define CIO_MCCR_PAE 0x04 - -#define CIO_CTMS1 0x1c /* Counter/timer mode specification #1 */ -#define CIO_CTMS2 0x1d /* Counter/timer mode specification #2 */ -#define CIO_CTMS3 0x1e /* Counter/timer mode specification #3 */ -#define CIO_CTMS_CSC 0x80 /* Continuous Single Cycle */ -#define CIO_CTMS_EOE 0x40 /* External Output Enable */ -#define CIO_CTMS_ECE 0x20 /* External Count Enable */ -#define CIO_CTMS_ETE 0x10 /* External Trigger Enable */ -#define CIO_CTMS_EGE 0x08 /* External Gate Enable */ -#define CIO_CTMS_REB 0x04 /* Retrigger Enable Bit */ -#define CIO_CTMS_PO 0x00 /* Pulse Output */ -#define CIO_CTMS_OSO 0x01 /* One Shot Output */ -#define CIO_CTMS_SWO 0x02 /* Square Wave Output */ - -#define CIO_IVR 0x04 /* Interrupt vector register */ - -#define CIO_CSR1 0x0a /* Command and status register CTC #1 */ -#define CIO_CSR2 0x0b /* Command and status register CTC #2 */ -#define CIO_CSR3 0x0c /* Command and status register CTC #3 */ - -#define CIO_CT1MSB 0x16 /* CTC #1 Timer constant - MSB */ -#define CIO_CT1LSB 0x17 /* CTC #1 Timer constant - LSB */ -#define CIO_CT2MSB 0x18 /* CTC #2 Timer constant - MSB */ -#define CIO_CT2LSB 0x19 /* CTC #2 Timer constant - LSB */ -#define CIO_CT3MSB 0x1a /* CTC #3 Timer constant - MSB */ -#define CIO_CT3LSB 0x1b /* CTC #3 Timer constant - LSB */ -#define CIO_PDCA 0x23 /* Port A data direction control */ -#define CIO_PDCB 0x2b /* Port B data direction control */ - -#define CIO_GCB 0x04 /* CTC Gate command bit */ -#define CIO_TCB 0x02 /* CTC Trigger command bit */ -#define CIO_IE 0xc0 /* CTC Interrupt enable (set) */ -#define CIO_CIP 0x20 /* CTC Clear interrupt pending */ -#define CIO_IP 0x20 /* CTC Interrupt pending */ - #define CONSOLE_DART_BASE 0xfff82000 #if defined(_KERNEL) && !defined(_LOCORE) diff --git a/sys/arch/aviion/include/board.h b/sys/arch/aviion/include/board.h index a9975f6ca31..2e894275dee 100644 --- a/sys/arch/aviion/include/board.h +++ b/sys/arch/aviion/include/board.h @@ -1,4 +1,4 @@ -/* $OpenBSD: board.h,v 1.5 2010/04/18 22:04:39 miod Exp $ */ +/* $OpenBSD: board.h,v 1.6 2010/04/21 19:33:47 miod Exp $ */ /* * Copyright (c) 2006, 2007, Miodrag Vallat * @@ -31,25 +31,25 @@ #include <machine/pmap_table.h> +struct vme_range; + struct board { - const char *descr; - void (*bootstrap)(void); - vaddr_t (*memsize)(void); - void (*startup)(void); + const char *descr; + void (*bootstrap)(void); + vaddr_t (*memsize)(void); + void (*startup)(void); - void (*intr)(struct trapframe *); - void (*init_clocks)(void); - u_int (*getipl)(void); - u_int (*setipl)(u_int); - u_int (*raiseipl)(u_int); + void (*intr)(struct trapframe *); + void (*init_clocks)(void); + u_int (*getipl)(void); + u_int (*setipl)(u_int); + u_int (*raiseipl)(u_int); - u_int64_t (*intsrc)(int); + u_int64_t (*intsrc)(int); - pmap_table_t ptable; + 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; + const struct vme_range *vme_ranges; }; #define md_interrupt_func(f) platform->intr(f) @@ -80,21 +80,27 @@ DECLARE_BOARD(6280); #define INTSRC_ABORT 1 /* abort button */ #define INTSRC_ACFAIL 2 /* AC failure */ #define INTSRC_SYSFAIL 3 /* system failure */ -#define INTSRC_CIO 4 /* Z8536 */ +#define INTSRC_CLOCK 4 /* clock chip */ #define INTSRC_DUART1 5 /* console MC68692 */ #define INTSRC_DUART2 6 /* secondary MC68692 */ #define INTSRC_ETHERNET1 7 /* first on-board Ethernet */ #define INTSRC_ETHERNET2 8 /* second on-board Ethernet */ #define INTSRC_SCSI1 9 /* first on-board SCSI controller */ #define INTSRC_SCSI2 10 /* second on-board SCSI controller */ -#define INTSRC_VME 11 /* seven VME interrupt levels */ +#define NINTSRC_SYSCON 11 /* total number of non-VME sources */ +#define INTSRC_VME(lvl) (NINTSRC_SYSCON + (lvl) - 1) /* seven VME levels */ + +#define IS_VME_INTSRC(intsrc) ((intsrc) >= NINTSRC_SYSCON) +#define VME_INTSRC_LEVEL(intsrc) ((intsrc) - NINTSRC_SYSCON + 1) void intsrc_enable(u_int, int); void intsrc_disable(u_int); +extern int32_t cpuid, sysid; extern const struct board *platform;/* just to have people confuse both names */ void cio_init_clocks(void); +void rtc_init_clocks(void); #endif /* _LOCORE */ #endif /* _MACHINE_BOARD_H_ */ |