Subject: port-sparc/32552: cgfourteen 24-bit support
To: None <port-sparc-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: None <tonio@abravo.org>
List: netbsd-bugs
Date: 01/17/2006 03:15:01
>Number:         32552
>Category:       port-sparc
>Synopsis:       cgfourteen 24-bit support
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    port-sparc-maintainer
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Jan 17 03:15:00 +0000 2006
>Originator:     Antonio Bravo
>Release:        NetBSD 3.0
>Organization:
>Environment:
NetBSD grizzly 3.0 NetBSD 3.0 (GRIZZLY) #0: Mon Jan 16 08:13:51 CET 2006  root@grizzly:/usr/src/sys/arch/sparc/compile/GRIZZLY sparc

>Description:
The cgfourteen is not supported in 24-bit mode by the stock 3.0 kernel.
The CG14_CG8 options doesn't work.
But a dev/cgfourteen.c and dev/cgfourteenvar.h files were posted on the mailing list by Jakob Menzi, adapting code from der Mouse:
http://mail-index.netbsd.org/port-sparc/2004/12/07/0003.html

I have successfully build kernels with those two different files, and so far my SS20-cg14 is working fine in 24-bit.

---------------------
Below is the unified patch for the two files (cgfourteen.c and cgfourteenvar.h in /usr/src/sys/arch/sparc/dev/).

I have put it, under the name "patch.cg14-24bit" here:
ftp://ftp.landstrykere.net/NetBSD/sparc/patch_cg14-24bit/patch.cg14-24bit

and a more verbose html:
http://bsd.landstrykere.net/netbsd.html

I think it could be worth to add a small paragraph to the FAQ:
http://netbsd.org/Ports/sparc/faq.html
and tell about in the "Supported hardware" page as well:
http://netbsd.org/Ports/sparc/hardware.html#sun4-fb

to make it more visible for people around who will be happy of running nice NetBSD desktops on SS20s when enough powered in CPU.

>How-To-Repeat:

>Fix:
--- /usr/src/sys/arch/sparc/dev/cgfourteen.c.old	2006-01-16 06:30:44.000000000 +0100
+++ /usr/src/sys/arch/sparc/dev/cgfourteen.c	2004-12-05 12:20:44.000000000 +0100
@@ -1,4 +1,4 @@
-/*	$NetBSD: cgfourteen.c,v 1.38 2003/11/13 03:09:28 chs Exp $ */
+/*	$NetBSD: cgfourteen.c,v 1.15 1999/03/24 05:51:10 mrg Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -66,19 +66,14 @@
  * enabled by allowing any user to map the control registers for the
  * cg14 into their space.
  */
-#undef CG14_MAP_REGS
+#define CG14_MAP_REGS
 
 /*
  * The following enables 24-bit operation: when opened, the framebuffer
  * will switch to 24-bit mode (actually 32-bit mode), and provide a
  * simple cg8 emulation.
- *
- * XXX Note that the code enabled by this define is currently untested/broken.
  */
-#undef CG14_CG8
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cgfourteen.c,v 1.38 2003/11/13 03:09:28 chs Exp $");
+#define CG14_CG8
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -92,13 +87,12 @@
 
 #include <uvm/uvm_extern.h>
 
-#include <machine/bus.h>
-#include <machine/autoconf.h>
-
-#include <dev/sbus/sbusvar.h>
-
 #include <dev/sun/fbio.h>
+#include <machine/autoconf.h>
+#include <machine/pmap.h>
 #include <dev/sun/fbvar.h>
+#include <machine/cpu.h>
+#include <dev/sbus/sbusvar.h>
 
 #include <sparc/dev/cgfourteenreg.h>
 #include <sparc/dev/cgfourteenvar.h>
@@ -110,25 +104,28 @@
 
 CFATTACH_DECL(cgfourteen, sizeof(struct cgfourteen_softc),
     cgfourteenmatch, cgfourteenattach, NULL, NULL);
-
+        
 extern struct cfdriver cgfourteen_cd;
 
 dev_type_open(cgfourteenopen);
 dev_type_close(cgfourteenclose);
 dev_type_ioctl(cgfourteenioctl);
 dev_type_mmap(cgfourteenmmap);
