summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-11-07 23:01:39 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-11-07 23:01:39 +0000
commita58f0d0e9d8006fa44a20b2594a97894f15d7b0d (patch)
treea9245280d8741870f1aead208cbd30b13a5e7488
parent9214a014e55b97cd6524fa80abf852fadb724e85 (diff)
Blink leds on the DEC 3000 models (three different led types).
-rw-r--r--sys/arch/alpha/alpha/machdep.c24
-rw-r--r--sys/arch/alpha/conf/files.alpha4
-rw-r--r--sys/arch/alpha/include/cpu.h6
-rw-r--r--sys/arch/alpha/tc/ioasic.c107
-rw-r--r--sys/dev/tc/ioasicvar.h3
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_ */