enable full (64bit) APIC support
- no SMP support
This commit is contained in:
parent
44ea32c241
commit
08bcc19626
2 changed files with 93 additions and 16 deletions
|
@ -58,7 +58,7 @@ typedef struct {
|
|||
|
||||
static const apic_processor_entry_t* apic_processors[MAX_CORES] = {[0 ... MAX_CORES-1] = NULL};
|
||||
static uint32_t boot_processor = MAX_CORES;
|
||||
static apic_mp_t* apic_mp = NULL;
|
||||
apic_mp_t* apic_mp __attribute__ ((section (".data"))) = NULL;
|
||||
static apic_config_table_t* apic_config = NULL;
|
||||
static size_t lapic = 0;
|
||||
static volatile ioapic_t* ioapic = NULL;
|
||||
|
@ -82,12 +82,15 @@ static inline uint32_t lapic_read(uint32_t addr)
|
|||
|
||||
static inline void lapic_write(uint32_t addr, uint32_t value)
|
||||
{
|
||||
#ifdef CONFIG_X86_32
|
||||
/*
|
||||
* to avoid a pentium bug, we have to read a apic register
|
||||
* before we write a value to this register
|
||||
*/
|
||||
asm volatile ("movl (%%eax), %%edx; movl %%ebx, (%%eax)" :: "a"(lapic+addr), "b"(value) : "%edx");
|
||||
//*((volatile uint32_t*) (lapic+addr)) = value;
|
||||
#else
|
||||
*((volatile uint32_t*) (lapic+addr)) = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint32_t ioapic_read(uint32_t reg)
|
||||
|
@ -457,6 +460,12 @@ int map_apic(void)
|
|||
lapic = map_region(0 /*lapic*/, lapic, 1, MAP_KERNEL_SPACE|MAP_NO_CACHE);
|
||||
if (BUILTIN_EXPECT(!lapic, 0))
|
||||
return -ENXIO;
|
||||
#else
|
||||
if (lapic != (size_t)&kernel_start - 0x1000) {
|
||||
lapic = map_region(0 /*lapic*/, lapic, 1, MAP_KERNEL_SPACE|MAP_NO_CACHE);
|
||||
if (BUILTIN_EXPECT(!lapic, 0))
|
||||
return -ENXIO;
|
||||
}
|
||||
#endif
|
||||
kprintf("Mapped LAPIC at 0x%x\n", lapic);
|
||||
|
||||
|
@ -469,7 +478,7 @@ int map_apic(void)
|
|||
// map all processor entries
|
||||
for(i=0; i<MAX_CORES; i++) {
|
||||
if (apic_processors[i] && (old != (((size_t)apic_processors[i]) & 0xFFFFF000)))
|
||||
old = map_region(((size_t) apic_processors[i]) & 0xFFFFF000, ((size_t) apic_processors[i]) & 0xFFFFF000, 1, MAP_KERNEL_SPACE|MAP_NO_CACHE);
|
||||
old = map_region(((size_t) apic_processors[i]) & 0xFFFFF000, ((size_t) apic_processors[i]) & 0xFFFFF000, 1, MAP_REMAP|MAP_KERNEL_SPACE|MAP_NO_CACHE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -563,8 +572,10 @@ 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);
|
||||
|
||||
|
@ -681,8 +692,8 @@ found_mp:
|
|||
apic_io_entry_t* io_entry = (apic_io_entry_t*) addr;
|
||||
ioapic = (ioapic_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 (ver. 0x%x)\n", ioapic, ioapic_read(IOAPIC_REG_VER));
|
||||
kprintf("Found IOAPIC at 0x%x\n", ioapic);
|
||||
} else if (*((uint8_t*) addr) == 3) { // IO_INT
|
||||
apic_ioirq_entry_t* extint = (apic_ioirq_entry_t*) addr;
|
||||
if (extint->src_bus == isa_bus) {
|
||||
|
@ -701,6 +712,7 @@ found_mp:
|
|||
ncores = count;
|
||||
|
||||
check_lapic:
|
||||
#ifdef CONFIG_X86_32
|
||||
if (apic_config) {
|
||||
lapic = apic_config->lapic;
|
||||
} else {
|
||||
|
@ -708,13 +720,16 @@ check_lapic:
|
|||
|
||||
cpuid(0x1, &dummy, &dummy, &dummy, &edx);
|
||||
if (edx & (1 << 9))
|
||||
#ifdef CONFIG_X86_32
|
||||
lapic = 0xFEE00000;
|
||||
#else
|
||||
// On a x64 system, we already map the lapic below the kernel
|
||||
lapic = (size_t)&kernel_start - 0x1000;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
if (apic_config->lapic == 0xFEE00000) {
|
||||
// On a x64 system, we already map the lapic below the kernel
|
||||
lapic = (size_t)&kernel_start - 0x1000;
|
||||
} else {
|
||||
lapic = apic_config->lapic;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!lapic)
|
||||
goto out;
|
||||
|
|
|
@ -24,6 +24,11 @@
|
|||
%include "config.inc"
|
||||
|
||||
[BITS 32]
|
||||
|
||||
extern kernel_start ; defined in linker script
|
||||
extern kernel_end
|
||||
extern apic_mp
|
||||
|
||||
; We use a special name to map this section at the begin of our kernel
|
||||
; => Multiboot needs its magic number at the begin of the kernel
|
||||
SECTION .mboot
|
||||
|
@ -90,6 +95,36 @@ boot_pd times 512 DQ 0
|
|||
boot_pt times (NOPTS*512) DQ 0
|
||||
|
||||
SECTION .text
|
||||
search_apic:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push ecx
|
||||
|
||||
xor eax, eax
|
||||
mov ecx, [ebp+8]
|
||||
L1:
|
||||
cmp [ecx], DWORD 0x5f504d5f ; MP_FLT_SIGNATURE
|
||||
jne L2
|
||||
mov al, BYTE [ecx+9]
|
||||
cmp eax, 4
|
||||
ja L2
|
||||
mov al, BYTE [ecx+11]
|
||||
cmp eax, 0
|
||||
jne L2
|
||||
mov eax, ecx
|
||||
jmp L3
|
||||
|
||||
L2:
|
||||
add ecx, 4
|
||||
cmp ecx, [ebp+12]
|
||||
jb L1
|
||||
xor eax, eax
|
||||
|
||||
L3:
|
||||
pop ecx
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
ALIGN 4
|
||||
stublet:
|
||||
mov esp, startup_stack-4
|
||||
|
@ -180,8 +215,7 @@ L0:
|
|||
cmp edx, 0
|
||||
je no_lapic
|
||||
; map lapic at 0xFEE00000 below the kernel
|
||||
mov edi, kernel_start
|
||||
sub edi, 0x1000
|
||||
mov edi, kernel_start - 0x1000
|
||||
shr edi, 9 ; (edi >> 12) * 8
|
||||
add edi, boot_pt
|
||||
mov ebx, 0xFEE00000
|
||||
|
@ -193,8 +227,36 @@ no_lapic:
|
|||
pop ebx
|
||||
pop eax
|
||||
|
||||
extern kernel_start ; defined in linker script
|
||||
extern kernel_end
|
||||
; search APIC
|
||||
push DWORD 0x100000
|
||||
push DWORD 0xF0000
|
||||
call search_apic
|
||||
add esp, 8
|
||||
|
||||
cmp eax, 0
|
||||
jne La
|
||||
|
||||
push DWORD 0xA0000
|
||||
push DWORD 0x9F000
|
||||
call search_apic
|
||||
add esp, 8
|
||||
|
||||
cmp eax, 0
|
||||
je Lb
|
||||
|
||||
La:
|
||||
; map MP Floating Pointer Structure
|
||||
mov DWORD [apic_mp], eax
|
||||
mov edi, eax
|
||||
and edi, 0xFFFFF000
|
||||
shr edi, 9 ; (edi >> 12) * 8
|
||||
add edi, boot_pt
|
||||
mov ebx, eax
|
||||
and ebx, 0xFFFFF000
|
||||
or ebx, 0x00000013
|
||||
mov DWORD [edi], ebx
|
||||
|
||||
Lb:
|
||||
mov edi, kernel_start
|
||||
shr edi, 9 ; (kernel_start >> 12) * 8
|
||||
add edi, boot_pt
|
||||
|
@ -205,11 +267,11 @@ no_lapic:
|
|||
shr ecx, 12
|
||||
inc ecx
|
||||
|
||||
L1:
|
||||
Lc:
|
||||
mov DWORD [edi], ebx ; Set the double word at the destination index to the B-register.
|
||||
add edi, 8
|
||||
add ebx, 0x1000
|
||||
loop L1
|
||||
loop Lc
|
||||
|
||||
; we need to enable PAE modus
|
||||
mov eax, cr4
|
||||
|
|
Loading…
Add table
Reference in a new issue