shithub: wip

ref: 83a46e69f4f8497df5e03a7f288de0d84b9ca91b
dir: /qemu-efi.diff/

View raw version
diff a584d29458e3fec3e1e3162068fc5ab516a2d00e uncommitted
--- a/sys/src/9/arm64/fns.h
+++ b/sys/src/9/arm64/fns.h
@@ -171,3 +171,6 @@
 
 /* bootargs */
 extern void bootargsinit(void);
+
+/* screen */
+extern void bootscreeninit(void);
--- a/sys/src/9/arm64/main.c
+++ b/sys/src/9/arm64/main.c
@@ -156,7 +156,7 @@
 }
 
 void
-main(void)
+main()
 {
 	machinit();
 	if(m->machno){
@@ -189,6 +189,7 @@
 	procinit0();
 	initseg();
 	links();
+	bootscreeninit();
 	chandevreset();
 	userinit();
 	mpinit();
--- a/sys/src/9/arm64/mkfile
+++ b/sys/src/9/arm64/mkfile
@@ -69,21 +69,24 @@
 	/$objtype/lib/libc.a\
 #	/$objtype/lib/libdtracy.a\
 
-9:V:	$p$CONF $p$CONF.u
+9:V:	$p$CONF s$p$CONF $p$CONF.u
 
-$p$CONF.u:D:	$p$CONF
-	aux/aout2uimage -Z$kzero $p$CONF
+$p$CONF:DQ:	$OBJ $CONF.$O $LIB
+	$LD -s -l -o $target -H6 -R0x10000 -T$loadaddr $prereq
 
-$p$CONF:D:	$OBJ $CONF.$O $LIB
+s$p$CONF:D:	$OBJ $CONF.$O $LIB
 	$LD -o $target -T$loadaddr -l $prereq
 	size $target
 
+$p$CONF.u:D:	s$p$CONF
+	aux/aout2uimage -Z$kzero -o $p$CONF.u s$p$CONF
+
 $OBJ: $HFILES
 
 install:V: /$objtype/$p$CONF
 
-/$objtype/$p$CONF:D: $p$CONF $p$CONF.u
-	cp -x $p$CONF $p$CONF.u /$objtype/
+/$objtype/$p$CONF:D: $p$CONF s$p$CONF $p$CONF.u
+	cp -x $p$CONF s$p$CONF $p$CONF.u /$objtype/
 
 <../boot/bootmkfile
 <../port/portmkfile
@@ -100,4 +103,4 @@
 	$LD -l -H6 -R1 -T0x40020000 -s -o $target $prereq
 
 $CONF.clean:
-	rm -rf $p$CONF $p$CONF.u errstr.h $CONF.c boot$CONF.c
+	rm -rf $p$CONF s$p$CONF $p$CONF.u errstr.h $CONF.c boot$CONF.c
--- a/sys/src/9/arm64/qemu
+++ b/sys/src/9/arm64/qemu
@@ -15,6 +15,8 @@
 	ether	netif
 	bridge	log
 	ip	arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
+	draw	screen swcursor
+	mouse	screen swcursor
 	uart
 	usb
 	rtc
--- /dev/null
+++ b/sys/src/9/arm64/screen.c
@@ -1,0 +1,369 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+
+#define	Image	IMAGE
+#include <draw.h>
+#include <memdraw.h>
+#include <cursor.h>
+#include "screen.h"
+
+enum {
+	Tabstop		= 4,
+	Scroll		= 8,
+};
+
+Memimage *gscreen;
+
+static ulong *fbraw;
+
+static Memimage *conscol;
+static Memimage *back;
+static Memsubfont *memdefont;
+
+static Lock screenlock;
+
+static Point	curpos;
+static int	h, w;
+static Rectangle window;
+
+static void myscreenputs(char *s, int n);
+static void screenputc(char *buf);
+static void screenwin(void);
+
+enum
+{
+	CMaccelerated,
+	CMlinear,
+};
+
+static Cmdtab mousectlmsg[] =
+{
+	CMaccelerated,		"accelerated",		0,
+	CMlinear,		"linear",		1,
+};
+
+void
+mousectl(Cmdbuf *cb)
+{
+	Cmdtab *ct;
+
+	ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
+	switch(ct->index){
+	case CMaccelerated:
+		mouseaccelerate(cb->nf == 1? 1: atoi(cb->f[1]));
+		break;
+	case CMlinear:
+		mouseaccelerate(0);
+		break;
+	}
+}
+
+void
+cursoron(void)
+{
+	swcursorhide(0);
+	swcursordraw(mousexy());
+}
+
+void
+cursoroff(void)
+{
+	swcursorhide(0);
+}
+
+void
+setcursor(Cursor* curs)
+{
+	swcursorload(curs);
+}
+
+int
+hwdraw(Memdrawparam *par)
+{
+	Memimage *dst, *src, *mask;
+	uchar *scrd;
+
+	if((dst = par->dst) == nil || dst->data == nil)
+		return 0;
+	if((src = par->src) && src->data == nil)
+		src = nil;
+	if((mask = par->mask) && mask->data == nil)
+		mask = nil;
+
+	scrd = gscreen->data->bdata;
+	if(dst->data->bdata == scrd)
+		swcursoravoid(par->r);
+	if(src && src->data->bdata == scrd)
+		swcursoravoid(par->sr);
+	if(mask && mask->data->bdata == scrd)
+		swcursoravoid(par->mr);
+
+	return 0;
+}
+
+void
+bootscreeninit()
+{
+	int width, height, z;
+	uvlong pa;
+	ulong chan;
+	char *s, *p;
+
+	/* *bootscreen=WIDTHxHEIGHTxDEPTH CHAN PA [SZ] */
+	s = getconf("*bootscreen");
+	if(s == nil)
+		return;
+
+	width = strtoul(s, &s, 0);
+	if(width == 0 || *s++ != 'x')
+		return;
+
+	height = strtoul(s, &s, 0);
+	if(height == 0 || *s++ != 'x')
+		return;
+
+	z = strtoul(s, &s, 0);
+	if(*s != ' ')
+		return;
+	if((p = strchr(++s, ' ')) == nil)
+		return;
+	*p = 0;
+	chan = strtochan(s);
+	*p = ' ';
+	if(chan == 0 || chantodepth(chan) != z)
+		return;
+
+	pa = strtoull(p+1, &s, 0);
+	if(pa == 0)
+		return;
+
+	memimageinit();
+
+	gscreen = allocmemimage(Rect(0, 0, width, height), chan);
+	if(gscreen == nil)
+		return;
+
+	conf.monitor = 1;
+	fbraw = vmap(pa, PGROUND(gscreen->width*sizeof(ulong)*height));
+
+	memdefont = getmemdefont();
+	screenwin();
+	myscreenputs(kmesg.buf, kmesg.n);
+	screenputs = myscreenputs;
+	swcursorinit();
+}
+
+void
+flushmemscreen(Rectangle r)
+{
+	int pitch, n;
+	ulong *d, *s;
+
+	if(!rectclip(&r, gscreen->r))
+		return;
+
+	s = wordaddr(gscreen, r.min);
+	d = fbraw + (s - wordaddr(gscreen, gscreen->r.min));
+	n = bytesperline(r, gscreen->depth);
+	pitch = wordsperline(gscreen->r, gscreen->depth);
+	while(r.min.y++ < r.max.y){
+		memmove(d, s, n);
+		d += pitch;
+		s += pitch;
+	}
+}
+
+Memdata*
+attachscreen(Rectangle *r, ulong *chan, int *d, int *width, int *softscreen)
+{
+	if(gscreen == nil)
+		return nil;
+
+	*r = gscreen->r;
+	*d = gscreen->depth;
+	*chan = gscreen->chan;
+	*width = gscreen->width;
+	*softscreen = 1;
+
+	gscreen->data->ref++;
+	return gscreen->data;
+}
+
+void
+getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb)
+{
+	USED(p, pr, pg, pb);
+}
+
+int
+setcolor(ulong p, ulong r, ulong g, ulong b)
+{
+	USED(p, r, g, b);
+	return 0;
+}
+
+static void
+myscreenputs(char *s, int n)
+{
+	int i;
+	Rune r;
+	char buf[4];
+
+	if(!islo()) {
+		/* don't deadlock trying to print in interrupt */
+		if(!canlock(&screenlock))
+			return;	
+	}
+	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);
+}
+
+static void
+screenwin(void)
+{
+	char *greet;
+	Memimage *orange;
+	Point p, q;
+	Rectangle r;
+
+	back = memblack;
+	conscol = memwhite;
+
+	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 = gscreen->r;
+	memimagedraw(gscreen, r, memwhite, ZP, memopaque, ZP, S);
+	window = insetrect(r, 4);
+	memimagedraw(gscreen, window, memblack, 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 void
+scroll(void)
+{
+	int o;
+	Point p;
+	Rectangle r;
+
+	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);
+	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;
+}
+
+static void
+screenputc(char *buf)
+{
+	int w;
+	uint pos;
+	Point p;
+	Rectangle r;
+	static int *xp;
+	static int xbuf[256];
+
+	if (xp < xbuf || xp >= &xbuf[nelem(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;
+		break;
+	}
+}
+
+void
+blankscreen(int blank)
+{
+	USED(blank);
+}
--- /dev/null
+++ b/sys/src/9/arm64/screen.h
@@ -1,0 +1,31 @@
+/* devmouse.c */
+typedef struct Cursor Cursor;
+extern Cursor cursor;
+extern void mousetrack(int, int, int, ulong);
+extern void absmousetrack(int, int, int, ulong);
+extern Point mousexy(void);
+extern void mouseaccelerate(int);
+
+/* screen.c */
+extern void	blankscreen(int);
+extern void	flushmemscreen(Rectangle);
+extern Memdata*	attachscreen(Rectangle*, ulong*, int*, int*, int*);
+extern void	cursoron(void);
+extern void	cursoroff(void);
+extern void	setcursor(Cursor*);
+
+extern void mousectl(Cmdbuf*);
+extern void mouseresize(void);
+extern void mouseredraw(void);
+
+/* devdraw.c */
+extern QLock	drawlock;
+
+#define ishwimage(i)	1		/* for ../port/devdraw.c */
+
+/* swcursor.c */
+void		swcursorhide(int);
+void		swcursoravoid(Rectangle);
+void		swcursordraw(Point);
+void		swcursorload(Cursor *);
+void		swcursorinit(void);
--- a/sys/src/boot/efi/aa64.s
+++ b/sys/src/boot/efi/aa64.s
@@ -86,7 +86,7 @@
 
 TEXT jump(SB), 1, $-4
 	MOV	R0, R3
-	MOV	R1, R4
+	MOV	0x08(FP), R4
 	BL	mmudisable<>(SB)
 	MOV	R4, R0
 	B	(R3)
--- a/sys/src/boot/efi/sub.c
+++ b/sys/src/boot/efi/sub.c
@@ -1,7 +1,6 @@
 #include <u.h>
 #include <a.out.h>
 #include "fns.h"
-#include "mem.h"
 
 char hex[] = "0123456789abcdef";
 
@@ -337,16 +336,43 @@
 	return ((uvlong)p[0]<<56) | ((uvlong)p[1]<<48) | ((uvlong)p[2]<<40) | ((uvlong)p[3]<<32) | ((uvlong)p[4]<<24) | ((uvlong)p[5]<<16) | ((uvlong)p[6]<<8) | (uvlong)p[7];
 }
 
+uintptr
+rnd(uintptr v, long r)
+{
+	long c;
+
+	v += r - 1;
+	c = v % r;
+	if(c < 0)
+		c += r;
+	v -= c;
+	return v;
+}
+
 char*
 bootkern(void *f)
 {
 	uchar *e, *d, *t;
-	ulong n;
+	ulong n, mask, align;
 	Exec ex;
 
 	if(readn(f, &ex, sizeof(ex)) != sizeof(ex))
 		return "bad header";
 
+	switch(beswal(ex.magic)){
+	case S_MAGIC:
+	case I_MAGIC:
+		mask = 0x0FFFFFFFUL;
+		align = 0x1000;
+		break;
+	case R_MAGIC:
+		mask = 0x7FFFFFFFUL;
+		align = 0x10000;
+		break;
+	default:
+		return "bad magic";
+	}
+
 	e = (uchar*)(beswal(ex.entry) & ~0xF0000000UL);
 	switch(beswal(ex.magic)){
 	case S_MAGIC:
@@ -354,7 +380,7 @@
 		if(readn(f, &e, 8) != 8)
 			goto Error;
 		/* load low address */
-		e = (uchar*)(beswall((uvlong)e) & 0x0FFFFFFFUL);
+		e = (uchar*)(beswall((uvlong)e) & mask);
 		break;
 	case I_MAGIC:
 		break;
@@ -367,14 +393,14 @@
 	if(readn(f, t, n) != n)
 		goto Error;
 	t += n;
-	d = (uchar*)PGROUND((uintptr)t);
+	d = (uchar*)rnd((uintptr)t, align);
 	memset(t, 0, d - t);
 	n = beswal(ex.data);
 	if(readn(f, d, n) != n)
 		goto Error;
 	d += n;
-	t = (uchar*)PGROUND((uintptr)d);
-	t += PGROUND(beswal(ex.bss));
+	t = (uchar*)rnd((uintptr)d, align);
+	t += rnd(beswal(ex.bss), align);
 	memset(d, 0, t - d);
 
 	close(f);