Module Name: src
Committed By: skrll
Date: Tue Jun 1 10:20:29 UTC 2010
Modified Files:
src/sys/arch/hp700/conf: GENERIC files.hp700
src/sys/arch/hp700/hp700: machdep.c mainbus.c
src/sys/arch/hp700/include: cpu.h
Added Files:
src/sys/arch/hp700/dev: lcd.c
Log Message:
Add the lcd(4) driver from OpenBSD. Thanks to Adam Hoka for doing most of
the work.
To generate a diff of this commit:
cvs rdiff -u -r1.99 -r1.100 src/sys/arch/hp700/conf/GENERIC
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/hp700/conf/files.hp700
cvs rdiff -u -r0 -r1.1 src/sys/arch/hp700/dev/lcd.c
cvs rdiff -u -r1.84 -r1.85 src/sys/arch/hp700/hp700/machdep.c
cvs rdiff -u -r1.69 -r1.70 src/sys/arch/hp700/hp700/mainbus.c
cvs rdiff -u -r1.46 -r1.47 src/sys/arch/hp700/include/cpu.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/hp700/conf/GENERIC
diff -u src/sys/arch/hp700/conf/GENERIC:1.99 src/sys/arch/hp700/conf/GENERIC:1.100
--- src/sys/arch/hp700/conf/GENERIC:1.99 Sat May 8 22:16:27 2010
+++ src/sys/arch/hp700/conf/GENERIC Tue Jun 1 10:20:28 2010
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.99 2010/05/08 22:16:27 mrg Exp $
+# $NetBSD: GENERIC,v 1.100 2010/06/01 10:20:28 skrll Exp $
#
# GENERIC machine description file
#
@@ -23,7 +23,7 @@
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
options SYSCTL_INCLUDE_DESCR # Include sysctl descriptions in kernel
-#ident "GENERIC-$Revision: 1.99 $"
+#ident "GENERIC-$Revision: 1.100 $"
maxusers 32 # estimated number of users
@@ -226,6 +226,7 @@
# Miscellaneous
pdc0 at mainbus0 # PDC/IODC wrapper for boot console
power0 at mainbus0 # power/fail manager
+lcd0 at mainbus0 # LCD
# STI graphics
sti* at mainbus0 # [H]CRX-{8,24,48}[Z] and Visualize graphics
Index: src/sys/arch/hp700/conf/files.hp700
diff -u src/sys/arch/hp700/conf/files.hp700:1.22 src/sys/arch/hp700/conf/files.hp700:1.23
--- src/sys/arch/hp700/conf/files.hp700:1.22 Thu May 28 08:41:29 2009
+++ src/sys/arch/hp700/conf/files.hp700 Tue Jun 1 10:20:28 2010
@@ -1,4 +1,4 @@
-# $NetBSD: files.hp700,v 1.22 2009/05/28 08:41:29 skrll Exp $
+# $NetBSD: files.hp700,v 1.23 2010/06/01 10:20:28 skrll Exp $
#
# $OpenBSD: files.hp700,v 1.31 2001/06/26 02:41:25 mickey Exp $
#
@@ -77,6 +77,10 @@
attach power at gedoens
file arch/hp700/dev/power.c power needs-flag
+device lcd
+attach lcd at gedoens
+file arch/hp700/dev/lcd.c lcd needs-flag
+
device mem
attach mem at gedoens
file arch/hp700/dev/mem.c mem
Index: src/sys/arch/hp700/hp700/machdep.c
diff -u src/sys/arch/hp700/hp700/machdep.c:1.84 src/sys/arch/hp700/hp700/machdep.c:1.85
--- src/sys/arch/hp700/hp700/machdep.c:1.84 Fri Apr 30 15:36:45 2010
+++ src/sys/arch/hp700/hp700/machdep.c Tue Jun 1 10:20:29 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.84 2010/04/30 15:36:45 skrll Exp $ */
+/* $NetBSD: machdep.c,v 1.85 2010/06/01 10:20:29 skrll Exp $ */
/*-
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.84 2010/04/30 15:36:45 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.85 2010/06/01 10:20:29 skrll Exp $");
#include "opt_cputype.h"
#include "opt_ddb.h"
@@ -130,6 +130,7 @@
#endif
#include "ksyms.h"
+#include "lcd.h"
/*
* Different kinds of flags used throughout the kernel.
@@ -205,6 +206,10 @@
int cpu_hvers;
int cpu_revision;
+#if NLCD > 0
+int lcd_blink_p;
+#endif
+
/*
* exported methods for cpus
*/
@@ -265,6 +270,9 @@
void dumpsys(void);
void cpuid(void);
enum hppa_cpu_type cpu_model_cpuid(int);
+#if NLCD > 0
+void blink_lcd_timeout(void *);
+#endif
/*
* wide used hardware params
@@ -1910,6 +1918,29 @@
return (sysctl_lookup(SYSCTLFN_CALL(&node)));
}
+#if NLCD > 0
+static int
+sysctl_machdep_heartbeat(SYSCTLFN_ARGS)
+{
+ int oldval, error;
+ struct sysctlnode node = *rnode;
+
+ oldval = lcd_blink_p;
+ /*
+ * If we were false and are now true, start the timer.
+ */
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+
+ if (error || newp == NULL)
+ return (error);
+
+ if (!oldval && lcd_blink_p > oldval)
+ blink_lcd_timeout(NULL);
+
+ return 0;
+}
+#endif
+
/*
* machine dependent system variables.
*/
@@ -1933,6 +1964,13 @@
CTLTYPE_STRING, "booted_kernel", NULL,
sysctl_machdep_boot, 0, NULL, 0,
CTL_MACHDEP, CPU_BOOTED_KERNEL, CTL_EOL);
+#if NLCD > 0
+ sysctl_createv(clog, 0, NULL, NULL,
+ CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+ CTLTYPE_BOOL, "lcd_blink", "Display heartbeat on the LCD display",
+ sysctl_machdep_heartbeat, 0, &lcd_blink_p, 0,
+ CTL_MACHDEP, CPU_LCD_BLINK, CTL_EOL);
+#endif
}
/*
@@ -1973,6 +2011,56 @@
}
}
+#if NLCD > 0
+struct blink_lcd_softc {
+ SLIST_HEAD(, blink_lcd) bls_head;
+ int bls_on;
+ struct callout bls_to;
+} blink_sc = { SLIST_HEAD_INITIALIZER(bls_head), 0 };
+
+void
+blink_lcd_register(struct blink_lcd *l)
+{
+ if (SLIST_EMPTY(&blink_sc.bls_head)) {
+ callout_init(&blink_sc.bls_to, 0);
+ callout_setfunc(&blink_sc.bls_to, blink_lcd_timeout, &blink_sc);
+ blink_sc.bls_on = 0;
+ if (lcd_blink_p)
+ callout_schedule(&blink_sc.bls_to, 1);
+ }
+ SLIST_INSERT_HEAD(&blink_sc.bls_head, l, bl_next);
+}
+
+void
+blink_lcd_timeout(void *vsc)
+{
+ struct blink_lcd_softc *sc = &blink_sc;
+ struct blink_lcd *l;
+ int t;
+
+ if (SLIST_EMPTY(&sc->bls_head))
+ return;
+
+ SLIST_FOREACH(l, &sc->bls_head, bl_next) {
+ (*l->bl_func)(l->bl_arg, sc->bls_on);
+ }
+ sc->bls_on = !sc->bls_on;
+
+ if (!lcd_blink_p)
+ return;
+
+ /*
+ * Blink rate is:
+ * full cycle every second if completely idle (loadav = 0)
+ * full cycle every 2 seconds if loadav = 1
+ * full cycle every 3 seconds if loadav = 2
+ * etc.
+ */
+ t = (((averunnable.ldavg[0] + FSCALE) * hz) >> (FSHIFT + 1));
+ callout_schedule(&sc->bls_to, t);
+}
+#endif
+
#ifdef MODULAR
/*
* Push any modules loaded by the boot loader.
Index: src/sys/arch/hp700/hp700/mainbus.c
diff -u src/sys/arch/hp700/hp700/mainbus.c:1.69 src/sys/arch/hp700/hp700/mainbus.c:1.70
--- src/sys/arch/hp700/hp700/mainbus.c:1.69 Fri Apr 30 15:49:40 2010
+++ src/sys/arch/hp700/hp700/mainbus.c Tue Jun 1 10:20:29 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: mainbus.c,v 1.69 2010/04/30 15:49:40 skrll Exp $ */
+/* $NetBSD: mainbus.c,v 1.70 2010/06/01 10:20:29 skrll Exp $ */
/*-
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@@ -58,10 +58,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.69 2010/04/30 15:49:40 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.70 2010/06/01 10:20:29 skrll Exp $");
#include "locators.h"
#include "power.h"
+#include "lcd.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -82,6 +83,10 @@
#include <hp700/dev/cpudevs.h>
static struct pdc_hpa pdc_hpa PDC_ALIGNMENT;
+#if NLCD > 0
+static struct pdc_chassis_info pdc_chassis_info PDC_ALIGNMENT;
+static struct pdc_chassis_lcd pdc_chassis_lcd PDC_ALIGNMENT;
+#endif
#ifdef MBUSDEBUG
@@ -1405,6 +1410,24 @@
config_found(self, &nca, mbprint);
#endif
+#if NLCD > 0
+ if (!pdc_call((iodcio_t)pdc, 0, PDC_CHASSIS, PDC_CHASSIS_INFO,
+ &pdc_chassis_info, &pdc_chassis_lcd, sizeof(pdc_chassis_lcd)) &&
+ pdc_chassis_lcd.enabled) {
+ memset(&nca, 0, sizeof(nca));
+ nca.ca_name = "lcd";
+ nca.ca_dp.dp_bc[0] = nca.ca_dp.dp_bc[1] = nca.ca_dp.dp_bc[2] =
+ nca.ca_dp.dp_bc[3] = nca.ca_dp.dp_bc[4] = nca.ca_dp.dp_bc[5] = -1;
+ nca.ca_dp.dp_mod = -1;
+ nca.ca_irq = -1;
+ nca.ca_iot = &hppa_bustag;
+ nca.ca_hpa = pdc_chassis_lcd.cmd_addr;
+ nca.ca_pdc_iodc_read = (void *)&pdc_chassis_lcd;
+
+ config_found(self, &nca, mbprint);
+ }
+#endif
+
switch (cpu_hvers) {
case HPPA_BOARD_HP809:
case HPPA_BOARD_HP819:
@@ -1489,12 +1512,15 @@
aprint_normal("\"%s\" at %s (type 0x%x, sv 0x%x)", ca->ca_name,
pnp, ca->ca_type.iodc_type, ca->ca_type.iodc_sv_model);
if (ca->ca_hpa) {
- aprint_normal(" hpa 0x%lx path ", ca->ca_hpa);
- for (n = 0; n < 6; n++) {
- if (ca->ca_dp.dp_bc[n] >= 0)
- aprint_normal("%d/", ca->ca_dp.dp_bc[n]);
+ aprint_normal(" hpa 0x%lx", ca->ca_hpa);
+ if (ca->ca_dp.dp_mod >=0) {
+ aprint_normal(" path ");
+ for (n = 0; n < 6; n++) {
+ if (ca->ca_dp.dp_bc[n] >= 0)
+ aprint_normal("%d/", ca->ca_dp.dp_bc[n]);
+ }
+ aprint_normal("%d", ca->ca_dp.dp_mod);
}
- aprint_normal("%d", ca->ca_dp.dp_mod);
if (!pnp && ca->ca_irq >= 0) {
aprint_normal(" irq %d", ca->ca_irq);
if (ca->ca_type.iodc_type != HPPA_TYPE_BHA)
Index: src/sys/arch/hp700/include/cpu.h
diff -u src/sys/arch/hp700/include/cpu.h:1.46 src/sys/arch/hp700/include/cpu.h:1.47
--- src/sys/arch/hp700/include/cpu.h:1.46 Mon Apr 26 15:25:24 2010
+++ src/sys/arch/hp700/include/cpu.h Tue Jun 1 10:20:29 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.46 2010/04/26 15:25:24 skrll Exp $ */
+/* $NetBSD: cpu.h,v 1.47 2010/06/01 10:20:29 skrll Exp $ */
/* $OpenBSD: cpu.h,v 1.55 2008/07/23 17:39:35 kettenis Exp $ */
@@ -322,8 +322,20 @@
*/
#define CPU_CONSDEV 1 /* dev_t: console terminal device */
#define CPU_BOOTED_KERNEL 2 /* string: booted kernel name */
-#define CPU_MAXID 3 /* number of valid machdep ids */
+#define CPU_LCD_BLINK 3 /* int: twiddle heartbeat LED/LCD */
+#define CPU_MAXID 4 /* number of valid machdep ids */
+#ifdef _KERNEL
+#include <sys/queue.h>
+
+struct blink_lcd {
+ void (*bl_func)(void *, int);
+ void *bl_arg;
+ SLIST_ENTRY(blink_lcd) bl_next;
+};
+
+extern void blink_lcd_register(struct blink_lcd *);
+#endif /* _KERNEL */
#endif /* !_LOCORE */
#endif /* _MACHINE_CPU_H_ */
Added files:
Index: src/sys/arch/hp700/dev/lcd.c
diff -u /dev/null src/sys/arch/hp700/dev/lcd.c:1.1
--- /dev/null Tue Jun 1 10:20:29 2010
+++ src/sys/arch/hp700/dev/lcd.c Tue Jun 1 10:20:29 2010
@@ -0,0 +1,146 @@
+/* $NetBSD: lcd.c,v 1.1 2010/06/01 10:20:29 skrll Exp $ */
+/* OpenBSD: lcd.c,v 1.2 2007/07/20 22:13:45 kettenis Exp */
+
+/*
+ * Copyright (c) 2007 Mark Kettenis
+ *
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/callout.h>
+
+#include <machine/autoconf.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/pdc.h>
+
+#define LCD_CLS 0x01
+#define LCD_HOME 0x02
+#define LCD_LOCATE(X, Y) (((Y) & 1 ? 0xc0 : 0x80) | ((X) & 0x0f))
+
+struct lcd_softc {
+ device_t sc_dv;
+
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_cmdh, sc_datah;
+
+ u_int sc_delay;
+ uint8_t sc_heartbeat[3];
+
+ struct callout sc_to;
+ int sc_on;
+ struct blink_lcd sc_blink;
+};
+
+int lcd_match(device_t, cfdata_t, void *);
+void lcd_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(lcd, sizeof(struct lcd_softc), lcd_match,
+ lcd_attach, NULL, NULL);
+
+void lcd_write(struct lcd_softc *, const char *);
+void lcd_blink(void *, int);
+void lcd_blink_finish(void *);
+
+int
+lcd_match(device_t parent, cfdata_t match, void *aux)
+{
+ struct confargs *ca = aux;
+
+ if (strcmp(ca->ca_name, "lcd") == 0)
+ return 1;
+
+ return 0;
+}
+
+void
+lcd_attach(device_t parent, device_t self, void *aux)
+{
+ struct lcd_softc *sc = device_private(self);
+ struct confargs *ca = aux;
+ struct pdc_chassis_lcd *pdc_lcd = (void *)ca->ca_pdc_iodc_read;
+ int i;
+
+ sc->sc_dv = self;
+ sc->sc_iot = ca->ca_iot;
+
+ if (bus_space_map(sc->sc_iot, pdc_lcd->cmd_addr,
+ 1, 0, &sc->sc_cmdh)) {
+ aprint_error(": cannot map cmd register\n");
+ return;
+ }
+
+ if (bus_space_map(sc->sc_iot, pdc_lcd->data_addr,
+ 1, 0, &sc->sc_datah)) {
+ aprint_error(": cannot map data register\n");
+ bus_space_unmap(sc->sc_iot, sc->sc_cmdh, 1);
+ return;
+ }
+
+ aprint_normal(": model %d\n", pdc_lcd->model);
+
+ sc->sc_delay = pdc_lcd->delay;
+ for (i = 0; i < 3; i++)
+ sc->sc_heartbeat[i] = pdc_lcd->heartbeat[i];
+
+ bus_space_write_1(sc->sc_iot, sc->sc_cmdh, 0, LCD_CLS);
+ delay(100 * sc->sc_delay);
+
+ bus_space_write_1(sc->sc_iot, sc->sc_cmdh, 0, LCD_LOCATE(0, 0));
+ delay(sc->sc_delay);
+ lcd_write(sc, "NetBSD/" MACHINE);
+
+ callout_init(&sc->sc_to, 0);
+ callout_setfunc(&sc->sc_to, lcd_blink_finish, sc);
+
+ sc->sc_blink.bl_func = lcd_blink;
+ sc->sc_blink.bl_arg = sc;
+ blink_lcd_register(&sc->sc_blink);
+}
+
+void
+lcd_write(struct lcd_softc *sc, const char *str)
+{
+ while (*str) {
+ bus_space_write_1(sc->sc_iot, sc->sc_datah, 0, *str++);
+ delay(sc->sc_delay);
+ }
+}
+
+void
+lcd_blink(void *v, int on)
+{
+ struct lcd_softc *sc = v;
+
+ sc->sc_on = on;
+ bus_space_write_1(sc->sc_iot, sc->sc_cmdh, 0, sc->sc_heartbeat[0]);
+ callout_schedule(&sc->sc_to, max(1, (sc->sc_delay * hz) / 1000000));
+}
+
+void
+lcd_blink_finish(void *v)
+{
+ struct lcd_softc *sc = v;
+ uint8_t data;
+
+ if (sc->sc_on)
+ data = sc->sc_heartbeat[1];
+ else
+ data = sc->sc_heartbeat[2];
+
+ bus_space_write_1(sc->sc_iot, sc->sc_datah, 0, data);
+}