Porting LCG framebuffer driver
Gabucino <[email protected]> Sun, 13 Jun 2004 23:55:44 +0200
| Newsgroups | gmane.os.openbsd.vax |
|---|---|
| Message-ID | <[email protected]> |
I've been trying to add Blaz Antonic's excellent NetBSD driver (patch attached,
with configfile) for the LCG colour framebuffer found in the VAXstation 4000
series, but I'm getting undefined symbols during linking, and it seems that not
all of them are LCG related (though I'd need some hint on the wsfont messages
too).
Hints are greatly appreciated.
--
Gabucino
diff ../sys/arch/vax/conf/files.vax sys/arch/vax/conf/files.vax
--- ../sys/arch/vax/conf/files.vax Thu May 16 09:37:41 2002
+++ sys/arch/vax/conf/files.vax Wed Jun 9 15:45:01 2004
@@ -160,6 +160,11 @@
attach smg at vsbus
file arch/vax/vsa/smg.c smg needs-flag
+# Colour framebuffer on VS4000.
+device lcg: wsemuldisplaydev
+attach lcg at vsbus
+file arch/vax/vsa/lcg.c lcg needs-flag
+
device lkkbd: wskbddev
attach lkkbd at dz with dzkbd
file arch/vax/dec/dzkbd.c dzkbd needs-flag
diff ../sys/arch/vax/conf/zsebivax sys/arch/vax/conf/zsebivax
--- ../sys/arch/vax/conf/zsebivax Thu Jan 1 01:00:00 1970
+++ sys/arch/vax/conf/zsebivax Wed Jun 9 15:59:01 2004
@@ -0,0 +1,150 @@
+# $OpenBSD: GENERIC,v 1.34 2003/03/08 04:43:45 hugh Exp $
+# $NetBSD: GENERIC,v 1.61 2000/04/19 06:50:36 itojun Exp $
+
+machine vax # machine type; required
+
+include "../../../conf/GENERIC"
+
+# Here are all different supported CPU types listed.
+# One of these is required.
+#option VAX8600
+#option VAX8200
+#option VAX780 # 11/780
+#option VAX750 # 11/750
+#option VAX630 # MV II
+#option VAX650 # MV III, 3300, 3600, 3800, 3900
+#option VAX660 # VAX 4000 200
+#option VAX670 # VAX 4000 300
+#option VAX680 # VAX 4000 {4,5,6,7}0{0,5}{,A}
+#option VAX410 # VS 2000, 3100/{30,}
+#option VAX43 # VS 3100/76
+#option VAX46 # VS 4000/60
+option VAX48 # VS 4000 VLC
+#option VAX49 # VS 4000/90
+#option VAX53 # VAX 4000 10X, MicroVAX 3100m9X
+
+# Max users on system; this is just a hint
+maxusers 8
+
+option SCSIVERBOSE # Verbose SCSI errors
+
+# Old compat stuff; needed to run 4.3BSD Reno programs.
+# Note that if COMPAT_ULTRIX is set, you lose compatibility with
+# 4.3BSD Reno programs and get Ultrix compatibility instead.
+# (They cannot coexist).
+option COMPAT_VAX1K # Must be present to run old binaries.
+#option COMPAT_ULTRIX
+
+option INSN_EMULATE # CPU lacks some hardware instructions.
+
+# Kernel(s) to compile
+config bsd swap generic
+#config nfsbsd root on nfs swap on nfs
+
+mainbus0 at root
+
+# All buses; from the beginning attached to mainbus.
+#abus0 at mainbus0 # Master bus on VAX 8600
+#sbi0 at mainbus0 # SBI, master bus on 11/780.
+#cmi0 at mainbus0 # 11/750 internal bus.
+#bi0 at mainbus0 # VAX 8200
+vsbus0 at mainbus0 # All VAXstations
+#ibus0 at mainbus0 # All Microvax
+#nbi0 at mainbus0 # VAX 8800
+#xmi0 at mainbus0 # VAX 6000
+
+# Vsbus, the virtual VAXstation bus, and possible devices.
+le0 at vsbus0 csr 0x200e0000 # LANCE ethernet
+#ze0 at vsbus0 csr 0x20008000 # SGEC ethernet
+dz0 at vsbus0 csr 0x200a0000 # DC-367 DZ-11 lookalike ctlr
+dz0 at vsbus0 csr 0x25000000 # VS4000/90 4000/10X MV3100/9X serial
+#hdc0 at vsbus0 csr 0x200c0000 # HDC9224 MFM/floppy ctlr
+#ncr0 at vsbus0 csr 0x200c0080 # VS2000/3100 SCSI-ctlr
+#ncr1 at vsbus0 csr 0x200c0180 # VS2000/3100 SCSI-ctlr
+asc0 at vsbus0 csr 0x200c0080 # VS4000/60 (or VLC) SCSI-ctlr
+asc0 at vsbus0 csr 0x26000080 # VS4000/90 4000/10X MV3100/9X SCSI
+#smg0 at vsbus0 csr 0x200f0000 # Small monochrome display ctlr.
+lcg0 at vsbus0 csr 0x21801000 # Colour display ctlr. for VS4000
+#clr0 at vsbus0 csr 0x30000000 # 4- or 8-bitplans color graphics
+
+#hd* at hdc0 drive? # RD5x disks
+#ry* at hdc0 drive? # RX floppies
+
+# Ibus, the internal bus on most Microvaxen
+#uba0 at ibus0 # Qbus adapter
+#ze0 at ibus0 # SGEC on-board ethernet
+#le0 at ibus0 # LANCE ethernet (MV3400)
+#shac0 at ibus0 # DSSI controller
+
+# Devices connected at VAXBI
+#cpu* at bi? node? # KA820/KA825 cpu
+#mem* at bi? node? # Memory subsystems
+#uba* at bi? node? # DWBUA BI-Unibus adapter
+#ni* at bi? node? # DEBNA/DEBNT ethernet adapter
+#kdb* at bi? node? # KDB50 MSCP disk ctlr
+#mscpbus* at kdb?
+
+# CMI (VAX 11/750)
+#mem* at cmi? tr? # Memory subsystems
+#uba* at cmi? tr? # Unibus adapters
+#mba* at cmi? tr? # Massbus adapters
+
+# SBI (VAX 11/780, VAX 8600)
+#sbi* at abus0 # VAX 8600 can have up to 4 SBI's.
+
+#mem* at sbi? tr? # Memory subsystems
+#uba* at sbi? tr? # Unibus adapters
+#mba* at sbi? tr? # Massbus adapters
+
+# Devices on Massbus adapters
+#hp* at mba? drive? # RM/RP disk drives
+
+# Devices on Unibus/Qbus adapters
+#uda0 at uba? csr 0172150 # UDA50/RQDX?
+#uda1 at uba? csr 0160334
+#mtc0 at uba? csr 0174500 # Tape MSCP ctlr
+#ts0 at uba? csr 0172520 # TS11/TSV05 tape.
+#qd0 at uba? csr 0177400 # 4- or 8-bitplans color graphics
+#qv0 at uba? csr 0177400 # Monochrome graphics
+#de0 at uba? csr 0174510 # DELUA/DEUNA
+#qe0 at uba? csr 0174440 # DEQNA/DELQA
+#dhu0 at uba? csr 0160440 # DHU-11
+#dz0 at uba? csr 0160100 # DZ-11
+#dl0 at uba? csr 0176500 # DL-11
+
+# MSCP devices
+#mscpbus* at uda?
+#mscpbus* at mtc?
+#mscpbus* at kdb?
+
+#ra* at mscpbus? drive? # MSCP disk
+#rx* at mscpbus? drive? # MSCP floppy
+#mt* at mscpbus? drive? # MSCP tape
+
+# VS2000 builtin MFM controller (HDC9224)
+#hdc0 at vsbus0 # The strange builtin MFM controller
+
+# SCSI devices
+scsibus* at asc?
+#scsibus* at ncr?
+
+sd* at scsibus? target? lun?
+st* at scsibus? target? lun?
+cd* at scsibus? target? lun?
+ch* at scsibus? target? lun?
+ss* at scsibus? target? lun?
+uk* at scsibus? target? lun?
+
+# Workstation console
+#wsdisplay0 at smg?
+wsdisplay0 at lcg?
+
+#wsdisplay0 at clr0
+#wsdisplay0 at qd0
+#wsdisplay0 at qv0
+
+lkkbd0 at dz0 line 0
+wskbd* at lkkbd? console ?
+lkms0 at dz0 line 1
+wsmouse* at lkms?
+pseudo-device wsmux
diff ../sys/arch/vax/include/lcgreg.h sys/arch/vax/include/lcgreg.h
--- ../sys/arch/vax/include/lcgreg.h Thu Jan 1 01:00:00 1970
+++ sys/arch/vax/include/lcgreg.h Thu Jun 10 09:00:48 2004
@@ -0,0 +1,194 @@
+/* $NetBSD: lcgreg.h,v 1.1 2000/04/24 17:09:03 matt Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VAX_LCGREG_H
+#define _VAX_LCGREG_H
+
+/* The registers of the LCG used in the VS4000/60 and VS4000/VLC.
+ * All relative to 0x20100000
+ */
+
+/* Memory Control, Flow Control, Configration Registers
+ */
+#define LCG_REG_MEM_CONFIG 0x001800
+#define LCG_REG_MEM_STATUS 0x001804
+#define LCG_REG_MEM_CURRENT_STATE 0x001808
+#define LCG_REG_MEM_ERROR 0x00180c
+#define LCG_REG_SLOW_CONTROL_STATUS 0x001810
+
+/* Video Control Registers
+ */
+#define LCG_REG_VIDEO_CONFIG 0x001e00
+#define LCG_REG_VIDEO_HTIMING 0x001e10
+#define LCG_REG_VIDEO_VTIMING 0x001e14
+#define LCG_REG_VIDEO_TIMING 0x001e18
+#define LCG_REG_VIDEO_X 0x000e30
+#define LCG_REG_VIDEO_Y 0x000e30
+#define LCG_REG_VIDEO_REFRESH_BASE 0x000e34
+#define LCG_REG_VIDEO_REFRESH_SHIFT 0x000e40
+#define LCG_REG_VIDEO_LUT_LOAD_COUNT 0x000e40
+#define LCG_REG_CURSOR_SCANLINE_LW0 0x000e50
+#define LCG_REG_CURSOR_SCANLINE_LW1 0x000e54
+#define LCG_REG_CURSOR_SCANLINE_LW2 0x000e58
+#define LCG_REG_CURSOR_SCANLINE_LW3 0x000e5c
+#define LCG_REG_CURSOR_BASE 0x000e80
+#define LCG_REG_CURSOR_XY 0x000e84
+#define LCG_REG_CURSOR_X 0x000e84
+#define LCG_REG_CURSOR_Y 0x000e84
+#define LCG_REG_LUT_CONSOLE_SEL 0x000ee0
+#define LCG_REG_LUT_COLOR_BASE_W 0x0006e4
+#define LCG_REG_LUT_COLOR_BASE_R 0x0006e4
+#define LCG_REG_LUT_CONTROL_BASE 0x000ee8
+#define LCG_REG_VIDEO_COUNTER_TEST 0x000f00
+#define LCG_REG_MEM_REFRESH_BASE 0x000f04
+
+/* Graphics Control and VM Registers
+ */
+#define LCG_REG_LCG_GO 0x000c80
+#define LCG_REG_NEXT_ADDRESS 0x001334
+#define LCG_REG_PA_SPTE_PTE 0x001338
+#define LCG_REG_TB_INVALIDATE_SINGLE 0x001a00
+#define LCG_REG_TB_INVALIDATE_ALL 0x001a08
+#define LCG_REG_TB_INVALIDATE_STATUS 0x001a10
+#define LCG_REG_TB_STATUS 0x001c00
+#define LCG_REG_TB_VPN_COUNT 0x001c04
+#define LCG_REG_TB_DEST_VPN 0x001c14
+#define LCG_REG_TB_SOURCE_VPN 0x001c18
+#define LCG_REG_TB_STENCIL_VPN 0x001c1c
+#define LCG_REG_TB_DEST_DATA_PFN_R 0x001c24
+#define LCG_REG_TB_DEST_DATA_PFN_W 0x001c24
+#define LCG_REG_TB_SOURCE_DATA_PFN_R 0x001c28
+#define LCG_REG_TB_SOURCE_DATA_PFN_W 0x001c28
+#define LCG_REG_TB_STENCIL_DATA_PFN_R 0x001c2c
+#define LCG_REG_TB_STENCIL_DATA_PFN_W 0x001c2c
+#define LCG_REG_TB_DEST_PRE_PFN_R 0x001c34
+#define LCG_REG_TB_DEST_PRE_PFN_W 0x001c34
+#define LCG_REG_TB_SOURCE_PTE_PFN_R 0x001c38
+#define LCG_REG_TB_SOURCE_PTE_PFN_W 0x001c38
+#define LCG_REG_TB_STENCIL_PTE_PFN_R 0x001c3c
+#define LCG_REG_TB_STENCIL_PTE_PFN_W 0x001c3c
+#define LCG_REG_GRAPHICS_CONFIG 0x001c90
+#define LCG_REG_GRAPHICS_INT_STATUS 0x001c94
+#define LCG_REG_GRAPHICS_INT_SET_ENABLE 0x001c98
+#define LCG_REG_GRAPHICS_INT_CLR_ENABLE 0x001c9c
+#define LCG_REG_GRAPHICS_SUB_STATUS 0x001ca0
+#define LCG_REG_GRAPHICS_CONTROL 0x001ca4
+#define LCG_REG_BREAKPT_ADDRESS 0x001cb0
+#define LCG_REG_BREAKPT_VIRTUAL 0x001cb0
+#define LCG_REG_WRITE_PROTECT_LOW_HIGH 0x001cc0
+#define LCG_REG_WRITE_PROTECT_LOW 0x001cc0
+#define LCG_REG_WRITE_PROTECT_HIGH 0x001cc0
+#define LCG_REG_MAX_VIRTUAL_ADDRESS 0x002350
+#define LCG_REG_PA_SPTE_POBR 0x002354
+
+/* Clip List / Command FIFO Registers
+ */
+#define LCG_REG_CLIP_LIST_OFFSET 0x0004e4
+#define LCG_REG_CLIP_LIST_BASE 0x0004e4
+#define LCG_REG_CLIP_LIST 0x0004e4
+#define LCG_REG_FIFO_MASKS 0x000570
+#define LCG_REG_FIFO_HEAD_OFFSET 0x000574
+#define LCG_REG_FIFO_BASE 0x000574
+#define LCG_REG_FIFO_HEAD 0x000574
+#define LCG_REG_FIFO_TAIL_OFFSET 0x000578
+#define LCG_REG_FIFO_BASE2 0x000578
+#define LCG_REG_FIFO_TAIL 0x000578
+#define LCG_REG_CLIP_LIST_SAVE_OFFSET 0x000ce4
+#define LCG_REG_FIFO_RESIDUE_LW0 0x000d00
+#define LCG_REG_FIFO_RESIDUE_LW1 0x000d04
+#define LCG_REG_FIFO_RESIDUE_LW2 0x000d0c
+#define LCG_REG_FIFO_LENGTH 0x000d70
+#define LCG_REG_FIFO_SAVE_HEAD_OFFSET 0x000d74
+#define LCG_REG_FIFO_WINDOW_BASE 0x080000
+#define LCG_REG_FIFO_WINDOW_END 0x100000
+
+/* Graphics Data Buffer and Pixel SLU Registers
+ */
+#define LCG_REG_LOGICAL_FUNCTION 0x000220
+#define LCG_REG_PLANE_MASK 0x000234
+#define LCG_REG_SOURCE_PLANE_INDEX 0x00026c
+#define LCG_REG_FOREGROUND_PIXEL 0x0002c0
+#define LCG_REG_BACKGROUND_PIXEL 0x0004c0
+#define LCG_REG_GDB_LW0 0x000d80
+#define LCG_REG_GDB_LW1 0x000d84
+#define LCG_REG_GDB_LW2 0x000d88
+#define LCG_REG_GDB_LW3 0x000d8c
+#define LCG_REG_GDB_LW4 0x000d90
+#define LCG_REG_GDB_LW5 0x000d94
+#define LCG_REG_GDB_LW6 0x000d98
+#define LCG_REG_GDB_LW7 0x000d9c
+#define LCG_REG_SLU_STATE 0x000da0
+
+/* Address Generator Registers
+ */
+#define LCG_REG_CLIP_MIN_Y 0x000244
+#define LCG_REG_CLIP_MIN_MAX_X 0x000248
+#define LCG_REG_CLIP_MIN_X 0x000248
+#define LCG_REG_CLIP_MAX_X 0x000248
+#define LCG_REG_CLIP_MAX_Y 0x00024c
+#define LCG_REG_DEST_X_BIAS 0x000250
+#define LCG_REG_DEST_Y_ORIGIN 0x000254
+#define LCG_REG_DEST_Y_STEP 0x000258
+#define LCG_REG_SOURCE_X_BIAS 0x000260
+#define LCG_REG_SOURCE_Y_BASE 0x000264
+#define LCG_REG_SOURCE_Y_STEP_WIDTH 0x000268
+#define LCG_REG_SOURCE_Y_STEP 0x000268
+#define LCG_REG_SOURCE_WIDTH 0x000268
+#define LCG_REG_STENCIL_X_BIAS 0x000270
+#define LCG_REG_STENCIL_Y_BASE 0x000274
+#define LCG_REG_STENCIL_Y_STEP 0x000278
+#define LCG_REG_DEST_Y_BASE 0x000284
+#define LCG_REG_DEST_X 0x000290
+#define LCG_REG_DEST_WIDTH_HEIGHT 0x000294
+#define LCG_REG_DEST_WIDTH 0x000294
+#define LCG_REG_DEST_HEIGHT 0x000294
+#define LCG_REG_AG_STATUS2 0x000320
+#define LCG_REG_AG_CURRENT_STATE 0x000320
+#define LCG_REG_CURRENT_OPCODE 0x000320
+#define LCG_REG_OP_ACTION_CODE 0x000320
+#define LCG_REG_AG_STATUS 0x000324
+#define LCG_REG_NEXT_X 0x000330
+#define LCG_REG_CLIP_X_DIFF 0x000330
+#define LCG_REG_SOURCE_X_BIAS0 0x000460
+#define LCG_REG_SOURCE_WIDTH0 0x000468
+#define LCG_REG_DEST_X0 0x000490
+#define LCG_REG_DEST_WIDTH0 0x000494
+#define LCG_REG_TILE_ROTATION 0x000660
+#define LCG_REG_TILE_WIDTH 0x000668
+
+#endif /* _VAX_LCGREG_H */
diff ../sys/arch/vax/vax/conf.c sys/arch/vax/vax/conf.c
--- ../sys/arch/vax/vax/conf.c Sat Feb 21 05:10:41 2004
+++ sys/arch/vax/vax/conf.c Wed Jun 9 15:57:07 2004
@@ -144,6 +144,7 @@
#include "wskbd.h"
#include "smg.h"
+#include "lcg.h"
#if NSMG > 0
#if NWSKBD > 0
#define smgcngetc wskbd_cngetc
@@ -159,10 +160,26 @@
#define smgcnputc wsdisplay_cnputc
#define smgcnpollc nullcnpollc
+#if NLCG > 0
+#if NWSKBD > 0
+#define lcgcngetc wskbd_cngetc
+#else
+static int
+lcgcngetc(dev_t dev)
+{
+ return 0;
+}
+#endif /* NWSKBD > 0 */
+#endif /* NSMG > 0 */
+
+#define lcgcnputc wsdisplay_cnputc
+#define lcgcnpollc nullcnpollc
+
cons_decl(gen);
cons_decl(dz);
cons_decl(qd);
cons_decl(smg);
+cons_decl(lcg);
#include "qv.h"
#include "qd.h"
@@ -187,6 +204,9 @@
#endif
#if NSMG
cons_init(smg),
+#endif
+#if NLCG
+ cons_init(lcg),
#endif
#ifdef notyet
diff ../sys/arch/vax/vsa/lcg.c sys/arch/vax/vsa/lcg.c
--- ../sys/arch/vax/vsa/lcg.c Thu Jan 1 01:00:00 1970
+++ sys/arch/vax/vsa/lcg.c Thu Jun 10 09:45:02 2004
@@ -0,0 +1,953 @@
+/* $NetBSD: lcg.c,v 1.1 2004/02/12 18:24:00 Blaz Antonic Exp $ */
+/*
+ * Copyright (c) 2003, 2004 Blaz Antonic
+ *
+ * Based on bits of ragge's lcspx code (interrupt faking)
+ * Copyright (c) 1998 Ludd, University of Lule}, Sweden.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+// __KERNEL_RCSID(0, "$NetBSD: lcg.c,v 1.1 2004/02/12 18:24:00 Blaz Antonic Exp $");
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <sys/timeout.h>
+#include <sys/time.h>
+#include <sys/malloc.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+
+#include <machine/vsbus.h>
+#include <machine/sid.h>
+#include <machine/cpu.h>
+#include <machine/lcgreg.h>
+
+#include <dev/cons.h>
+
+#include <../../qbus/dzreg.h>
+#include <../../qbus/dzvar.h>
+#include <../../dec/dzkbdvar.h>
+
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wscons_callbacks.h>
+#include <dev/wsfont/wsfont.h>
+
+#include "machine/scb.h"
+
+#include "dzkbd.h"
+
+/* Screen hardware defs */
+
+#define LCG_FB_ADDR 0x21801000 /* Frame buffer */
+
+/* register space defines */
+#define LCG_REG_ADDR 0x20100000 /* LCG registers */
+#define LCG_REG_SIZE 0x4000 /* 16384 bytes */
+#define LCG_REG(reg) regaddr[(reg / 4)]
+
+/* LUT defines */
+#define LCG_LUT_ADDR 0x21800800 /* LUT right before onscreen FB */
+#define LCG_LUT_OFFSET 0x00000800
+#define LCG_LUT_SIZE 0x800 /* 2048 bytes */
+
+#define LCG_BG_COLOR WSCOL_BLACK
+#define LCG_FG_COLOR WSCOL_WHITE
+
+#define LCG_CONFIG 0x200f0010 /* LCG model information */
+
+static int lcg_match(struct device *, struct cfdata *, void *);
+static void lcg_attach(struct device *, struct device *, void *);
+
+struct lcg_softc {
+ struct device ss_dev;
+};
+
+struct cfattach lcg_ca = {
+ sizeof(struct lcg_softc), (cfmatch_t)lcg_match, lcg_attach,
+};
+
+struct cfdriver lcg_cd = {
+ NULL, "lcg", DV_DULL
+};
+
+static void lcg_cursor(void *, int, int, int);
+static int lcg_mapchar(void *, int, unsigned int *);
+static void lcg_putchar(void *, int, int, u_int, long);
+static void lcg_copycols(void *, int, int, int,int);
+static void lcg_erasecols(void *, int, int, int, long);
+static void lcg_copyrows(void *, int, int, int);
+static void lcg_eraserows(void *, int, int, long);
+static int lcg_alloc_attr(void *, int, int, int, long *);
+static int lcg_get_cmap(struct wsdisplay_cmap *);
+static int lcg_set_cmap(struct wsdisplay_cmap *);
+static void lcg_init_common(struct device *, struct vsbus_attach_args *);
+
+const struct wsdisplay_emulops lcg_emulops = {
+ lcg_cursor,
+ lcg_mapchar,
+ lcg_putchar,
+ lcg_copycols,
+ lcg_erasecols,
+ lcg_copyrows,
+ lcg_eraserows,
+ lcg_alloc_attr
+};
+
+const struct wsscreen_descr lcg_stdscreen = {
+ "160x68", 160, 68, /* dynamically set */
+ &lcg_emulops,
+ 8, 15, /* dynamically set */
+ WSSCREEN_UNDERLINE|WSSCREEN_REVERSE|WSSCREEN_WSCOLORS,
+};
+
+const struct wsscreen_descr *_lcg_scrlist[] = {
+ &lcg_stdscreen,
+};
+
+const struct wsscreen_list lcg_screenlist = {
+ sizeof(_lcg_scrlist) / sizeof(struct wsscreen_descr *),
+ _lcg_scrlist,
+};
+
+static char *lcgaddr;
+static char *lutaddr;
+static volatile long *regaddr;
+
+static int lcg_xsize;
+static int lcg_ysize;
+static int lcg_depth;
+static int lcg_cols;
+static int lcg_rows;
+static int lcg_onerow;
+static int lcg_fb_size;
+
+/* Our current hardware colormap */
+static struct hwcmap256 {
+#define CMAP_SIZE 256 /* 256 R/G/B entries */
+ u_int8_t r[CMAP_SIZE];
+ u_int8_t g[CMAP_SIZE];
+ u_int8_t b[CMAP_SIZE];
+} lcg_cmap;
+
+/* The default colormap */
+static struct {
+ u_int8_t r[8];
+ u_int8_t g[8];
+ u_int8_t b[8];
+} lcg_default_cmap = {
+ { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
+ { 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff },
+ { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff }
+};
+
+struct wsdisplay_font lcg_font;
+static u_char *qf;
+static u_short *qf2;
+
+#define QCHAR(c) (c < lcg_font.firstchar ? 0 : \
+ (c >= (lcg_font.firstchar + lcg_font.numchars) ? 0 : c - lcg_font.firstchar))
+#define QFONT(c,line) ((lcg_font.stride == 2 ? \
+ qf2[QCHAR(c) * lcg_font.fontheight + line] : \
+ qf[QCHAR(c) * lcg_font.fontheight + line]))
+#define LCG_ADDR(row, col, line, dot) \
+ lcgaddr[((col) * lcg_font.fontwidth) + ((row) * lcg_font.fontheight * lcg_xsize) + \
+ (line) * lcg_xsize + dot]
+
+
+static int lcg_ioctl(void *, u_long, caddr_t, int, struct proc *);
+static paddr_t lcg_mmap(void *, off_t, int);
+static int lcg_alloc_screen(void *, const struct wsscreen_descr *,
+ void **, int *, int *, long *);
+static void lcg_free_screen(void *, void *);
+static int lcg_show_screen(void *, void *, int,
+ void (*) (void *, int, int), void *);
+static void lcg_crsr_blink(void *);
+
+const struct wsdisplay_accessops lcg_accessops = {
+ lcg_ioctl,
+ lcg_mmap,
+ lcg_alloc_screen,
+ lcg_free_screen,
+ lcg_show_screen,
+ 0 /* load_font */
+};
+
+/* XXX What to do about the size of ss_image? */
+struct lcg_screen {
+ int ss_curx;
+ int ss_cury;
+ int ss_cur_fg;
+ int ss_cur_bg;
+ struct {
+ u_char data; /* Image character */
+ u_char attr; /* Attribute: 80/70/08/07 */
+ } ss_image[160 * 128]; /* XXXX Sized for 8x8 font FIXME? XXXX */
+};
+#define LCG_ATTR_UNDERLINE 0x80
+#define LCG_BG_MASK 0x70
+#define LCG_ATTR_REVERSE 0x08
+#define LCG_FG_MASK 0x07
+
+static struct lcg_screen lcg_conscreen;
+static struct lcg_screen *curscr;
+static struct lcg_screen *savescr;
+
+static struct timeout lcg_blink_timeout;
+
+extern int getmajor(void *);
+
+int
+lcg_match(struct device *parent, struct cfdata *match, void *aux)
+{
+ struct vsbus_softc *sc = (void *)parent;
+ struct vsbus_attach_args *va = aux;
+ char *ch = (char *)va->va_addr;
+
+ if ((vax_boardtype != VAX_BTYP_46) && (vax_boardtype != VAX_BTYP_48))
+ return 0;
+
+ *ch = 1;
+ if ((*ch & 1) == 0)
+ return 0;
+ *ch = 0;
+ if ((*ch & 1) != 0)
+ return 0;
+
+ /* XXX use vertical interrupt? */
+ sc->sc_mask = 0x04; /* XXX - should be generated */
+ scb_fake(0x120, 0x15);
+ return 20;
+}
+
+void
+lcg_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct vsbus_attach_args *va = aux;
+ struct wsemuldisplaydev_attach_args aa;
+
+ printf("\n");
+ aa.console = lcgaddr != NULL;
+
+ lcg_init_common(self, va);
+
+ curscr = &lcg_conscreen;
+
+ aa.scrdata = &lcg_screenlist;
+ aa.accessops = &lcg_accessops;
+
+ /* enable software cursor */
+ timeout_set(&lcg_blink_timeout, lcg_crsr_blink, NULL);
+ timeout_add(&lcg_blink_timeout, hz / 2);
+
+ config_found(self, &aa, wsemuldisplaydevprint);
+}
+
+static char *cursor;
+
+static int cur_on;
+
+static int cur_fg, cur_bg;
+
+static void
+lcg_crsr_blink(void *arg)
+{
+ int dot;
+
+ if (cur_on && curscr != NULL)
+ for (dot = 0; dot < lcg_font.fontwidth; dot++)
+ cursor[dot] = ((cursor[dot] & 0x0f) == cur_fg) ? cur_bg : cur_fg;
+
+ timeout_add(&lcg_blink_timeout, hz / 2);
+}
+
+void
+lcg_cursor(void *id, int on, int row, int col)
+{
+ struct lcg_screen *ss = id;
+ int dot, attr;
+
+ attr = ss->ss_image[row * lcg_cols + col].attr;
+ if (ss == curscr) {
+ if (cursor != NULL) {
+ int ch = QFONT(ss->ss_image[ss->ss_cury * lcg_cols +
+ ss->ss_curx].data, lcg_font.fontheight - 1);
+ int attr = ss->ss_image[ss->ss_cury * lcg_cols +
+ ss->ss_curx].attr;
+
+ if (attr & LCG_ATTR_REVERSE) {
+ cur_bg = attr & LCG_FG_MASK;
+ cur_fg = (attr & LCG_BG_MASK) >> 4;
+ } else {
+ cur_fg = attr & LCG_FG_MASK;
+ cur_bg = (attr & LCG_BG_MASK) >> 4;
+ }
+ for (dot = 0; dot < lcg_font.fontwidth; dot++)
+ cursor[dot] = (ch & (1 << dot)) ?
+ cur_fg : cur_bg;
+ }
+
+ cursor = &LCG_ADDR(row, col, lcg_font.fontheight - 1, 0);
+ cur_on = on;
+ if (attr & LCG_ATTR_REVERSE) {
+ cur_bg = attr & LCG_FG_MASK;
+ cur_fg = (attr & LCG_BG_MASK) >> 4;
+ } else {
+ cur_fg = attr & LCG_FG_MASK;
+ cur_bg = (attr & LCG_BG_MASK) >> 4;
+ }
+ }
+ ss->ss_curx = col;
+ ss->ss_cury = row;
+ if (attr & LCG_ATTR_REVERSE) {
+ ss->ss_cur_bg = attr & LCG_FG_MASK;
+ ss->ss_cur_fg = (attr & LCG_BG_MASK) >> 4;
+ } else {
+ ss->ss_cur_fg = attr & LCG_FG_MASK;
+ ss->ss_cur_bg = (attr & LCG_BG_MASK) >> 4;
+ }
+}
+
+int
+lcg_mapchar(void *id, int uni, unsigned int *index)
+{
+ if (uni < 256) {
+ *index = uni;
+ return (5);
+ }
+ *index = ' ';
+ return (0);
+}
+
+static void
+lcg_putchar(void *id, int row, int col, u_int c, long attr)
+{
+ struct lcg_screen *ss = id;
+ int i, j;
+ char dot_fg, dot_bg;
+
+ c &= 0xff;
+
+ ss->ss_image[row * lcg_cols + col].data = c;
+ ss->ss_image[row * lcg_cols + col].attr = attr;
+ if (ss != curscr)
+ return;
+
+ dot_fg = attr & LCG_FG_MASK;
+ dot_bg = (attr & LCG_BG_MASK) >> 4;
+ if (attr & LCG_ATTR_REVERSE) {
+ dot_fg = (attr & LCG_BG_MASK) >> 4;
+ dot_bg = attr & LCG_FG_MASK;
+ }
+
+ for (i = 0; i < lcg_font.fontheight; i++) {
+ int ch = QFONT(c, i);
+ char *p = &LCG_ADDR(row, col, i, 0);
+
+ for (j = 0; j < lcg_font.fontwidth; ++j) {
+ *p++ = ch & (1 << j) ? dot_fg : dot_bg;
+ }
+ }
+ if (attr & LCG_ATTR_UNDERLINE) {
+ char *p = &LCG_ADDR(row, col, lcg_font.fontheight - 1, 0);
+ for (i = 0; i < lcg_font.fontwidth; i++)
+ p[i] = ~p[i];
+ }
+}
+
+/*
+ * copies columns inside a row.
+ */
+static void
+lcg_copycols(void *id, int row, int srccol, int dstcol, int ncols)
+{
+ struct lcg_screen *ss = id;
+ int i;
+
+ bcopy(&ss->ss_image[row * lcg_cols + srccol], &ss->ss_image[row *
+ lcg_cols + dstcol], ncols * sizeof(ss->ss_image[0]));
+ if (ss != curscr)
+ return;
+ for (i = 0; i < lcg_font.fontheight; i++)
+ memcpy(&LCG_ADDR(row, dstcol, i, 0),
+ &LCG_ADDR(row,srccol, i, 0), ncols * lcg_font.fontwidth);
+}
+
+/*
+ * Erases a bunch of chars inside one row.
+ */
+static void
+lcg_erasecols(void *id, int row, int startcol, int ncols, long fillattr)
+{
+ struct lcg_screen *ss = id;
+ int i;
+
+ bzero(&ss->ss_image[row * lcg_cols + startcol], ncols * sizeof(ss->ss_image[0]));
+ for (i = row * lcg_cols + startcol; i < row * lcg_cols + startcol + ncols; ++i)
+ ss->ss_image[i].attr = fillattr;
+ if (ss != curscr)
+ return;
+ for (i = 0; i < lcg_font.fontheight; i++)
+ memset(&LCG_ADDR(row, startcol, i, 0),
+ (fillattr & LCG_BG_MASK) >> 4, ncols * lcg_font.fontwidth);
+}
+
+static void
+lcg_copyrows(void *id, int srcrow, int dstrow, int nrows)
+{
+ struct lcg_screen *ss = id;
+
+ bcopy(&ss->ss_image[srcrow * lcg_cols], &ss->ss_image[dstrow * lcg_cols],
+ nrows * lcg_cols * sizeof(ss->ss_image[0]));
+ if (ss != curscr)
+ return;
+ memcpy(&lcgaddr[dstrow * lcg_onerow], &lcgaddr[srcrow * lcg_onerow],
+ nrows * lcg_onerow);
+}
+
+static void
+lcg_eraserows(void *id, int startrow, int nrows, long fillattr)
+{
+ struct lcg_screen *ss = id;
+ int i;
+
+ bzero(&ss->ss_image[startrow * lcg_cols], nrows * lcg_cols *
+ sizeof(ss->ss_image[0]));
+ for (i = startrow * lcg_cols; i < (startrow + nrows) * lcg_cols; ++i)
+ ss->ss_image[i].attr = fillattr;
+ if (ss != curscr)
+ return;
+ memset(&lcgaddr[startrow * lcg_onerow], (fillattr & LCG_BG_MASK) >> 4,
+ nrows * lcg_onerow);
+}
+
+static int
+lcg_alloc_attr(void *id, int fg, int bg, int flags, long *attrp)
+{
+ long myattr;
+
+ if (flags & WSATTR_WSCOLORS)
+ myattr = (fg & LCG_FG_MASK) | ((bg << 4) & LCG_BG_MASK);
+ else
+ myattr = WSCOL_WHITE << 4; /* XXXX */
+ if (flags & WSATTR_REVERSE)
+ myattr |= LCG_ATTR_REVERSE;
+ if (flags & WSATTR_UNDERLINE)
+ myattr |= LCG_ATTR_UNDERLINE;
+ *attrp = myattr;
+ return 0;
+}
+
+int
+lcg_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct wsdisplay_fbinfo *fb = (void *)data;
+ int i;
+
+ switch (cmd) {
+ case WSDISPLAYIO_GTYPE:
+ *(u_int *)data = WSDISPLAY_TYPE_LCG;
+ break;
+
+ case WSDISPLAYIO_GINFO:
+ fb->height = lcg_ysize;
+ fb->width = lcg_xsize;
+ fb->depth = lcg_depth;
+ fb->cmsize = 1 << lcg_depth;
+ break;
+
+ case WSDISPLAYIO_GETCMAP:
+ return lcg_get_cmap((struct wsdisplay_cmap *)data);
+
+ case WSDISPLAYIO_PUTCMAP:
+ return lcg_set_cmap((struct wsdisplay_cmap *)data);
+
+ case WSDISPLAYIO_GMODE:
+ return ENOTTY;
+
+ case WSDISPLAYIO_SMODE:
+ /* if setting WSDISPLAYIO_MODE_EMUL, restore console cmap, current screen */
+ if (*(u_int *)data == WSDISPLAYIO_MODE_EMUL) {
+ bzero(lutaddr, LCG_LUT_SIZE);
+ for (i = 0; i < 8; ++i) {
+ lcg_cmap.r[i] = lcg_default_cmap.r[i];
+ lcg_cmap.g[i] = lcg_default_cmap.g[i];
+ lcg_cmap.b[i] = lcg_default_cmap.b[i];
+ lutaddr[i * 8 + 1] = i;
+ lutaddr[i * 8 + 2] = 1;
+ lutaddr[i * 8 + 3] = lcg_cmap.r[i] >> (lcg_depth & 7);
+ lutaddr[i * 8 + 4] = 1;
+ lutaddr[i * 8 + 5] = lcg_cmap.g[i] >> (lcg_depth & 7);
+ lutaddr[i * 8 + 6] = 1;
+ lutaddr[i * 8 + 7] = lcg_cmap.b[i] >> (lcg_depth & 7);
+ }
+ if (savescr != NULL)
+ lcg_show_screen(NULL, savescr, 0, NULL, NULL);
+ savescr = NULL;
+ } else { /* WSDISPLAYIO_MODE_MAPPED */
+ savescr = curscr;
+ curscr = NULL;
+ /* clear screen? */
+ }
+
+ return ENOTTY;
+#if 0
+ case WSDISPLAYIO_SVIDEO:
+ if (*(u_int *)data == WSDISPLAYIO_VIDEO_ON) {
+ curcmd = curc;
+ } else {
+ curc = curcmd;
+ curcmd &= ~(CUR_CMD_FOPA|CUR_CMD_ENPA);
+ curcmd |= CUR_CMD_FOPB;
+ }
+ WRITECUR(CUR_CMD, curcmd);
+ break;
+
+ case WSDISPLAYIO_GVIDEO:
+ *(u_int *)data = (curcmd & CUR_CMD_FOPB ?
+ WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON);
+ break;
+
+#endif
+ default:
+ return ENOTTY;
+ }
+ return 0;
+}
+
+static paddr_t
+lcg_mmap(void *v, off_t offset, int prot)
+{
+ if (offset >= lcg_fb_size || offset < 0)
+ return -1;
+ return (LCG_FB_ADDR + offset) >> PGSHIFT;
+}
+
+int
+lcg_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
+ int *curxp, int *curyp, long *defattrp)
+{
+ int i;
+ struct lcg_screen *ss;
+
+ *cookiep = malloc(sizeof(struct lcg_screen), M_DEVBUF, M_WAITOK);
+ bzero(*cookiep, sizeof(struct lcg_screen));
+ *curxp = *curyp = 0;
+ *defattrp = (LCG_BG_COLOR << 4) | LCG_FG_COLOR;
+ ss = *cookiep;
+ for (i = 0; i < lcg_cols * lcg_rows; ++i)
+ ss->ss_image[i].attr = (LCG_BG_COLOR << 4) | LCG_FG_COLOR;
+ return 0;
+}
+
+void
+lcg_free_screen(void *v, void *cookie)
+{
+}
+
+int
+lcg_show_screen(void *v, void *cookie, int waitok,
+ void (*cb)(void *, int, int), void *cbarg)
+{
+ struct lcg_screen *ss = cookie;
+ int row, col, line, dot_fg, dot_bg, j, attr;
+ char *p;
+
+ if (ss == curscr)
+ return (0);
+
+ for (row = 0; row < lcg_rows; row++)
+ for (col = 0; col < lcg_cols; col++) {
+ attr = ss->ss_image[row * lcg_cols + col].attr;
+ if (attr & LCG_ATTR_REVERSE) {
+ dot_fg = (attr & LCG_BG_MASK) >> 4;
+ dot_bg = attr & LCG_FG_MASK;
+ } else {
+ dot_fg = attr & LCG_FG_MASK;
+ dot_bg = (attr & LCG_BG_MASK) >> 4;
+ }
+ for (line = 0; line < lcg_font.fontheight; line++) {
+ u_char c = ss->ss_image[row * lcg_cols + col].data;
+ int s;
+
+ if (c < 32)
+ c = 32;
+ s = QFONT(c, line);
+
+ p = &LCG_ADDR(row, col, line, 0);
+ for (j = 0; j < lcg_font.fontwidth; ++j)
+ *p++ = s & (1 << j) ? dot_fg : dot_bg;
+ }
+ if (attr & LCG_ATTR_UNDERLINE)
+ for (j = 0; j < lcg_font.fontwidth; j++)
+ LCG_ADDR(row, col,
+ lcg_font.fontheight - 1, j) = dot_fg;
+ }
+
+ cursor = &lcgaddr[(ss->ss_cury * lcg_onerow) +
+ ((lcg_font.fontheight - 1) * lcg_xsize) +
+ (ss->ss_curx * lcg_font.fontwidth)];
+ cur_fg = ss->ss_cur_fg;
+ cur_bg = ss->ss_cur_bg;
+
+ curscr = ss;
+ return (0);
+}
+
+static int
+lcg_get_cmap(p)
+ struct wsdisplay_cmap *p;
+{
+ u_int index = p->index, count = p->count;
+ int error;
+
+ if (index >= (1 << lcg_depth) || count > (1 << lcg_depth) - index)
+ return (EINVAL);
+
+ error = copyout(&lcg_cmap.r[index], p->red, count);
+ if (error)
+ return error;
+ error = copyout(&lcg_cmap.g[index], p->green, count);
+ if (error)
+ return error;
+ error = copyout(&lcg_cmap.b[index], p->blue, count);
+ return error;
+}
+
+static int
+lcg_set_cmap(p)
+ struct wsdisplay_cmap *p;
+{
+ u_int index = p->index, count = p->count;
+ int error, s;
+
+ if (index >= (1 << lcg_depth) || count > (1 << lcg_depth) - index)
+ return (EINVAL);
+
+ error = copyin(p->red, &lcg_cmap.r[index], count);
+ if (error)
+ return error;
+ error = copyin(p->green, &lcg_cmap.g[index], count);
+ if (error)
+ return error;
+ error = copyin(p->blue, &lcg_cmap.b[index], count);
+ if (error)
+ return error;
+
+ s = spltty();
+ while (count-- > 0) {
+ lutaddr[index * 8 + 0] = 0;
+ lutaddr[index * 8 + 1] = index;
+ lutaddr[index * 8 + 2] = 1;
+ lutaddr[index * 8 + 3] = lcg_cmap.r[index] >> (lcg_depth & 7);
+ lutaddr[index * 8 + 4] = 1;
+ lutaddr[index * 8 + 5] = lcg_cmap.g[index] >> (lcg_depth & 7);
+ lutaddr[index * 8 + 6] = 1;
+ lutaddr[index * 8 + 7] = lcg_cmap.b[index] >> (lcg_depth & 7);
+ ++index;
+ }
+ splx(s);
+ return (0);
+}
+
+cons_decl(lcg);
+
+void
+lcgcninit(struct consdev *cndev)
+{
+ int i;
+ /* Clear screen */
+ memset(lcgaddr, LCG_BG_COLOR, lcg_xsize * lcg_ysize);
+
+ curscr = &lcg_conscreen;
+ for (i = 0; i < lcg_cols * lcg_rows; ++i)
+ lcg_conscreen.ss_image[i].attr =
+ (LCG_BG_COLOR << 4) | LCG_FG_COLOR;
+ wsdisplay_cnattach(&lcg_stdscreen, &lcg_conscreen, 0, 0,
+ (LCG_BG_COLOR << 4) | LCG_FG_COLOR);
+ cn_tab->cn_pri = CN_INTERNAL;
+
+#if NDZKBD > 0
+ dzkbd_cnattach(0); /* Connect keyboard and screen together */
+#endif
+}
+
+/*
+ * Called very early to setup the glass tty as console.
+ * Because it's called before the VM system is inited, virtual memory
+ * for the framebuffer can be stolen directly without disturbing anything.
+ */
+void
+lcgcnprobe(struct consdev *cndev)
+{
+ if ((vax_boardtype != VAX_BTYP_46) && (vax_boardtype != VAX_BTYP_48))
+ return; /* Only for VS 4000/60 and VLC */
+
+ if (vax_confdata & 0x100)
+ return; /* Diagnostic console */
+
+ lcg_init_common(NULL, NULL);
+
+ /* Set up default LUT */
+
+ cndev->cn_pri = CN_INTERNAL;
+ cndev->cn_dev = makedev(getmajor(wsdisplayopen), 0);
+}
+
+void
+lcg_init_common(struct device *self, struct vsbus_attach_args *va)
+{
+ u_int magic, *lcg_config;
+ int i;
+ extern vaddr_t virtual_avail;
+ long video_conf;
+ int cookie;
+ struct wsdisplay_font *wf;
+
+ if (regaddr != NULL)
+ return;
+
+ /* map LCG registers first */
+ if (self != NULL) {
+ regaddr = (long*)vax_map_physmem(LCG_REG_ADDR, (LCG_REG_SIZE/VAX_NBPG));
+ if (regaddr == 0) {
+ printf("%s: Couldn't allocate register memory.\n", self->dv_xname);
+ return;
+ }
+ } else {
+ regaddr = (long*)virtual_avail;
+ virtual_avail += LCG_REG_SIZE;
+ ioaccess((vaddr_t)regaddr, LCG_REG_ADDR, (LCG_REG_SIZE/VAX_NBPG));
+ }
+
+ /*
+ * v = *0x200f0010 & VLC ? 0x07 : 0xf0;
+ * switch(v) {
+ * 0x05: 1280x1024
+ * 0x06: conf & 0x80 ? 1024x768 : 640x480
+ * 0x07: conf & 0x80 ? 1024x768 ? 1024x864
+ * 0x20: 1024x864
+ * 0x40: 1024x768
+ * 0x60: 1024x864
+ * 0x80: 1280x1024 4BPN
+ * 0x90: 1280x1024 8BPN
+ * 0xb0: 1280x1024 8BPN 2HD
+ */
+ if (self != NULL) {
+ lcg_config = (u_int *)vax_map_physmem(LCG_CONFIG, 1);
+ } else {
+ lcg_config = (u_int *)virtual_avail;
+ ioaccess((vaddr_t)lcg_config, LCG_CONFIG, 1);
+ }
+ magic = *lcg_config & (vax_boardtype == VAX_BTYP_46 ? 0xf0 : 0x07);
+ if (self != NULL) {
+ vax_unmap_physmem((vaddr_t)lcg_config, 1);
+ } else {
+ iounaccess((vaddr_t)lcg_config, 1);
+ }
+ lcg_depth = 8;
+ switch(magic) {
+ case 0x80: /* KA46 HR 1280x1024 4BPLN */
+ lcg_depth = 4;
+ case 0x05: /* KA48 HR 1280x1024 8BPLN */
+ case 0x90: /* KA46 HR 1280x1024 8BPLN */
+ case 0xb0: /* KA46 HR 1280x1024 8BPLN 2HD */
+ lcg_xsize = 1280;
+ lcg_ysize = 1024;
+ break;
+ case 0x06: /* KA48 1024x768 or 640x480 */
+ if (vax_confdata & 0x80) {
+ lcg_xsize = 1024;
+ lcg_ysize = 768;
+ } else {
+ lcg_xsize = 640;
+ lcg_ysize = 480;
+ }
+ break;
+ case 0x07: /* KA48 1024x768 or 1024x864 */
+ lcg_xsize = 1024;
+ lcg_ysize = (vax_confdata & 0x80) ? 768 : 864;
+ break;
+ case 0x20: /* KA46 1024x864 */
+ case 0x60: /* KA46 1024x864 */
+ lcg_xsize = 1024;
+ lcg_ysize = 864;
+ break;
+ case 0x40: /* KA46 1024x768 */
+ lcg_xsize = 1024;
+ lcg_ysize = 768;
+ break;
+ default:
+ panic("LCG model not supported");
+ }
+
+ wsfont_init();
+ cookie = wsfont_find(NULL, 12, 22, 0);
+ if (cookie == -1)
+ cookie = wsfont_find(NULL, 8, 0, 0);
+ if (cookie == -1)
+ cookie = wsfont_find(NULL, 0, 0, 0);
+ if (cookie == -1 || wsfont_lock(cookie, &wf, WSDISPLAY_FONTORDER_L2R,
+ WSDISPLAY_FONTORDER_R2L))
+ panic("lcg_common_init: can't load console font");
+ lcg_font = *wf;
+ if (self != NULL) {
+ printf("lcg0: Using font %s\n", wf->name);
+ }
+ lcg_cols = lcg_xsize / lcg_font.fontwidth;
+ lcg_rows = lcg_ysize / lcg_font.fontheight;
+ lcg_onerow = lcg_xsize * lcg_font.fontheight;
+ lcg_fb_size = lcg_xsize * lcg_ysize;
+/* lcg_stdscreen.ncols = lcg_cols;
+ lcg_stdscreen.nrows = lcg_rows;
+ lcg_stdscreen.fontwidth = lcg_font.fontwidth;
+ lcg_stdscreen.fontheight = lcg_font.fontheight; */
+ sprintf("160x68", "%dx%d", lcg_cols, lcg_rows);
+ qf = lcg_font.data;
+ qf2 = (u_short *)lcg_font.data;
+
+ if (self != NULL) {
+ lcgaddr = (caddr_t)vax_map_physmem(va->va_paddr, (lcg_fb_size/VAX_NBPG));
+ if (lcgaddr == 0) {
+ printf("%s: Couldn't allocate graphics memory.\n", self->dv_xname);
+ return;
+ }
+ lutaddr = (caddr_t)vax_map_physmem(LCG_LUT_ADDR, (LCG_LUT_SIZE/VAX_NBPG));
+ if (lutaddr == 0) {
+ printf("%s: Couldn't allocate LUT memory.\n", self->dv_xname);
+ return;
+ }
+ } else {
+ lcgaddr = (caddr_t)virtual_avail;
+ virtual_avail += lcg_fb_size;
+ ioaccess((vaddr_t)lcgaddr, LCG_FB_ADDR, (lcg_fb_size/VAX_NBPG));
+
+ lutaddr = (caddr_t)virtual_avail;
+ virtual_avail += LCG_LUT_SIZE;
+ ioaccess((vaddr_t)lutaddr, LCG_LUT_ADDR, (LCG_LUT_SIZE/VAX_NBPG));
+ }
+
+ bzero(lutaddr, LCG_LUT_SIZE);
+ for (i = 0; i < 8; ++i) {
+ lcg_cmap.r[i] = lcg_default_cmap.r[i];
+ lcg_cmap.g[i] = lcg_default_cmap.g[i];
+ lcg_cmap.b[i] = lcg_default_cmap.b[i];
+ lutaddr[i * 8 + 1] = i;
+ lutaddr[i * 8 + 2] = 1;
+ lutaddr[i * 8 + 3] = lcg_cmap.r[i] >> (lcg_depth & 7);
+ lutaddr[i * 8 + 4] = 1;
+ lutaddr[i * 8 + 5] = lcg_cmap.g[i] >> (lcg_depth & 7);
+ lutaddr[i * 8 + 6] = 1;
+ lutaddr[i * 8 + 7] = lcg_cmap.b[i] >> (lcg_depth & 7);
+ }
+
+ /* XXX Use existing video_config register setting? */
+ /*
+ * 0xf100165b 4000/60
+ * 1111 0001 0000 0000 0001 0110 0101 1011
+ * vvvv vvvv vvvv vvvv vvvv vvvv vvvv vvvv
+ * 3322 2222 2222 1111 1111 11
+ * 1098 7654 3210 9876 5432 1098 7654 3210
+ *
+ * 0xf1001d7b 4000/VLC
+ * 1111 0001 0000 0000 0001 1101 0111 1011
+ * vvvv vvvv vvvv vvvv vvvv vvvv vvvv vvvv
+ * 3322 2222 2222 1111 1111 11
+ * 1098 7654 3210 9876 5432 1098 7654 3210
+ *
+ * 31-30 11 Vertical state
+ * 29-38 11 Horizontal state
+ * 27-26 00
+ * 25 0 console LUT select
+ * 24 1 control LUT select
+ * 23 0
+ * 22 0 cursor active
+ * 21-16 000000
+ * 15 0 video subsystem reset
+ * 14 0
+ * 13 0 LUT load size 2KB
+ * 12 1 enable H sync
+ * 11 0 Full LUT load 1
+ * 10 1 video clock select
+ * 9- 8 10 memory refresh rate 01
+ * 7- 6 01 video refresh rate
+ * 5 0 load select 1
+ * 4 1 read cursor output
+ * 3 1 LUT load enable
+ * 2 0 cursor enable
+ * 1 1 video enable
+ * 0 1 refresh clock enable
+ */
+ /* prepare video_config reg for LUT relaod */
+ video_conf
+ = (3 << 30) /* vertical state */
+ | (3 << 28) /* horizontal state */
+ | (0 << 26) /* unused */
+ | (0 << 25) /* console LUT select */
+ | (0 << 24) /* control LUT select */
+ | (0 << 23) /* unused */
+ | (0 << 22) /* cursor active */
+ | (0 << 16) /* current cursor scanline showing */
+ | (0 << 15) /* video subsystem reset */
+ | (0 << 14) /* unused */
+ | (1 << 13) /* LUT load size 2 KB */
+ | (1 << 12) /* enable horizontal sync */
+ | (1 << 10) /* video clock select */
+ | (1 << 6) /* video refresh select */
+ | (1 << 4) /* read curosr output */
+ | (1 << 3) /* LUT load enable */
+ | (0 << 2) /* cursor enable */
+ | (1 << 1) /* video enable */
+ | (1 << 0); /* refresh clock enable */
+ if (lcg_xsize == 1280) { /* 4000/60 HR 4PLN */
+ video_conf |= (0 << 11); /* split LUT load */
+ video_conf |= (2 << 8); /* memory refresh select */
+ video_conf |= (0 << 5); /* split shift register load */
+ } else { /* 4000/VLC LR 8PLN */
+ video_conf |= (1 << 11); /* Full LUT load */
+ video_conf |= (1 << 8); /* memory refresh select */
+ video_conf |= (1 << 5); /* split shift register load */
+ }
+
+ LCG_REG(LCG_REG_VIDEO_CONFIG) = video_conf;
+
+ /* vital !!! */
+ LCG_REG(LCG_REG_LUT_CONSOLE_SEL) = 1;
+
+ LCG_REG(LCG_REG_LUT_COLOR_BASE_W) = LCG_LUT_OFFSET;
+
+ delay(1000);
+
+ LCG_REG(LCG_REG_LUT_CONSOLE_SEL) = 0;
+
+ if (self != NULL)
+ printf("lcg: video config register set 0x%08lx\n", video_conf);
+}
making sure the compat library is up to date...
`libcompat.a' is up to date.
mkdir -p /usr/src/sys/arch/vax/compile/zsebivax/lib/kern
making sure the kern library is up to date...
`libkern.o' is up to date.
sh /usr/src/sys/arch/vax/compile/zsebivax/../../../../conf/newvers.sh
cc -O2 -Werror -Wall -Wmissing-prototypes -Wstrict-prototypes -Wno-main -Wno-format -Wno-uninitialized -fno-builtin-printf -fno-builtin-log -I. -I/usr/src/sys/arch/vax/compile/zsebivax/../../../../arch -I/usr/src/sys/arch/vax/compile/zsebivax/../../../.. -nostdinc -DDDB -DDIAGNOSTIC -DKTRACE -DKMEMSTATS -DPTRACE -DCRYPTO -DSYSVMSG -DSYSVSEM -DSYSVSHM -DUVM_SWAP_ENCRYPT -DCOMPAT_43 -DLKM -DFFS -DFFS_SOFTUPDATES -DUFS_DIRHASH -DQUOTA -DEXT2FS -DMFS -DXFS -DTCP_SACK -DTCP_ECN -DTCP_SIGNATURE -DNFSCLIENT -DNFSSERVER -DCD9660 -DMSDOSFS -DFDESC -DFIFO -DKERNFS -DPORTAL -DPROCFS -DNULLFS -DUMAPFS -DUNION -DINET -DALTQ -DINET6 -DIPSEC -DPPP_BSDCOMP -DPPP_DEFLATE -DBOOT_CONFIG -DVAX48 -DSCSIVERBOSE -DCOMPAT_VAX1K -DINSN_EMULATE -DMAXUSERS=8 -D_KERNEL -D_VAX_INLINE_ -c vers.c
ld -N -Ttext 80000000 -e start -S -o bsd ${SYSTEM_OBJ} vers.o
lcg.o: Undefined symbol `_wsfont_init' referenced from text segment
lcg.o: Undefined symbol `_wsfont_find' referenced from text segment
lcg.o: Undefined symbol `_wsfont_lock' referenced from text segment
lcg.o: Undefined symbol `_sprintf' referenced from text segment
ka48.o: Undefined symbol `_clk_adrshift' referenced from text segment
ka48.o: Undefined symbol `_clk_tweak' referenced from text segment
ka48.o: Undefined symbol `_clk_page' referenced from text segment
ka48.o: Undefined symbol `_clk_page' referenced from text segment
ka48.o: Undefined symbol `_clk_page' referenced from text segment
ka48.o: Undefined symbol `_chip_clkread' referenced from data segment
ka48.o: Undefined symbol `_chip_clkwrite' referenced from data segment
*** Error code 1
Stop in /usr/src/sys/arch/vax/compile/zsebivax (line 377 of Makefile).