diff --git a/arch/x86_64/acpi/apic.cpp b/arch/x86_64/acpi/apic.cpp index a12328b..5294350 100644 --- a/arch/x86_64/acpi/apic.cpp +++ b/arch/x86_64/acpi/apic.cpp @@ -70,7 +70,7 @@ static io_apic *get_ioapic_for_irq(unsigned int vec) static void configure_legacy_pic(void) { printk("acpi: APIC unavailable"); - pit_start(10); + pit_start(HZ); } static void ioapic_init(uintptr_t base, unsigned int int_base) @@ -172,14 +172,21 @@ static void init_all_ioapic(struct acpi_madt *madt) parse_legacy_irq_override(madt); } +kern_status_t ap_apic_init(void) +{ + struct acpi_madt *madt = (struct acpi_madt *)acpi_find_sdt(ACPI_SIG_MADT); + local_apic_enable(madt); + + //irq_enable(); + local_apic_config_timer(); + + return KERN_OK; +} + +/* only the bootstrap processor should call apic_init() + all other APs should call ap_apic_init() instead */ kern_status_t apic_init(void) { - /* the bootstrap processor will be the first one ro call apic_init(). - it is responsible for initialising the I/O APICs */ - if (bsp_id == (unsigned int)-1) { - bsp_id = this_cpu(); - } - struct acpi_madt *madt = (struct acpi_madt *)acpi_find_sdt(ACPI_SIG_MADT); if (check_apic() == 0 || !madt) { @@ -187,9 +194,8 @@ kern_status_t apic_init(void) return KERN_UNSUPPORTED; } - if (this_cpu() == bsp_id) { - init_all_ioapic(madt); - } + bsp_id = this_cpu(); + init_all_ioapic(madt); local_apic_enable(madt); disable_8259(); @@ -198,7 +204,6 @@ kern_status_t apic_init(void) irq_enable(); pit_start(HZ); - return KERN_OK; local_apic_config_timer(); pit_stop(); diff --git a/arch/x86_64/acpi/smp.cpp b/arch/x86_64/acpi/smp.cpp index c80b043..e0e8471 100644 --- a/arch/x86_64/acpi/smp.cpp +++ b/arch/x86_64/acpi/smp.cpp @@ -10,32 +10,37 @@ using namespace arch::acpi; extern "C" uint8_t acpi_bsp_lapic_id(void); extern "C" char ap_trampoline[]; +volatile struct vm_page *__ap_stack_page = NULL; volatile uintptr_t __ap_stack_top = 0; volatile uint8_t __this_ap_ok = 0; volatile uint8_t __all_ap_ok = 0; - -/* -static int __used send_ipi(void *lapic, unsigned int target_id, uint32_t -payload) -{ - uintptr_t lapic_ptr = (uintptr_t)lapic; - - *((volatile uint32_t*)(lapic_ptr + LAPIC_IPI_STATUS_REG)) = 0; - *((volatile uint32_t*)(lapic_ptr + LAPIC_IPI_DEST_REG)) = (*((volatile -uint32_t*)(lapic_ptr + LAPIC_IPI_DEST_REG)) & 0x00ffffff) | (target_id << 24); - *((volatile uint32_t*)(lapic_ptr + LAPIC_IPI_ICR_REG)) = (*((volatile -uint32_t*)(lapic_ptr + LAPIC_IPI_ICR_REG)) & 0xfff00000) | payload; do { __asm__ -__volatile__ ("pause" : : : "memory"); }while(*((volatile uint32_t*)(lapic_ptr + -LAPIC_IPI_ICR_REG)) & (1 << 12)); - - return 0; -} -*/ +volatile unsigned int __this_ap_id = 0; extern "C" void ap_trampoline_exit(void) { - printk("OK!"); + ml_cpu_block *this_cpu = (ml_cpu_block *)kmalloc(sizeof *this_cpu, VM_NORMAL); + ml_cpu_block_init(this_cpu); + ml_cpu_block_use(this_cpu); + + this_cpu->c_cpu_id = __this_ap_id; + + struct cpu_data *self = get_this_cpu(); + self->c_flags = CPU_ONLINE; + self->c_id = __this_ap_id; + this_cpu->c_data = self; + + struct thread *this_thread = create_idle_thread(); + this_thread->tr_kstack = (struct vm_page *)__ap_stack_page; + self->c_rq.rq_idle = self->c_rq.rq_cur = this_thread; + + put_cpu(self); + + ap_apic_init(); + __this_ap_ok = 1; + irq_enable(); + + idle(); } static int init_ap(struct acpi_madt_record *rec, local_apic& lapic, uint8_t bsp_id) @@ -46,12 +51,13 @@ static int init_ap(struct acpi_madt_record *rec, local_apic& lapic, uint8_t bsp_ } if (ap_lapic->l_apic_id == bsp_id) { - printk("acpi: core %u online [BSP]", ap_lapic->l_apic_id); + //printk("acpi: core %u online [BSP]", ap_lapic->l_apic_id); return 0; } - struct vm_page *ap_stack = vm_page_alloc(VM_PAGE_4K, VM_NORMAL); - __ap_stack_top = (uintptr_t)vm_page_get_vaddr(ap_stack) + VM_PAGE_SIZE; + __ap_stack_page = vm_page_alloc(VM_PAGE_4K, VM_NORMAL); + __ap_stack_top = (uintptr_t)vm_page_get_vaddr((struct vm_page *)__ap_stack_page) + VM_PAGE_SIZE; + __this_ap_id = ap_lapic->l_apic_id; lapic.send_ipi(ap_lapic->l_apic_id, 0xC500); lapic.send_ipi(ap_lapic->l_apic_id, 0x8500); @@ -62,7 +68,7 @@ static int init_ap(struct acpi_madt_record *rec, local_apic& lapic, uint8_t bsp_ ml_cpu_relax(); } while (__this_ap_ok == 0); - printk("acpi: core %u online [AP]", ap_lapic->l_apic_id); + //printk("acpi: core %u online [AP]", ap_lapic->l_apic_id); return 0; } diff --git a/arch/x86_64/include/arch/acpi.h b/arch/x86_64/include/arch/acpi.h index 969f1e7..14173fa 100644 --- a/arch/x86_64/include/arch/acpi.h +++ b/arch/x86_64/include/arch/acpi.h @@ -111,6 +111,7 @@ struct lapic_override_record { extern kern_status_t acpi_init(void); extern kern_status_t acpi_scan_cpu_topology(void); +extern kern_status_t ap_apic_init(void); extern kern_status_t apic_init(void); extern kern_status_t smp_init(void);