From 563437cb6dca9aa9d50835ba0a4ac346af007332 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sat, 5 Nov 2011 06:19:52 +0100 Subject: [PATCH] remove realmode and e820 code from kernel --- sys/man/8/plan9.ini | 7 -- sys/src/9/pc/devarch.c | 34 ++++++++ sys/src/9/pc/l.s | 172 ---------------------------------------- sys/src/9/pc/mem.h | 2 - sys/src/9/pc/memory.c | 88 ++++---------------- sys/src/9/pc/pccpuf | 1 - sys/src/9/pc/pcf | 1 - sys/src/9/pc/realmode.c | 140 -------------------------------- 8 files changed, 51 insertions(+), 394 deletions(-) delete mode 100644 sys/src/9/pc/realmode.c diff --git a/sys/man/8/plan9.ini b/sys/man/8/plan9.ini index 68d4da96d..ce23d746d 100644 --- a/sys/man/8/plan9.ini +++ b/sys/man/8/plan9.ini @@ -642,13 +642,6 @@ hexadecimal 64-bit and .I end addresses of the usable memory areas. -.SS \fL*norealmode=\fP -The PC kernel switches the processor to 16-bit real mode -to run BIOS interrupts, for example to find the memory map or to enable VESA. -This variable disables such switches. -.SS \fL*noe820scan=\fP -When available, the PC kernel uses the BIOS E820 memory map -to size memory. This variable disables the scan. .SS \fL*maxmem=\fIvalue\fP This defines the maximum physical address that the system will scan when sizing memory. By default the PC operating system will scan up to 3.75 gigabytes diff --git a/sys/src/9/pc/devarch.c b/sys/src/9/pc/devarch.c index 46c98b19c..081607fe3 100644 --- a/sys/src/9/pc/devarch.c +++ b/sys/src/9/pc/devarch.c @@ -989,6 +989,39 @@ archctlwrite(Chan*, void *a, long n, vlong) return n; } +static long +rmemrw(int isr, void *a, long n, vlong off) +{ + if(off < 0 || n < 0) + error("bad offset/count"); + if(isr){ + if(off >= MB) + return 0; + if(off+n >= MB) + n = MB - off; + memmove(a, KADDR((ulong)off), n); + }else{ + /* allow vga framebuf's access */ + if(off >= MB || off+n > MB || + (off < 0xA0000 || off+n > 0xB0000+0x10000)) + error("bad offset/count in write"); + memmove(KADDR((ulong)off), a, n); + } + return n; +} + +static long +rmemread(Chan*, void *a, long n, vlong off) +{ + return rmemrw(1, a, n, off); +} + +static long +rmemwrite(Chan*, void *a, long n, vlong off) +{ + return rmemrw(0, a, n, off); +} + void archinit(void) { @@ -1037,6 +1070,7 @@ archinit(void) addarchfile("cputype", 0444, cputyperead, nil); addarchfile("archctl", 0664, archctlread, archctlwrite); + addarchfile("realmodemem", 0660, rmemread, rmemwrite); } /* diff --git a/sys/src/9/pc/l.s b/sys/src/9/pc/l.s index 4c6fba386..8f8534384 100644 --- a/sys/src/9/pc/l.s +++ b/sys/src/9/pc/l.s @@ -309,178 +309,6 @@ TEXT restoreregs(SB), $0 POPL AX RET -/* - * Assumed to be in protected mode at time of call. - * Switch to real mode, execute an interrupt, and - * then switch back to protected mode. - * - * Assumes: - * - * - no device interrupts are going to come in - * - 0-16MB is identity mapped in page tables - * - realmode() has copied us down from 0x100000 to 0x8000 - * - can use code segment 0x0800 in real mode - * to get at l.s code - * - l.s code is less than 1 page - */ -#define RELOC (RMCODE-KTZERO) - -TEXT realmodeidtptr(SB), $0 - WORD $(4*256-1) - LONG $0 - -TEXT realmode0(SB), $0 - CALL saveregs(SB) - - /* switch to low code address */ - LEAL physcode-KZERO(SB), AX - JMP *AX - -TEXT physcode(SB), $0 - - /* switch to low stack */ - MOVL SP, AX - MOVL $0x7C00, SP - PUSHL AX - - /* change gdt to physical pointer */ - MOVL m0rgdtptr-KZERO(SB), GDTR - - /* load IDT with real-mode version*/ - MOVL realmodeidtptr-KZERO(SB), IDTR - - /* edit INT $0x00 instruction below */ - MOVL $(RMUADDR-KZERO+48), AX /* &rmu.trap */ - MOVL (AX), AX - MOVB AX, realmodeintrinst+(-KZERO+1+RELOC)(SB) - - /* disable paging */ - MOVL CR0, AX - ANDL $0x7FFFFFFF, AX - MOVL AX, CR0 - /* JMP .+2 to clear prefetch queue*/ - BYTE $0xEB; BYTE $0x00 - - /* jump to 16-bit code segment */ -/* JMPFAR SELECTOR(KESEG16, SELGDT, 0):$again16bit(SB) /**/ - BYTE $0xEA - LONG $again16bit-KZERO(SB) - WORD $SELECTOR(KESEG16, SELGDT, 0) - -TEXT again16bit(SB), $0 - /* - * Now in 16-bit compatibility mode. - * These are 32-bit instructions being interpreted - * as 16-bit instructions. I'm being lazy and - * not using the macros because I know when - * the 16- and 32-bit instructions look the same - * or close enough. - */ - - /* disable protected mode and jump to real mode cs */ - OPSIZE; MOVL CR0, AX - OPSIZE; XORL BX, BX - OPSIZE; INCL BX - OPSIZE; XORL BX, AX - OPSIZE; MOVL AX, CR0 - - /* JMPFAR 0x0800:now16real */ - BYTE $0xEA - WORD $now16real-KZERO(SB) - WORD $0x0800 - -TEXT now16real(SB), $0 - /* copy the registers for the bios call */ - LWI(0x0000, rAX) - MOVW AX,SS - LWI(RMUADDR, rBP) - - /* offsets are in Ureg */ - LXW(44, xBP, rAX) - MOVW AX, DS - LXW(40, xBP, rAX) - MOVW AX, ES - - OPSIZE; LXW(0, xBP, rDI) - OPSIZE; LXW(4, xBP, rSI) - OPSIZE; LXW(16, xBP, rBX) - OPSIZE; LXW(20, xBP, rDX) - OPSIZE; LXW(24, xBP, rCX) - OPSIZE; LXW(28, xBP, rAX) - - CLC - -TEXT realmodeintrinst(SB), $0 - INT $0x00 - - /* save the registers after the call */ - - LWI(0x7bfc, rSP) - OPSIZE; PUSHFL - OPSIZE; PUSHL AX - - LWI(0, rAX) - MOVW AX,SS - LWI(RMUADDR, rBP) - - OPSIZE; SXW(rDI, 0, xBP) - OPSIZE; SXW(rSI, 4, xBP) - OPSIZE; SXW(rBX, 16, xBP) - OPSIZE; SXW(rDX, 20, xBP) - OPSIZE; SXW(rCX, 24, xBP) - OPSIZE; POPL AX - OPSIZE; SXW(rAX, 28, xBP) - - MOVW DS, AX - OPSIZE; SXW(rAX, 44, xBP) - MOVW ES, AX - OPSIZE; SXW(rAX, 40, xBP) - - OPSIZE; POPL AX - OPSIZE; SXW(rAX, 64, xBP) /* flags */ - - /* re-enter protected mode and jump to 32-bit code */ - OPSIZE; MOVL $1, AX - OPSIZE; MOVL AX, CR0 - -/* JMPFAR SELECTOR(KESEG, SELGDT, 0):$again32bit(SB) /**/ - OPSIZE - BYTE $0xEA - LONG $again32bit-KZERO(SB) - WORD $SELECTOR(KESEG, SELGDT, 0) - -TEXT again32bit(SB), $0 - MOVW $SELECTOR(KDSEG, SELGDT, 0),AX - MOVW AX,DS - MOVW AX,SS - MOVW AX,ES - MOVW AX,FS - MOVW AX,GS - - /* enable paging and jump to kzero-address code */ - MOVL CR0, AX - ORL $0x80010000, AX /* PG|WP */ - MOVL AX, CR0 - LEAL again32kzero(SB), AX - JMP* AX - -TEXT again32kzero(SB), $0 - /* breathe a sigh of relief - back in 32-bit protected mode */ - - /* switch to old stack */ - PUSHL AX /* match popl below for 8l */ - MOVL $0x7BFC, SP - POPL SP - - /* restore idt */ - MOVL m0idtptr(SB),IDTR - - /* restore gdt */ - MOVL m0gdtptr(SB), GDTR - - CALL restoreregs(SB) - RET - /* * BIOS32. */ diff --git a/sys/src/9/pc/mem.h b/sys/src/9/pc/mem.h index 24b8260b3..3a688a675 100644 --- a/sys/src/9/pc/mem.h +++ b/sys/src/9/pc/mem.h @@ -60,8 +60,6 @@ #define CONFADDR (KZERO+0x1200) /* info passed from boot loader */ #define TMPADDR (KZERO+0x2000) /* used for temporary mappings */ #define APBOOTSTRAP (KZERO+0x3000) /* AP bootstrap code */ -#define RMUADDR (KZERO+0x7C00) /* real mode Ureg */ -#define RMCODE (KZERO+0x8000) /* copy of first page of KTEXT */ #define RMBUF (KZERO+0x9000) /* buffer for user space - known to vga */ #define IDTADDR (KZERO+0x10800) /* idt */ #define REBOOTADDR (0x11000) /* reboot code - physical address */ diff --git a/sys/src/9/pc/memory.c b/sys/src/9/pc/memory.c index 33121d647..c1c30d5cf 100644 --- a/sys/src/9/pc/memory.c +++ b/sys/src/9/pc/memory.c @@ -526,20 +526,10 @@ struct Emap { uvlong base; uvlong len; - ulong type; }; static Emap emap[16]; int nemap; -static char *etypes[] = -{ - "type=0", - "memory", - "reserved", - "acpi reclaim", - "acpi nvs", -}; - static int emapcmp(const void *va, const void *vb) { @@ -551,11 +541,7 @@ emapcmp(const void *va, const void *vb) return -1; if(a->base > b->base) return 1; - if(a->len < b->len) - return -1; - if(a->len > b->len) - return 1; - return a->type - b->type; + return a->len - b->len; } static void @@ -668,66 +654,29 @@ map(ulong base, ulong len, int type) static int e820scan(void) { - int i; - Ureg u; - ulong cont, base, len; + ulong base, len; uvlong last; Emap *e; char *s; + int i; - if((s = getconf("e820")) != nil){ - for(nemap = 0; nemap < nelem(emap); nemap++){ - if(*s == 0) - break; - e = emap + nemap; - e->base = strtoull(s, &s, 16); - if(*s != ' ') - break; - e->len = strtoull(s, &s, 16) - e->base; - if(*s != ' ' && *s != 0 || e->len >= 1ull<<32 || e->len == 0) - break; - e->type = Ememory; - } - }else{ - if(getconf("*norealmode") || getconf("*noe820scan")) - return -1; - cont = 0; - for(i=0; i>4)&0xF000; - u.di = PADDR(RMBUF)&0xFFFF; - u.trap = 0x15; - realmode(&u); - cont = u.bx; - if((u.flags&Carry) || u.ax != SMAP || u.cx != 20) - break; - e = &emap[nemap++]; - *e = *(Emap*)RMBUF; - if(u.bx == 0) - break; - } + /* passed by bootloader */ + if((s = getconf("e820")) == nil) + return -1; + for(nemap = 0; nemap < nelem(emap); nemap++){ + if(*s == 0) + break; + e = emap + nemap; + e->base = strtoull(s, &s, 16); + if(*s != ' ') + break; + e->len = strtoull(s, &s, 16) - e->base; + if(*s != ' ' && *s != 0 || e->len >= 1ull<<32 || e->len == 0) + break; } - if(nemap == 0) return -1; - qsort(emap, nemap, sizeof emap[0], emapcmp); - - if(s == nil && getconf("*noe820print") == nil){ - for(i=0; ibase, e->base+e->len); - if(e->type < nelem(etypes)) - print("%s\n", etypes[e->type]); - else - print("type=%lud\n", e->type); - } - } - last = 0; for(i=0; ibase) map(last, e->base-last, MemUPA); last = base+len; - if(e->type == Ememory) - map(base, len, MemRAM); - else - map(base, len, MemReserved); + map(base, len, MemRAM); } if(last < (1LL<<32)) map(last, (u32int)-last, MemUPA); diff --git a/sys/src/9/pc/pccpuf b/sys/src/9/pc/pccpuf index 4605736aa..f1c9d6481 100644 --- a/sys/src/9/pc/pccpuf +++ b/sys/src/9/pc/pccpuf @@ -38,7 +38,6 @@ dev link segdesc - realmode devpccard devi82365 apm apmjump diff --git a/sys/src/9/pc/pcf b/sys/src/9/pc/pcf index f4e31d9eb..053087a99 100644 --- a/sys/src/9/pc/pcf +++ b/sys/src/9/pc/pcf @@ -39,7 +39,6 @@ dev link segdesc - realmode devpccard devi82365 apm apmjump diff --git a/sys/src/9/pc/realmode.c b/sys/src/9/pc/realmode.c deleted file mode 100644 index 7e892a240..000000000 --- a/sys/src/9/pc/realmode.c +++ /dev/null @@ -1,140 +0,0 @@ -#include "u.h" -#include "tos.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "ureg.h" -#include "../port/error.h" - -/* - * Back the processor into real mode to run a BIOS call, - * then return. This must be used carefully, since it - * completely disables hardware interrupts (e.g., the i8259) - * while running. It is *not* using VM86 mode. - * Maybe that's really the right answer, but real mode - * is fine for now. We don't expect to use this very much -- - * just for VGA and APM. - */ -#define realmoderegs (*(Ureg*)RMUADDR) - -#define LORMBUF (RMBUF-KZERO) - -static Ureg rmu; -static Lock rmlock; - -void -realmode(Ureg *ureg) -{ - int s; - ulong cr3; - extern void realmode0(void); /* in l.s */ - - if(getconf("*norealmode")) - return; - - lock(&rmlock); - realmoderegs = *ureg; - - /* copy l.s so that it can be run from 16-bit mode */ - memmove((void*)RMCODE, (void*)KTZERO, 0x1000); - - s = splhi(); - m->pdb[PDX(0)] = m->pdb[PDX(KZERO)]; /* identity map low */ - cr3 = getcr3(); - putcr3(PADDR(m->pdb)); - if (arch) - arch->introff(); - else - i8259off(); - realmode0(); - if(m->tss){ - /* - * Called from memory.c before initialization of mmu. - * Don't turn interrupts on before the kernel is ready! - */ - if (arch) - arch->intron(); - else - i8259on(); - } - m->pdb[PDX(0)] = 0; /* remove low mapping */ - putcr3(cr3); - splx(s); - *ureg = realmoderegs; - unlock(&rmlock); -} - -static long -rtrapread(Chan*, void *a, long n, vlong off) -{ - if(off < 0) - error("badarg"); - if(n+off > sizeof rmu) - n = sizeof rmu - off; - if(n <= 0) - return 0; - memmove(a, (char*)&rmu+off, n); - return n; -} - -static long -rtrapwrite(Chan*, void *a, long n, vlong off) -{ - if(off || n != sizeof rmu) - error("write a Ureg"); - memmove(&rmu, a, sizeof rmu); - /* - * Sanity check - */ - if(rmu.trap == 0x10){ /* VBE */ - rmu.es = (LORMBUF>>4)&0xF000; - rmu.di = LORMBUF&0xFFFF; - }else - error("invalid trap arguments"); - realmode(&rmu); - return n; -} - -static long -rmemrw(int isr, void *a, long n, vlong off) -{ - if(off < 0 || n < 0) - error("bad offset/count"); - if(isr){ - if(off >= MB) - return 0; - if(off+n >= MB) - n = MB - off; - memmove(a, KADDR((ulong)off), n); - }else{ - /* realmode buf page ok, allow vga framebuf's access */ - if(off >= MB || off+n > MB || - (off < LORMBUF || off+n > LORMBUF+BY2PG) && - (off < 0xA0000 || off+n > 0xB0000+0x10000)) - error("bad offset/count in write"); - memmove(KADDR((ulong)off), a, n); - } - return n; -} - -static long -rmemread(Chan*, void *a, long n, vlong off) -{ - return rmemrw(1, a, n, off); -} - -static long -rmemwrite(Chan*, void *a, long n, vlong off) -{ - return rmemrw(0, a, n, off); -} - -void -realmodelink(void) -{ - addarchfile("realmode", 0660, rtrapread, rtrapwrite); - addarchfile("realmodemem", 0660, rmemread, rmemwrite); -} -