ref: 83a46e69f4f8497df5e03a7f288de0d84b9ca91b
author: kws <kws@cirno>
date: Thu Aug 15 17:20:31 EDT 2024
unfinished qemu efi
--- /dev/null
+++ b/qemu-efi.diff
@@ -1,0 +1,578 @@
+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);