add LAPIC support of the 64bit kernel
This commit is contained in:
parent
609500a6d8
commit
654e91b0a2
3 changed files with 46 additions and 7 deletions
|
@ -151,7 +151,7 @@ inline static void wmb(void) { asm volatile("sfence" ::: "memory"); }
|
|||
* @param d EDX value will be stores here
|
||||
*/
|
||||
inline static void cpuid(uint32_t code, uint32_t* a, uint32_t* b, uint32_t* c, uint32_t* d) {
|
||||
asm volatile ("cpuid" : "=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d) : "0"(code));
|
||||
asm volatile ("cpuid" : "=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d) : "0"(code), "2"(*c));
|
||||
}
|
||||
|
||||
/** @brief Read MSR
|
||||
|
@ -335,9 +335,7 @@ uint32_t read_eip(void);
|
|||
inline static int system_init(void)
|
||||
{
|
||||
gdt_install();
|
||||
#ifdef CONFIG_X86_32
|
||||
apic_init();
|
||||
#endif
|
||||
#ifdef CONFIG_PCI
|
||||
pci_init();
|
||||
#endif
|
||||
|
|
|
@ -42,6 +42,13 @@
|
|||
#error RockCreek is not a SMP system
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Note that linker symbols are not variables, they have no memory allocated for
|
||||
* maintaining a value, rather their address is their value.
|
||||
*/
|
||||
extern const void kernel_start;
|
||||
extern const void kernel_end;
|
||||
|
||||
// IO APIC MMIO structure: write reg, then read or write data.
|
||||
typedef struct {
|
||||
uint32_t reg;
|
||||
|
@ -53,7 +60,7 @@ static const apic_processor_entry_t* apic_processors[MAX_CORES] = {[0 ... MAX_CO
|
|||
static uint32_t boot_processor = MAX_CORES;
|
||||
static apic_mp_t* apic_mp = NULL;
|
||||
static apic_config_table_t* apic_config = NULL;
|
||||
static uint32_t lapic = 0;
|
||||
static size_t lapic = 0;
|
||||
static volatile ioapic_t* ioapic = NULL;
|
||||
static uint32_t icr = 0;
|
||||
static uint32_t ncores = 1;
|
||||
|
@ -329,7 +336,7 @@ void smp_start(uint32_t id)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#ifdef CONFIG_X86_32
|
||||
static apic_mp_t* search_apic(size_t base, size_t limit) {
|
||||
size_t ptr;
|
||||
apic_mp_t* tmp;
|
||||
|
@ -446,9 +453,11 @@ int map_apic(void)
|
|||
if (!has_apic())
|
||||
return -ENXIO;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
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);
|
||||
|
||||
if (ioapic) {
|
||||
|
@ -569,12 +578,15 @@ static int apic_probe(void)
|
|||
int isa_bus = -1;
|
||||
|
||||
#if 1
|
||||
#ifdef CONFIG_X86_32
|
||||
apic_mp = search_apic(0xF0000, 0x100000);
|
||||
if (apic_mp)
|
||||
goto found_mp;
|
||||
apic_mp = search_apic(0x9F000, 0xA0000);
|
||||
if (apic_mp)
|
||||
goto found_mp;
|
||||
#elif defined(CONFIG_X86_64)
|
||||
#endif
|
||||
#else
|
||||
// searching MP signature in the reserved memory areas
|
||||
if (mb_info && (mb_info->flags & MULTIBOOT_INFO_MEM_MAP)) {
|
||||
|
@ -620,7 +632,7 @@ found_mp:
|
|||
goto no_mp;
|
||||
}
|
||||
|
||||
apic_config = (apic_config_table_t*) apic_mp->mp_config;
|
||||
apic_config = (apic_config_table_t*) ((size_t) apic_mp->mp_config);
|
||||
if (!apic_config || strncmp((void*) &apic_config->signature, "PCMP", 4) !=0) {
|
||||
kputs("Invalid MP config table\n");
|
||||
goto no_mp;
|
||||
|
@ -693,11 +705,16 @@ check_lapic:
|
|||
if (apic_config) {
|
||||
lapic = apic_config->lapic;
|
||||
} else {
|
||||
uint32_t edx, dummy;
|
||||
uint32_t edx, dummy=0;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if (!lapic)
|
||||
|
|
|
@ -177,6 +177,30 @@ L0:
|
|||
or ebx, 0x00000003
|
||||
mov DWORD [edi], ebx
|
||||
|
||||
; check if lapic is available
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
mov eax, 1
|
||||
cpuid
|
||||
and edx, 0x200
|
||||
cmp edx, 0
|
||||
je no_lapic
|
||||
; map lapic at 0xFEE00000 below the kernel
|
||||
mov edi, kernel_start
|
||||
sub edi, 0x1000
|
||||
shr edi, 9 ; (edi >> 12) * 8
|
||||
add edi, boot_pt
|
||||
mov ebx, 0xFEE00000
|
||||
or ebx, 0x00000013
|
||||
mov DWORD [edi], ebx
|
||||
no_lapic:
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
|
||||
extern kernel_start ; defined in linker script
|
||||
extern kernel_end
|
||||
mov edi, kernel_start
|
||||
|
|
Loading…
Add table
Reference in a new issue