+dev_type_poll(cgfourteenpoll);
 
 const struct cdevsw cgfourteen_cdevsw = {
-	cgfourteenopen, cgfourteenclose, noread, nowrite, cgfourteenioctl,
-	nostop, notty, nopoll, cgfourteenmmap, nokqfilter,
+        cgfourteenopen, cgfourteenclose, noread, nowrite, cgfourteenioctl,
+        nostop, notty, cgfourteenpoll, cgfourteenmmap, nokqfilter,
 };
 
 /* frame buffer generic driver */
 static struct fbdriver cgfourteenfbdriver = {
 	cgfourteenunblank, cgfourteenopen, cgfourteenclose, cgfourteenioctl,
-	nopoll, cgfourteenmmap, nokqfilter
+	cgfourteenpoll, cgfourteenmmap, nokqfilter
 };
 
+extern struct tty *fbconstty;
+
 static void cg14_set_video __P((struct cgfourteen_softc *, int));
 static int  cg14_get_video __P((struct cgfourteen_softc *));
 static int  cg14_get_cmap __P((struct fbcmap *, union cg14cmap *, int));
@@ -136,19 +133,6 @@
 static void cg14_load_hwcmap __P((struct cgfourteen_softc *, int, int));
 static void cg14_init __P((struct cgfourteen_softc *));
 static void cg14_reset __P((struct cgfourteen_softc *));
-static void cg14_loadomap __P((struct cgfourteen_softc *));/* cursor overlay */
-static void cg14_setcursor __P((struct cgfourteen_softc *));/* set position */
-static void cg14_loadcursor __P((struct cgfourteen_softc *));/* set shape */
-
-/*
- * We map the display memory with an offset of 256K when emulating the cg3 or
- * cg8; the cg3 uses this offset for compatibility with the cg4, and both the
- * cg4 and cg8 have a mono overlay plane and an overlay enable plane in the
- * first 256K.  Mapping at an offset of 0x04000000 causes only the color
- * frame buffer to be mapped, without the overlay planes.
- */
-#define START		(128*1024 + 128*1024)
-#define NOOVERLAY	(0x04000000)
 
 /*
  * Match a cgfourteen.
@@ -177,6 +161,24 @@
 }
 
 /*
+ * Set COLOUR_OFFSET to the offset of the video RAM.  This is to provide
+ *  space for faked overlay junk for the cg8 emulation.
+ *
+ * As it happens, this value is correct for both cg3 and cg8 emulation!
+ */
+#define COLOUR_OFFSET (256*1024)
+
+static void cg14_set_rcons_luts(struct cgfourteen_softc *sc)
+{
+	int i;
+
+	for (i=0;i<CG14_CLUT_SIZE;i++) sc->sc_xlut->xlut_lut[i] = 0x22;
+	for (i=0;i<CG14_CLUT_SIZE;i++) sc->sc_clut2->clut_lut[i] = 0x00ffffff;
+	sc->sc_clut2->clut_lut[0] = 0x00ffffff;
+	sc->sc_clut2->clut_lut[255] = 0;
+}
+
+/*
  * Attach a display.  We need to notice if it is the console, too.
  */
 void
@@ -209,29 +211,16 @@
 #ifdef CG14_CG8
 	fb->fb_type.fb_type = FBTYPE_MEMCOLOR;
 	fb->fb_type.fb_depth = 32;
+	fb_setsize_obp(fb, sc->sc_fb.fb_type.fb_depth, 1152, 900, node);
+	ramsize = roundup(fb->fb_type.fb_height * 1152 * 4, NBPG);
 #else
 	fb->fb_type.fb_type = FBTYPE_SUN3COLOR;
 	fb->fb_type.fb_depth = 8;
-#endif
 	fb_setsize_obp(fb, sc->sc_fb.fb_type.fb_depth, 1152, 900, node);
-#ifdef CG14_CG8
-	/*
-	 * fb_setsize_obp set fb->fb_linebytes based on the current
-	 * depth reported by obp, but that defaults to 8 bits (as
-	 * reported by getpropint().  Update the value to reflect
-	 * the depth that will be used after open.
-	 * The display memory size returned by the cg8 driver includes
-	 * the space used by the overlay planes, but the size returned
-	 * by the cg3 driver does not; emulate the other drivers.
-	 */
-	fb->fb_linebytes = (fb->fb_type.fb_width * fb->fb_type.fb_depth) / 8;
-	ramsize = roundup(START + (fb->fb_type.fb_height * fb->fb_linebytes),
-			PAGE_SIZE);
-#else
-	ramsize = roundup(fb->fb_type.fb_height * fb->fb_linebytes, PAGE_SIZE);
+	ramsize = roundup(fb->fb_type.fb_height * fb->fb_linebytes, NBPG);
 #endif
 	fb->fb_type.fb_cmsize = CG14_CLUT_SIZE;
