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);
+}

Reply via email to