Add better support for controlling the LEDs, and use it. Now the

LEDs blink on network receive, network send, and disk interrupt,
and the high LEDs display the current load average (up to 15).
This commit is contained in:
fredette 2002-08-11 19:53:41 +00:00
parent 960ef7a15a
commit 2e5e562514
4 changed files with 112 additions and 90 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ie_gsc.c,v 1.2 2002/08/11 19:39:37 fredette Exp $ */
/* $NetBSD: if_ie_gsc.c,v 1.3 2002/08/11 19:53:41 fredette Exp $ */
/* $OpenBSD: if_ie_gsc.c,v 1.6 2001/01/12 22:57:04 mickey Exp $ */
@ -61,6 +61,7 @@
#include <hp700/dev/cpudevs.h>
#include <hp700/gsc/gscbusvar.h>
#include <hp700/hp700/machdep.h>
#include <dev/ic/i82586reg.h>
#include <dev/ic/i82586var.h>
@ -132,9 +133,6 @@ void ie_gsc_reset __P((struct ie_softc *sc, int what));
void ie_gsc_attend __P((struct ie_softc *, int));
void ie_gsc_run __P((struct ie_softc *sc));
void ie_gsc_port __P((struct ie_softc *sc, u_int));
#ifdef USELEDS
int ie_gsc_intrhook __P((struct ie_softc *sc, int what));
#endif
u_int16_t ie_gsc_read16 __P((struct ie_softc *sc, int offset));
void ie_gsc_write16 __P((struct ie_softc *sc, int offset, u_int16_t v));
void ie_gsc_write24 __P((struct ie_softc *sc, int offset, int addr));
@ -244,27 +242,6 @@ ie_gsc_port(sc, cmd)
}
}
#ifdef USELEDS
int
ie_gsc_intrhook(sc, where)
struct ie_softc *sc;
int where;
{
switch (where) {
case INTR_ENTER:
/* turn it on */
break;
case INTR_LOOP:
/* quick drop and raise */
break;
case INTR_EXIT:
/* drop it */
break;
}
return 0;
}
#endif
u_int16_t
ie_gsc_read16(sc, offset)
struct ie_softc *sc;
@ -328,6 +305,7 @@ ie_gsc_memcopyin(sc, p, offset, size)
memcpy (p, (void *)((caddr_t)sc->sc_maddr + offset), size);
bus_dmamap_sync(gsc->iemt, sc->sc_dmamap, offset, size,
BUS_DMASYNC_PREREAD);
hp700_led_blink(HP700_LED_NETRCV);
}
void
@ -342,6 +320,7 @@ ie_gsc_memcopyout(sc, p, offset, size)
memcpy ((void *)((caddr_t)sc->sc_maddr + offset), p, size);
bus_dmamap_sync(gsc->iemt, sc->sc_dmamap, offset, size,
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
hp700_led_blink(HP700_LED_NETSND);
}
/*
@ -516,11 +495,7 @@ ie_gsc_attach(parent, self, aux)
sc->ie_bus_read16 = ie_gsc_read16;
sc->ie_bus_write16 = ie_gsc_write16;
sc->ie_bus_write24 = ie_gsc_write24;
#ifdef USELEDS
sc->intrhook = ie_gsc_intrhook;
#else
sc->intrhook = NULL;
#endif
/* Clear all RAM. */
memset(sc->sc_maddr, 0, sc->sc_msize);

View File

