diff --git a/hermit/arch/x86/kernel/apic.c b/hermit/arch/x86/kernel/apic.c index f73ee7707..02af40d11 100644 --- a/hermit/arch/x86/kernel/apic.c +++ b/hermit/arch/x86/kernel/apic.c @@ -51,6 +51,7 @@ extern const void kernel_start; #define IOAPIC_ADDR ((size_t) &kernel_start - 2*PAGE_SIZE) #define LAPIC_ADDR ((size_t) &kernel_start - 1*PAGE_SIZE) +#define MAX_APIC_CORES 256 // IO APIC MMIO structure: write reg, then read or write data. typedef struct { @@ -59,7 +60,7 @@ typedef struct { uint32_t data; } ioapic_t; -static const apic_processor_entry_t* apic_processors[MAX_CORES] = {[0 ... MAX_CORES-1] = NULL}; +static const apic_processor_entry_t* apic_processors[MAX_APIC_CORES] = {[0 ... MAX_APIC_CORES-1] = NULL}; extern int32_t boot_processor; extern uint32_t cpu_freq; apic_mp_t* apic_mp __attribute__ ((section (".data"))) = NULL; @@ -70,7 +71,7 @@ static uint32_t icr = 0; static uint32_t ncores = 1; static uint8_t irq_redirect[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}; static uint8_t initialized = 0; -static uint8_t online[MAX_CORES] = {[0 ... MAX_CORES-1] = 0}; +static uint8_t online[MAX_APIC_CORES] = {[0 ... MAX_APIC_CORES-1] = 0}; spinlock_t bootlock = SPINLOCK_INIT; @@ -469,7 +470,7 @@ found_mp: if (*((uint8_t*) addr) == 0) { // cpu entry apic_processor_entry_t* cpu = (apic_processor_entry_t*) addr; - if (j < MAX_CORES) { + if (j < MAX_APIC_CORES) { // is the processor usable? if (cpu->cpu_flags & 0x01) { apic_processors[j] = cpu; @@ -564,6 +565,7 @@ extern int smp_main(void); extern void gdt_flush(void); extern int set_idle_task(void); +#if MAX_CORES > 1 int smp_start(void) { if (lapic && has_x2apic()) // enable x2APIC support @@ -599,7 +601,6 @@ int smp_start(void) return smp_main(); } -#if MAX_CORES > 1 static inline void set_ipi_dest(uint32_t cpu_id) { uint32_t tmp; @@ -624,7 +625,7 @@ int ipi_tlb_flush(void) } flags = irq_nested_disable(); - for(i=0; i 1 mov eax, DWORD [cpu_online] cmp eax, 0 jne Lsmp_main +%endif ; set default stack pointer mov rsp, boot_stack @@ -364,6 +366,7 @@ L1: call main jmp $ +%if MAX_CORES > 1 Lsmp_main: ; dirty to hack to determine the cpu id ; with a temporary stack @@ -385,6 +388,7 @@ Lsmp_main: DQ 0, 0, 0, 0 DQ 0, 0, 0, 0 tmp_stack: +%endif global gdt_flush extern gp diff --git a/hermit/arch/x86/kernel/processor.c b/hermit/arch/x86/kernel/processor.c index e2ec26f5b..9da65458d 100644 --- a/hermit/arch/x86/kernel/processor.c +++ b/hermit/arch/x86/kernel/processor.c @@ -235,13 +235,19 @@ int cpu_detection(void) { wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NXE); wrmsr(MSR_FS_BASE, 0); +#if MAX_CORES > 1 wrmsr(MSR_GS_BASE, apic_cpu_id() * ((size_t) &percore_end0 - (size_t) &percore_start)); +#else + wrmsr(MSR_GS_BASE, 0); +#endif wrmsr(MSR_KERNEL_GS_BASE, 0); kprintf("Core %d set per_core offset to 0x%x\n", apic_cpu_id(), rdmsr(MSR_GS_BASE)); +#if MAX_CORES > 1 /* set core id to apic_cpu_id */ set_per_core(__core_id, apic_cpu_id()); +#endif if (first_time && has_sse()) wmb = sfence; diff --git a/hermit/include/hermit/stddef.h b/hermit/include/hermit/stddef.h index 0d4c460f1..9edecfbb0 100644 --- a/hermit/include/hermit/stddef.h +++ b/hermit/include/hermit/stddef.h @@ -58,10 +58,13 @@ DECLARE_PER_CORE(struct task*, current_task); /* allows fast access to the kernel stack */ DECLARE_PER_CORE(char*, kernel_stack); +#if MAX_CORES > 1 /* allows fast access to the core id */ DECLARE_PER_CORE(uint32_t, __core_id); - #define CORE_ID per_core(__core_id) +#else +#define CORE_ID 0 +#endif #ifdef __cplusplus } diff --git a/hermit/kernel/main.c b/hermit/kernel/main.c index 4cf1dd97d..5936992c4 100644 --- a/hermit/kernel/main.c +++ b/hermit/kernel/main.c @@ -94,6 +94,7 @@ static int hermit_init(void) return 0; } +#if MAX_CORES > 1 int smp_main(void) { int32_t cpu = atomic_int32_inc(&cpu_online); @@ -109,6 +110,7 @@ int smp_main(void) return 0; } +#endif // init task => creates all other tasks an initialize the LwIP static int initd(void* arg) diff --git a/hermit/kernel/tasks.c b/hermit/kernel/tasks.c index 97471f516..328f28ebc 100644 --- a/hermit/kernel/tasks.c +++ b/hermit/kernel/tasks.c @@ -56,7 +56,9 @@ static readyqueues_t readyqueues[1] = {[0] = {task_table+0, NULL, 0, 0, 0, {[0 . DEFINE_PER_CORE(task_t*, current_task, task_table+0); DEFINE_PER_CORE(char*, kernel_stack, NULL); +#if MAX_CORES > 1 DEFINE_PER_CORE(uint32_t, __core_id, 0); +#endif extern const void boot_stack; /** @brief helper function for the assembly code to determine the current task