ref: 83a46e69f4f8497df5e03a7f288de0d84b9ca91b
dir: /qemu-efi.diff/
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);