Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Mar 2017 17:20:37 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Ravi Pokala <rpokala@mac.com>
Cc:        Bruce Evans <bde@freebsd.org>, src-committers@freebsd.org,  svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   Re: svn commit: r314646 - head/sys/dev/syscons
Message-ID:  <20170316165626.F2172@besplex.bde.org>
In-Reply-To: <B73BD6A4-28FB-4710-85C6-7D6BB683987A@panasas.com>
References:  <201703040847.v248lVZS064744@repo.freebsd.org> <B73BD6A4-28FB-4710-85C6-7D6BB683987A@panasas.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 14 Mar 2017, Ravi Pokala wrote:

> This breaks all sparc64 kernconfs. (And no, this is *not* fixed by r314997.)
>
>    --- syscons.o ---
>    cc1: warnings being treated as errors
>    /usr/home/rpokala/freebsd/clean/base/head/sys/dev/syscons/syscons.c:261: warning: 'ec_scroffset' defined but not used
>    /usr/home/rpokala/freebsd/clean/base/head/sys/dev/syscons/syscons.c:269: warning: 'fake_main_console' defined but not used
>    *** [syscons.o] Error code 1
>
> -----Original Message-----
> [Lost to top posting]

Oops.  I tried to do minimal ifdefs without leaving anything unused.

I'm testing the following more elaborate patch.  It reduces
initialization hacks and finds the frame buffer in a more portable
way.

scr and its scr.vtb_buffer are apparently just optimizations for
x86 only, but they are not ifdefed away on other arches except sparc64.
They are used on all arches expect sparc64 for preserving the initial
screen, which I recently fixed on x86.  I doubt that this actually
works except on x86, but if it does then ec_putc() should work too
(after cninit()).  This depends on the frame buffer address
main_console.sc->adp->va_window being a mapped virtual address at
the base of the frame buffer, with no offsets, and not needing
bus_space to address it, and characters in CGA text encoding.  I think
it often points to pixels, and that is the least of the problems.

In graphics mode, ec_putc() doesn't work, but fails harmlessly (just
returns).  Preserving the initial screen doesn't check, but copies
garbage from the screen to a temporary buffer which is supposed to be
converted to history later, but history is text mode so the copy can't
be converted and might be copied directly, giving garbage in the history
buffer.  That is if the mapping is actually to the screen.  If not,
reading garbage might crash but is otherwise harmless.  Writing to a
garbage address is more dangerous.

This version might be too successful in finding text mode but a garbage
address.  Please check it at runtime.  I think it will usually find
graphics mode and do nothing.

X Index: syscons.c
X ===================================================================
X --- syscons.c	(revision 315183)
X +++ syscons.c	(working copy)
X @@ -260,40 +260,36 @@
X 
X  static	u_int	ec_scroffset;
X 
X -/*
X - * Fake enough of main_console for ec_putc() to work very early on x86 if
X - * the kernel starts in normal color text mode.  On non-x86, scribbling
X - * to the x86 normal color text frame buffer's addresses is unsafe, so
X - * set (likely non-fake) graphics mode to get a null initial ec_putc().
X - */
X -static	scr_stat	fake_main_console = {
X -#ifndef __sparc64__
X -	.scr.vtb_buffer = 0xb8000,
X -#endif
X -	.xsize = 80,
X -	.ysize = 25,
X -#if !defined(__amd64__) && !defined(__i386__)
X -	.status = GRAPHICS_MODE,
X -#endif
X -};
X -
X -#define	main_console	(sc_console == NULL ? fake_main_console : main_console)
X -
X  static void
X  ec_putc(int c)
X  {
X -#ifndef __sparc64__
X +	uintptr_t fb;
X  	u_short *scrptr;
X  	u_int ind;
X  	int attr, column, mysize, width, xsize, yborder, ysize;
X 
X -	if (main_console.status & GRAPHICS_MODE ||
X -	    c < 0 || c > 0xff || c == '\a')
X +	if (c < 0 || c > 0xff || c == '\a')
X  		return;
X -	xsize = main_console.xsize;
X -	ysize = main_console.ysize;
X +	if (sc_console == NULL) {
X +#if !defined(__amd64__) && !defined(__i386__)
X +		return;
X +#endif
X +		/*
X +		 * This is enough for ec_putc() to work very early on x86
X +		 * if the kernel starts in normal color text mode.
X +		 */
X +		fb = 0xb8000;
X +		xsize = 80;
X +		ysize = 25;
X +	} else {
X +		if (main_console.status & GRAPHICS_MODE)
X +			return;
X +		fb = main_console.sc->adp->va_window;
X +		xsize = main_console.xsize;
X +		ysize = main_console.ysize;
X +	}
X  	yborder = ysize / 5;
X -	scrptr = (u_short *)main_console.scr.vtb_buffer + xsize * yborder;
X +	scrptr = (u_short *)(void *)fb + xsize * yborder;
X  	mysize = xsize * (ysize - 2 * yborder);
X  	do {
X  		ind = ec_scroffset;
X @@ -314,11 +310,8 @@
X  	do
X  		scrptr[ind++ % mysize] = (attr << 8) | c;
X  	while (--width != 0);
X -#endif /* !__sparc64__ */
X  }
X 
X -#undef main_console
X -
X  int
X  sc_probe_unit(int unit, int flags)
X  {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20170316165626.F2172>