x86_64: acpi: bring up other APs in long mode
This commit is contained in:
@@ -21,7 +21,6 @@ static unsigned int bsp_id = (unsigned int)-1;
|
||||
|
||||
using namespace arch::acpi;
|
||||
|
||||
static uint32_t *lapic_base;
|
||||
static struct queue io_apics;
|
||||
|
||||
extern "C" {
|
||||
@@ -46,45 +45,13 @@ static void disable_8259(void)
|
||||
outportb(PIC2_DATA, 0xFF);
|
||||
}
|
||||
|
||||
static void *find_lapic(struct acpi_madt *madt)
|
||||
kern_status_t local_apic_enable(struct acpi_madt *madt)
|
||||
{
|
||||
phys_addr_t local_apic = madt->m_lapic_ptr;
|
||||
|
||||
unsigned char *p = (unsigned char *)madt + sizeof *madt;
|
||||
unsigned char *madt_end = (unsigned char *)madt + madt->m_base.s_length;
|
||||
|
||||
while (p < madt_end) {
|
||||
struct acpi_madt_record *rec = (struct acpi_madt_record *)p;
|
||||
struct lapic_override_record *lapic;
|
||||
|
||||
switch (rec->r_type) {
|
||||
case ACPI_MADT_LAPIC_OVERRIDE:
|
||||
lapic = (struct lapic_override_record *)(rec + 1);
|
||||
return vm_phys_to_virt(lapic->l_lapic_ptr);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
p += rec->r_length;
|
||||
}
|
||||
|
||||
return vm_phys_to_virt(local_apic);
|
||||
}
|
||||
|
||||
|
||||
kern_status_t local_apic_enable(void)
|
||||
{
|
||||
struct acpi_madt *madt = (struct acpi_madt *)acpi_find_sdt(ACPI_SIG_MADT);
|
||||
if (!madt) {
|
||||
return KERN_UNSUPPORTED;
|
||||
}
|
||||
|
||||
apic_set_base(apic_get_base());
|
||||
lapic_base = (uint32_t *)find_lapic(madt);
|
||||
local_apic lapic(lapic_base);
|
||||
local_apic::find(madt, local_apic::get());
|
||||
|
||||
lapic.write(0xF0, 0x1FF);
|
||||
lapic.ack();
|
||||
local_apic::get().write(0xF0, 0x1FF);
|
||||
local_apic::get().ack();
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
@@ -136,7 +103,8 @@ static struct irq_hook lapic_clock_irq_hook = {
|
||||
|
||||
void local_apic_config_timer(void)
|
||||
{
|
||||
local_apic lapic(lapic_base);
|
||||
local_apic& lapic = local_apic::get();
|
||||
|
||||
lapic.write(local_apic::TIMER_DIV, 0x3);
|
||||
lapic.write(local_apic::TIMER_INITCOUNT, (uint32_t)-1);
|
||||
clock_wait(10);
|
||||
@@ -223,7 +191,7 @@ kern_status_t apic_init(void)
|
||||
init_all_ioapic(madt);
|
||||
}
|
||||
|
||||
local_apic_enable();
|
||||
local_apic_enable(madt);
|
||||
disable_8259();
|
||||
|
||||
apic_enabled = 1;
|
||||
@@ -243,8 +211,7 @@ kern_status_t apic_init(void)
|
||||
void irq_ack(unsigned int vec)
|
||||
{
|
||||
if (apic_enabled) {
|
||||
local_apic lapic(lapic_base);
|
||||
lapic.ack();
|
||||
local_apic::get().ack();
|
||||
} else {
|
||||
if (vec >= 40) {
|
||||
outportb(0xA0, 0x20);
|
||||
|
||||
Reference in New Issue
Block a user