-	fb->fb_type.fb_size = ramsize;
+	fb->fb_type.fb_size = ramsize + COLOUR_OFFSET;
 
 	if (sa->sa_nreg < 2) {
 		printf("%s: only %d register sets\n",
@@ -239,7 +228,7 @@
 		return;
 	}
 	bcopy(sa->sa_reg, sc->sc_physadr,
-	      sa->sa_nreg * sizeof(struct openprom_addr));
+	      sa->sa_nreg * sizeof(struct sbus_reg));
 
 	/*
 	 * Now map in the 8 useful pages of registers
@@ -250,9 +239,11 @@
 #endif
 		sa->sa_size = 0x10000;
 	}
-	if (sbus_bus_map(sa->sa_bustag,
-			 sa->sa_slot, sa->sa_offset, sa->sa_size,
-			 BUS_SPACE_MAP_LINEAR, &bh) != 0) {
+	if (sbus_bus_map(sa->sa_bustag, sa->sa_slot,
+			 sa->sa_offset,
+			 sa->sa_size,
+			 BUS_SPACE_MAP_LINEAR,
+			 &bh) != 0) {
 		printf("%s: cannot map control registers\n", self->dv_xname);
 		return;
 	}
@@ -277,7 +268,7 @@
 		fb->fb_type.fb_width, fb->fb_type.fb_height);
 #endif
 	/*
-	 * Enable the video, but don't change the pixel depth.
+	 * Enable the video.
 	 */
 	cg14_set_video(sc, 1);
 
@@ -289,19 +280,32 @@
 		sc->sc_cmap.cm_chip[i] = lut[i];
 
 	/* See if we're the console */
-	isconsole = fb_is_console(node);
+        isconsole = fb_is_console(node);
 
 	if (isconsole) {
 		printf(" (console)\n");
-#ifdef notdef
-		/*
-		 * We don't use the raster console since the cg14 is
-		 * fast enough already.
-		 */
 #ifdef RASTERCONSOLE
-		fbrcons_init(fb);
+		/* *sbus*_bus_map?  but that's how we map the regs... */
+		if (sbus_bus_map( sc->sc_bustag,
+				  sc->sc_physadr[CG14_PXL_IDX].sbr_slot,
+				  sc->sc_physadr[CG14_PXL_IDX].sbr_offset+0x03800000,
+				  1152*900, BUS_SPACE_MAP_LINEAR,
+				  &bh) != 0) {
+			printf("%s: cannot map pixels\n",&sc->sc_dev.dv_xname[0]);
+		} else {
+			sc->sc_rcfb = sc->sc_fb;
+			sc->sc_rcfb.fb_type.fb_type = FBTYPE_SUN3COLOR;
+			sc->sc_rcfb.fb_type.fb_depth = 8;
+			sc->sc_rcfb.fb_linebytes = 1152;
+			sc->sc_rcfb.fb_type.fb_size = roundup(1152*900,NBPG);
+			sc->sc_rcfb.fb_pixels = (void *)bh;
+			printf("vram at %p\n",(void *)bh);
+			for (i=0;i<1152*900;i++) ((unsigned char *)bh)[i] = 0;
+			fbrcons_init(&sc->sc_rcfb);
+			cg14_set_rcons_luts(sc);
+			sc->sc_ctl->ctl_mctl = CG14_MCTL_ENABLEVID | CG14_MCTL_PIXMODE_32 | CG14_MCTL_POWERCTL;
+		}
 #endif
-#endif /* notdef */
 	} else
 		printf("\n");
 
