From 3f4d53d4db401a69aca0708883159090d60ac37a Mon Sep 17 00:00:00 2001 From: Pawel Wieczorkiewicz Date: Thu, 7 Jul 2022 16:56:03 +0200 Subject: [PATCH] smp,drivers,arch: use new CPU API for using detected CPUs Signed-off-by: Pawel Wieczorkiewicz --- arch/x86/apic.c | 16 +++++--- arch/x86/traps.c | 6 +-- common/acpi.c | 83 +++++++++++++++++--------------------- common/setup.c | 24 +++++------ drivers/acpi/acpica/osl.c | 13 +++--- drivers/hpet.c | 4 +- drivers/keyboard.c | 6 +-- drivers/pit.c | 4 +- drivers/serial.c | 6 +-- include/acpi_ktf.h | 4 +- include/arch/x86/apic.h | 2 +- include/arch/x86/traps.h | 3 +- include/drivers/hpet.h | 4 +- include/drivers/keyboard.h | 3 +- include/drivers/pit.h | 3 +- include/drivers/serial.h | 3 +- include/percpu.h | 3 -- smp/mptables.c | 25 +++++++----- smp/smp.c | 31 ++++++-------- 19 files changed, 120 insertions(+), 123 deletions(-) diff --git a/arch/x86/apic.c b/arch/x86/apic.c index 89bb6088..bbb4223e 100644 --- a/arch/x86/apic.c +++ b/arch/x86/apic.c @@ -24,6 +24,7 @@ */ #include #include +#include #include #include #include @@ -107,10 +108,10 @@ void apic_icr_write(const apic_icr_t *icr) { apic_mode_t apic_get_mode(void) { return apic_mode; } -void init_apic(unsigned int cpu, apic_mode_t mode) { - percpu_t *percpu = get_percpu_page(cpu); +void init_apic(unsigned int cpu_id, apic_mode_t mode) { apic_base_t apic_base; apic_spiv_t spiv; + cpu_t *cpu; BUG_ON(mode < APIC_MODE_DISABLED); @@ -128,8 +129,8 @@ void init_apic(unsigned int cpu, apic_mode_t mode) { BUG(); } - printk("CPU%u: Initializing APIC mode: %s -> %s\n", cpu, apic_mode_names[apic_mode], - apic_mode_names[mode]); + printk("CPU%u: Initializing APIC mode: %s -> %s\n", cpu_id, + apic_mode_names[apic_mode], apic_mode_names[mode]); /* Disable APIC */ apic_base.en = apic_base.extd = 0; @@ -146,8 +147,11 @@ void init_apic(unsigned int cpu, apic_mode_t mode) { } apic_mode = mode; - percpu->apic_base = apic_base; - PERCPU_SET(bsp, apic_base.bsp); + + cpu = !!apic_base.bsp ? get_bsp_cpu() : get_cpu(cpu_id); + BUG_ON(!cpu || cpu->id != cpu_id); + + cpu->percpu->apic_base = apic_base; /* XAPIC requires MMIO accesses, thus the APIC_BASE page needs to be mapped. * X2APIC uses MSRs for accesses, so no mapping needed. diff --git a/arch/x86/traps.c b/arch/x86/traps.c index a50b6936..46285ae0 100644 --- a/arch/x86/traps.c +++ b/arch/x86/traps.c @@ -117,8 +117,8 @@ static void init_gdt(percpu_t *percpu) { init_tss(percpu); } -void init_traps(unsigned int cpu) { - percpu_t *percpu = get_percpu_page(cpu); +void init_traps(const cpu_t *cpu) { + percpu_t *percpu = cpu->percpu; BUG_ON(!percpu); @@ -173,7 +173,7 @@ void init_traps(unsigned int cpu) { init_gdt(percpu); - wrmsr(MSR_TSC_AUX, cpu); + wrmsr(MSR_TSC_AUX, cpu->id); } static void dump_general_regs(const struct cpu_regs *regs) { diff --git a/common/acpi.c b/common/acpi.c index f72d4ae4..8ad79aa3 100644 --- a/common/acpi.c +++ b/common/acpi.c @@ -23,8 +23,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include +#include #include -#include #include #include @@ -46,10 +46,6 @@ static const char *madt_int_trigger_names[] = { [ACPI_MADT_INT_TRIGGER_LT] = "Level", }; -static unsigned nr_cpus; - -unsigned acpi_get_nr_cpus(void) { return nr_cpus; } - #ifndef KTF_ACPICA #include #include @@ -232,7 +228,7 @@ static int process_fadt(void) { return 0; } -static int process_madt_entries(unsigned bsp_cpu_id) { +static int process_madt_entries(void) { acpi_madt_t *madt = (acpi_madt_t *) acpi_find_table(MADT_SIGNATURE); acpi_madt_entry_t *entry; bus_t *isa_bus = NULL; @@ -257,7 +253,6 @@ static int process_madt_entries(unsigned bsp_cpu_id) { switch (entry->type) { case ACPI_MADT_TYPE_LAPIC: { acpi_madt_processor_t *madt_cpu = (acpi_madt_processor_t *) entry->data; - percpu_t *percpu; bool enabled; /* Some systems report all CPUs, marked as disabled */ @@ -265,15 +260,16 @@ static int process_madt_entries(unsigned bsp_cpu_id) { if (!enabled) break; - percpu = get_percpu_page(madt_cpu->apic_proc_id); + cpu_t *cpu = get_cpu(madt_cpu->apic_proc_id) + ?: add_cpu(madt_cpu->apic_proc_id, false, enabled); + cpu->enabled = enabled; + + percpu_t *percpu = cpu->percpu; percpu->cpu_id = madt_cpu->apic_proc_id; percpu->apic_id = madt_cpu->apic_id; - percpu->bsp = !!(madt_cpu->apic_proc_id == bsp_cpu_id); - percpu->enabled = enabled; - nr_cpus++; printk("ACPI: [MADT] APIC Processor ID: %u, APIC ID: %u, Flags: %08x\n", - madt_cpu->apic_proc_id, madt_cpu->apic_id, madt_cpu->flags); + cpu->id, percpu->apic_id, madt_cpu->flags); break; } case ACPI_MADT_TYPE_IOAPIC: { @@ -383,7 +379,7 @@ acpi_table_t *acpi_find_table(uint32_t signature) { return NULL; } -int init_acpi(unsigned bsp_cpu_id) { +int init_acpi(void) { unsigned acpi_nr_tables; rsdt_t *rsdt = NULL; xsdt_t *xsdt = NULL; @@ -437,7 +433,7 @@ int init_acpi(unsigned bsp_cpu_id) { if (rc < 0) return rc; - return process_madt_entries(bsp_cpu_id); + return process_madt_entries(); } #else /* KTF_ACPICA */ #include "acpi.h" @@ -486,8 +482,6 @@ static void madt_parser(ACPI_SUBTABLE_HEADER *entry, void *arg) { switch (entry->Type) { case ACPI_MADT_TYPE_LOCAL_APIC: { ACPI_MADT_LOCAL_APIC *lapic = (ACPI_MADT_LOCAL_APIC *) entry; - uint32_t bsp_cpu_id = (uint32_t) _ul(arg); - percpu_t *percpu; bool enabled; /* Some systems report all CPUs, marked as disabled */ @@ -495,15 +489,15 @@ static void madt_parser(ACPI_SUBTABLE_HEADER *entry, void *arg) { if (!enabled) break; - percpu = get_percpu_page(lapic->ProcessorId); - percpu->cpu_id = lapic->ProcessorId; + cpu_t *cpu = + get_cpu(lapic->ProcessorId) ?: add_cpu(lapic->ProcessorId, false, enabled); + cpu->enabled = enabled; + + percpu_t *percpu = cpu->percpu; percpu->apic_id = lapic->Id; - percpu->bsp = !!(lapic->ProcessorId == bsp_cpu_id); - percpu->enabled = enabled; - nr_cpus++; - printk("ACPI: [MADT] APIC Processor ID: %u, APIC ID: %u, Flags: %08x\n", - percpu->cpu_id, percpu->apic_id, lapic->LapicFlags); + printk("ACPI: [MADT] APIC Processor ID: %u, APIC ID: %u, Flags: %08x\n", cpu->id, + percpu->apic_id, lapic->LapicFlags); break; } case ACPI_MADT_TYPE_IO_APIC: { @@ -597,25 +591,23 @@ static void madt_parser(ACPI_SUBTABLE_HEADER *entry, void *arg) { } case ACPI_MADT_TYPE_LOCAL_SAPIC: { ACPI_MADT_LOCAL_SAPIC *slapic = (ACPI_MADT_LOCAL_SAPIC *) entry; - percpu_t *percpu = get_percpu_page(slapic->ProcessorId); - uint32_t bsp_cpu_id = (uint32_t) _ul(arg); + bool enabled = !!(slapic->LapicFlags & 0x1); + cpu_t *cpu = + get_cpu(slapic->ProcessorId) ?: add_cpu(slapic->ProcessorId, false, enabled); - percpu->cpu_id = slapic->ProcessorId; + cpu->enabled = enabled; + + percpu_t *percpu = cpu->percpu; percpu->sapic_id = slapic->Id; percpu->sapic_eid = slapic->Eid; - percpu->sapic_uid = slapic->Uid; percpu->sapic_uid_str[0] = slapic->UidString[0]; - percpu->bsp = !!(slapic->ProcessorId == bsp_cpu_id); - percpu->enabled = !!(slapic->LapicFlags & 0x1); - - if (percpu->enabled) { - nr_cpus++; + if (cpu->enabled) { printk("ACPI: [MADT] SAPIC Processor ID: %u, SAPIC ID: %u, SAPIC EID: %u, " "SAPIC UID: %u, SAPIC UID Str: %c Flags: %08x\n", - percpu->cpu_id, slapic->Id, slapic->Eid, slapic->Uid, - slapic->UidString[0], slapic->LapicFlags); + cpu->id, slapic->Id, slapic->Eid, slapic->Uid, slapic->UidString[0], + slapic->LapicFlags); } break; } @@ -625,18 +617,17 @@ static void madt_parser(ACPI_SUBTABLE_HEADER *entry, void *arg) { } case ACPI_MADT_TYPE_LOCAL_X2APIC: { ACPI_MADT_LOCAL_X2APIC *x2lapic = (ACPI_MADT_LOCAL_X2APIC *) entry; - percpu_t *percpu = get_percpu_page(x2lapic->Uid); - uint32_t bsp_cpu_id = (uint32_t) _ul(arg); + bool enabled = !!(x2lapic->LapicFlags & 0x1); + cpu_t *cpu = get_cpu(x2lapic->Uid) ?: add_cpu(x2lapic->Uid, false, enabled); + + cpu->enabled = enabled; - percpu->cpu_id = x2lapic->Uid; + percpu_t *percpu = cpu->percpu; percpu->apic_id = x2lapic->LocalApicId; - percpu->bsp = !!(x2lapic->Uid == bsp_cpu_id); - percpu->enabled = !!(x2lapic->LapicFlags & 0x1); - if (percpu->enabled) { - nr_cpus++; + if (cpu->enabled) { printk("ACPI: [MADT] X2APIC Processor ID: %u, APIC ID: %u, Flags: %08x\n", - percpu->cpu_id, percpu->apic_id, x2lapic->LapicFlags); + cpu->id, percpu->apic_id, x2lapic->LapicFlags); } break; } @@ -703,7 +694,7 @@ static ACPI_STATUS init_fadt(void) { return AE_OK; } -static ACPI_STATUS init_madt(unsigned bsp_cpu_id) { +static ACPI_STATUS init_madt(void) { ACPI_TABLE_MADT *madt = acpi_find_table(ACPI_SIG_MADT); ACPI_SUBTABLE_HEADER *subtbl = (void *) madt + sizeof(*madt); @@ -712,7 +703,7 @@ static ACPI_STATUS init_madt(unsigned bsp_cpu_id) { uint32_t length = madt->Header.Length - sizeof(*madt); - acpi_walk_subtables(subtbl, length, madt_parser, (void *) _ul(bsp_cpu_id)); + acpi_walk_subtables(subtbl, length, madt_parser, NULL); return AE_OK; } @@ -733,7 +724,7 @@ void acpi_walk_subtables(ACPI_SUBTABLE_HEADER *entry, uint32_t length, } } -ACPI_STATUS init_acpi(unsigned bsp_cpu_id) { +ACPI_STATUS init_acpi(void) { ACPI_STATUS status; printk("Initializing ACPI support\n"); @@ -746,7 +737,7 @@ ACPI_STATUS init_acpi(unsigned bsp_cpu_id) { if (status != AE_OK) return status; - status = init_madt(bsp_cpu_id); + status = init_madt(); return status; } diff --git a/common/setup.c b/common/setup.c index 42cbdaf9..321aa99a 100644 --- a/common/setup.c +++ b/common/setup.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -63,11 +64,6 @@ boot_flags_t boot_flags; -static unsigned bsp_cpu_id = 0; - -unsigned get_bsp_cpu_id(void) { return bsp_cpu_id; } -void set_bsp_cpu_id(unsigned cpu_id) { bsp_cpu_id = cpu_id; } - #define QEMU_CONSOLE_PORT 0x0e9 static void __text_init init_console(void) { @@ -204,7 +200,9 @@ void __noreturn __text_init kernel_start(uint32_t multiboot_magic, init_percpu(); - init_traps(get_bsp_cpu_id()); + cpu_t *bsp = init_cpus(); + + init_traps(bsp); init_extables(); @@ -212,16 +210,16 @@ void __noreturn __text_init kernel_start(uint32_t multiboot_magic, /* Try to initialize ACPI (and MADT) */ #ifndef KTF_ACPICA - if (init_acpi(get_bsp_cpu_id()) < 0) { + if (init_acpi() < 0) { #else - if (ACPI_FAILURE(init_acpi(get_bsp_cpu_id()))) { + if (ACPI_FAILURE(init_acpi())) { #endif /* Fallback to MP tables when no ACPI */ if (init_mptables() < 0) BUG(); } - init_apic(get_bsp_cpu_id(), APIC_MODE_XAPIC); + init_apic(bsp->id, APIC_MODE_XAPIC); init_tasks(); @@ -232,20 +230,20 @@ void __noreturn __text_init kernel_start(uint32_t multiboot_magic, init_pci(); /* Initialize console input */ - init_uart_input(get_bsp_cpu_id()); + init_uart_input(bsp); /* Initialize timers */ bool hpet_initialized = false; if (opt_hpet) - hpet_initialized = init_hpet(get_bsp_cpu_id()); + hpet_initialized = init_hpet(bsp); if (!hpet_initialized && opt_pit) - init_pit(get_bsp_cpu_id()); + init_pit(bsp); if (opt_apic_timer) init_apic_timer(); /* Initialize keyboard */ if (opt_keyboard) - init_keyboard(get_bsp_cpu_id()); + init_keyboard(bsp); if (opt_fpu) { printk("Enabling FPU instructions support\n"); diff --git a/drivers/acpi/acpica/osl.c b/drivers/acpi/acpica/osl.c index 23511159..6fd7a1ac 100644 --- a/drivers/acpi/acpica/osl.c +++ b/drivers/acpi/acpica/osl.c @@ -23,6 +23,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef KTF_ACPICA +#include #include #include #include @@ -359,12 +360,12 @@ unsigned long _osd_exec_cb_wrapper(void *arg) { ACPI_STATUS AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function, void *Context) { static unsigned counter = 0; - unsigned cpu = smp_processor_id(); + cpu_t *cpu = get_cpu(smp_processor_id()); osd_exec_cb_wrapper_t cb; char name[40]; task_t *task; - snprintf(name, sizeof(name), "acpi_%u_%u_%u", Type, counter++, cpu); + snprintf(name, sizeof(name), "acpi_%u_%u_%u", Type, counter++, cpu->id); cb.Function = Function; cb.Context = Context; @@ -373,7 +374,7 @@ ACPI_STATUS AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Functio return AE_NO_MEMORY; set_task_group(task, TASK_GROUP_ACPI); - schedule_task(task, cpu); + schedule_task(task, cpu->id); return AE_OK; } @@ -555,7 +556,8 @@ void acpi_interrupt_handler(void) { ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 InterruptLevel, ACPI_OSD_HANDLER Handler, void *Context) { - percpu_t *percpu = get_percpu_page(get_bsp_cpu_id()); + cpu_t *cpu = get_bsp_cpu(); + percpu_t *percpu = cpu->percpu; if (acpi_irq_installed) return AE_ALREADY_EXISTS; @@ -577,7 +579,8 @@ ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 InterruptLevel, ACPI_OSD_HANDLE ACPI_STATUS AcpiOsRemoveInterruptHandler(UINT32 InterruptLevel, ACPI_OSD_HANDLER Handler) { - percpu_t *percpu = get_percpu_page(get_bsp_cpu_id()); + cpu_t *cpu = get_bsp_cpu(); + percpu_t *percpu = cpu->percpu; if (!acpi_irq_installed) return AE_NOT_EXIST; diff --git a/drivers/hpet.c b/drivers/hpet.c index 6a1a92f7..4046a8d3 100644 --- a/drivers/hpet.c +++ b/drivers/hpet.c @@ -27,7 +27,7 @@ #include #include -bool init_hpet(uint8_t dst_cpus) { +bool init_hpet(const cpu_t *cpu) { #ifndef KTF_ACPICA acpi_hpet_t *hpet; #else @@ -99,7 +99,7 @@ bool init_hpet(uint8_t dst_cpus) { general->leg_repl_cfg = 0; /* Disable legacy route */ general->enabled = 1; - configure_isa_irq(HPET_IRQ, HPET_IRQ_OFFSET, IOAPIC_DEST_MODE_PHYSICAL, dst_cpus); + configure_isa_irq(HPET_IRQ, HPET_IRQ_OFFSET, IOAPIC_DEST_MODE_PHYSICAL, cpu->id); dprintk("Initialized HPET\n"); return true; } diff --git a/drivers/keyboard.c b/drivers/keyboard.c index 0c2e072e..daf0d11b 100644 --- a/drivers/keyboard.c +++ b/drivers/keyboard.c @@ -62,7 +62,7 @@ typedef struct keyboard_state keyboard_state_t; static keyboard_state_t keyboard_state; -void init_keyboard(uint8_t dst_cpus) { +void init_keyboard(const cpu_t *cpu) { if (!boot_flags.i8042) { dprintk("No i8042 microcontroller detected\n"); return; @@ -144,7 +144,7 @@ void init_keyboard(uint8_t dst_cpus) { outb(KEYBOARD_PORT_DATA, current_status.config); configure_isa_irq(KEYBOARD_PORT1_IRQ, KEYBOARD_PORT1_IRQ0_OFFSET, - IOAPIC_DEST_MODE_PHYSICAL, dst_cpus); + IOAPIC_DEST_MODE_PHYSICAL, cpu->id); outb(KEYBOARD_PORT_CMD, KEYBOARD_CMD_ENABLE_PORT_1); } else { @@ -154,7 +154,7 @@ void init_keyboard(uint8_t dst_cpus) { outb(KEYBOARD_PORT_DATA, current_status.config); configure_isa_irq(KEYBOARD_PORT2_IRQ, KEYBOARD_PORT2_IRQ0_OFFSET, - IOAPIC_DEST_MODE_PHYSICAL, dst_cpus); + IOAPIC_DEST_MODE_PHYSICAL, cpu->id); outb(KEYBOARD_PORT_CMD, KEYBOARD_CMD_ENABLE_PORT_2); } diff --git a/drivers/pit.c b/drivers/pit.c index d90597c9..de81e679 100644 --- a/drivers/pit.c +++ b/drivers/pit.c @@ -30,12 +30,12 @@ #include #include -void init_pit(uint8_t dst_cpus) { +void init_pit(const cpu_t *cpu) { printk("Initializing PIT\n"); outb(PIT_COMMAND_PORT, PIT_CHANNEL_0 | PIT_ACCESS_MODE_LH | PIT_OP_MODE_RATE); outb(PIT_DATA_PORT_CH0, PIT_FREQUENCY & 0xFF); /* send low byte */ outb(PIT_DATA_PORT_CH0, (PIT_FREQUENCY & 0xFF00) >> 8); /* send high byte */ - configure_isa_irq(PIT_IRQ, PIT_IRQ0_OFFSET, IOAPIC_DEST_MODE_PHYSICAL, dst_cpus); + configure_isa_irq(PIT_IRQ, PIT_IRQ0_OFFSET, IOAPIC_DEST_MODE_PHYSICAL, cpu->id); } void pit_disable(void) { pic_disable_irq(PIC1_DEVICE_SEL, PIT_IRQ); } diff --git a/drivers/serial.c b/drivers/serial.c index 67d5bd80..12f6f93f 100644 --- a/drivers/serial.c +++ b/drivers/serial.c @@ -155,15 +155,15 @@ void __text_init init_uart(uart_config_t *cfg) { com_ports[0] = cfg->port; } -void __text_init init_uart_input(uint8_t dst_cpus) { +void __text_init init_uart_input(const cpu_t *cpu) { /* Initialize input state */ memset(&input_state, 0, sizeof(input_state)); /* Enable IRQ lines */ printk("Enabling serial input\n"); - configure_isa_irq(COM1_IRQ, COM1_IRQ0_OFFSET, IOAPIC_DEST_MODE_PHYSICAL, dst_cpus); - configure_isa_irq(COM2_IRQ, COM2_IRQ0_OFFSET, IOAPIC_DEST_MODE_PHYSICAL, dst_cpus); + configure_isa_irq(COM1_IRQ, COM1_IRQ0_OFFSET, IOAPIC_DEST_MODE_PHYSICAL, cpu->id); + configure_isa_irq(COM2_IRQ, COM2_IRQ0_OFFSET, IOAPIC_DEST_MODE_PHYSICAL, cpu->id); } static inline int uart_port_status(io_port_t port) { diff --git a/include/acpi_ktf.h b/include/acpi_ktf.h index 2d571fc1..72a6ada4 100644 --- a/include/acpi_ktf.h +++ b/include/acpi_ktf.h @@ -267,7 +267,7 @@ typedef struct acpi_madt acpi_madt_t; /* External Declarations */ extern acpi_table_t *acpi_find_table(uint32_t signature); -extern int init_acpi(unsigned bsp_cpu_id); +extern int init_acpi(void); #else /* KTF_ACPICA */ @@ -289,7 +289,7 @@ extern void *acpi_find_table(char *signature); extern void acpi_walk_subtables(ACPI_SUBTABLE_HEADER *entry, uint32_t length, acpi_subtable_parser_t parser, void *arg); -extern ACPI_STATUS init_acpi(unsigned bsp_cpu_id); +extern ACPI_STATUS init_acpi(void); extern void acpi_power_off(void); #endif /* KTF_ACPICA */ diff --git a/include/arch/x86/apic.h b/include/arch/x86/apic.h index 027afb11..953861e7 100644 --- a/include/arch/x86/apic.h +++ b/include/arch/x86/apic.h @@ -457,7 +457,7 @@ typedef union apic_self_ipi apic_self_ipi_t; extern uint64_t apic_read(unsigned int reg); extern void apic_write(unsigned int reg, uint64_t val); extern apic_mode_t apic_get_mode(void); -extern void init_apic(unsigned int cpu, apic_mode_t mode); +extern void init_apic(unsigned int cpu_id, apic_mode_t mode); extern apic_icr_t apic_icr_read(void); extern void apic_icr_write(const apic_icr_t *icr); diff --git a/include/arch/x86/traps.h b/include/arch/x86/traps.h index cd3ee1fa..cd5dc680 100644 --- a/include/arch/x86/traps.h +++ b/include/arch/x86/traps.h @@ -33,8 +33,9 @@ #define X86_RET2KERN_INT 32 #ifndef __ASSEMBLY__ +#include -extern void init_traps(unsigned int cpu); +extern void init_traps(const cpu_t *cpu); extern void init_boot_traps(void); extern void init_rmode_traps(void); diff --git a/include/drivers/hpet.h b/include/drivers/hpet.h index aa9f122b..d9974606 100644 --- a/include/drivers/hpet.h +++ b/include/drivers/hpet.h @@ -27,6 +27,8 @@ #ifndef KTF_HPET_H #define KTF_HPET_H +#include + #ifndef KTF_ACPICA #include #else @@ -109,6 +111,6 @@ enum { /* External Declarations */ -extern bool init_hpet(uint8_t dst_cpus); +extern bool init_hpet(const cpu_t *cpu); #endif /* KTF_HPET_H */ diff --git a/include/drivers/keyboard.h b/include/drivers/keyboard.h index 508c41ef..e9bc8643 100644 --- a/include/drivers/keyboard.h +++ b/include/drivers/keyboard.h @@ -25,6 +25,7 @@ #ifndef KTF_KEYBOARD_H #define KTF_KEYBOARD_H +#include #include #define KEYBOARD_PORT_CMD 0x64 /* keyboard command port */ @@ -114,7 +115,7 @@ typedef enum scan_code scan_code_t; /* External Declarations */ -extern void init_keyboard(uint8_t dst_cpus); +extern void init_keyboard(const cpu_t *cpu); extern void keyboard_interrupt_handler(void); extern unsigned int keyboard_process_keys(void); diff --git a/include/drivers/pit.h b/include/drivers/pit.h index b1e8aedd..c90b8f55 100644 --- a/include/drivers/pit.h +++ b/include/drivers/pit.h @@ -25,6 +25,7 @@ #ifndef KTF_PIT_H #define KTF_PIT_H +#include #include #include @@ -56,7 +57,7 @@ typedef enum pit_operational_mode pit_operational_mode_t; #define PIT_BCD_MODE 1 -extern void init_pit(uint8_t dst_cpus); +extern void init_pit(const cpu_t *cpu); extern void pit_disable(void); #endif diff --git a/include/drivers/serial.h b/include/drivers/serial.h index 6145135b..8e7463e2 100644 --- a/include/drivers/serial.h +++ b/include/drivers/serial.h @@ -25,6 +25,7 @@ #ifndef KTF_DRV_SERIAL_H #define KTF_DRV_SERIAL_H +#include #include #include @@ -197,7 +198,7 @@ extern io_port_t com_ports[4]; extern io_port_t get_first_com_port(void); extern void init_uart(uart_config_t *cfg); -extern void init_uart_input(uint8_t dst_cpus); +extern void init_uart_input(const cpu_t *cpu); extern void uart_interrupt_handler(void); extern int serial_putchar(io_port_t port, char c); extern int serial_write(io_port_t port, const char *buf, size_t len); diff --git a/include/percpu.h b/include/percpu.h index bd07c450..06fe7cbb 100644 --- a/include/percpu.h +++ b/include/percpu.h @@ -42,8 +42,6 @@ struct percpu { char sapic_uid_str[1]; apic_base_t apic_base; - bool enabled; - bool bsp; uint8_t family; uint8_t model; uint8_t stepping; @@ -130,6 +128,5 @@ typedef struct percpu percpu_t; extern void init_percpu(void); extern percpu_t *get_percpu_page(unsigned int cpu); -extern void for_each_percpu(void (*func)(percpu_t *percpu)); #endif /* KTF_PERCPU_H */ diff --git a/smp/mptables.c b/smp/mptables.c index f708ef82..fdfb3679 100644 --- a/smp/mptables.c +++ b/smp/mptables.c @@ -23,6 +23,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include +#include #include #include #include @@ -34,8 +35,6 @@ #include -static unsigned nr_cpus; - static inline uint8_t get_mp_checksum(void *ptr, size_t len) { uint8_t checksum = 0; @@ -207,18 +206,25 @@ static void process_mpc_entries(mpc_hdr_t *mpc_ptr) { switch (*entry_ptr) { case MPC_PROCESSOR_ENTRY: { mpc_processor_entry_t *mpc_cpu = (mpc_processor_entry_t *) entry_ptr; - percpu_t *percpu = get_percpu_page(nr_cpus++); + bool enabled = !!mpc_cpu->en; + cpu_t *cpu; + + if (!!mpc_cpu->bsp) { + cpu = get_bsp_cpu(); + BUG_ON(!cpu); + } + else + cpu = get_cpu(mpc_cpu->lapic_id) + ?: add_cpu(mpc_cpu->lapic_id, false, enabled); + + cpu->enabled = enabled; + percpu_t *percpu = cpu->percpu; percpu->apic_id = mpc_cpu->lapic_id; - percpu->enabled = !!mpc_cpu->en; - percpu->bsp = !!mpc_cpu->bsp; percpu->family = mpc_cpu->family; percpu->model = mpc_cpu->model; percpu->stepping = mpc_cpu->stepping; - if (percpu->bsp) - set_bsp_cpu_id(percpu->cpu_id); - dump_mpc_processor_entry(mpc_cpu); entry_ptr += sizeof(*mpc_cpu); break; @@ -283,15 +289,12 @@ static void process_mpc_entries(mpc_hdr_t *mpc_ptr) { } } -unsigned mptables_get_nr_cpus(void) { return nr_cpus; } - int init_mptables(void) { mpf_t *mpf_ptr = get_mpf_addr(); mpc_hdr_t *mpc_ptr; if (!mpf_ptr) { printk("No MP Floating Structure Pointer found!\n"); - nr_cpus = 0; return -ENODEV; } diff --git a/smp/smp.c b/smp/smp.c index 0ebddfc9..ca6d83f4 100644 --- a/smp/smp.c +++ b/smp/smp.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -50,13 +51,15 @@ cr3_t __data_init ap_cr3; void __noreturn ap_startup(void) { WRITE_SP(ap_new_sp); - init_traps(ap_cpuid); + cpu_t *cpu = get_cpu(ap_cpuid); + + init_traps(cpu); init_apic(ap_cpuid, apic_get_mode()); ap_callin = true; smp_wmb(); - run_tasks(smp_processor_id()); + run_tasks(cpu->id); while (true) halt(); @@ -64,18 +67,19 @@ void __noreturn ap_startup(void) { UNREACHABLE(); } -static __text_init void boot_cpu(percpu_t *percpu) { +static __text_init void boot_cpu(cpu_t *cpu) { + percpu_t *percpu = cpu->percpu; apic_icr_t icr; - if (percpu->bsp) + if (cpu->bsp) return; ap_new_sp = get_free_pages_top(PAGE_ORDER_2M, GFP_KERNEL); - ap_cpuid = percpu->cpu_id; + ap_cpuid = cpu->id; ap_callin = false; smp_wmb(); - dprintk("Starting AP: %u\n", percpu->cpu_id); + dprintk("Starting AP: %u\n", cpu->id); memset(&icr, 0, sizeof(icr)); apic_icr_set_dest(&icr, percpu->apic_id); @@ -98,23 +102,14 @@ static __text_init void boot_cpu(percpu_t *percpu) { while (!ap_callin) cpu_relax(); - dprintk("AP: %u Done \n", percpu->cpu_id); + dprintk("AP: %u Done \n", cpu->id); } void __text_init init_smp(void) { - nr_cpus = acpi_get_nr_cpus(); - if (nr_cpus == 0) { - nr_cpus = mptables_get_nr_cpus(); - if (nr_cpus == 0) { - nr_cpus++; - return; - } - } + nr_cpus = get_nr_cpus(); printk("Initializing SMP support (CPUs: %u)\n", nr_cpus); ap_cr3 = cr3; - for_each_percpu(boot_cpu); + for_each_cpu(boot_cpu); } - -unsigned get_nr_cpus(void) { return nr_cpus; }