@ -1,4 +1,4 @@
/* $NetBSD: osiop_gsc.c,v 1.1 2002/06/06 19:48:05 fredette Exp $ */
/* $NetBSD: osiop_gsc.c,v 1.2 2002/08/11 19:53:41 fredette Exp $ */
/*
* Copyright (c) 2001 Matt Fredette. All rights reserved.
@ -80,6 +80,7 @@
#include <hp700/dev/cpudevs.h>
#include <hp700/gsc/gscbusvar.h>
#include <hp700/hp700/machdep.h>
#define OSIOP_GSC_RESET 0x0000
#define OSIOP_GSC_OFFSET 0x0100
@ -212,5 +213,8 @@ osiop_gsc_intr(arg)
/* Deal with the interrupt */
osiop_intr(sc);
/* Blink the LED. */
hp700_led_blink(HP700_LED_DISK);
return (1);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: autoconf.c,v 1.1 2002/06/06 19:48:05 fredette Exp $ */
/* $NetBSD: autoconf.c,v 1.2 2002/08/11 19:53:41 fredette Exp $ */
/* $OpenBSD: autoconf.c,v 1.15 2001/06/25 00:43:10 mickey Exp $ */
@ -79,8 +79,9 @@ register_t kpsw = PSW_Q | PSW_P | PSW_C | PSW_D;
* LED blinking thing
*/
#ifdef USELEDS
struct callout heartbeat_tmo;
void heartbeat __P((void *));
int _hp700_led_on_cycles[_HP700_LEDS_BLINKABLE];
static struct callout hp700_led_callout;
static void hp700_led_blinker __P((void *));
extern int hz;
#endif
@ -120,41 +121,96 @@ cpu_configure()
(*cold_hook)();
#ifdef USELEDS
callout_init(&heartbeat_tmo);
heartbeat((void*) 0);
memset(_hp700_led_on_cycles, 0, sizeof(_hp700_led_on_cycles));
callout_init(&hp700_led_callout);
hp700_led_blinker((void *) 0);
#endif
}
#ifdef USELEDS
/*
* turn the heartbeat alive.
* right thing would be to pass counter to each subsequent timeout
* as an argument to heartbeat() incrementing every turn,
* i.e. avoiding the static hbcnt, but doing timeout_set() on each
* timeout_add() sounds ugly, guts of struct timeout looks ugly
* to ponder in even more.
* This sets LEDs.
*/
void
heartbeat(arg)
hp700_led_ctl(int off, int on, int toggle)
{
int r;
if (machine_ledaddr == NULL)
return;
/* The mask is reversed when pushed out to the hardware. */
r = ~(machine_leds = ((machine_leds & ~off) | on) ^ toggle);
if (machine_ledword)
*machine_ledaddr = r;
else {
#define HP700_LED_DATA 0x01
#define HP700_LED_STROBE 0x02
register int b;
for (b = 0x80; b; b >>= 1) {
*machine_ledaddr = (r & b)? HP700_LED_DATA : 0;
DELAY(1);
*machine_ledaddr = ((r & b)? HP700_LED_DATA : 0) |
HP700_LED_STROBE;
}
#undef HP700_LED_DATA
#undef HP700_LED_STROBE
}
}
/*
* This callout handler blinks LEDs.
*/
static void
hp700_led_blinker(arg)
void *arg;
{
u_int hbcnt = (u_int) arg;
u_int led_cycle = (u_int) arg;
int leds, led_i, led;
int load;
/*
* do this:
* Blink the heartbeat LED like this:
*
* |~| |~|
* _| |_| |_,_,_,_
* 0 1 2 3 4 6 7
*/
if (hbcnt < 4) {
ledctl(0, 0, PALED_HEARTBEAT);
callout_reset(&heartbeat_tmo, hz / 8, heartbeat, (void *) (hbcnt + 1));
} else {
callout_reset(&heartbeat_tmo, hz / 2, heartbeat, (void *) 0);
#define HP700_HEARTBEAT_CYCLES (_HP700_LED_FREQ / 8)
if (led_cycle == (0 * HP700_HEARTBEAT_CYCLES) ||
led_cycle == (2 * HP700_HEARTBEAT_CYCLES)) {
_hp700_led_on_cycles[HP700_LED_HEARTBEAT] =
HP700_HEARTBEAT_CYCLES;
}
/* Form the new LED mask. */
leds = 0;
for (led_i = 0, led = (1 << 0);
led_i < _HP700_LEDS_BLINKABLE;
led_i++, led <<= 1) {
if (_hp700_led_on_cycles[led_i] > 0)
leds |= led;
if (_hp700_led_on_cycles[led_i] >= 0)
_hp700_led_on_cycles[led_i]--;
}
/* Add in the system load. */
load = averunnable.ldavg[0] >> FSHIFT;
if (load >= (1 << (_HP700_LEDS_COUNT - _HP700_LEDS_BLINKABLE)))
load = (1 << (_HP700_LEDS_COUNT - _HP700_LEDS_BLINKABLE)) - 1;
leds |= (load << _HP700_LEDS_BLINKABLE);
/* Set the LEDs. */
hp700_led_ctl(-1, leds, 0);
/* NB: this assumes _HP700_LED_FREQ is a power of two. */
led_cycle = (led_cycle + 1) & (_HP700_LED_FREQ - 1);
callout_reset(&hp700_led_callout, hz / _HP700_LED_FREQ,
hp700_led_blinker, (void *) led_cycle);
}
#endif
#endif /* USELEDS */
/*
* This is called by configure to set dumplo and dumpsize.

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.h,v 1.1 2002/06/06 19:48:06 fredette Exp $ */
/* $NetBSD: machdep.h,v 1.2 2002/08/11 19:53:42 fredette Exp $ */
/* $OpenBSD: cpufunc.h,v 1.17 2000/05/15 17:22:40 mickey Exp $ */
@ -77,6 +77,14 @@
#include <hppa/hppa/machdep.h>
/* The LEDs. */
#define HP700_LED_NETSND (0)
#define HP700_LED_NETRCV (1)
#define HP700_LED_DISK (2)
#define HP700_LED_HEARTBEAT (3)
#define _HP700_LEDS_BLINKABLE (4)
#define _HP700_LEDS_COUNT (8)
/* This forcefully reboots the machine. */
void cpu_die __P((void));
@ -84,47 +92,26 @@ void cpu_die __P((void));
int hp700_pagezero_map __P((void));
void hp700_pagezero_unmap __P((int));
/* Blinking the LEDs. */
#ifdef USELEDS
#define PALED_NETSND 0x01
#define PALED_NETRCV 0x02
#define PALED_DISK 0x04
#define PALED_HEARTBEAT 0x08
#define PALED_LOADMASK 0xf0
#define PALED_DATA 0x01
#define PALED_STROBE 0x02
#define _HP700_LED_FREQ (16)
extern volatile u_int8_t *machine_ledaddr;
extern int machine_ledword, machine_leds;
static __inline void
ledctl(int on, int off, int toggle)
{
if (machine_ledaddr) {
int r;
if (on)
machine_leds |= on;
if (off)
machine_leds &= ~off;
if (toggle)
machine_leds ^= toggle;
r = ~machine_leds; /* it seems they should be reversed */
if (machine_ledword)
*machine_ledaddr = r;
else {
register int b;
for (b = 0x80; b; b >>= 1) {
*machine_ledaddr = (r & b)? PALED_DATA : 0;
DELAY(1);
*machine_ledaddr = ((r & b)? PALED_DATA : 0) |
PALED_STROBE;
}
}
}
}
#endif /* USELEDS */
extern int _hp700_led_on_cycles[];
#define hp700_led_blink(i) \
do { \
if (_hp700_led_on_cycles[i] == -1) \
_hp700_led_on_cycles[i] = 1; \
} while (/* CONSTCOND */ 0)
#define hp700_led_on(i, ms) \
do { \
_hp700_led_on_cycles[i] = (((ms) * _HP700_LED_FREQ) / 1000); \
} while (/* CONSTCOND */ 0)
void hp700_led_ctl __P((int, int, int));
#else /* !USELEDS */
#define hp700_led_blink(i)
#define hp700_led_on(i, ms)
#define hp700_led_ctl(off, on, toggle)
#endif /* !USELEDS */
#endif /* _MACHINE_CPUFUNC_H_ */