@@ -323,14 +327,16 @@
 	int flags, mode;
 	struct proc *p;
 {
-	struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
-	int unit = minor(dev);
+	struct cgfourteen_softc *sc;
+	int unit;
 	int s, oldopens;
 
-	if (unit >= cgfourteen_cd.cd_ndevs ||
-	    cgfourteen_cd.cd_devs[unit] == NULL)
-		return (ENXIO);
-
+	unit = minor(dev);
+	if (unit >= cgfourteen_cd.cd_ndevs)
+		return(ENXIO);
+	sc = cgfourteen_cd.cd_devs[minor(dev)];
+	if (sc == NULL)
+		return(ENXIO);
 	s = splhigh();
 	oldopens = cg14_opens++;
 	splx(s);
@@ -376,10 +382,7 @@
 {
 	struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
 	struct fbgattr *fba;
-	union cg14cursor_cmap tcm;
-	int v, error;
-	u_int count;
-	u_int eplane[32], cplane[32];
+	int error;
 
 	switch (cmd) {
 
@@ -400,7 +403,7 @@
 		break;
 
 	case FBIOGETCMAP:
-		return (cg14_get_cmap((struct fbcmap *)data, &sc->sc_cmap,
+		return(cg14_get_cmap((struct fbcmap *)data, &sc->sc_cmap,
 				     CG14_CLUT_SIZE));
 
 	case FBIOPUTCMAP:
@@ -426,112 +429,6 @@
 		cg14_set_video(sc, *(int *)data);
 		break;
 
-/* these are for both FBIOSCURSOR and FBIOGCURSOR */
-#define p ((struct fbcursor *)data)
-#define cc (&sc->sc_cursor)
-	case FBIOGCURSOR:
-		/* do not quite want everything here... */
-		p->set = FB_CUR_SETALL;	/* close enough, anyway */
-		p->enable = cc->cc_enable;
-		p->pos = cc->cc_pos;
-		p->hot = cc->cc_hot;
-		p->size = cc->cc_size;
-
-		/* begin ugh ... can we lose some of this crap?? */
-		if (p->image != NULL) {
-			count = cc->cc_size.y * 32 / NBBY;
-			error = copyout(cc->cc_cplane, p->image, count);
-			if (error)
-				return (error);
-			error = copyout(cc->cc_eplane, p->mask, count);
-			if (error)
-				return (error);
-		}
-		if (p->cmap.red != NULL) {
-			error = cg14_get_cmap(&p->cmap,
-			    (union cg14cmap *)&cc->cc_color, 2);
-			if (error)
-				return (error);
-		} else {
-			p->cmap.index = 0;
-			p->cmap.count = 2;
-		}
-		/* end ugh */
-		break;
-
-	case FBIOSCURSOR:
-		/*
-		 * For setcmap and setshape, verify parameters, so that
-		 * we do not get halfway through an update and then crap
-		 * out with the software state screwed up.
-		 */
-		v = p->set;
-		if (v & FB_CUR_SETCMAP) {
-			/*
-			 * This use of a temporary copy of the cursor
-			 * colormap is not terribly efficient, but these
-			 * copies are small (8 bytes)...
-			 */
-			tcm = cc->cc_color;
-			error = cg14_put_cmap(&p->cmap, (union cg14cmap *)&tcm,
-					      2);
-			if (error)
-				return (error);
-		}
-		if (v & FB_CUR_SETSHAPE) {
-			if ((u_int)p->size.x > 32 || (u_int)p->size.y > 32)
-				return (EINVAL);
-			count = p->size.y * 32 / NBBY;
-			error = copyin(p->mask, eplane, count);
-			if (error)
-				return error;
-			error = copyin(p->image, cplane, count);
-			if (error)
-				return error;
-		}
-
-		/* parameters are OK; do it */
-		if (v & (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT)) {
-			if (v & FB_CUR_SETCUR)
-				cc->cc_enable = p->enable;
-			if (v & FB_CUR_SETPOS)
-				cc->cc_pos = p->pos;
-			if (v & FB_CUR_SETHOT)
-				cc->cc_hot = p->hot;
-			cg14_setcursor(sc);
-		}
-		if (v & FB_CUR_SETCMAP) {
-			cc->cc_color = tcm;
-			cg14_loadomap(sc); /* XXX defer to vertical retrace */
-		}
-		if (v & FB_CUR_SETSHAPE) {
-			cc->cc_size = p->size;
-			count = p->size.y * 32 / NBBY;
-			memset(cc->cc_eplane, 0, sizeof cc->cc_eplane);
-			memcpy(cc->cc_eplane, eplane, count);
-			memset(cc->cc_cplane, 0, sizeof cc->cc_cplane);
-			memcpy(cc->cc_cplane, cplane, count);
-			cg14_loadcursor(sc);
-		}
-		break;
-
-#undef cc
-#undef p
-	case FBIOGCURPOS:
-		*(struct fbcurpos *)data = sc->sc_cursor.cc_pos;
-		break;
-
-	case FBIOSCURPOS:
-		sc->sc_cursor.cc_pos = *(struct fbcurpos *)data;
-		cg14_setcursor(sc);
-		break;
-
-	case FBIOGCURMAX:
-		/* max cursor size is 32x32 */
-		((struct fbcurpos *)data)->x = 32;
-		((struct fbcurpos *)data)->y = 32;
-		break;
-
 	default:
 		return (ENOTTY);
 	}
@@ -553,17 +450,27 @@
  * Return the address that would map the given device at the given
  * offset, allowing for the given protection, or return -1 for error.
  *
- * The cg14 frame buffer can be mapped in either 8-bit or 32-bit mode
- * starting at the address stored in the PROM. In 8-bit mode, the X
- * channel is not present, and can be ignored. In 32-bit mode, mapping
- * at 0K delivers a 32-bpp buffer where the upper 8 bits select the X
- * channel information. We hardwire the Xlut to all zeroes to insure
- * that, regardless of this value, direct 24-bit color access will be
- * used.
- *
- * Alternatively, mapping the frame buffer at an offset of 16M seems to
- * tell the chip to ignore the X channel. XXX where does it get the X value
- * to use?
+ * Since we're pretending to be a cg8, we put the main video RAM at the
+ *  same place the cg8 does, at offset 256k.  The cg8 has an enable
+ *  plane in the 256k space; our "enable" plane works differently.  We
+ *  can't emulate the enable plane very well, but all X uses it for is
+ *  to clear it at startup - so we map the first page of video RAM over
+ *  and over to fill that 256k space.  We also map some other views of
+ *  the video RAM space.
+ *
+ * Our memory map thus looks like
+ *
+ *	mmap range		space	base offset
+ *	00000000-00040000	vram	0 (multi-mapped - see above)
+ *	00040000-00434800	vram	00000000
+ *	01000000-01400000	vram	01000000
+ *	02000000-02200000	vram	02000000
+ *	02800000-02a00000	vram	02800000
+ *	03000000-03100000	vram	03000000
+ *	03400000-03500000	vram	03400000
+ *	03800000-03900000	vram	03800000
+ *	03c00000-03d00000	vram	03c00000
+ *	10000000-10010000	regs	00000000 (only if CG14_MAP_REGS)
  */
 paddr_t
 cgfourteenmmap(dev, off, prot)
@@ -579,50 +486,55 @@
 	if (off < 0)
 		return (-1);
 
-#if defined(DEBUG) && defined(CG14_MAP_REGS) /* XXX: security hole */
+#if defined(CG14_MAP_REGS) /* XXX: security hole */
 	/*
 	 * Map the control registers into user space. Should only be
 	 * used for debugging!
 	 */
 	if ((u_int)off >= 0x10000000 && (u_int)off < 0x10000000 + 16*4096) {
 		off -= 0x10000000;
-		if (bus_space_mmap(sc->sc_bustag,
+		return (bus_space_mmap(sc->sc_bustag,
 			BUS_ADDR(sc->sc_physadr[CG14_CTL_IDX].sbr_slot,
-				sc->sc_physadr[CG14_CTL_IDX].sbr_offset),
+				   sc->sc_physadr[CG14_CTL_IDX].sbr_offset),
 			off, prot, BUS_SPACE_MAP_LINEAR));
 	}
 #endif
-	
-	if ((u_int)off >= NOOVERLAY)
-		off -= NOOVERLAY;
-	else if ((u_int)off >= START)
-		off -= START;
-	else
-		off = 0;
 
-	/*
-	 * fb_size includes the overlay space only for the CG8.
-	 */
-#ifdef CG14_CG8
-	if (off >= sc->sc_fb.fb_type.fb_size - START)
-#else
-	if (off >= sc->sc_fb.fb_type.fb_size)
-#endif
-	{
-#ifdef DEBUG
-		printf("\nmmap request out of bounds: request 0x%x, "
-		    "bound 0x%x\n", (unsigned) off,
-		    (unsigned)sc->sc_fb.fb_type.fb_size);
-#endif
-		return (-1);
+	if (off < COLOUR_OFFSET)
+		off = 0;
+	else if (off < COLOUR_OFFSET+(1152*900*4))
+		off -= COLOUR_OFFSET;
+	else {
+		switch (off >> 20) {
+			case 0x010: case 0x011: case 0x012: case 0x013:
+			case 0x020: case 0x021:
+			case 0x028: case 0x029:
+			case 0x030:
+			case 0x034:
+			case 0x038:
+			case 0x03c:
+				break;
+			default:
+				return(-1);
+		}
 	}
 
 	return (bus_space_mmap(sc->sc_bustag,
-		BUS_ADDR(sc->sc_physadr[CG14_PXL_IDX].oa_space,
-			sc->sc_physadr[CG14_PXL_IDX].oa_base),
+		BUS_ADDR(sc->sc_physadr[CG14_PXL_IDX].sbr_slot,
+			   sc->sc_physadr[CG14_PXL_IDX].sbr_offset),
 		off, prot, BUS_SPACE_MAP_LINEAR));
 }
 
+int
+cgfourteenpoll(dev, events, p)
+	dev_t dev;
+	int events;
+	struct proc *p;
+{
+
+	return (seltrue(dev, events, p));
+}
+
 /*
  * Miscellaneous helper functions
  */
@@ -664,7 +576,8 @@
 	/*
 	 * Zero the xlut to enable direct-color mode
 	 */
-	memset(sc->sc_xlut, 0, CG14_CLUT_SIZE);
+	for (i = 0; i < CG14_CLUT_SIZE; i++)
+		sc->sc_xlut->xlut_lut[i] = 0;
 #else
 	/*
 	 * Enable the video and put it in 8 bit mode
@@ -747,61 +660,61 @@
 	union cg14cmap *cm;
 	int cmsize;
 {
-	u_int i, start, count;
-	u_char *cp;
-	int error;
-
-	start = p->index;
-	count = p->count;
-	if (start >= cmsize || count > cmsize - start)
-		return (EINVAL);
-
-	for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 4, i++) {
-		error = copyout(&cp[3], &p->red[i], 1);
-		if (error)
-			return error;
-		error = copyout(&cp[2], &p->green[i], 1);
-		if (error)
-			return error;
-		error = copyout(&cp[1], &p->blue[i], 1);
-		if (error)
-			return error;
-	}
-	return (0);
+        u_int i, start, count;
+        u_char *cp;
+        int error;
+
+        start = p->index;
+        count = p->count;
+        if (start >= cmsize || count > cmsize - start)
+                return (EINVAL);
+
+        for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 4, i++) {
+                error = copyout(&cp[3], &p->red[i], 1);
+                if (error)
+                        return error;
+                error = copyout(&cp[2], &p->green[i], 1);
+                if (error)
+                        return error;
+                error = copyout(&cp[1], &p->blue[i], 1);
+                if (error)
+                        return error;
+        }
+        return (0);
 }
 
 /* Write the software shadow colormap */
 static int
 cg14_put_cmap(p, cm, cmsize)
-	struct fbcmap *p;
-	union cg14cmap *cm;
-	int cmsize;
-{
-	u_int i, start, count;
-	u_char *cp;
-	u_char cmap[256][4];
-	int error;
-
-	start = p->index;
-	count = p->count;
-	if (start >= cmsize || count > cmsize - start)
-		return (EINVAL);
-
-	memcpy(&cmap, &cm->cm_map, sizeof cmap);
-	for (cp = &cmap[start][0], i = 0; i < count; cp += 4, i++) {
-		error = copyin(&p->red[i], &cp[3], 1);
-		if (error)
-			return error;
-		error = copyin(&p->green[i], &cp[2], 1);
-		if (error)
-			return error;
-		error = copyin(&p->blue[i], &cp[1], 1);
-		if (error)
-			return error;
-		cp[0] = 0;	/* no alpha channel */
-	}
-	memcpy(&cm->cm_map, &cmap, sizeof cmap);
-	return (0);
+        struct fbcmap *p;
+        union cg14cmap *cm;
+        int cmsize;
+{
+        u_int i, start, count;
+        u_char *cp;
+        u_char cmap[256][4];
+        int error;
+
+        start = p->index;
+        count = p->count;
+        if (start >= cmsize || count > cmsize - start)
+                return (EINVAL);
+
+        memcpy(&cmap, &cm->cm_map, sizeof cmap);
+        for (cp = &cmap[start][0], i = 0; i < count; cp += 4, i++) {
+                error = copyin(&p->red[i], &cp[3], 1);
+                if (error)
+                        return error;
+                error = copyin(&p->green[i], &cp[2], 1);
+                if (error)
+                        return error;
+                error = copyin(&p->blue[i], &cp[1], 1);
+                if (error)
+                        return error;
+                cp[0] = 0;      /* no alpha channel */
+        }
+        memcpy(&cm->cm_map, &cmap, sizeof cmap);
+        return (0);
 }
 
 static void
@@ -820,56 +733,3 @@
 		*lutp++ = *colp++;
 }
 
-/*
- * Load the cursor (overlay `foreground' and `background') colors.
- */
-static void
-cg14_setcursor(sc)
-	struct cgfourteen_softc *sc;
-{
-	/* we need to subtract the hot-spot value here */
-#define COORD(f) (sc->sc_cursor.cc_pos.f - sc->sc_cursor.cc_hot.f)
-
-	sc->sc_hwc->curs_ctl = (sc->sc_cursor.cc_enable ? CG14_CURS_ENABLE : 0);
-	sc->sc_hwc->curs_x = COORD(x);
-	sc->sc_hwc->curs_y = COORD(y);
-
-#undef COORD
-}
-
-static void
-cg14_loadcursor(sc)
-	struct cgfourteen_softc *sc;
-{
-	volatile struct cg14curs *hwc;
-	u_int edgemask, m;
-	int i;
-
-	/*
-	 * Keep the top size.x bits.  Here we *throw out* the top
-	 * size.x bits from an all-one-bits word, introducing zeros in
-	 * the top size.x bits, then invert all the bits to get what
-	 * we really wanted as our mask.  But this fails if size.x is
-	 * 32---a sparc uses only the low 5 bits of the shift count---
-	 * so we have to special case that.
-	 */
-	edgemask = ~0;
-	if (sc->sc_cursor.cc_size.x < 32)
-		edgemask = ~(edgemask >> sc->sc_cursor.cc_size.x);
-	hwc = sc->sc_hwc;
-	for (i = 0; i < 32; i++) {
-		m = sc->sc_cursor.cc_eplane[i] & edgemask;
-		hwc->curs_plane0[i] = m;
-		hwc->curs_plane1[i] = m & sc->sc_cursor.cc_cplane[i];
-	}
-}
-
-static void
-cg14_loadomap(sc)
-	struct cgfourteen_softc *sc;
-{
-	/* set background color */
-	sc->sc_hwc->curs_color1 = sc->sc_cursor.cc_color.cm_chip[0];
-	/* set foreground color */
-	sc->sc_hwc->curs_color2 = sc->sc_cursor.cc_color.cm_chip[1];
-}
--- /usr/src/sys/arch/sparc/dev/cgfourteenvar.h.old	2006-01-16 06:32:23.000000000 +0100
+++ /usr/src/sys/arch/sparc/dev/cgfourteenvar.h	2004-11-30 22:58:15.000000000 +0100
@@ -1,4 +1,4 @@
-/*	$NetBSD: cgfourteenvar.h,v 1.4 2002/08/23 02:53:11 thorpej Exp $ */
+/*	$NetBSD: cgfourteenvar.h,v 1.3 1998/07/29 18:36:08 pk Exp $ */
 
 /*
  * Copyright (c) 1996 
@@ -32,7 +32,11 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-
+struct sbus_reg {
+	u_int32_t	sbr_slot;
+	u_int32_t	sbr_offset;
+	u_int32_t	sbr_size;
+};
 /*
  * Layout of cg14 hardware colormap
  */
@@ -68,8 +72,11 @@
 struct cgfourteen_softc {
 	struct device	sc_dev;		/* base device */
 	struct fbdevice	sc_fb;		/* frame buffer device */
+#ifdef RASTERCONSOLE
+	struct fbdevice	sc_rcfb;	/* sc_fb variant for rcons */
+#endif
 	bus_space_tag_t	sc_bustag;
-	struct openprom_addr sc_physadr[2]; /* phys addrs of h/w */
+	struct sbus_reg	sc_physadr[2];	/* phys addrs of h/w */
 #define CG14_CTL_IDX	0
 #define CG14_PXL_IDX	1