Port-sparc archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Panic at boot on 4/330 with cgfour and cgsix
On Sat, Mar 29, 2025 at 7:19 AM Julian Coleman <jdc%coris.org.uk@localhost> wrote:
>
> Hi,
>
> [had a chance to look at this again]
>
> > > Sounds like it's easiest to just use (-0x00100000).
> >
> > Yes that is what I think now as well. I checked cvs history and the
> > sun3 cgfour driver has been using a negative offset since 1998 and has
> > worked for many people including me. So if it's good enough for sun3 I
> > don't see why it can't be good enough for sparc.
>
> Agreed. Let's just use:
>
> #define PFOUR_COLOR_OFF_CMAP 0x00100000
>
> > > > memset(sc->sc_fb.fb_pixels, (defattr >> 16) & 0xff, sc->sc_stride *
> > > > sc->sc_height);
> > > >
> > > > I don't understand what's wrong with this line. Some other drivers use
> > > > something like this with no issues so I don't know why this doesn't
> > > > work but since it's just clearing the screen it's not really needed so
> > > > I commented it out. This allowed it to continue for a few more lines
> > > > then I got a watchdog timeout on this line. Not sure why this fails.
> > > >
> > > > wsdisplay_cnattach(&cgfour_defaultscreen, ri, 0, 0, defattr);
> > >
> > > I'm guessing that we have the location of the video ram wrong. If I read
> > > correctly, everything should be relative to PFOUR_COLOR_OFF_COLOR. What
> > > value do we calculate for that?
> >
> > It seems like the start address is the pfour regesters actually.
> > PFOUR_COLOR_OFF_COLOR seems correct, at least it's the same offset
> > that sun3 calls CG4B_OFF_PIXMAP. But the bigger problem is that
> > fb_pixels is never assigned a value so there's no actual pointer to
> > the framebuffer and I assume that's why the memset() is failing. I
> > tried to add in a bus_space_map() for it but I keep getting a panic
> > for <WRITE,SZERR> at the memset() so I assume I'm doing something
> > wrong.
>
> I looked at cgthree for a reference, and there fb_pixels is mapped in
> the front end attach (cgthree_sbus.c [1]). I see that the old mmap is
> #if 0 so not used, with the comment "We don't do any of the console
> handling here." I'm not 100% sure why the BW2 isn't console, but for
> CG4 as console, can you remove the #if 0 around line 328 [2] and replace
> the mapiodev() call with:
>
> if (fb->fb_pixels = bus_space_map(oba->oba_bustag,
> (paddr_t)oba->oba_paddr + PFOUR_COLOR_OFF_COLOR,
> ramsize,
> BUS_SPACE_MAP_LINEAR, &bh) != 0) {
> aprint_error_dev(self, "cannot map pixels\n");
> return;
> }
> fb->fb_pixels = (char *)bh;
>
> PFOUR_COLOR_OFF_COLOR should be the correct offset. I based the above
> on the code just below where we "Map the Brooktree".
>
> > Also I found this code which looks very wrong to me.
> >
> > in pfourreg.h
> > #define PFOUR_COLOR_OFF_OVERLAY 0x00100000
> > ...
> > #define PFOUR_COLOR_OFF_END 0x00700000
> >
> >
> > in cgfour.c
> > ramsize = PFOUR_COLOR_OFF_END - PFOUR_COLOR_OFF_OVERLAY;
> > ...
> > fb->fb_type.fb_size = ramsize;
> >
> > This comes out to 0x600000 or 6MB but the board only has 1MB. Am I
> > misunderstanding this?
>
> I'm assuming that PFOUR_COLOR_OFF_END is the maximum address for any of
> the P4 colour framebuffers. However, as you point out, this doesn't make
> sense for a CG4. Also based on the CG3 code [3], I think that we need to
> calculate width/height from the EEPROM values with fb_setsize_pfour() [4],
> or maybe just start with hardcoding 1152 x 900 x 8 to see if we have the
> rest of the code correct.
I think I understand the intent of the code now. The board actually
has 1.25MB of RAM, 128KB for the mono plane, 128KB for the enable
plane, and 1MB for the color plane. In order to work we need all the
planes so setting the size based on the resolution won't be enough. I
believe the code was trying to use the offsets to get all of the
memory, however the offsets are aligned to 1MB so there's large gaps
of empty space and that's where the 6MB came from. Since there's only
one type of cgfour that works on sparc with known memory sizes it may
be better to just hard code these values in.
Also in the bwtwo driver I found it used a for loop to limit memset()
to 4 bytes at a time to prevent write errors, copying that fixed my
panic on memset(). However it still hangs at wsdisplay_cnattach(). I
don't know if it's not being set up properly or if it's fighting the
bwtwo driver over who gets to be console. Attaching a work in progress
patch. It doesn't handle the overlay and enable planes yet. In the
sun3 driver it handles them separately instead of lumping them all
together like the sparc driver does. Not sure which is better.
Index: sys/dev/sun/pfourreg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/sun/pfourreg.h,v
retrieving revision 1.4
diff -u -r1.4 pfourreg.h
--- sys/dev/sun/pfourreg.h 28 Apr 2008 20:23:58 -0000 1.4
+++ sys/dev/sun/pfourreg.h 31 Mar 2025 00:49:48 -0000
@@ -66,7 +66,7 @@
#define PFOUR_COLOR_OFF_ENABLE 0x00300000
#define PFOUR_COLOR_OFF_COLOR 0x00500000
#define PFOUR_COLOR_OFF_END 0x00700000
-#define PFOUR_COLOR_OFF_CMAP 0xfff00000 /* (-0x00100000) */
+#define PFOUR_COLOR_OFF_CMAP (-0x00100000)
#define PFOUR_REG_DIAG 0x80
#define PFOUR_REG_READBACKCLR 0x40
Index: sys/arch/sparc/conf/files.sparc
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/conf/files.sparc,v
retrieving revision 1.164
diff -u -r1.164 files.sparc
--- sys/arch/sparc/conf/files.sparc 26 Oct 2023 10:41:03 -0000 1.164
+++ sys/arch/sparc/conf/files.sparc 31 Mar 2025 00:49:48 -0000
@@ -245,7 +245,7 @@
attach cgtwo at vme
file arch/sparc/dev/cgtwo.c cgtwo needs-flag
-device cgfour: bt_dac, fb, rasops8, pfour
+device cgfour: bt_dac, fb, pfour, rasops8, wsemudisplaydev, vcons
attach cgfour at obio
file arch/sparc/dev/cgfour.c cgfour needs-flag
Index: sys/arch/sparc/dev/cgfour.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/dev/cgfour.c,v
retrieving revision 1.51
diff -u -r1.51 cgfour.c
--- sys/arch/sparc/dev/cgfour.c 20 Dec 2023 05:33:18 -0000 1.51
+++ sys/arch/sparc/dev/cgfour.c 31 Mar 2025 00:49:48 -0000
@@ -101,6 +101,8 @@
* XXX should defer colormap updates to vertical retrace interrupts
*/
+#include "wsdisplay.h"
+
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cgfour.c,v 1.51 2023/12/20 05:33:18
thorpej Exp $");
@@ -122,6 +124,15 @@
#include <dev/sun/btvar.h>
#include <dev/sun/pfourreg.h>
+#if NWSDISPLAY > 0
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplay_vconsvar.h>
+#include <dev/wsfont/wsfont.h>
+#include <dev/rasops/rasops.h>
+
+#include "opt_wsemul.h"
+#endif
+
/* per-display variables */
struct cgfour_softc {
struct fbdevice sc_fb; /* frame buffer device */
@@ -129,6 +140,13 @@
bus_addr_t sc_paddr; /* phys address for device mmap() */
volatile struct fbcontrol *sc_fbc; /* Brooktree registers */
+#if NWSDISPLAY > 0
+ uint32_t sc_width;
+ uint32_t sc_height; /* display width / height */
+ uint32_t sc_stride;
+ int sc_mode;
+ struct vcons_data sc_vd;
+#endif
union bt_cmap sc_cmap; /* Brooktree color map */
};
@@ -178,6 +196,44 @@
static void cgfour_set_video(struct cgfour_softc *, int);
#endif
+#if NWSDISPLAY > 0
+static void cgfour_setup_palette(struct cgfour_softc *);
+
+static struct wsscreen_descr cgfour_defaultscreen = {
+ .name = "std",
+ /* all other members will be filled by rasops */
+};
+
+static int cgfour_ioctl(void *, void *, u_long, void *, int, struct lwp *);
+static paddr_t cgfour_mmap(void *, void *, off_t, int);
+static void cgfour_init_screen(void *, struct vcons_screen *, int, long *);
+
+static int cgfour_putcmap(struct cgfour_softc *, struct wsdisplay_cmap *);
+static int cgfour_getcmap(struct cgfour_softc *, struct wsdisplay_cmap *);
+
+static struct wsdisplay_accessops cgfour_accessops = {
+ .ioctl = cgfour_ioctl,
+ .mmap = cgfour_mmap,
+ .alloc_screen = NULL,
+ .free_screen = NULL,
+ .show_screen = NULL,
+ .load_font = NULL,
+ .pollc = NULL,
+ .scroll = NULL
+};
+
+static const struct wsscreen_descr *_cgfour_scrlist[] = {
+ &cgfour_defaultscreen
+};
+
+static struct wsscreen_list cgfour_screenlist = {
+ .nscreens = sizeof(_cgfour_scrlist) / sizeof(struct wsscreen_descr *),
+ .screens = _cgfour_scrlist
+};
+
+static struct vcons_screen cgfour_console_screen;
+#endif
+
/*
* Match a cgfour.
*/
@@ -219,7 +275,12 @@
volatile struct bt_regs *bt;
struct fbdevice *fb = &sc->sc_fb;
int ramsize, i, isconsole;
-
+ char *bits;
+#if NWSDISPLAY > 0
+ struct wsemuldisplaydev_attach_args wsemul_aa;
+ struct rasops_info *ri = &cgfour_console_screen.scr_ri;
+ unsigned long defattr;
+#endif
sc->sc_bustag = oba->oba_bustag;
sc->sc_paddr = (bus_addr_t)oba->oba_paddr;
@@ -240,13 +301,14 @@
fb->fb_flags = device_cfdata(self)->cf_flags & FB_USERMASK;
fb->fb_flags |= FB_PFOUR;
- ramsize = PFOUR_COLOR_OFF_END - PFOUR_COLOR_OFF_OVERLAY;
+ ramsize = 0x100000;
fb->fb_type.fb_depth = 8;
fb_setsize_eeprom(fb, fb->fb_type.fb_depth, 1152, 900);
fb->fb_type.fb_cmsize = 256;
fb->fb_type.fb_size = ramsize;
+
printf(": cgfour/p4, %d x %d",
fb->fb_type.fb_width, fb->fb_type.fb_height);
@@ -263,7 +325,6 @@
isconsole = fb_is_console(0);
}
-#if 0
/*
* We don't do any of the console handling here. Instead,
* we let the bwtwo driver pick up the overlay plane and
@@ -281,10 +342,19 @@
if (isconsole) {
/* XXX this is kind of a waste */
- fb->fb_pixels = mapiodev(ca->ca_ra.ra_reg,
- PFOUR_COLOR_OFF_OVERLAY, ramsize);
+
+ /* Map the 8bit plane. */
+ if (bus_space_map(oba->oba_bustag,
+ oba->oba_paddr + PFOUR_COLOR_OFF_COLOR,
+ ramsize,
+ BUS_SPACE_MAP_LINEAR,
+ &bh) != 0) {
+ printf("%s: cannot map pixels\n",
+ device_xname(self));
+ return;
+ }
+ fb->fb_pixels = (char *)bh;
}
-#endif
/* Map the Brooktree. */
if (bus_space_map(oba->oba_bustag,
@@ -321,6 +391,53 @@
* to notice if we're the console framebuffer.
*/
fb_attach(fb, isconsole);
+
+#if NWSDISPLAY > 0
+ sc->sc_width = fb->fb_type.fb_width;
+ sc->sc_stride = fb->fb_type.fb_width;
+ sc->sc_height = fb->fb_type.fb_height;
+
+ /* setup rasops and so on for wsdisplay */
+ sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
+
+ vcons_init(&sc->sc_vd, sc, &cgfour_defaultscreen, &cgfour_accessops);
+ sc->sc_vd.init_screen = cgfour_init_screen;
+
+ if (isconsole) {
+ /* we mess with cgfour_console_screen only once */
+ vcons_init_screen(&sc->sc_vd, &cgfour_console_screen, 1,
+ &defattr);
+ for(bits = (char *)sc->sc_fb.fb_pixels;
+ bits < (char *)sc->sc_fb.fb_pixels + sc->sc_stride * sc->sc_height;
+ bits += 4)
+ memset(bits, (defattr >> 16) & 0xff, 4);
+
+ cgfour_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
+
+ cgfour_defaultscreen.textops = &ri->ri_ops;
+ cgfour_defaultscreen.capabilities = ri->ri_caps;
+ cgfour_defaultscreen.nrows = ri->ri_rows;
+ cgfour_defaultscreen.ncols = ri->ri_cols;
+ sc->sc_vd.active = &cgfour_console_screen;
+ wsdisplay_cnattach(&cgfour_defaultscreen, ri, 0, 0, defattr);
+ vcons_replay_msgbuf(&cgfour_console_screen);
+ } else {
+ /*
+ * we're not the console so we just clear the screen and don't
+ * set up any sort of text display
+ */
+ }
+
+ /* Initialize the default color map. */
+ cgfour_setup_palette(sc);
+
+ wsemul_aa.scrdata = &cgfour_screenlist;
+ wsemul_aa.console = isconsole;
+ wsemul_aa.accessops = &cgfour_accessops;
+ wsemul_aa.accesscookie = &sc->sc_vd;
+ config_found(self, &wsemul_aa, wsemuldisplaydevprint,
+ CFARGS_NONE);
+#endif /* NWSDISPLAY > 0 */
#endif /* SUN4 */
}
@@ -503,4 +620,181 @@
bt->bt_cmap = i << 24;
}
}
+
+#if NWSDISPLAY > 0
+static void
+cgfour_setup_palette(struct cgfour_softc *sc)
+{
+ int i, j;
+
+ j = 0;
+ for (i = 0; i < 256; i++) {
+ sc->sc_cmap.cm_map[i][0] = rasops_cmap[j];
+ j++;
+ sc->sc_cmap.cm_map[i][1] = rasops_cmap[j];
+ j++;
+ sc->sc_cmap.cm_map[i][2] = rasops_cmap[j];
+ j++;
+ }
+ cgfourloadcmap(sc, 0, 256);
+}
+
+static int
+cgfour_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
+ struct lwp *l)
+{
+ /* we'll probably need to add more stuff here */
+ struct vcons_data *vd = v;
+ struct cgfour_softc *sc = vd->cookie;
+ struct wsdisplay_fbinfo *wdf;
+ struct vcons_screen *ms = sc->sc_vd.active;
+ struct rasops_info *ri = &ms->scr_ri;
+ switch (cmd) {
+ case WSDISPLAYIO_GTYPE:
+ *(u_int *)data = WSDISPLAY_TYPE_SUNTCX; /* XXX */
+ return 0;
+ case WSDISPLAYIO_GINFO:
+ wdf = (void *)data;
+ wdf->height = ri->ri_height;
+ wdf->width = ri->ri_width;
+ wdf->depth = 8;
+ wdf->cmsize = 256;
+ return 0;
+
+ case WSDISPLAYIO_GETCMAP:
+ return cgfour_getcmap(sc,
+ (struct wsdisplay_cmap *)data);
+ case WSDISPLAYIO_PUTCMAP:
+ return cgfour_putcmap(sc,
+ (struct wsdisplay_cmap *)data);
+
+ case WSDISPLAYIO_SMODE:
+ {
+ int new_mode = *(int *)data;
+
+ if (new_mode != sc->sc_mode) {
+ sc->sc_mode = new_mode;
+ if (new_mode == WSDISPLAYIO_MODE_EMUL) {
+ cgfour_setup_palette(sc);
+ vcons_redraw_screen(ms);
+ }
+ }
+ }
+ return 0;
+ case WSDISPLAYIO_GET_FBINFO:
+ {
+ struct wsdisplayio_fbinfo *fbi = data;
+
+ return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi);
+ }
+ }
+ return EPASSTHROUGH;
+}
+
+static paddr_t
+cgfour_mmap(void *v, void *vs, off_t offset, int prot)
+{
+ struct vcons_data *vd = v;
+ struct cgfour_softc *sc = vd->cookie;
+ paddr_t cookie = -1;
+
+ switch (sc->sc_mode) {
+ case WSDISPLAYIO_MODE_DUMBFB:
+ if (offset >= 0 && offset >= sc->sc_fb.fb_type.fb_size) {
+ cookie = bus_space_mmap(sc->sc_bustag,
+ sc->sc_paddr, PFOUR_COLOR_OFF_COLOR + offset,
+ prot, BUS_SPACE_MAP_LINEAR);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return cookie;
+}
+
+static int
+cgfour_putcmap(struct cgfour_softc *sc, struct wsdisplay_cmap *cm)
+{
+ u_int index = cm->index;
+ u_int count = cm->count;
+ int error,i;
+ if (index >= 256 || count > 256 || index + count > 256)
+ return EINVAL;
+
+ for (i = 0; i < count; i++)
+ {
+ error = copyin(&cm->red[i],
+ &sc->sc_cmap.cm_map[index + i][0], 1);
+ if (error)
+ return error;
+ error = copyin(&cm->green[i],
+ &sc->sc_cmap.cm_map[index + i][1],
+ 1);
+ if (error)
+ return error;
+ error = copyin(&cm->blue[i],
+ &sc->sc_cmap.cm_map[index + i][2], 1);
+ if (error)
+ return error;
+ }
+ cgfourloadcmap(sc, index, count);
+
+ return 0;
+}
+
+static int
+cgfour_getcmap(struct cgfour_softc *sc, struct wsdisplay_cmap *cm)
+{
+ u_int index = cm->index;
+ u_int count = cm->count;
+ int error,i;
+
+ if (index >= 256 || count > 256 || index + count > 256)
+ return EINVAL;
+
+ for (i = 0; i < count; i++)
+ {
+ error = copyout(&sc->sc_cmap.cm_map[index + i][0],
+ &cm->red[i], 1);
+ if (error)
+ return error;
+ error = copyout(&sc->sc_cmap.cm_map[index + i][1],
+ &cm->green[i], 1);
+ if (error)
+ return error;
+ error = copyout(&sc->sc_cmap.cm_map[index + i][2],
+ &cm->blue[i], 1);
+ if (error)
+ return error;
+ }
+
+ return 0;
+}
+
+static void
+cgfour_init_screen(void *cookie, struct vcons_screen *scr,
+ int existing, long *defattr)
+{
+ struct cgfour_softc *sc = cookie;
+ struct rasops_info *ri = &scr->scr_ri;
+
+ scr->scr_flags |= VCONS_DONT_READ;
+
+ ri->ri_depth = 8;
+ ri->ri_width = sc->sc_width;
+ ri->ri_height = sc->sc_height;
+ ri->ri_stride = sc->sc_stride;
+ ri->ri_flg = RI_CENTER;
+
+ ri->ri_bits = sc->sc_fb.fb_pixels;
+
+ rasops_init(ri, 0, 0);
+ ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_REVERSE;
+ rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
+ sc->sc_width / ri->ri_font->fontwidth);
+
+ ri->ri_hw = scr;
+}
+#endif /* NWSDISPLAY > 0 */
#endif /* SUN4 */
Home |
Main Index |
Thread Index |
Old Index