Basic MP bootup works

This commit is contained in:
Ali Mashtizadeh 2015-02-15 17:00:55 -08:00
parent 658ab8571b
commit 4808b746f5
10 changed files with 296 additions and 9 deletions

View File

@ -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",

View File

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

View File

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

View File

@ -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()
{

View File

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

View File

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

View File

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

View File

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

View File

@ -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()
{

View File

@ -82,6 +82,12 @@ Trap_Init()
kprintf("Done!\n");
}
void
Trap_InitAP()
{
lidt(&idtdesc);
}
void
Trap_Dump(TrapFrame *tf)
{