enable SMP support for 64bit systems

This commit is contained in:
Stefan Lankes 2012-06-12 23:42:02 +02:00
parent 531556f53c
commit e06d910514
2 changed files with 72 additions and 6 deletions

View file

@ -290,6 +290,13 @@ extern void cpu_init(void);
*/
extern int smp_main(void);
#ifdef CONFIG_X86_64
/*
* 32bit entry point, which jumps to the 64bit code smp_start
*/
extern void smp_entry(void);
#endif
void smp_start(uint32_t id)
{
size_t i;
@ -385,8 +392,13 @@ int smp_init(void)
{
// replace 0xDEADC0DE with the address of the smp entry code
if (*((uint32_t*) (bootaddr+j)) == 0xDEADC0DE) {
*((uint32_t*) (bootaddr+j)) = (size_t) smp_start;
kprintf("Set entry point of the application processors at 0x%x\n", (size_t) smp_start);
#ifdef CONFIG_X86_32
*((uint32_t*) (bootaddr+j)) = (uint32_t) smp_start;
kprintf("Set entry point of the application processors at 0x%x\n", (uint32_t) smp_start);
#else
*((uint32_t*) (bootaddr+j)) = (uint32_t) smp_entry;
kprintf("Set entry point of the application processors at 0x%lx\n", (size_t) smp_entry);
#endif
}
// replace APIC ID 0xDEADDEAD
@ -572,10 +584,8 @@ int apic_calibration(void)
ioapic_inton(i, apic_processors[boot_processor]->id);
}
initialized = 1;
#ifdef CONFIG_X86_32
#if MAX_CORES > 1
smp_init();
#endif
#endif
irq_nested_enable(flags);
@ -690,7 +700,7 @@ found_mp:
addr += 20;
} else if (*((uint8_t*) addr) == 2) { // IO_APIC
apic_io_entry_t* io_entry = (apic_io_entry_t*) addr;
ioapic = (ioapic_t*) io_entry->addr;
ioapic = (ioapic_t*) ((size_t) io_entry->addr);
addr += 8;
//kprintf("Found IOAPIC at 0x%x (ver. 0x%x)\n", ioapic, ioapic_read(IOAPIC_REG_VER));
kprintf("Found IOAPIC at 0x%x\n", ioapic);

View file

@ -95,6 +95,48 @@ boot_pd times 512 DQ 0
boot_pt times (NOPTS*512) DQ 0
SECTION .text
ALIGN 8
global smp_entry
smp_entry:
; enable caching, disable paging and fpu emulation
and eax, 0x1ffffffb
; ...and turn on FPU exceptions
or eax, 0x22
mov cr0, eax
; clears the current pgd entry
xor eax, eax
mov cr3, eax
; at this stage, we disable the SSE support
mov eax, cr4
and eax, 0xfffbf9ff
mov cr4, eax
; initialize page table
mov edi, boot_pgd
mov cr3, edi
; we need to enable PAE modus
mov eax, cr4
or eax, 1 << 5
mov cr4, eax
; switch to the compatibility mode (which is part of long mode)
mov ecx, 0xC0000080
rdmsr
or eax, 1 << 8
wrmsr
; enable paging
mov eax, cr0
or eax, 1 << 31 | 1 << 0 ; Set the PG-bit, which is the 31nd bit, and the PM-bit, which is the 0th bit.
mov cr0, eax
mov edi, [esp+4] ; set argumet for smp_start
lgdt [GDT64.Pointer] ; Load the 64-bit global descriptor table.
jmp GDT64.Code:smp_start64 ; Set the code segment and enter 64-bit long mode.
jmp $ ; endless loop
search_apic:
push ebp
mov ebp, esp
@ -322,11 +364,25 @@ start64:
extern multiboot_init
mov rdi, rbx
call multiboot_init
; jump to the boot processors's C code
; jump to the boot processors's C code
extern main
call main
jmp $
smp_start64:
; initialize segment registers
mov ax, GDT64.Data
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
; jump to the boot processors's C code
extern smp_start
call smp_start
jmp $
global cpu_init
cpu_init:
; mov eax, cr0