summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/man/8/plan9.ini12
-rw-r--r--sys/src/9/pc/main.c2
-rw-r--r--sys/src/9/pc/screen.c102
3 files changed, 110 insertions, 6 deletions
diff --git a/sys/man/8/plan9.ini b/sys/man/8/plan9.ini
index 09436d9b6..7a441106b 100644
--- a/sys/man/8/plan9.ini
+++ b/sys/man/8/plan9.ini
@@ -831,6 +831,18 @@ If
is set to
.B ask
then the user is prompted for a choice on boot.
+.SS \fL*bootscreen=\fIvalue\fP
+This is used by the kernel to attach a pre-initialized
+linear framebuffer that was setup by the bootloader
+or firmware.
+The
+.I value
+has four space separated fields: the resolution and bitdepth
+of the screen, the color channel descriptor, the physical
+address of the framebuffer and a optional aperture size.
+.EX
+ *bootscreen=800x600x32 x8r8g8b8 0x80000000 0x001d4c00
+.EE
.SS \fL*dpms=\fIvalue\fP
This is used to specify the screen blanking behavior of the MGA4xx
video driver.
diff --git a/sys/src/9/pc/main.c b/sys/src/9/pc/main.c
index f1e40b6de..637895575 100644
--- a/sys/src/9/pc/main.c
+++ b/sys/src/9/pc/main.c
@@ -124,6 +124,7 @@ options(void)
extern void mmuinit0(void);
extern void (*i8237alloc)(void);
+extern void bootscreeninit(void);
void
main(void)
@@ -153,6 +154,7 @@ main(void)
printinit();
cpuidprint();
mmuinit();
+ bootscreeninit();
if(arch->intrinit) /* launches other processors on an mp */
arch->intrinit();
timersinit();
diff --git a/sys/src/9/pc/screen.c b/sys/src/9/pc/screen.c
index de742cd84..37fcc5b91 100644
--- a/sys/src/9/pc/screen.c
+++ b/sys/src/9/pc/screen.c
@@ -13,10 +13,6 @@
#include <cursor.h>
#include "screen.h"
-#define RGB2K(r,g,b) ((156763*(r)+307758*(g)+59769*(b))>>19)
-
-Point ZP = {0, 0};
-
Rectangle physgscreenr;
Memimage *gscreen;
@@ -531,7 +527,6 @@ vgalinearaddr(VGAscr *scr, ulong paddr, int size)
* later, let's assume that we can just allocate the
* entire window to start with.
*/
-
if(scr->paddr == paddr && size <= scr->apsize)
return;
@@ -542,7 +537,7 @@ vgalinearaddr(VGAscr *scr, ulong paddr, int size)
*/
error("cannot grow vga frame buffer");
}
-
+
/* round to page boundary, just in case */
x = paddr&(BY2PG-1);
npaddr = paddr-x;
@@ -560,9 +555,104 @@ vgalinearaddr(VGAscr *scr, ulong paddr, int size)
scr->vaddr = (char*)scr->vaddr+x;
scr->paddr = paddr;
scr->apsize = nsize;
+
/* let mtrr harmlessly fail on old CPUs, e.g., P54C */
if(!waserror()){
mtrr(npaddr, nsize, "wc");
poperror();
}
}
+
+/*
+ * called early on boot to attach to framebuffer
+ * setup by bootloader or firmware.
+ */
+void
+bootscreeninit(void)
+{
+ static Memdata md;
+ VGAscr *scr;
+ int x, y, z;
+ ulong chan, pa, sz;
+ char *s, *p;
+
+ /* *bootscreen=WIDTHxHEIGHTxDEPTH CHAN PA [SZ] */
+ s = getconf("*bootscreen");
+ if(s == nil)
+ return;
+
+ x = strtoul(s, &s, 0);
+ if(x == 0 || *s++ != 'x')
+ return;
+
+ y = strtoul(s, &s, 0);
+ if(y == 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;
+
+ sz = 0;
+ pa = strtoul(p+1, &s, 0);
+ if(pa == 0)
+ return;
+ if(*s++ == ' ')
+ sz = strtoul(s, nil, 0);
+ if(sz < x * y * (z+7)/8)
+ sz = x * y * (z+7)/8;
+
+ /* round to pages */
+ z = pa&(BY2PG-1);
+ pa -= z;
+ sz += z;
+
+ /* map framebuffer */
+ scr = &vgascreen[0];
+ scr->apsize = PGROUND(sz);
+ scr->vaddr = vmap(pa, scr->apsize);
+ if(scr->vaddr == 0){
+ scr->apsize = 0;
+ return;
+ }
+ scr->vaddr = (char*)scr->vaddr + z;
+ scr->paddr = pa + z;
+
+ if(memimageinit() < 0)
+ return;
+
+ md.ref = 1;
+ md.bdata = scr->vaddr;
+ gscreen = allocmemimaged(Rect(0,0,x,y), chan, &md);
+ if(gscreen == nil)
+ return;
+
+ scr->palettedepth = 6; /* default */
+ scr->memdefont = getmemdefont();
+ scr->gscreen = gscreen;
+ scr->gscreendata = gscreen->data;
+ scr->softscreen = 0;
+ scr->useflush = 0;
+ scr->dev = nil;
+
+ hwblank = 0;
+ hwaccel = 0;
+
+ physgscreenr = gscreen->r;
+
+ vgaimageinit(chan);
+ vgascreenwin(scr);
+
+ /* turn mouse cursor on */
+ swcursorinit();
+ scr->cur = &swcursor;
+ scr->cur->enable(scr);
+ cursoron();
+}