summaryrefslogtreecommitdiff
path: root/sys/arch/aviion
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/aviion')
-rw-r--r--sys/arch/aviion/aviion/av400_machdep.c103
-rw-r--r--sys/arch/aviion/aviion/av530_machdep.c137
-rw-r--r--sys/arch/aviion/aviion/cio_clock.c166
-rw-r--r--sys/arch/aviion/aviion/machdep.c4
-rw-r--r--sys/arch/aviion/aviion/rtc_clock.c123
-rw-r--r--sys/arch/aviion/conf/GENERIC3
-rw-r--r--sys/arch/aviion/conf/files.aviion5
-rw-r--r--sys/arch/aviion/dev/mainbus.c4
-rw-r--r--sys/arch/aviion/dev/nvram.c54
-rw-r--r--sys/arch/aviion/dev/oosiop_syscon.c29
-rw-r--r--sys/arch/aviion/dev/syscon.c6
-rw-r--r--sys/arch/aviion/dev/sysconvar.h4
-rw-r--r--sys/arch/aviion/dev/vme.c524
-rw-r--r--sys/arch/aviion/dev/vmevar.h30
-rw-r--r--sys/arch/aviion/include/_types.h5
-rw-r--r--sys/arch/aviion/include/av400.h59
-rw-r--r--sys/arch/aviion/include/av530.h162
-rw-r--r--sys/arch/aviion/include/avcommon.h59
-rw-r--r--sys/arch/aviion/include/board.h40
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_ */