Basic MP bootup works
This commit is contained in:
parent
658ab8571b
commit
4808b746f5
@ -18,6 +18,8 @@ src_amd64 = [
|
||||
"amd64/irq.c",
|
||||
"amd64/lapic.c",
|
||||
"amd64/machine.c",
|
||||
"amd64/mp.c",
|
||||
"amd64/mpboot.S",
|
||||
"amd64/pci.c",
|
||||
"amd64/pmap.c",
|
||||
"amd64/support.S",
|
||||
|
@ -8,6 +8,7 @@
|
||||
void LAPIC_Init();
|
||||
uint32_t LAPIC_CPU();
|
||||
void LAPIC_SendEOI();
|
||||
void LAPIC_StartAP(uint8_t apicid, uint32_t addr);
|
||||
void LAPIC_Periodic(uint64_t rate);
|
||||
|
||||
#endif /* __LAPIC_H__ */
|
||||
|
@ -47,7 +47,12 @@
|
||||
#define DMPA2VA(pa) ((pa) + MEM_DIRECTMAP_BASE)
|
||||
#define VA2PA(va) PMap_Translate(PMap_CurrentAS(), va)
|
||||
|
||||
typedef struct AS AS;
|
||||
typedef struct AS
|
||||
{
|
||||
PageTable *root;
|
||||
uint64_t tables;
|
||||
uint64_t mappings;
|
||||
} AS;
|
||||
|
||||
void PMap_Init();
|
||||
AS* PMap_NewAS();
|
||||
|
@ -36,6 +36,7 @@
|
||||
#define LAPIC_ICR_FIXED 0x0000 /* Delivery Mode */
|
||||
#define LAPIC_ICR_INIT 0x0500
|
||||
#define LAPIC_ICR_STARTUP 0x0600
|
||||
#define LAPIC_ICR_ASSERT 0x4000
|
||||
#define LAPIC_ICR_TRIG 0x8000
|
||||
#define LAPIC_ICR_SELF 0x00080000 /* Destination */
|
||||
#define LAPIC_ICR_INCSELF 0x00080000
|
||||
@ -110,6 +111,33 @@ LAPIC_Periodic(uint64_t rate)
|
||||
LAPIC_Write(LAPIC_TICR, rate);
|
||||
}
|
||||
|
||||
void
|
||||
LAPIC_StartAP(uint8_t apicid, uint32_t addr)
|
||||
{
|
||||
// Setup CMOS stuff
|
||||
outb(0x70, 0x0F);
|
||||
outb(0x71, 0x0A);
|
||||
uint16_t *cmosStartup = (uint16_t *)DMPA2VA(0x467);
|
||||
cmosStartup[0] = 0;
|
||||
cmosStartup[1] = addr >> 4;
|
||||
|
||||
// Send INIT
|
||||
LAPIC_Write(LAPIC_ICR_HI, apicid << 24);
|
||||
LAPIC_Write(LAPIC_ICR_LO, LAPIC_ICR_INIT | LAPIC_ICR_TRIG | LAPIC_ICR_ASSERT);
|
||||
// XXX: Delay
|
||||
LAPIC_Write(LAPIC_ICR_HI, apicid << 24);
|
||||
LAPIC_Write(LAPIC_ICR_LO, LAPIC_ICR_INIT | LAPIC_ICR_TRIG);
|
||||
// XXX: Delay
|
||||
|
||||
// Send STARTUP
|
||||
LAPIC_Write(LAPIC_ICR_HI, apicid << 24);
|
||||
LAPIC_Write(LAPIC_ICR_LO, LAPIC_ICR_STARTUP | (addr >> 12));
|
||||
// XXX: Delay
|
||||
LAPIC_Write(LAPIC_ICR_HI, apicid << 24);
|
||||
LAPIC_Write(LAPIC_ICR_LO, LAPIC_ICR_STARTUP | (addr >> 12));
|
||||
// XXX: Delay
|
||||
}
|
||||
|
||||
void
|
||||
LAPIC_Init()
|
||||
{
|
||||
|
@ -31,6 +31,10 @@ extern void IDE_Init();
|
||||
extern void MachineBoot_AddMem();
|
||||
extern void Loader_LoadInit();
|
||||
extern void PAlloc_LateInit();
|
||||
extern void MP_Init();
|
||||
|
||||
extern void PMap_InitAP();
|
||||
extern void Trap_InitAP();
|
||||
|
||||
#define GDT_MAX 8
|
||||
|
||||
@ -66,7 +70,7 @@ void Machine_GDTInit()
|
||||
GDT[c][6] = 0x00AFFA000000FFFFULL; /* User CS */
|
||||
GDT[c][7] = 0x00CFF2000000FFFFULL; /* User DS */
|
||||
|
||||
GDTDescriptor[c].off = (uint64_t)&GDT[0];
|
||||
GDTDescriptor[c].off = (uint64_t)&GDT[c];
|
||||
GDTDescriptor[c].lim = 8*GDT_MAX - 1;
|
||||
|
||||
lgdt(&GDTDescriptor[c]);
|
||||
@ -150,6 +154,8 @@ void Machine_Init()
|
||||
|
||||
KTimer_Init(); // Depends on RTC and KTime
|
||||
|
||||
MP_Init();
|
||||
|
||||
PS2_Init();
|
||||
PCI_Init();
|
||||
IDE_Init();
|
||||
@ -173,3 +179,16 @@ void Machine_Init()
|
||||
breakpoint();
|
||||
}
|
||||
|
||||
void Machine_InitAP()
|
||||
{
|
||||
Trap_InitAP();
|
||||
PMap_InitAP();
|
||||
Machine_GDTInit();
|
||||
Machine_TSSInit();
|
||||
//Machine_SyscallInit();
|
||||
|
||||
kprintf("AP %d booted!\n", CPU());
|
||||
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,50 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/kassert.h>
|
||||
#include <sys/kdebug.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/mp.h>
|
||||
|
||||
#include <machine/amd64.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/lapic.h>
|
||||
|
||||
extern uint8_t mpstart_begin[];
|
||||
extern uint8_t mpstart_end[];
|
||||
|
||||
extern AS systemAS;
|
||||
|
||||
void
|
||||
MP_Init()
|
||||
{
|
||||
/*
|
||||
* arg[0] = CR3
|
||||
* arg[1] = RSP
|
||||
*/
|
||||
volatile uint64_t *args = (uint64_t *)DMPA2VA(0x6F00);
|
||||
|
||||
kprintf("Booting on CPU %u\n", CPU());
|
||||
|
||||
kprintf("Starting processor 1\n");
|
||||
memcpy((void *)DMPA2VA(0x7000), mpstart_begin, mpstart_end - mpstart_begin);
|
||||
|
||||
args[0] = DMVA2PA((uint64_t)systemAS.root);
|
||||
args[1] = PGSIZE + (uint64_t)PAlloc_AllocPage();
|
||||
|
||||
kprintf("CR3: %016llx RSP: %016llx\n", args[0], args[1]);
|
||||
|
||||
LAPIC_StartAP(1, 0x7000);
|
||||
|
||||
uint16_t old = 0;
|
||||
uint16_t new;
|
||||
while (1) {
|
||||
new = *((volatile uint16_t*)DMPA2VA(0x7000));
|
||||
if (old != new)
|
||||
kprintf("OLD: %x NEW: %x\n", old, new);
|
||||
old = new;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,172 @@
|
||||
|
||||
#define KERNEL_BASE 0xFFFF800000000000
|
||||
#define LOWMEM(_x) (_x - KERNEL_BASE)
|
||||
#define MPLOWMEM(_x) (_x - KERNEL_BASE + 0x7000)
|
||||
|
||||
.extern bootpgtbl1
|
||||
.extern stack
|
||||
.extern Machine_InitAP
|
||||
|
||||
.text
|
||||
|
||||
.code16
|
||||
.globl mpstart_begin
|
||||
mpstart_begin:
|
||||
cli
|
||||
|
||||
xorw %ax, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
//.byte 0xf1
|
||||
|
||||
# Load 32-bit GDT
|
||||
lgdt (mpstartgdtdesc32 - mpstart_begin + 0x7000)
|
||||
|
||||
movl %cr0, %eax
|
||||
orl 0x00000011, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
ljmp $0x08, $(mpstart_enter32 - mpstart_begin + 0x7000)
|
||||
|
||||
nop
|
||||
nop
|
||||
|
||||
.code32
|
||||
mpstart_enter32:
|
||||
|
||||
nop
|
||||
nop
|
||||
|
||||
// Initialize segment registers
|
||||
movw $0x10, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
//.byte 0xf1
|
||||
|
||||
// Setup stack
|
||||
movw %ax,%ss
|
||||
movl $0x7000, %esp
|
||||
|
||||
// Reset EFLAGS
|
||||
pushl $0x0
|
||||
popf
|
||||
|
||||
// Set CR4
|
||||
movl %cr4, %eax
|
||||
orl $0x0000006A0, %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
// Temporary Page Table
|
||||
movl $LOWMEM(bootpgtbl1), %eax
|
||||
movl %eax, %cr3
|
||||
|
||||
// Set EFER
|
||||
movl $0xC0000080, %ecx
|
||||
rdmsr
|
||||
orl $0x0900, %eax
|
||||
wrmsr
|
||||
|
||||
// Load 64-bit GDT
|
||||
movl $LOWMEM(mpstartgdtdesc), %eax
|
||||
lgdt (%eax)
|
||||
|
||||
// Set CR0
|
||||
movl %cr0, %eax
|
||||
orl $0x8005002B, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
movl $LOWMEM(mpstart_enter64ptr), %edi
|
||||
ljmp *(%edi)
|
||||
|
||||
nop
|
||||
nop
|
||||
|
||||
.code64
|
||||
mpstart_enter64:
|
||||
nop
|
||||
nop
|
||||
|
||||
//.byte 0xf1
|
||||
|
||||
movq $LOWMEM(mpstart_high64ptr), %rdi
|
||||
jmp *(%rdi)
|
||||
|
||||
nop
|
||||
nop
|
||||
|
||||
mpstart_high64:
|
||||
nop
|
||||
nop
|
||||
|
||||
//.byte 0xf1
|
||||
|
||||
// Load Initial CPU State
|
||||
movq (0x6F00), %rax
|
||||
movq (0x6F08), %rbx
|
||||
movq %rax, %cr3
|
||||
movq %rbx, %rsp
|
||||
|
||||
call Machine_InitAP
|
||||
|
||||
1:
|
||||
movw $(0x5000 + 'H'), (0xB8098)
|
||||
movw $(0x5000 + 'A'), (0xB809A)
|
||||
movw $(0x5000 + 'L'), (0xB809C)
|
||||
movw $(0x5000 + 'T'), (0xB809E)
|
||||
jmp 1b
|
||||
|
||||
.p2align 4
|
||||
mpstart_enter64ptr:
|
||||
.long LOWMEM(mpstart_enter64)
|
||||
.word 0x08
|
||||
|
||||
.p2align 4
|
||||
mpstart_high64ptr:
|
||||
.quad mpstart_high64
|
||||
|
||||
.p2align 12
|
||||
mpstartgdt32:
|
||||
.quad 0x0000000000000000 /* Null */
|
||||
.quad 0x00CF9A000000FFFF /* Temporary CS */
|
||||
.quad 0x00CF92000000FFFF /* Temporary DS */
|
||||
.quad 0x0000000000000000
|
||||
.quad 0x0000000000000000
|
||||
.quad 0x0000000000000000
|
||||
.quad 0x0000000000000000
|
||||
.quad 0x0000000000000000
|
||||
|
||||
.p2align 4
|
||||
mpstartgdtdesc32:
|
||||
.word 0x003F
|
||||
.long LOWMEM(mpstartgdt32)
|
||||
|
||||
.p2align 12
|
||||
mpstartgdt:
|
||||
.quad 0x0000000000000000 /* Null */
|
||||
.quad 0x00AF9C000000FFFF /* Kernel CS */
|
||||
.quad 0x00CF92000000FFFF /* Kernel DS */
|
||||
.quad 0x0000000000000000
|
||||
.quad 0x0000000000000000
|
||||
.quad 0x0000000000000000
|
||||
.quad 0x0000000000000000
|
||||
.quad 0x0000000000000000
|
||||
|
||||
.p2align 4
|
||||
.quad 0x0
|
||||
mpstartgdtdesc:
|
||||
.word 0x003F
|
||||
.quad LOWMEM(mpstartgdt)
|
||||
|
||||
.globl mpstart_end
|
||||
mpstart_end:
|
||||
|
||||
// Boot stack
|
||||
//.globl mpstack
|
||||
//.comm mpstack, STACK_SIZE
|
||||
|
@ -106,10 +106,12 @@ loop:
|
||||
hlt
|
||||
jmp loop
|
||||
|
||||
.p2align 4
|
||||
lmfarptr:
|
||||
.long LOWMEM(lmenter)
|
||||
.word 0x08
|
||||
|
||||
.p2align 4
|
||||
lmhighptr:
|
||||
.quad lmhigh
|
||||
|
||||
@ -125,10 +127,13 @@ bootgdt:
|
||||
.quad 0x0000000000000000
|
||||
|
||||
.p2align 4
|
||||
.globl bootgdtdesc
|
||||
bootgdtdesc:
|
||||
.word 0x003F
|
||||
.quad LOWMEM(bootgdt)
|
||||
|
||||
// Boot stack
|
||||
.p2align 12
|
||||
.globl stack
|
||||
.comm stack, STACK_SIZE
|
||||
|
||||
|
@ -12,13 +12,6 @@
|
||||
#include <machine/mp.h>
|
||||
#include <machine/pmap.h>
|
||||
|
||||
typedef struct AS
|
||||
{
|
||||
PageTable *root;
|
||||
uint64_t tables;
|
||||
uint64_t mappings;
|
||||
} AS;
|
||||
|
||||
AS systemAS;
|
||||
AS *currentAS[MAX_CPUS];
|
||||
|
||||
@ -70,6 +63,12 @@ PMap_Init()
|
||||
kprintf("Done!\n");
|
||||
}
|
||||
|
||||
void
|
||||
PMap_InitAP()
|
||||
{
|
||||
PMap_LoadAS(&systemAS);
|
||||
}
|
||||
|
||||
AS*
|
||||
PMap_NewAS()
|
||||
{
|
||||
|
@ -82,6 +82,12 @@ Trap_Init()
|
||||
kprintf("Done!\n");
|
||||
}
|
||||
|
||||
void
|
||||
Trap_InitAP()
|
||||
{
|
||||
lidt(&idtdesc);
|
||||
}
|
||||
|
||||
void
|
||||
Trap_Dump(TrapFrame *tf)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user