enable SMP support for 64bit systems
This commit is contained in:
parent
531556f53c
commit
e06d910514
2 changed files with 72 additions and 6 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue