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