diff options
-rw-r--r-- | sys/arch/alpha/alpha/machdep.c | 24 | ||||
-rw-r--r-- | sys/arch/alpha/conf/files.alpha | 4 | ||||
-rw-r--r-- | sys/arch/alpha/include/cpu.h | 6 | ||||
-rw-r--r-- | sys/arch/alpha/tc/ioasic.c | 107 | ||||
-rw-r--r-- | sys/dev/tc/ioasicvar.h | 3 |
5 files changed, 135 insertions, 9 deletions
diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c index 57460e66997..cff6e9d13e7 100644 --- a/sys/arch/alpha/alpha/machdep.c +++ b/sys/arch/alpha/alpha/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.120 2009/08/11 19:17:14 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.121 2009/11/07 23:01:36 miod Exp $ */ /* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */ /*- @@ -113,6 +113,14 @@ #include <ddb/db_extern.h> #endif +#include "ioasic.h" + +#if NIOASIC > 0 +#include <machine/tc_machdep.h> +#include <dev/tc/tcreg.h> +#include <dev/tc/ioasicvar.h> +#endif + int cpu_dump(void); int cpu_dumpsize(void); u_long cpu_dump_mempagecnt(void); @@ -183,6 +191,9 @@ int alpha_unaligned_sigbus = 1; /* SIGBUS on fixed-up accesses */ #ifndef NO_IEEE int alpha_fp_sync_complete = 0; /* fp fixup if sync even without /s */ #endif +#if NIOASIC > 0 +int alpha_led_blink = 0; +#endif /* used by hw_sysctl */ extern char *hw_serial; @@ -1615,6 +1626,9 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) struct proc *p; { dev_t consdev; +#if NIOASIC > 0 + int oldval, ret; +#endif if (name[0] != CPU_CHIPSET && namelen != 1) return (ENOTDIR); /* overloaded */ @@ -1669,6 +1683,14 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) #else return (sysctl_rdint(oldp, oldlenp, newp, 0)); #endif +#if NIOASIC > 0 + case CPU_LED_BLINK: + oldval = alpha_led_blink; + ret = sysctl_int(oldp, oldlenp, newp, newlen, &alpha_led_blink); + if (oldval != alpha_led_blink) + ioasic_led_blink(NULL); + return (ret); +#endif default: return (EOPNOTSUPP); } diff --git a/sys/arch/alpha/conf/files.alpha b/sys/arch/alpha/conf/files.alpha index 34610f64c5b..b38f8a84dbf 100644 --- a/sys/arch/alpha/conf/files.alpha +++ b/sys/arch/alpha/conf/files.alpha @@ -1,4 +1,4 @@ -# $OpenBSD: files.alpha,v 1.88 2008/11/09 15:11:18 oga Exp $ +# $OpenBSD: files.alpha,v 1.89 2009/11/07 23:01:38 miod Exp $ # $NetBSD: files.alpha,v 1.32 1996/11/25 04:03:21 cgd Exp $ # # alpha-specific configuration info @@ -97,7 +97,7 @@ file arch/alpha/tc/tc_3000_300.c tcasic & dec_3000_300 # the TURBOchannel IOCTL ASIC # IOASIC device and attachment defined in sys/dev/tc/files.tc -file arch/alpha/tc/ioasic.c ioasic +file arch/alpha/tc/ioasic.c ioasic needs-flag # PMAG-B CX device cfb: wsemuldisplaydev diff --git a/sys/arch/alpha/include/cpu.h b/sys/arch/alpha/include/cpu.h index 3c6a8a0b6c8..119470b8582 100644 --- a/sys/arch/alpha/include/cpu.h +++ b/sys/arch/alpha/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.38 2009/03/26 17:24:32 oga Exp $ */ +/* $OpenBSD: cpu.h,v 1.39 2009/11/07 23:01:38 miod Exp $ */ /* $NetBSD: cpu.h,v 1.45 2000/08/21 02:03:12 thorpej Exp $ */ /*- @@ -344,8 +344,9 @@ do { \ #define CPU_FP_SYNC_COMPLETE 7 /* int: always fixup sync fp traps */ #define CPU_CHIPSET 8 /* chipset information */ #define CPU_ALLOWAPERTURE 9 +#define CPU_LED_BLINK 10 /* int: blink leds on DEC 3000 */ -#define CPU_MAXID 10 /* valid machdep IDs */ +#define CPU_MAXID 11 /* valid machdep IDs */ #define CPU_CHIPSET_MEM 1 /* PCI memory address */ #define CPU_CHIPSET_BWX 2 /* PCI supports BWX */ @@ -366,6 +367,7 @@ do { \ { "fp_sync_complete", CTLTYPE_INT }, \ { "chipset", CTLTYPE_NODE }, \ { "allowaperture", CTLTYPE_INT }, \ + { "led_blink", CTLTYPE_INT } \ } #define CTL_CHIPSET_NAMES { \ diff --git a/sys/arch/alpha/tc/ioasic.c b/sys/arch/alpha/tc/ioasic.c index b903314a6e5..d3542e8d409 100644 --- a/sys/arch/alpha/tc/ioasic.c +++ b/sys/arch/alpha/tc/ioasic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ioasic.c,v 1.15 2008/08/09 16:42:29 miod Exp $ */ +/* $OpenBSD: ioasic.c,v 1.16 2009/11/07 23:01:38 miod Exp $ */ /* $NetBSD: ioasic.c,v 1.34 2000/07/18 06:10:06 thorpej Exp $ */ /*- @@ -63,6 +63,7 @@ #include <sys/systm.h> #include <sys/device.h> #include <sys/malloc.h> +#include <sys/timeout.h> #include <machine/autoconf.h> #include <machine/bus.h> @@ -72,6 +73,9 @@ #include <dev/tc/tcvar.h> #include <dev/tc/ioasicreg.h> #include <dev/tc/ioasicvar.h> +#ifdef DEC_3000_300 +#include <alpha/tc/tc_3000_300.h> +#endif /* Definition of the driver for autoconfig. */ int ioasicmatch(struct device *, void *, void *); @@ -88,7 +92,8 @@ struct cfdriver ioasic_cd = { int ioasic_intr(void *); int ioasic_intrnull(void *); -#define C(x) ((void *)(x)) +#define C(x) ((void *)(u_long)(x)) +#define KV(x) (ALPHA_PHYS_TO_K0SEG(x)) #define IOASIC_DEV_LANCE 0 #define IOASIC_DEV_SCC0 1 @@ -181,7 +186,7 @@ ioasicattach(parent, self, aux) /* * Turn off all device interrupt bits. - * (This does _not_ include 3000/300 TC option slot bits. + * (This does _not_ include 3000/300 TC option slot bits). */ imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK); for (i = 0; i < ioasic_ndevs; i++) @@ -325,3 +330,99 @@ ioasic_intr(val) return (gifound); } + +/* + * Blink leds + */ + +struct { + int patpos; + struct timeout tmo; +} led_blink_state; + +static const uint8_t led_pattern8[] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, + 0x40, 0x20, 0x10, 0x08, 0x04, 0x02 +}; + +void +ioasic_led_blink(void *unused) +{ + extern int alpha_led_blink; + vaddr_t rw_csr; + u_int32_t pattern; + int display_loadavg; + + if (alpha_led_blink == 0) { + pattern = 0; /* all clear */ + led_blink_state.patpos = 0; + } else { +#ifdef DEC_3000_300 + if (cputype == ST_DEC_3000_300) + display_loadavg = 0; + else +#endif + switch (hwrpb->rpb_variation & SV_ST_MASK) { + case SV_ST_FLAMINGO: + case SV_ST_HOTPINK: + case SV_ST_FLAMINGOPLUS: + case SV_ST_ULTRA: + case SV_ST_FLAMINGO45: + /* 500/800/900, 2 7-segment display, display loadavg */ + display_loadavg = 1; + break; + case SV_ST_SANDPIPER: + case SV_ST_SANDPLUS: + case SV_ST_SANDPIPER45: + default: + /* 400/600/700, 8 leds, display moving pattern */ + display_loadavg = 0; + break; + } + + if (display_loadavg) + pattern = averunnable.ldavg[0] >> FSHIFT; + else { + pattern = led_pattern8[led_blink_state.patpos]; + led_blink_state.patpos = + (led_blink_state.patpos + 1) % sizeof(led_pattern8); + } + } + + /* + * The low 8 bits, controlling the leds, are read-only in the + * CSR register, but read-write in its image at CSR + 4. + * + * On model 300, however, the internal 8 leds are at a different + * address, but the (better visible) power supply led is actually + * bit 5 in CSR (active low). + */ +#ifdef DEC_3000_300 + if (cputype == ST_DEC_3000_300) { + rw_csr = KV(0x1a0000000 + IOASIC_CSR + 4); + + *(volatile uint32_t *)TC_3000_300_LED = + (*(volatile uint32_t *)TC_3000_300_LED & ~(0xff << 16)) | + (pattern << 16); + /* + * Blink the power supply led 8x slower. This relies + * on led_pattern8[] being a < 16 element array. + */ + *(volatile uint32_t *)rw_csr = + (*(volatile uint32_t *)rw_csr & ~(1 << 5)) ^ + ((led_blink_state.patpos >> 3) << 5); + } else +#endif + { + rw_csr = KV(0x1e0000000 + IOASIC_CSR + 4); + + *(volatile uint32_t *)rw_csr = + (*(volatile uint32_t *)rw_csr & ~0xff) | pattern; + } + + if (alpha_led_blink != 0) { + timeout_set(&led_blink_state.tmo, ioasic_led_blink, NULL); + timeout_add(&led_blink_state.tmo, + (((averunnable.ldavg[0] + FSCALE) * hz) >> (FSHIFT + 3))); + } +} diff --git a/sys/dev/tc/ioasicvar.h b/sys/dev/tc/ioasicvar.h index f7be0c79a21..cf7b700d126 100644 --- a/sys/dev/tc/ioasicvar.h +++ b/sys/dev/tc/ioasicvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ioasicvar.h,v 1.9 2008/08/09 16:42:30 miod Exp $ */ +/* $OpenBSD: ioasicvar.h,v 1.10 2009/11/07 23:01:38 miod Exp $ */ /* $NetBSD: ioasicvar.h,v 1.14 2000/10/17 09:45:49 nisimura Exp $ */ /* @@ -72,5 +72,6 @@ void ioasic_intr_disestablish(struct device *, void *); int ioasic_submatch(void *, struct ioasicdev_attach_args *); void ioasic_attach_devs(struct ioasic_softc *, struct ioasic_dev *, int); +void ioasic_led_blink(void *); #endif /* _DEV_TC_IOASICVAR_ */ |