remove realmode and e820 code from kernel
parent
d8c69ebafd
commit
563437cb6d
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
172
sys/src/9/pc/l.s
172
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.
|
||||
*/
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,14 +654,15 @@ 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){
|
||||
/* passed by bootloader */
|
||||
if((s = getconf("e820")) == nil)
|
||||
return -1;
|
||||
for(nemap = 0; nemap < nelem(emap); nemap++){
|
||||
if(*s == 0)
|
||||
break;
|
||||
|
@ -686,48 +673,10 @@ e820scan(void)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
if(last < (1LL<<32))
|
||||
map(last, (u32int)-last, MemUPA);
|
||||
|
|
|
@ -38,7 +38,6 @@ dev
|
|||
|
||||
link
|
||||
segdesc
|
||||
realmode
|
||||
devpccard
|
||||
devi82365
|
||||
apm apmjump
|
||||
|
|
|
@ -39,7 +39,6 @@ dev
|
|||
|
||||
link
|
||||
segdesc
|
||||
realmode
|
||||
devpccard
|
||||
devi82365
|
||||
apm apmjump
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue