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);