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
.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

View File

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

View File

@ -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.
*/

View File

@ -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 */

View File

@ -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<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;
}
/* 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; 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;
for(i=0; i<nemap; i++){
e = &emap[i];
@ -747,10 +696,7 @@ e820scan(void)
if(last < e->base)
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);

View File

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

View File

@ -39,7 +39,6 @@ dev
link
segdesc
realmode
devpccard
devi82365
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);
}