Browse Source

Add coreboot screen

It gets a little odd as the coreboot screen can be architecture independent, or at least
I think it can. It has no IO ports or anything.

Change-Id: I88c71707b36f2f7ae50217da31541bfce7e4caaf
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Ronald G. Minnich 8 years ago
parent
commit
c28f841b61

+ 13 - 0
sys/src/9/boot/bootrc.c

@@ -20,6 +20,19 @@ configrc(Method* m)
 	configloopback();
 	bind("#S", "/dev", MAFTER);
 	char *argv[] = {"rc", "-m", "/boot/rcmain", "-i", 0,};
+	print("Step 1. Run an rc. Set things up.\n");
+	switch(fork()){
+	case -1:
+		print("configrc: fork failed: %r\n");
+	case 0:
+		exec("/boot/rc", argv);
+		fatal("can't exec rc");
+	default:
+		break;
+	}
+	while(waitpid() != -1)
+		;
+	print("Step 2. Run an rc. Verify that things are as you want them.\n");
 	switch(fork()){
 	case -1:
 		print("configrc: fork failed: %r\n");

+ 116 - 0
sys/src/9/k10/k8coreboot.json

@@ -0,0 +1,116 @@
+{
+	"k8cpu": {
+		"Env": [
+			"CONF=k8cpu"
+		],
+		"Include": [
+			"core.json",
+			"../386/386.json",
+			"../ip/ip.json",
+			"../port/port.json"
+		],
+		"Kernel": {
+			"Config": {
+				"Code": [
+					"int cpuserver = 1;",
+					"uint32_t kerndate = 1;"
+				],
+				"Dev": [
+					"acpi",
+					"arch",
+					"cap",
+					"cons",
+					"coreboot",
+					"draw",
+					"dup",
+					"env",
+					"ether",
+					"ip",
+					"kprof",
+					"mnt",
+					"mouse",
+					"pci",
+					"pipe",
+					"pmc",
+					"proc",
+					"regress",
+					"root",
+					"rtc",
+					"sd",
+					"segment",
+					"srv",
+					"ssl",
+					"tls",
+					"uart",
+					"ws",
+					"usb",
+					"zp"
+				],
+				"Ip": [
+					"tcp",
+					"udp",
+					"ipifc",
+					"icmp",
+					"icmp6",
+					"gre"
+				],
+				"Link": [
+					"ether8169",
+					"ether82557",
+					"ether82563",
+					"etherigbe",
+					"ether8139",
+					"ethermedium",
+					"loopbackmedium",
+					"netdevmedium",
+					"usbuhci",
+					"usbohci",
+					"usbehci"
+				],
+				"Sd": [
+					"sdiahci"
+				],
+				"Systab": "/sys/src/libc/9syscall/sys.h",
+				"Uart": [
+					"i8250",
+					"pci"
+				]
+			},
+			"Ramfiles": {
+				"bind": "/amd64/bin/bind",
+				"boot": "/sys/src/9/boot/bootk8cpu.elf.out",
+				"cat": "/amd64/bin/cat",
+				"date": "/amd64/bin/date",
+				"echo": "/amd64/bin/echo",
+				"factotum": "/amd64/bin/auth/factotum",
+				"ipconfig": "/amd64/bin/ip/ipconfig",
+				"ls": "/amd64/bin/ls",
+				"mount": "/amd64/bin/mount",
+				"nvram": "/util/nvram",
+				"rc": "/amd64/bin/rc",
+				"rcmain": "/rc/lib/rcmain",
+				"screenconsole": "/amd64/bin/aux/screenconsole",
+				"srv": "/amd64/bin/srv",
+				"fdisk": "/amd64/bin/disk/fdisk",
+				"prep": "/amd64/bin/disk/prep",
+				"venti": "/amd64/bin/venti/venti",
+				"fossil": "/amd64/bin/fossil/fossil",
+				"startdisk" : "startdisk"
+			}
+		},
+		"Program": "9k8cpu",
+		"SourceFiles": [
+			"cga.c",
+			"devacpi.c",
+			"devusb.c",
+			"ether8139.c",
+			"ether82563.c",
+			"k8cpu.c",
+			"mouse.c",
+			"sdata.c",
+			"usbehcipc.c",
+			"usbohci.c",
+			"usbuhci.c"
+		]
+	}
+}

+ 668 - 0
sys/src/9/port/corebootscreen.c

@@ -0,0 +1,668 @@
+/* 
+ * This file is part of the UCB release of Plan 9. It is subject to the license
+ * terms in the LICENSE file found in the top-level directory of this
+ * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
+ * part of the UCB release of Plan 9, including this file, may be copied,
+ * modified, propagated, or distributed except according to the terms contained
+ * in the LICENSE file.
+ */
+
+/*
+ * Simple coreboot framebuffer screen inspired by the omap code.
+ * coreboot gives us an x by y screen with 24 bpp, 8 of rgb, always.
+ * Note that in the coreboot case, this is architecture-independent code.
+ */
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "ureg.h"
+#include "../port/error.h"
+
+#define	Image	IMAGE
+#include <draw.h>
+#include <memdraw.h>
+#include <cursor.h>
+#include "screen.h"
+#include "corebootscreen.h"
+
+enum {
+	Tabstop	= 4,		/* should be 8 */
+	Scroll	= 8,		/* lines to scroll at one time */
+};
+
+int	drawdebug = 1;
+Point	ZP = {0, 0};
+Cursor	arrow = {
+	{ -1, -1 },
+	{ 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C,
+	  0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04,
+	  0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04,
+	  0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40,
+	},
+	{ 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0,
+	  0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8,
+	  0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8,
+	  0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00,
+	},
+};
+
+static Memdata xgdata;
+
+static Memimage xgscreen =
+{
+	{ 0, 0, 1024, 768 },	/* r */
+	{ 0, 0, 1024, 768 },	/* clipr */
+	24,			/* depth */
+	3,			/* nchan */
+	RGB24,			/* chan */
+	nil,			/* cmap */
+	&xgdata,		/* data */
+	0,			/* zero */
+	1024*768*40, 	/* width in words of a single scan line */
+	0,			/* layer */
+	0,			/* flags */
+};
+
+Memimage *gscreen;
+static CorebootScreen Cbscreen;
+static Memimage *conscol;
+static Memimage *back;
+static Corebootfb *framebuf;
+static Memsubfont *memdefont;
+
+//static Lock screenlock;
+
+static Point	curpos;
+static int	h, w;
+static int	landscape = 0;	/* screen orientation, default is 0: portrait */
+//static uint32_t	*vscreen;	/* virtual screen */
+static Rectangle window;
+
+static struct VGAdev cbvgadev = {
+	.name =  "coreboot",
+/*		
+		
+		void	(*enable)(VGAscr*);
+		void	(*disable)(VGAscr*);
+		void	(*page)(VGAscr*, int);
+		void	(*linear)(VGAscr*, int, int);
+		void	(*drawinit)(VGAscr*);
+		int	(*fill)(VGAscr*, Rectangle, uint32_t);
+		void	(*ovlctl)(VGAscr*, Chan*, void*, int);
+		int	(*ovlwrite)(VGAscr*, void*, int, int64_t);
+		void (*flush)(VGAscr*, Rectangle);
+*/
+
+};
+
+struct VGAcur cbvgacur = {
+	"coreboot",
+/*
+	void	(*enable)(VGAscr*);
+	void	(*disable)(VGAscr*);
+	void	(*load)(VGAscr*, Cursor*);
+	int	(*move)(VGAscr*, Point);
+
+	int	doespanning;
+*/
+};
+
+
+static int scroll(VGAscr*, Rectangle, Rectangle);
+
+// for devdraw
+VGAscr vgascreen[1] = {
+	{
+	.dev = &cbvgadev,
+	.cur = &cbvgacur,
+	.gscreen = &xgscreen,
+//	.memdefont = memdefont,
+	.scroll = scroll,
+	},
+};
+
+//static	void	corebootscreenputs(char *s, int n);
+//static	uint32_t rep(uint32_t, int);
+//static	void	screenputc(char *buf);
+static	void	screenwin(void);
+
+/*
+ * Software cursor. 
+ */
+int	swvisible;	/* is the cursor visible? */
+int	swenabled;	/* is the cursor supposed to be on the screen? */
+Memimage*	swback;	/* screen under cursor */
+Memimage*	swimg;	/* cursor image */
+Memimage*	swmask;	/* cursor mask */
+Memimage*	swimg1;
+Memimage*	swmask1;
+
+Point	swoffset;
+Rectangle	swrect;	/* screen rectangle in swback */
+Point	swpt;	/* desired cursor location */
+Point	swvispt;	/* actual cursor location */
+int	swvers;	/* incremented each time cursor image changes */
+int	swvisvers;	/* the version on the screen */
+
+static void
+lcdoff(void)
+{
+	print("LCD OFF\n");
+	delay(20);			/* worst case for 1 frame, 50Hz */
+}
+
+static void
+lcdon(int enable)
+{
+	print("%s\n", __func__);
+	print("LCD ON\n");
+	delay(10);
+}
+
+static void
+lcdstop(void)
+{
+	print("%s\n", __func__);
+	lcdoff();
+	print("lcdstop\n");
+}
+
+static void
+lcdinit(void)
+{
+	print("%s\n", __func__);
+	print("lcdinit\n");
+	lcdstop();
+
+}
+
+/* Paint the image data with blue pixels */
+void
+screentest(void)
+{
+	int i;
+
+	print("%s\n", __func__);
+	for (i = sizeof(framebuf->pixel)/sizeof(framebuf->pixel[0]) - 1; i >= 0; i--)
+		framebuf->pixel[i] = 0x1f;			/* blue */
+//	memset(framebuf->pixel, ~0, sizeof framebuf->pixel);	/* white */
+}
+
+void
+screenpower(int on)
+{
+	print("%s\n", __func__);
+	blankscreen(on == 0);
+}
+
+/*
+ * called with drawlock locked for us, most of the time.
+ * kernel prints at inopportune times might mean we don't
+ * hold the lock, but memimagedraw is now reentrant so
+ * that should be okay: worst case we get cursor droppings.
+ */
+void
+swcursorhide(void)
+{
+	print("%s\n", __func__);
+	if(swvisible == 0)
+		return;
+	if(swback == nil)
+		return;
+	swvisible = 0;
+	memimagedraw(gscreen, swrect, swback, ZP, memopaque, ZP, S);
+	flushmemscreen(swrect);
+}
+
+void
+swcursoravoid(Rectangle r)
+{
+	print("%s\n", __func__);
+	if(swvisible && rectXrect(r, swrect))
+		swcursorhide();
+}
+
+void
+swcursordraw(void)
+{
+	print("%s\n", __func__);
+	if(swvisible)
+		return;
+	if(swenabled == 0)
+		return;
+	if(swback == nil || swimg1 == nil || swmask1 == nil)
+		return;
+//	assert(!canqlock(&drawlock));		// assertion fails on omap
+	swvispt = swpt;
+	swvisvers = swvers;
+	swrect = rectaddpt(Rect(0,0,16,16), swvispt);
+	memimagedraw(swback, swback->r, gscreen, swpt, memopaque, ZP, S);
+	memimagedraw(gscreen, swrect, swimg1, ZP, swmask1, ZP, SoverD);
+	flushmemscreen(swrect);
+	swvisible = 1;
+}
+
+int
+cursoron(int dolock)
+{
+	print("%s\n", __func__);
+	if (dolock)
+		lock(&Cbscreen.l);
+	cursoroff(0);
+	swcursordraw();
+	if (dolock)
+		unlock(&Cbscreen.l);
+	return 0;
+}
+
+void
+cursoroff(int dolock)
+{
+	if (dolock)
+		lock(&Cbscreen.l);
+	swcursorhide();
+	if (dolock)
+		unlock(&Cbscreen.l);
+}
+
+void
+swload(Cursor *curs)
+{
+	print("%s\n", __func__);
+	uint8_t *ip, *mp;
+	int i, j, set, clr;
+
+	if(!swimg || !swmask || !swimg1 || !swmask1)
+		return;
+	/*
+	 * Build cursor image and mask.
+	 * Image is just the usual cursor image
+	 * but mask is a transparent alpha mask.
+	 * 
+	 * The 16x16x8 memimages do not have
+	 * padding at the end of their scan lines.
+	 */
+	ip = byteaddr(swimg, ZP);
+	mp = byteaddr(swmask, ZP);
+	for(i=0; i<32; i++){
+		set = curs->set[i];
+		clr = curs->clr[i];
+		for(j=0x80; j; j>>=1){
+			*ip++ = set&j ? 0x00 : 0xFF;
+			*mp++ = (clr|set)&j ? 0xFF : 0x00;
+		}
+	}
+	swoffset = curs->offset;
+	swvers++;
+	memimagedraw(swimg1,  swimg1->r,  swimg,  ZP, memopaque, ZP, S);
+	memimagedraw(swmask1, swmask1->r, swmask, ZP, memopaque, ZP, S);
+}
+
+/* called from devmouse */
+void
+setcursor(Cursor* curs)
+{
+	print("%s\n", __func__);
+	cursoroff(1);
+	Cbscreen.Cursor = *curs;
+	swload(curs);
+	cursoron(1);
+}
+
+int
+swmove(Point p)
+{
+	print("%s\n", __func__);
+	swpt = addpt(p, swoffset);
+	return 0;
+}
+
+void
+swcursorclock(void)
+{
+	print("%s\n", __func__);
+	int x;
+
+	if(!swenabled)
+		return;
+	swmove(mousexy());
+	if(swvisible && eqpt(swpt, swvispt) && swvers==swvisvers)
+		return;
+
+	x = splhi();
+	if(swenabled)
+	if(!swvisible || !eqpt(swpt, swvispt) || swvers!=swvisvers)
+	if(canqlock(&drawlock)){
+		swcursorhide();
+		swcursordraw();
+		qunlock(&drawlock);
+	}
+	splx(x);
+}
+
+void
+swcursorinit(void)
+{
+	print("%s\n", __func__);
+	static int init;
+
+	if(!init){
+		init = 1;
+		addclock0link(swcursorclock, 10);
+	}
+	if(swback){
+		freememimage(swback);
+		freememimage(swmask);
+		freememimage(swmask1);
+		freememimage(swimg);
+		freememimage(swimg1);
+	}
+
+	swback  = allocmemimage(Rect(0,0,32,32), gscreen->chan);
+	swmask  = allocmemimage(Rect(0,0,16,16), GREY8);
+	swmask1 = allocmemimage(Rect(0,0,16,16), GREY1);
+	swimg   = allocmemimage(Rect(0,0,16,16), GREY8);
+	swimg1  = allocmemimage(Rect(0,0,16,16), GREY1);
+	if(swback==nil || swmask==nil || swmask1==nil || swimg==nil || swimg1 == nil){
+		print("software cursor: allocmemimage fails\n");
+		return;
+	}
+
+	memfillcolor(swmask, DOpaque);
+	memfillcolor(swmask1, DOpaque);
+	memfillcolor(swimg, DBlack);
+	memfillcolor(swimg1, DBlack);
+}
+
+/* called from main and possibly later from devdss to change resolution */
+void
+screeninit(void)
+{
+	print("%s\n", __func__);
+	static int first = 1;
+
+	if (first) {
+		iprint("screeninit...");
+		lcdstop();
+		if (framebuf)
+			free(framebuf);
+		/* mode is 16*32 = 512 */
+		// ?? framebuf = xspanalloc(sizeof *framebuf, 16*32, 0);
+	}
+
+	lcdinit();
+	lcdon(1);
+	if (first) {
+		memimageinit();
+		memdefont = getmemdefont();
+		screentest();
+	}
+
+	xgdata.ref = 1;
+	xgdata.bdata = (uint8_t *)framebuf->pixel;
+
+	gscreen = &xgscreen;
+	gscreen->r = Rect(0, 0, Wid, Ht);
+	gscreen->clipr = gscreen->r;
+	/* width, in words, of a single scan line */
+	gscreen->width = Wid * (Depth / BI2BY) / BY2WD;
+	flushmemscreen(gscreen->r);
+
+	blanktime = 3;				/* minutes */
+
+	if (first) {
+		iprint("on: blue for 3 seconds...");
+		delay(3*1000);
+		iprint("\n");
+
+		screenwin();		/* draw border & top orange bar */
+		// ? screenputs = corebootcreenputs;
+		iprint("screen: frame buffer at %#p for %dx%d\n",
+			framebuf, Cbscreen.wid, Cbscreen.ht);
+
+		swenabled = 1;
+		swcursorinit();		/* needs gscreen set */
+		setcursor(&arrow);
+
+		first = 0;
+	}
+}
+
+/* flushmemscreen should change buffer? */
+void
+flushmemscreen(Rectangle r)
+{
+	print("%s\n", __func__);
+	uintptr_t start, end;
+
+	if (r.min.x < 0)
+		r.min.x = 0;
+	if (r.max.x > Wid)
+		r.max.x = Wid;
+	if (r.min.y < 0)
+		r.min.y = 0;
+	if (r.max.y > Ht)
+		r.max.y = Ht;
+	if (rectclip(&r, gscreen->r) == 0)
+		return;
+	start = (uintptr_t)&framebuf->pixel[r.min.y*Wid + r.min.x];
+	end   = (uintptr_t)&framebuf->pixel[(r.max.y - 1)*Wid + r.max.x -1];
+	print("Flushmemscreen %p %p\n", start, end);
+	// for now. Don't think we need it. cachedwbse((uint32_t *)start, end - start);
+	coherence();
+}
+
+/*
+ * export screen to devdraw
+ */
+uint8_t*
+attachscreen(Rectangle *r, uint32_t *chan, int *d, int *width, int *softscreen)
+{
+	print("%s\n", __func__);
+	*r = gscreen->r;
+	*d = gscreen->depth;
+	*chan = gscreen->chan;
+	*width = gscreen->width;
+	*softscreen = (landscape == 0);
+	return (uint8_t *)gscreen->data->bdata;
+}
+
+void
+getcolor(uint32_t p, uint32_t *pr, uint32_t *pg, uint32_t *pb)
+{
+	print("%s\n", __func__);
+	//USED(p, pr, pg, pb);
+}
+
+int
+setcolor(uint32_t p, uint32_t r, uint32_t g, uint32_t b)
+{
+	print("%s\n", __func__);
+	//USED(p, r, g, b);
+	return 0;
+}
+
+void
+blankscreen(int blank)
+{
+	print("%s\n", __func__);
+	if (blank)
+		lcdon(0);
+	else {
+		lcdinit();
+		lcdon(1);
+	}
+}
+
+/* Not sure if we ever need this ... */
+#if 0
+void
+corebootscreenputs(char *s, int n)
+{
+	print("%s\n", __func__);
+	int i;
+	Rune r;
+	char buf[4];
+
+	if (!islo()) {
+		/* don't deadlock trying to print in interrupt */
+		if (!canlock(&screenlock))
+			return;			/* discard s */
+	} else
+		lock(&screenlock);
+
+	while (n > 0) {
+		i = chartorune(&r, s);
+		if (i == 0) {
+			s++;
+			--n;
+			continue;
+		}
+		memmove(buf, s, i);
+		buf[i] = 0;
+		n -= i;
+		s += i;
+		screenputc(buf);
+	}
+	unlock(&screenlock);
+}
+#endif
+static void
+screenwin(void)
+{
+	print("%s\n", __func__);
+	char *greet;
+	Memimage *orange;
+	Point p; //, q;
+	Rectangle r;
+
+	memsetchan(gscreen, RGB16);
+
+	back = memwhite;
+	conscol = memblack;
+
+	orange = allocmemimage(Rect(0, 0, 1, 1), RGB16);
+	orange->flags |= Frepl;
+	orange->clipr = gscreen->r;
+	orange->data->bdata[0] = 0x40;		/* magic: colour? */
+	orange->data->bdata[1] = 0xfd;		/* magic: colour? */
+
+	w = memdefont->info[' '].width;
+	h = memdefont->height;
+
+	r = insetrect(gscreen->r, 4);
+
+	memimagedraw(gscreen, r, memblack, ZP, memopaque, ZP, S);
+	window = insetrect(r, 4);
+	memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
+
+	memimagedraw(gscreen, Rect(window.min.x, window.min.y,
+		window.max.x, window.min.y + h + 5 + 6), orange, ZP, nil, ZP, S);
+	freememimage(orange);
+	window = insetrect(window, 5);
+
+	greet = " Plan 9 Console ";
+	p = addpt(window.min, Pt(10, 0));
+	//q = memsubfontwidth(memdefont, greet);
+	memimagestring(gscreen, p, conscol, ZP, memdefont, greet);
+	flushmemscreen(r);
+	window.min.y += h + 6;
+	curpos = window.min;
+	window.max.y = window.min.y + ((window.max.y - window.min.y) / h) * h;
+}
+
+static int
+scroll(VGAscr* _1, Rectangle _2, Rectangle _3)
+{
+	print("%s\n", __func__);
+	int o;
+	Point p;
+	Rectangle r;
+
+	/* move window contents up Scroll text lines */
+	o = Scroll * h;
+	r = Rpt(window.min, Pt(window.max.x, window.max.y - o));
+	p = Pt(window.min.x, window.min.y + o);
+	memimagedraw(gscreen, r, gscreen, p, nil, p, S);
+	flushmemscreen(r);
+
+	/* clear the bottom Scroll text lines */
+	r = Rpt(Pt(window.min.x, window.max.y - o), window.max);
+	memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
+	flushmemscreen(r);
+
+	curpos.y -= o;
+	return 0;
+}
+
+#if 0
+void
+screenputc(char *buf)
+{
+	print("%s\n", __func__);
+	int w;
+	uint pos;
+	Point p;
+	Rectangle r;
+	static int *xp;
+	static int xbuf[256];
+
+	if (xp < xbuf || xp >= &xbuf[sizeof(xbuf)])
+		xp = xbuf;
+
+	switch (buf[0]) {
+	case '\n':
+		if (curpos.y + h >= window.max.y)
+			scroll();
+		curpos.y += h;
+		screenputc("\r");
+		break;
+	case '\r':
+		xp = xbuf;
+		curpos.x = window.min.x;
+		break;
+	case '\t':
+		p = memsubfontwidth(memdefont, " ");
+		w = p.x;
+		if (curpos.x >= window.max.x - Tabstop * w)
+			screenputc("\n");
+
+		pos = (curpos.x - window.min.x) / w;
+		pos = Tabstop - pos % Tabstop;
+		*xp++ = curpos.x;
+		r = Rect(curpos.x, curpos.y, curpos.x + pos * w, curpos.y + h);
+		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
+		flushmemscreen(r);
+		curpos.x += pos * w;
+		break;
+	case '\b':
+		if (xp <= xbuf)
+			break;
+		xp--;
+		r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
+		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
+		flushmemscreen(r);
+		curpos.x = *xp;
+		break;
+	case '\0':
+		break;
+	default:
+		p = memsubfontwidth(memdefont, buf);
+		w = p.x;
+
+		if (curpos.x >= window.max.x - w)
+			screenputc("\n");
+
+		*xp++ = curpos.x;
+		r = Rect(curpos.x, curpos.y, curpos.x + w, curpos.y + h);
+		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
+		memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
+		flushmemscreen(r);
+		curpos.x += w;
+	}
+}
+#endif
+

+ 73 - 0
sys/src/9/port/corebootscreen.h

@@ -0,0 +1,73 @@
+/* 
+ * This file is part of the UCB release of Plan 9. It is subject to the license
+ * terms in the LICENSE file found in the top-level directory of this
+ * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
+ * part of the UCB release of Plan 9, including this file, may be copied,
+ * modified, propagated, or distributed except according to the terms contained
+ * in the LICENSE file.
+ */
+
+typedef struct Cursor Cursor;
+typedef struct Cursorinfo	Cursorinfo;
+typedef struct CorebootScreen CorebootScreen;
+typedef struct Corebootfb Corebootfb;
+typedef struct Settings Settings;
+
+extern Cursor	arrow;
+extern Cursorinfo cursor;
+
+/* devmouse.c */
+extern void mousetrack(int, int, int, int);
+extern Point mousexy(void);
+
+extern void	mouseaccelerate(int);
+extern void	mouseresize(void);
+
+/* screen.c */
+extern uint8_t* attachscreen(Rectangle*, uint32_t*, int*, int*, int*);
+extern void	flushmemscreen(Rectangle);
+extern int	cursoron(int);
+extern void	cursoroff(int);
+extern void	setcursor(Cursor*);
+extern int	screensize(int, int, int, uint32_t);
+extern int	screenaperture(int, int);
+extern Rectangle physgscreenr;	/* actual monitor size */
+extern void	blankscreen(int);
+
+extern void swcursorinit(void);
+extern void swcursorhide(void);
+extern void swcursoravoid(Rectangle);
+extern void swcursorunhide(void);
+
+/* devdraw.c */
+extern void	deletescreenimage(void);
+extern void	resetscreenimage(void);
+extern int		drawhasclients(void);
+extern uint32_t	blanktime;
+extern void	setscreenimageclipr(Rectangle);
+extern void	drawflush(void);
+extern int drawidletime(void);
+extern QLock	drawlock;
+
+/* for communication between devdss.c and screen.c */
+
+enum {
+	/* maxima */
+	Wid		= 1280,
+	Ht		= 1024,
+	Depth		= 24,		/* bits per pixel */
+};
+
+struct CorebootScreen {
+	Lock l;
+	Cursor Cursor;
+	uint	wid;		/* width in pixels */
+	uint	ht;		/* height in pixels */
+	int	open;
+};
+
+struct Corebootfb {		/* frame buffer for 24-bit active color */
+	uint8_t *pixel;
+};
+
+

+ 1 - 0
sys/src/9/port/port.json

@@ -15,6 +15,7 @@
 			"../port/awake.c",
 			"../port/cache.c",
 			"../port/chan.c",
+			"../port/corebootscreen.c",
 			"../port/cpu_buffer.c",
 			"../port/dev.c",
 			"../port/devcap.c",