diff options
| -rw-r--r-- | sys/man/8/plan9.ini | 12 | ||||
| -rw-r--r-- | sys/src/9/pc/main.c | 2 | ||||
| -rw-r--r-- | sys/src/9/pc/screen.c | 102 |
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(); +} |
