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);
|
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)
|
void smp_start(uint32_t id)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -385,8 +392,13 @@ int smp_init(void)
|
||||||
{
|
{
|
||||||
// replace 0xDEADC0DE with the address of the smp entry code
|
// replace 0xDEADC0DE with the address of the smp entry code
|
||||||
if (*((uint32_t*) (bootaddr+j)) == 0xDEADC0DE) {
|
if (*((uint32_t*) (bootaddr+j)) == 0xDEADC0DE) {
|
||||||
*((uint32_t*) (bootaddr+j)) = (size_t) smp_start;
|
#ifdef CONFIG_X86_32
|
||||||
kprintf("Set entry point of the application processors at 0x%x\n", (size_t) smp_start);
|
*((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
|
// replace APIC ID 0xDEADDEAD
|
||||||
|
@ -572,10 +584,8 @@ int apic_calibration(void)
|
||||||
ioapic_inton(i, apic_processors[boot_processor]->id);
|
ioapic_inton(i, apic_processors[boot_processor]->id);
|
||||||
}
|
}
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
#ifdef CONFIG_X86_32
|
|
||||||
#if MAX_CORES > 1
|
#if MAX_CORES > 1
|
||||||
smp_init();
|
smp_init();
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
irq_nested_enable(flags);
|
irq_nested_enable(flags);
|
||||||
|
|
||||||
|
@ -690,7 +700,7 @@ found_mp:
|
||||||
addr += 20;
|
addr += 20;
|
||||||
} else if (*((uint8_t*) addr) == 2) { // IO_APIC
|
} else if (*((uint8_t*) addr) == 2) { // IO_APIC
|
||||||
apic_io_entry_t* io_entry = (apic_io_entry_t*) addr;
|
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;
|
addr += 8;
|
||||||
//kprintf("Found IOAPIC at 0x%x (ver. 0x%x)\n", ioapic, ioapic_read(IOAPIC_REG_VER));
|
//kprintf("Found IOAPIC at 0x%x (ver. 0x%x)\n", ioapic, ioapic_read(IOAPIC_REG_VER));
|
||||||
kprintf("Found IOAPIC at 0x%x\n", ioapic);
|
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
|
boot_pt times (NOPTS*512) DQ 0
|
||||||
|
|
||||||
SECTION .text
|
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:
|
search_apic:
|
||||||
push ebp
|
push ebp
|
||||||
mov ebp, esp
|
mov ebp, esp
|
||||||
|
@ -322,11 +364,25 @@ start64:
|
||||||
extern multiboot_init
|
extern multiboot_init
|
||||||
mov rdi, rbx
|
mov rdi, rbx
|
||||||
call multiboot_init
|
call multiboot_init
|
||||||
; jump to the boot processors's C code
|
; jump to the boot processors's C code
|
||||||
extern main
|
extern main
|
||||||
call main
|
call main
|
||||||
jmp $
|
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
|
global cpu_init
|
||||||
cpu_init:
|
cpu_init:
|
||||||
; mov eax, cr0
|
; mov eax, cr0
|
||||||
|
|
Loading…
Add table
Reference in a new issue