remove realmode and e820 code from kernel

front
cinap_lenrek 2011-11-05 06:19:52 +01:00
parent d8c69ebafd
commit 563437cb6d
8 changed files with 51 additions and 394 deletions

View File

@ -642,13 +642,6 @@ hexadecimal 64-bit
and and
.I end .I end
addresses of the usable memory areas. 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 .SS \fL*maxmem=\fIvalue\fP
This defines the maximum physical address that the system will scan when sizing memory. 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 By default the PC operating system will scan up to 3.75 gigabytes

View File

@ -989,6 +989,39 @@ archctlwrite(Chan*, void *a, long n, vlong)
return n; 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 void
archinit(void) archinit(void)
{ {
@ -1037,6 +1070,7 @@ archinit(void)
addarchfile("cputype", 0444, cputyperead, nil); addarchfile("cputype", 0444, cputyperead, nil);
addarchfile("archctl", 0664, archctlread, archctlwrite); addarchfile("archctl", 0664, archctlread, archctlwrite);
addarchfile("realmodemem", 0660, rmemread, rmemwrite);
} }
/* /*

View File

@ -309,178 +309,6 @@ TEXT restoreregs(SB), $0
POPL AX POPL AX
RET 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. * BIOS32.
*/ */

View File

@ -60,8 +60,6 @@
#define CONFADDR (KZERO+0x1200) /* info passed from boot loader */ #define CONFADDR (KZERO+0x1200) /* info passed from boot loader */
#define TMPADDR (KZERO+0x2000) /* used for temporary mappings */ #define TMPADDR (KZERO+0x2000) /* used for temporary mappings */
#define APBOOTSTRAP (KZERO+0x3000) /* AP bootstrap code */ #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 RMBUF (KZERO+0x9000) /* buffer for user space - known to vga */
#define IDTADDR (KZERO+0x10800) /* idt */ #define IDTADDR (KZERO+0x10800) /* idt */
#define REBOOTADDR (0x11000) /* reboot code - physical address */ #define REBOOTADDR (0x11000) /* reboot code - physical address */

View File

@ -526,20 +526,10 @@ struct Emap
{ {
uvlong base; uvlong base;
uvlong len; uvlong len;
ulong type;
}; };
static Emap emap[16]; static Emap emap[16];
int nemap; int nemap;
static char *etypes[] =
{
"type=0",
"memory",
"reserved",
"acpi reclaim",
"acpi nvs",
};
static int static int
emapcmp(const void *va, const void *vb) emapcmp(const void *va, const void *vb)
{ {
@ -551,11 +541,7 @@ emapcmp(const void *va, const void *vb)
return -1; return -1;
if(a->base > b->base) if(a->base > b->base)
return 1; return 1;
if(a->len < b->len) return a->len - b->len;
return -1;
if(a->len > b->len)
return 1;
return a->type - b->type;
} }
static void static void
@ -668,66 +654,29 @@ map(ulong base, ulong len, int type)
static int static int
e820scan(void) e820scan(void)
{ {
int i; ulong base, len;
Ureg u;
ulong cont, base, len;
uvlong last; uvlong last;
Emap *e; Emap *e;
char *s; char *s;
int i;
if((s = getconf("e820")) != nil){ /* passed by bootloader */
for(nemap = 0; nemap < nelem(emap); nemap++){ if((s = getconf("e820")) == nil)
if(*s == 0) return -1;
break; for(nemap = 0; nemap < nelem(emap); nemap++){
e = emap + nemap; if(*s == 0)
e->base = strtoull(s, &s, 16); break;
if(*s != ' ') e = emap + nemap;
break; e->base = strtoull(s, &s, 16);
e->len = strtoull(s, &s, 16) - e->base; if(*s != ' ')
if(*s != ' ' && *s != 0 || e->len >= 1ull<<32 || e->len == 0) break;
break; e->len = strtoull(s, &s, 16) - e->base;
e->type = Ememory; if(*s != ' ' && *s != 0 || e->len >= 1ull<<32 || e->len == 0)
} break;
}else{
if(getconf("*norealmode") || getconf("*noe820scan"))
return -1;
cont = 0;
for(i=0; i<nelem(emap); i++){
memset(&u, 0, sizeof u);
u.ax = 0xE820;
u.bx = cont;
u.cx = 20;
u.dx = SMAP;
u.es = (PADDR(RMBUF)>>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;
}
} }
if(nemap == 0) if(nemap == 0)
return -1; return -1;
qsort(emap, nemap, sizeof emap[0], emapcmp); qsort(emap, nemap, sizeof emap[0], emapcmp);
if(s == nil && getconf("*noe820print") == nil){
for(i=0; i<nemap; i++){
e = &emap[i];
print("E820: %.8llux %.8llux ", e->base, e->base+e->len);
if(e->type < nelem(etypes))
print("%s\n", etypes[e->type]);
else
print("type=%lud\n", e->type);
}
}
last = 0; last = 0;
for(i=0; i<nemap; i++){ for(i=0; i<nemap; i++){
e = &emap[i]; e = &emap[i];
@ -747,10 +696,7 @@ e820scan(void)
if(last < e->base) if(last < e->base)
map(last, e->base-last, MemUPA); map(last, e->base-last, MemUPA);
last = base+len; last = base+len;
if(e->type == Ememory) map(base, len, MemRAM);
map(base, len, MemRAM);
else
map(base, len, MemReserved);
} }
if(last < (1LL<<32)) if(last < (1LL<<32))
map(last, (u32int)-last, MemUPA); map(last, (u32int)-last, MemUPA);

View File

@ -38,7 +38,6 @@ dev
link link
segdesc segdesc
realmode
devpccard devpccard
devi82365 devi82365
apm apmjump apm apmjump

View File

@ -39,7 +39,6 @@ dev
link link
segdesc segdesc
realmode
devpccard devpccard
devi82365 devi82365
apm apmjump apm apmjump

View File

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