ref: c88203b29aa39982ea701c083bb0d6bb2ea0483b
parent: 8d8022281735dcf8a6c0c2c52568180e1d4ba17c
author: 9ferno <gophone2015@gmail.com>
date: Thu Sep 16 02:52:09 EDT 2021
cleaned up the memory code
--- a/os/pc/devarch.c
+++ b/os/pc/devarch.c
@@ -477,6 +477,10 @@
print("cpu%d: %dMHz %s %s (AX %8.8uX CX %8.8uX DX %8.8uX)\n",
m->machno, m->cpumhz, m->cpuidid, m->cpuidtype,
m->cpuidax, m->cpuidcx, m->cpuiddx);
+ print(" family %d model %d stepping %d tsc %d\n"
+ " pge %d watchpoint %d\n",
+ m->cpuidfamily, m->cpuidmodel, m->cpuidstepping, m->havetsc,
+ m->havepge, m->havewatchpt8);
}
/*
--- a/os/pc/mp.c
+++ b/os/pc/mp.c
@@ -197,6 +197,8 @@
}
else
ncpu = MAXMACH;
+ if(sizeof(apbootstrap) > 4*KiB)
+ print("mpinit: sizeof(apbootstrap) 0x%x > 4*KiB -- fix it\n", sizeof(apbootstrap));
memmove((void*)APBOOTSTRAP, apbootstrap, sizeof(apbootstrap));
for(i=0; i<nelem(mpapic); i++){
if((apic = mpapic[i]) == nil)
--- a/os/pc64/apbootstrap.i
+++ b/os/pc64/apbootstrap.i
@@ -1,21 +1,21 @@
uchar apbootstrap[]={
-0xea,0x30,0x70,0x00,0x00,0x90,0x90,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xea,0x30,0x50,0x00,0x00,0x90,0x90,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
-0x8c,0xc8,0x8e,0xd8,0x0f,0x01,0x16,0xff,0x70,0x0f,0x20,0xc0,0x83,0xc8,0x01,0x0f,
-0x22,0xc0,0xeb,0x00,0xea,0x49,0x70,0x18,0x00,0x66,0xb8,0x10,0x00,0x8e,0xd8,0x8e,
-0xc0,0x8e,0xe0,0x8e,0xe8,0x8e,0xd0,0x8b,0x05,0x10,0x70,0x00,0x00,0x0f,0x22,0xd8,
+0x8c,0xc8,0x8e,0xd8,0x0f,0x01,0x16,0xfd,0x50,0x0f,0x20,0xc0,0x83,0xc8,0x01,0x0f,
+0x22,0xc0,0xeb,0x00,0xea,0x49,0x50,0x18,0x00,0x66,0xb8,0x10,0x00,0x8e,0xd8,0x8e,
+0xc0,0x8e,0xe0,0x8e,0xe8,0x8e,0xd0,0x8b,0x05,0x10,0x50,0x00,0x00,0x0f,0x22,0xd8,
0xeb,0x00,0x0f,0x20,0xe0,0x83,0xe0,0xef,0x0d,0xa0,0x00,0x00,0x00,0x0f,0x22,0xe0,
-0xb9,0x80,0x00,0x00,0xc0,0x0f,0x32,0x0b,0x05,0x28,0x70,0x00,0x00,0x0f,0x30,0x0f,
+0xb9,0x80,0x00,0x00,0xc0,0x0f,0x32,0x0b,0x05,0x28,0x50,0x00,0x00,0x0f,0x30,0x0f,
0x20,0xc2,0x81,0xe2,0xf5,0xff,0xff,0x9f,0x81,0xca,0x00,0x00,0x01,0x80,0x0f,0x22,
-0xc2,0xea,0x98,0x70,0x00,0x00,0x08,0x00,0x48,0xc7,0xc0,0x0f,0x71,0x00,0x80,0x0f,
-0x01,0x10,0x48,0x31,0xc0,0x8e,0xd8,0x8e,0xc0,0x8e,0xe0,0x8e,0xe8,0x8e,0xd0,0x0f,
-0x00,0xd0,0x48,0x8b,0x24,0x25,0x20,0x70,0x00,0x80,0x49,0x89,0xc6,0x49,0x89,0xe7,
-0x48,0x81,0xc4,0x00,0x80,0x00,0x00,0x50,0x9d,0x48,0x8b,0x04,0x25,0x08,0x70,0x00,
-0x80,0x48,0x8b,0x2c,0x25,0x18,0x70,0x00,0x80,0x55,0xff,0xd0,0xf4,0xeb,0xfd,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x9a,0xaf,0x00,0xff,
-0xff,0x00,0x00,0x00,0x92,0xcf,0x00,0xff,0xff,0x00,0x00,0x00,0x9a,0xcf,0x00,0x1f,
-0x00,0xdf,0x70,0x00,0x00,0x1f,0x00,0xdf,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,
-0x00,0xdf,0x70,0x00,0x80,0xff,0xff,0xff,0xff,
+0xc2,0xea,0x98,0x50,0x00,0x00,0x08,0x00,0xb8,0x0d,0x51,0x00,0x00,0x0f,0x01,0x10,
+0x48,0x31,0xc0,0x8e,0xd8,0x8e,0xc0,0x8e,0xe0,0x8e,0xe8,0x8e,0xd0,0x0f,0x00,0xd0,
+0x48,0x8b,0x24,0x25,0x20,0x50,0x00,0x00,0x49,0x89,0xc6,0x49,0x89,0xe7,0x48,0x81,
+0xc4,0x00,0x00,0x01,0x00,0x50,0x9d,0x48,0x8b,0x04,0x25,0x08,0x50,0x00,0x00,0x48,
+0x8b,0x2c,0x25,0x18,0x50,0x00,0x00,0x55,0xff,0xd0,0xf4,0xeb,0xfd,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x9a,0xaf,0x00,0xff,0xff,0x00,
+0x00,0x00,0x92,0xcf,0x00,0xff,0xff,0x00,0x00,0x00,0x9a,0xcf,0x00,0x1f,0x00,0xdd,
+0x50,0x00,0x00,0x1f,0x00,0xdd,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x00,0xdd,
+0x50,0x00,0x00,0x00,0x00,0x00,0x00,
};
--- a/os/pc64/apbootstrap.s
+++ b/os/pc64/apbootstrap.s
@@ -1,29 +1,4 @@
-#include "mem.h"
-
-#define NOP BYTE $0x90 /* NOP */
-#define LGDT(gdtptr) BYTE $0x0F; /* LGDT */ \
- BYTE $0x01; BYTE $0x16; \
- WORD $gdtptr
-#define FARJUMP16(s, o) BYTE $0xEA; /* far jump to ptr16:16 */ \
- WORD $o; WORD $s; \
- NOP; NOP; NOP
-#define FARJUMP32(s, o) BYTE $0x66; /* far jump to ptr32:16 */ \
- BYTE $0xEA; LONG $o; WORD $s
-
-#define DELAY BYTE $0xEB; /* JMP .+2 */ \
- BYTE $0x00
-#define INVD BYTE $0x0F; BYTE $0x08
-#define WBINVD BYTE $0x0F; BYTE $0x09
-
/*
- * Macros for calculating offsets within the page directory base
- * and page tables. Note that these are assembler-specific hence
- * the '<<2'.
- */
-#define PDO(a) (((((a))>>22) & 0x03FF)<<2)
-#define PTO(a) (((((a))>>12) & 0x03FF)<<2)
-
-/*
* Start an Application Processor. This must be placed on a 4KB boundary
* somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However,
* due to some shortcuts below it's restricted further to within the 1st
@@ -33,19 +8,48 @@
* CS limit set to 64KB;
* CPL and IP set to 0.
*/
-TEXT apbootstrap(SB), $0
- FARJUMP16(0, _apbootstrap(SB))
-TEXT _apvector(SB), $0 /* address APBOOTSTRAP+0x08 */
- LONG $0
-TEXT _appdb(SB), $0 /* address APBOOTSTRAP+0x0C */
- LONG $0
-TEXT _apapic(SB), $0 /* address APBOOTSTRAP+0x10 */
- LONG $0
-TEXT _apbootstrap(SB), $0 /* address APBOOTSTRAP+0x14 */
+#include "mem.h"
+
+#define NOP BYTE $0x90 /* NOP */
+
+#define pFARJMP32(s, o) BYTE $0xea; /* far jmp ptr32:16 */ \
+ LONG $o; WORD $s
+#define rFARJMP16(s, o) BYTE $0xea; /* far jump ptr16:16 */ \
+ WORD $o; WORD $s;
+#define rFARJMP32(s, o) BYTE $0x66; /* far jump ptr32:16 */ \
+ pFARJMP32(s, o)
+
+#define rLGDT(gdtptr) BYTE $0x0f; /* LGDT */ \
+ BYTE $0x01; BYTE $0x16; \
+ WORD $gdtptr
+
+#define rMOVAX(i) BYTE $0xb8; /* i -> AX */ \
+ WORD $i;
+
+#define DELAY BYTE $0xEB; /* JMP .+2 */ \
+ BYTE $0x00
+
+MODE $16
+
+TEXT apbootstrap(SB), 1, $-4
+ rFARJMP16(0, _apbootstrap-KZERO(SB))
+ NOP; NOP; NOP;
+TEXT _apvector(SB), 1, $-4 /* address APBOOTSTRAP+0x08 */
+ QUAD $0
+TEXT _appml4(SB), 1, $-4 /* address APBOOTSTRAP+0x10 */
+ QUAD $0
+TEXT _apapic(SB), 1, $-4 /* address APBOOTSTRAP+0x18 */
+ QUAD $0
+TEXT _apmach(SB), 1, $-4 /* address APBOOTSTRAP+0x20 */
+ QUAD $0
+TEXT _apefer(SB), 1, $-4
+ QUAD $0x100 /* Long Mode Enable */
+
+TEXT _apbootstrap(SB), 1, $-4
MOVW CS, AX
MOVW AX, DS /* initialise DS */
- LGDT(gdtptr(SB)) /* load a basic gdt */
+ rLGDT(_gdtptr32p<>-KZERO(SB)) /* load a basic gdt */
MOVL CR0, AX
ORL $1, AX
@@ -52,7 +56,21 @@
MOVL AX, CR0 /* turn on protected mode */
DELAY /* JMP .+2 */
- BYTE $0xB8; WORD $SELECTOR(1, SELGDT, 0)/* MOVW $SELECTOR(1, SELGDT, 0), AX */
+ rFARJMP16(SELECTOR(3, SELGDT, 0), _ap32-KZERO(SB))
+
+/*
+ * Enable and activate Long Mode. From the manual:
+ * make sure Page Size Extentions are off, and Page Global
+ * Extensions and Physical Address Extensions are on in CR4;
+ * set Long Mode Enable in the Extended Feature Enable MSR;
+ * set Paging Enable in CR0;
+ * make an inter-segment jump to the Long Mode code.
+ * It's all in 32-bit mode until the jump is made.
+ */
+MODE $32
+
+TEXT _ap32(SB), 1, $-4
+ MOVW $SELECTOR(2, SELGDT, 0), AX
MOVW AX, DS
MOVW AX, ES
MOVW AX, FS
@@ -59,52 +77,95 @@
MOVW AX, GS
MOVW AX, SS
- FARJUMP32(SELECTOR(2, SELGDT, 0), _ap32-KZERO(SB))
+ MOVL _appml4-KZERO(SB), AX /* physical address of PML4 */
+ MOVL AX, CR3 /* load the mmu */
+ DELAY
+ MOVL CR4, AX
+ ANDL $~0x00000010, AX /* Page Size */
+ ORL $0x000000A0, AX /* Page Global, Phys. Address */
+ MOVL AX, CR4
+
+ MOVL $0xc0000080, CX /* Extended Feature Enable */
+ RDMSR
+ ORL _apefer-KZERO(SB), AX
+ WRMSR
+
+ MOVL CR0, DX
+ ANDL $~0x6000000a, DX
+ ORL $0x80010000, DX /* Paging Enable, Write Protect */
+ MOVL DX, CR0
+
+ pFARJMP32(SELECTOR(KESEG, SELGDT, 0), _ap64-KZERO(SB))
+
/*
- * For Pentiums and higher, the code that enables paging must come from
- * pages that are identity mapped.
- * To this end double map KZERO at virtual 0 and undo the mapping once virtual
- * nirvana has been obtained.
+ * Long mode. Welcome to 2003.
+ * Jump out of the identity map space;
+ * load a proper long mode GDT;
+ * initialise the stack and call the
+ * C startup code in m->splpc.
*/
-TEXT _ap32(SB), $0
- MOVL _appdb-KZERO(SB), CX /* physical address of PDB */
- MOVL (PDO(KZERO))(CX), DX /* double-map KZERO at 0 */
- MOVL DX, (PDO(0))(CX)
- MOVL CX, CR3 /* load and flush the mmu */
+MODE $64
- MOVL CR0, DX
- ORL $0x80010000, DX /* PG|WP */
- ANDL $~0x6000000A, DX /* ~(CD|NW|TS|MP) */
+TEXT _ap64(SB), 1, $-4
+ MOVQ $_gdtptr64v<>(SB), AX
+ MOVL (AX), GDTR
- MOVL $_appg(SB), AX
- MOVL DX, CR0 /* turn on paging */
- JMP* AX
+ XORQ AX, AX
+ MOVW AX, DS /* not used in long mode */
+ MOVW AX, ES /* not used in long mode */
+ MOVW AX, FS
+ MOVW AX, GS
+ MOVW AX, SS /* not used in long mode */
-TEXT _appg(SB), $0
- MOVL CX, AX /* physical address of PDB */
- ORL $KZERO, AX
- MOVL $0, (PDO(0))(AX) /* undo double-map of KZERO at 0 */
- MOVL CX, CR3 /* load and flush the mmu */
+ MOVW AX, LDTR
- MOVL $(MACHADDR+MACHSIZE-4), SP
+ MOVQ _apmach(SB), SP
- MOVL $0, AX
- PUSHL AX
- POPFL
+ MOVQ AX, RUSER /* up = 0; */
+ MOVQ SP, RMACH /* m = apmach */
- MOVL _apapic(SB), AX
- MOVL AX, (SP)
- MOVL _apvector(SB), AX
- CALL* AX
-_aphalt:
+ ADDQ $MACHSIZE, SP
+
+ PUSHQ AX /* clear flags */
+ POPFQ
+
+ MOVQ _apvector(SB), AX
+ MOVQ _apapic(SB), RARG
+ PUSHQ RARG
+
+ CALL *AX
+
+_halt:
HLT
- JMP _aphalt
+ JMP _halt
+
+TEXT _gdt<>(SB), 1, $-4
+ /* null descriptor */
+ LONG $0
+ LONG $0
-TEXT gdt(SB), $0
- LONG $0x0000; LONG $0
- LONG $0xFFFF; LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
- LONG $0xFFFF; LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
-TEXT gdtptr(SB), $0
- WORD $(3*8-1)
- LONG $gdt-KZERO(SB)
+ /* (KESEG) 64 bit long mode exec segment */
+ LONG $(0xFFFF)
+ LONG $(SEGL|SEGG|SEGP|(0xF<<16)|SEGPL(0)|SEGEXEC|SEGR)
+
+ /* 32 bit data segment descriptor for 4 gigabytes (PL 0) */
+ LONG $(0xFFFF)
+ LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
+
+ /* 32 bit exec segment descriptor for 4 gigabytes (PL 0) */
+ LONG $(0xFFFF)
+ LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
+
+
+TEXT _gdtptr32p<>(SB), 1, $-4
+ WORD $(4*8-1)
+ LONG $_gdt<>-KZERO(SB)
+
+TEXT _gdtptr64p<>(SB), 1, $-4
+ WORD $(4*8-1)
+ QUAD $_gdt<>-KZERO(SB)
+
+TEXT _gdtptr64v<>(SB), 1, $-4
+ WORD $(4*8-1)
+ QUAD $_gdt<>(SB)
--- a/os/pc64/fns.h
+++ b/os/pc64/fns.h
@@ -161,7 +161,7 @@
void poolsizeinit(void);
void procsave(Proc*);
void procsetup(Proc*);
-void punmap(uintptr, vlong);
+void punmap(uintptr, uvlong);
void putcr0(u64);
void putcr2(u64);
void putcr3(u64);
@@ -200,8 +200,8 @@
void upareserve(uintptr, u32);
u64 us2fastticks(u64);
void vectortable(void);
-void* vmap(uintptr, int);
-void vunmap(void*, int);
+void* vmap(uintptr, s32);
+void vunmap(void*, s32);
void wbinvd(void);
s32 wrmsr(ulong, ulong);
int xchgw(ushort*, int);
--- a/os/pc64/main.c
+++ b/os/pc64/main.c
@@ -5,6 +5,7 @@
#include "fns.h"
#include "io.h"
#include "ureg.h"
+#include "rebootcode.i"
#define X86STEPPING(x) ((x) & 0x0F)
#define X86MODEL(x) (((x)>>4) & 0x0F)
@@ -142,6 +143,7 @@
doc("arch->clockinit");
if(arch->clockinit)
arch->clockinit();
+ doc("meminit");
meminit(); /* builds the conf.mem entries */
doc("confinit");
confinit();
@@ -151,12 +153,14 @@
i8237alloc(); */
doc("pcicfginit");
pcicfginit();
+ doc("bootscreeninit");
bootscreeninit(); /* vga maps pages for the frame buffer TODO bug causes an i8042 system reset in poolsizeinit() */
trapinit();
printinit();
cpuidprint();
+ doc("mmuinit");
mmuinit(); /* builds the page tables, lgdt, lidt */
- print("after mmuinit\n");
+ print("poolsizeinit\n");
poolsizeinit();
memmapdump();
eve = strdup("inferno");
--- a/os/pc64/mem.h
+++ b/os/pc64/mem.h
@@ -43,14 +43,15 @@
/*
* Address spaces. Kernel, sorted by address.
*/
-#define KZERO (0) /* with identity mapping, KZERO = 0 */
+#define KZERO (0ull) /* with identity mapping, KZERO = 0 */
/* Leave the 1st MiB to the BIOS (0 to 1MiB-1)
* From the first MiB to KTZERO is used by the global data tables
* acid expects plan9 userspace program text at 2MiB. So, having KTZERO at 2MiB
* 1MiB for l.s data structures (1 to 2MiB-1)
+ * check the e820 memory map to see the available memory
*/
-#define KDZERO (0x100000)
-#define KTZERO (0x200000)
+#define KDZERO (0x100000ull)
+#define KTZERO (0x200000ull)
#define VMAPSIZE (512ull*GiB)
/*
@@ -57,11 +58,17 @@
* Fundamental addresses
*/
#define CONFADDR (0x1200ull) /* info passed from boot loader */
-#define REBOOTADDR (0x11000ull) /* reboot code - physical address */
-#define APBOOTSTRAP (KDZERO+ 0x7000ull) /* AP bootstrap code */
+ /* Both these should be below 1MiB as they are addressed from real
+ * mode which can address only upto 1MiB.
+ * check the e820 memory map to figure out the availble memory below
+ * 1MiB
+ * The intel manual mentions a 4KiB (0x1000) page for ap bootstrap code
+ */
+#define REBOOTADDR (0x4000ull) /* reboot code - physical address */
+#define APBOOTSTRAP (0x5000ull) /* Application Processor (AP) bootstrap code */
#define IDTADDR (KDZERO+0x10000ull) /* idt */
#define GDTADDR (KDZERO+0x11000ull) /* gdt */
-#define CPU0MACH (KDZERO+0x12000ull) /* Mach for bootstrap processor */
+#define CPU0MACH (KDZERO+0x12000ull) /* Mach for bootstrap processor (BSP) */
#define CPU0END (KDZERO+0x22000ull) /* CPU0MACH + (MACHSIZE = 64 KiB = 0x10 000) */
/* MACHSIZE includes stack size */
#define CPU0SP (KDZERO+0x22000ull)
--- a/os/pc64/memory.c
+++ b/os/pc64/memory.c
@@ -30,13 +30,14 @@
u64 MemMin; /* set by l.s */
-/* TODO just use xspanalloc. I do not know what the memmapalloc() does. It does not seem to work anyway. inferno pc does not use it either? can refactor all this code.
- */
void*
rampage(void)
{
- uintptr pa;
+ intptr pa;
+ /* no need to add page tables with pmap() here as
+ * mmuinit() has done it for us
+ */
if(conf.mem[0].npage != 0)
return xspanalloc(BY2PG, BY2PG, 0);
@@ -48,16 +49,20 @@
pa = memmapalloc(-1, BY2PG, BY2PG, MemRAM);
if(pa == -1)
panic("rampage: out of memory\n");
- DP("rampage returned 0x%p\n", pa);
+ DP("rampage returned 0x%p\n", (void*)pa);
+ DP("rampage pmap base 0x%p size %zd 0x%zx\n",
+ (void*)pa, BY2PG+BY2PG, BY2PG+BY2PG);
+ pmap(pa, PTEGLOBAL|PTEWRITE|PTEVALID, BY2PG+BY2PG);
return (void*)pa;
}
+/* maps page tables for the kernel to run */
static void
mapkzero(uintptr base, uintptr len, int type)
{
- uintptr flags, n;
+ uintptr flags;
- DP("mapkzero base 0x%p len %llud 0x%llux type 0x%x\n",
+ print("mapkzero base 0x%p len %llud 0x%llux type 0x%x\n",
base, len, len, type);
if(base < MemMin && base+len > MemMin){
mapkzero(base, MemMin-base, type);
@@ -65,17 +70,26 @@
base = MemMin;
}
+ /* arbitrarily limiting the page table size while the
+ * kernel is still booting
+ */
+ if(base > 1*GiB && type == MemRAM)
+ return;
+ if(base >= MemMin && len > 1*GiB && type == MemRAM){
+ len=2*MemMin;
+ }
switch(type){
default:
return;
case MemRAM:
- if(base < MemMin)
- return;
flags = PTEGLOBAL|PTEWRITE|PTEVALID;
break;
case MemUMB:
flags = PTEGLOBAL|PTEWRITE|PTEUNCACHED|PTEVALID;
break;
+ case MemACPI:
+ flags = PTEGLOBAL|PTEVALID;
+ break;
}
pmap(base, flags, len);
}
@@ -158,6 +172,22 @@
/* Reserve BIOS tables */
memmapadd(pa, 1*KB, MemReserved);
+ /* Allocate memory to be used for reboot code */
+ len=4*KiB /* sizeof(rebootcode) */;
+ memmapadd(PADDR(PGROUND((uintptr)REBOOTADDR)), len, MemRAM);
+ if(memmapalloc(PADDR(PGROUND((uintptr)REBOOTADDR)), len, BY2PG, MemRAM) == -1){
+ print("lowraminit: could not memmapalloc REBOOTADDR 0x%p len 0x%zd\n",
+ PADDR(PGROUND((uintptr)REBOOTADDR)), len);
+ }
+
+ /* Allocate memory to be used for ap bootstrap code */
+ len=4*KiB /*sizeof(apbootstrap)*/;
+ memmapadd(PADDR(PGROUND((uintptr)APBOOTSTRAP)), len, MemRAM);
+ if(memmapalloc(PADDR(PGROUND((uintptr)APBOOTSTRAP)), len, BY2PG, MemRAM) == -1){
+ print("lowraminit: could not memmapalloc APBOOTSTRAP 0x%p len 0x%zd\n",
+ PADDR(PGROUND((uintptr)APBOOTSTRAP)), len);
+ }
+
/* Reserve EBDA */
if((pa = ebdaseg()) != 0)
memmapadd(pa, 1*KB, MemReserved);
@@ -433,6 +463,28 @@
/* RAM needs to be writeback */
mtrrexclude(MemRAM, "wb");
+ /* do not bother allocating page tables for UPA.
+ * UPA users call vmap() to do that.
+ */
+print("e820scan building page tables for the kernel to work\n");
+ for(base = memmapnext(-1, MemRAM); base != -1; base = memmapnext(base, MemRAM)){
+ size = memmapsize(base, BY2PG) & ~(BY2PG-1);
+ if(size != 0)
+ mapkzero(PGROUND(base), size, MemRAM);
+ }
+print("e820scan building page tables after RAM\n");
+ for(base = memmapnext(-1, MemUMB); base != -1; base = memmapnext(base, MemUMB)){
+ size = memmapsize(base, BY2PG) & ~(BY2PG-1);
+ if(size != 0)
+ mapkzero(PGROUND(base), size, MemUMB);
+ }
+print("e820scan building page tables after UMB\n");
+ for(base = memmapnext(-1, MemACPI); base != -1; base = memmapnext(base, MemACPI)){
+ size = memmapsize(base, BY2PG) & ~(BY2PG-1);
+ if(size != 0)
+ mapkzero(PGROUND(base), size, MemACPI);
+ }
+print("e820scan building page tables after ACPI\n");
return 0;
}
@@ -593,27 +645,23 @@
void
meminit0(void)
{
- uintptr prevbase = 0, base, size = 0;
-
print("Memory Configuration\n"
- "\tMemMin 0x%llux end 0x%p KZERO 0x%x KDZERO 0x%x\n"
- "\tKTZERO 0x%x etext 0x%p\n\tCPU0END 0x%llux\n"
- "\tPADDR(PGROUND((uintptr)end)) 0x%zux\n"
- "\tMemMin-PADDR(PGROUND((uintptr)end)) 0x%zux\n",
+ "\tMemMin 0x%llux end 0x%p KZERO 0x%p KDZERO 0x%p\n"
+ "\tKTZERO 0x%p etext 0x%p\n\tCPU0END 0x%p\n"
+ "\tPADDR(PGROUND((uintptr)end)) 0x%p\n"
+ "\tMemMin-PADDR(PGROUND((uintptr)end)) 0x%p\n",
MemMin, end, KZERO, KDZERO, KTZERO, etext, (uintptr)CPU0END,
PADDR(PGROUND((uintptr)end)), MemMin-PADDR(PGROUND((uintptr)end)));
/*
* Add the already mapped memory after the kernel.
- */
- if(MemMin < PADDR(PGROUND((uintptr)end)))
- panic("kernel too big");
- memmapadd(PADDR(PGROUND((uintptr)end)), MemMin-PADDR(PGROUND((uintptr)end)), MemRAM);
-
- /*
* Memory below MemMin is reserved for the kernel.
+ * From KDZERO to MemMin is the kernel's RAM.
* Also, set the kernel text pages read only
*/
- memreserve(PADDR(KDZERO), PADDR(PGROUND((uintptr)MemMin))-PADDR(KDZERO));
+ if(MemMin < PADDR(PGROUND((uintptr)end)))
+ panic("kernel too big");
+ memmapadd(PADDR(KDZERO), PADDR(PGROUND((uintptr)MemMin))-PADDR(KDZERO), MemRAM);
+ memmapalloc(PADDR(KDZERO), PADDR(PGROUND((uintptr)MemMin))-PADDR(KDZERO), BY2PG, MemRAM);
kernelro();
/*
@@ -645,6 +693,9 @@
*/
mtrrexclude(MemUMB, "uc");
mtrrexclude(MemUPA, "uc");
+
+ /* Reserve RAM below MemMin to avoid being trashed */
+ memreserve(KZERO, MemMin);
}
/*
--- a/os/pc64/mkfile
+++ b/os/pc64/mkfile
@@ -12,9 +12,9 @@
#INSTALLDIR=/$OBJTYPE
# must match mem.h
+REBOOTADDR=0x4000
+APBOOTSTRAP=0x5000
KTZERO=0x200000
-APBOOTSTRAP=0x107000
-REBOOTADDR=0x11000
#end configurable parameters
@@ -84,7 +84,7 @@
clock.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
devether.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
fault386.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
-main.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
+main.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h rebootcode.i
trap.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
devether.$O $ETHERS: etherif.h ../port/netif.h
@@ -99,6 +99,16 @@
sdiahci.$O: ahci.h
ether8169.$O: ../port/ethermii.h
+
+$O.rebootcode: rebootcode.$O
+ $LD -l -R1 -s -o $target -T$REBOOTADDR $prereq
+rebootcode.out: $O.rebootcode
+ dd -if $prereq(1) -of $target -bs 1 -iseek 40
+
+$O.apbootstrap: apbootstrap.$O
+ $LD -l -R1 -s -o $target -T$APBOOTSTRAP $prereq
+apbootstrap.out: $O.apbootstrap
+ dd -if $prereq(1) -of $target -bs 1 -iseek 40
# to be moved to port/interp
bench.h:D: ../../module/bench.m
--- a/os/pc64/mmu.c
+++ b/os/pc64/mmu.c
@@ -136,9 +136,7 @@
/* pre allocate pages */
Confmem *cm;
- ulong np, nt;
- np = 0;
for(i=0; i<nelem(conf.mem); i++){
cm = &conf.mem[i];
if(cm->npage == 0)
@@ -145,7 +143,6 @@
continue;
DP("i %d base 0x%p npage 0x%d\n", i, cm->base, cm->npage);
pmap(cm->base, PTEGLOBAL|PTEWRITE|PTENOEXEC|PTEVALID, cm->npage*BY2PG);
-
}
}
@@ -152,6 +149,7 @@
int
mmukmapsync(uintptr va)
{
+USED(va);
return 0;
}
@@ -158,6 +156,7 @@
uintptr
mmukmap(uintptr pa, uintptr va, int size)
{
+USED(pa, va, size);
return 0;
}
@@ -172,7 +171,7 @@
* < cinap_lenrek> vmap() and kmap() are all built ontop of it
*/
void*
-vmap(uintptr pa, int size)
+vmap(uintptr pa, s32 size)
{
int o;
@@ -187,13 +186,14 @@
o = pa & (BY2PG-1);
pa -= o;
size += o;
- pmap(pa, PTEUNCACHED|PTEWRITE|PTENOEXEC|PTEVALID, size);
+ pmap(pa, PTEGLOBAL|PTEUNCACHED|PTEWRITE|PTENOEXEC|PTEVALID, size);
return (void*)(pa+o);
}
void
-vunmap(void *va, int size)
+vunmap(void *va, s32 size)
{
+USED(va, size);
/* nothing to do */
}
@@ -207,7 +207,6 @@
mmucreate(uintptr *table, uintptr pa, int level, int index)
{
uintptr *page, flags;
- MMU *p;
DP("mmucreate table 0x%p pa 0x%p level %d index %d\n",
table, pa, level, index);
@@ -224,12 +223,12 @@
uintptr*
mmuwalk(uintptr* table, uintptr pa, int level, int create)
{
- uintptr pte, flags;
+ uintptr pte /*, flags*/;
int i, x;
DP("mmuwalk table 0x%p pa 0x%p level %d create %d\n",
table, pa, level, create);
- flags = PTEWRITE | PTEVALID;
+ /* flags = PTEWRITE | PTEVALID; */
x = PTLX(pa, 3);
DP("\tpml4 index %d\n", x);
for(i = 2; i >= level; i--){
@@ -290,7 +289,7 @@
/* reducing complexity, use 4096 byte pages all through */
l = 0;
z = PGLSZ(0);
- pte = mmuwalk((uintptr*)PML4ADDR, pa, l, 1);
+ pte = mmuwalk(m->pml4, pa, l, 1);
if(pte == nil){
panic("pmap: pa=%#p size=%lld", pa, size);
}
@@ -304,7 +303,7 @@
}
void
-punmap(uintptr pa, vlong size)
+punmap(uintptr pa, uvlong size)
{
uintptr *pte;
int l;
--- a/os/pc64/screen.c
+++ b/os/pc64/screen.c
@@ -601,7 +601,7 @@
nsize = 64*MB;
print("vgalinearaddr0 paddr 0x%p size 0x%x %d pmap npaddr 0x%p nsize 0x%x %d\n",
paddr, size, size, npaddr, nsize, nsize);
- pmap(npaddr, PTEGLOBAL|PTEUNCACHED|PTEWRITE|PTENOEXEC|PTEVALID, nsize);
+ vmap(npaddr, nsize);
scr->vaddr = (void*)npaddr;
if(allocupa){
--- a/os/pc64/squidboy.c
+++ b/os/pc64/squidboy.c
@@ -35,7 +35,7 @@
uintptr *apbootp, *pml4, *pdp0;
Segdesc *gdt;
Mach *mach;
- uchar *p;
+ uchar *p, *q;
int i;
/*
@@ -62,15 +62,14 @@
MACHP(mach->machno) = mach;
/*
- * map KZERO (note that we share the KZERO (and VMAP)
+ * map KZERO (note that we share the KZERO
* PDP between processors.
*/
pml4[PTLX(KZERO, 3)] = MACHP(0)->pml4[PTLX(KZERO, 3)];
- /* TODO pml4[PTLX(VMAP, 3)] = MACHP(0)->pml4[PTLX(VMAP, 3)]; */
/* double map */
pml4[0] = PADDR(pdp0) | PTEWRITE|PTEVALID;
- /* TODO Why do I need this? Why not use the same page tables for all the processors? pdp0[0] = *mmuwalk(KZERO, 2, 0); */
+ pdp0[0] = *mmuwalk(pml4, KZERO, 2, 0);
/*
* Tell the AP where its kernel vector and pdb are.
--- a/os/port/memmap.c
+++ b/os/port/memmap.c
@@ -234,7 +234,7 @@
unlock(&mapalloc);
}
-uintptr
+intptr
memmapalloc(uintptr addr, uintptr size, uintptr align, u32 type)
{
Mapent *i, *e;
--- a/os/port/portfns.h
+++ b/os/port/portfns.h
@@ -160,7 +160,7 @@
uintptr memmapnext(uintptr, u32);
uintptr memmapsize(uintptr, uintptr);
void memmapadd(uintptr, uintptr, u32);
-uintptr memmapalloc(uintptr, uintptr, uintptr, u32);
+intptr memmapalloc(uintptr, uintptr, uintptr, u32);
void memmapfree(uintptr, uintptr, u32);
int memusehigh(void);
void microdelay(int);
--- a/os/port/portmkfile
+++ b/os/port/portmkfile
@@ -146,4 +146,10 @@
$CONF.root.s $CONF.root.h: $CONF ../init/$INIT.dis ../port/mkroot $ROOTFILES
$SHELLNAME ../port/mkroot $CONF
+%.i:D: %.out
+ {echo 'uchar '^$stem^'[]={'
+ xd -1x <$stem.out |
+ sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
+ echo '};'} > $target
+
%.$O: $ROOT/Inferno/$OBJTYPE/include/u.h ../port/lib.h mem.h dat.h fns.h io.h ../port/error.h ../port/portdat.h ../port/portfns.h