forked from Bananymous/banan-os
Kernel: Cleanup multiprocessor startup by removing magic numbers
This commit is contained in:
parent
29fd682672
commit
23a2f8b903
|
@ -31,6 +31,35 @@ extern volatile uint8_t g_ap_stack_loaded[];
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
enum ICR_LO : uint32_t
|
||||||
|
{
|
||||||
|
ICR_LO_reserved_mask = 0xFFF32000,
|
||||||
|
|
||||||
|
ICR_LO_delivery_mode_fixed = 0b000 << 8,
|
||||||
|
ICR_LO_delivery_mode_lowest_priority = 0b001 << 8,
|
||||||
|
ICR_LO_delivery_mode_smi = 0b010 << 8,
|
||||||
|
ICR_LO_delivery_mode_nmi = 0b100 << 8,
|
||||||
|
ICR_LO_delivery_mode_init = 0b101 << 8,
|
||||||
|
ICR_LO_delivery_mode_start_up = 0b110 << 8,
|
||||||
|
|
||||||
|
ICR_LO_destination_mode_physical = 0 << 11,
|
||||||
|
ICR_LO_destination_mode_logical = 1 << 11,
|
||||||
|
|
||||||
|
ICR_LO_delivery_status_idle = 0 << 12,
|
||||||
|
ICR_LO_delivery_status_send_pending = 1 << 12,
|
||||||
|
|
||||||
|
ICR_LO_level_deassert = 0 << 14,
|
||||||
|
ICR_LO_level_assert = 1 << 14,
|
||||||
|
|
||||||
|
ICR_LO_trigger_mode_edge = 0 << 15,
|
||||||
|
ICR_LO_trigger_mode_level = 1 << 15,
|
||||||
|
|
||||||
|
ICR_LO_destination_shorthand_none = 0b00 << 18,
|
||||||
|
ICR_LO_destination_shorthand_self = 0b01 << 18,
|
||||||
|
ICR_LO_destination_shorthand_all_including_self = 0b10 << 18,
|
||||||
|
ICR_LO_destination_shorthand_all_excluding_self = 0b11 << 18,
|
||||||
|
};
|
||||||
|
|
||||||
struct MADT : public Kernel::ACPI::SDTHeader
|
struct MADT : public Kernel::ACPI::SDTHeader
|
||||||
{
|
{
|
||||||
uint32_t local_apic;
|
uint32_t local_apic;
|
||||||
|
@ -208,7 +237,7 @@ namespace Kernel
|
||||||
write_to_local_apic(LAPIC_ICR_HI_REG, (read_from_local_apic(LAPIC_ICR_HI_REG) & 0x00FFFFFF) | (processor << 24));
|
write_to_local_apic(LAPIC_ICR_HI_REG, (read_from_local_apic(LAPIC_ICR_HI_REG) & 0x00FFFFFF) | (processor << 24));
|
||||||
write_to_local_apic(LAPIC_ICR_LO_REG, data);
|
write_to_local_apic(LAPIC_ICR_LO_REG, data);
|
||||||
udelay(ud);
|
udelay(ud);
|
||||||
while (read_from_local_apic(LAPIC_ICR_LO_REG) & (1 << 12))
|
while ((read_from_local_apic(LAPIC_ICR_LO_REG) & ICR_LO_delivery_status_send_pending) == ICR_LO_delivery_status_send_pending)
|
||||||
__builtin_ia32_pause();
|
__builtin_ia32_pause();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -232,30 +261,55 @@ namespace Kernel
|
||||||
|
|
||||||
dprintln("Trying to enable processor (lapic id {})", processor.apic_id);
|
dprintln("Trying to enable processor (lapic id {})", processor.apic_id);
|
||||||
|
|
||||||
auto& proc = Kernel::Processor::create(processor.processor_id);
|
auto& proc = Kernel::Processor::create(processor.apic_id);
|
||||||
PageTable::with_fast_page((paddr_t)g_ap_init_addr, [&] {
|
PageTable::with_fast_page((paddr_t)g_ap_init_addr, [&] {
|
||||||
PageTable::fast_page_as_sized<uint32_t>(2) = V2P(proc.stack_top());
|
PageTable::fast_page_as_sized<uint32_t>(2) = V2P(proc.stack_top());
|
||||||
});
|
});
|
||||||
*g_ap_stack_loaded = 0;
|
*g_ap_stack_loaded = 0;
|
||||||
|
|
||||||
write_to_local_apic(LAPIC_ERROR_REG, 0x00);
|
write_to_local_apic(LAPIC_ERROR_REG, 0x00);
|
||||||
send_ipi(processor.processor_id, (read_from_local_apic(LAPIC_ICR_LO_REG) & 0xFFF00000) | 0x0000C500, 0);
|
|
||||||
send_ipi(processor.processor_id, (read_from_local_apic(LAPIC_ICR_LO_REG) & 0xFFF0F800) | 0x00008500, 0);
|
// send INIT IPI
|
||||||
|
send_ipi(processor.apic_id,
|
||||||
|
(read_from_local_apic(LAPIC_ICR_LO_REG) & ICR_LO_reserved_mask)
|
||||||
|
| ICR_LO_delivery_mode_init
|
||||||
|
| ICR_LO_destination_mode_physical
|
||||||
|
| ICR_LO_level_assert
|
||||||
|
| ICR_LO_trigger_mode_edge
|
||||||
|
| ICR_LO_destination_shorthand_none
|
||||||
|
, 0
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: If we are on processor predating Pentium, we need to send deassert
|
||||||
|
|
||||||
udelay(10 * 1000);
|
udelay(10 * 1000);
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
write_to_local_apic(LAPIC_ERROR_REG, 0x00);
|
write_to_local_apic(LAPIC_ERROR_REG, 0x00);
|
||||||
send_ipi(processor.processor_id, (read_from_local_apic(LAPIC_ICR_LO_REG) & 0xFFF0F800) | 0x00000600 | ap_init_page, 200);
|
|
||||||
|
// send 2 SETUP IPIs with 200 us delay
|
||||||
|
send_ipi(processor.apic_id,
|
||||||
|
(read_from_local_apic(LAPIC_ICR_LO_REG) & ICR_LO_reserved_mask)
|
||||||
|
| ICR_LO_delivery_mode_start_up
|
||||||
|
| ICR_LO_destination_mode_physical
|
||||||
|
| ICR_LO_level_assert
|
||||||
|
| ICR_LO_trigger_mode_edge
|
||||||
|
| ICR_LO_destination_shorthand_none
|
||||||
|
| ap_init_page
|
||||||
|
, 200
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// give processor upto 100 * 100 us (10 ms to boot)
|
// give processor upto 100 * 100 us + 200 us to boot
|
||||||
for (int i = 0; *g_ap_stack_loaded == 0 && i < 100; i++)
|
for (int i = 0; *g_ap_stack_loaded == 0 && i < 100; i++)
|
||||||
udelay(100);
|
udelay(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
*g_ap_startup_done = 1;
|
*g_ap_startup_done = 1;
|
||||||
|
|
||||||
|
// give processors 100 us time to increment running count
|
||||||
|
udelay(100);
|
||||||
dprintln("{} processors started", *g_ap_running_count);
|
dprintln("{} processors started", *g_ap_running_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue