24 if (lapicPhysAddr ==
NULL)
26 LOG_ERR(
"madt has invalid lapic address\n");
34 LOG_ERR(
"failed to map local apic\n");
38 LOG_INFO(
"local apic mapped base=0x%016lx phys=0x%016lx\n",
lapicBase, lapicPhysAddr);
58 LOG_ERR(
"failed to map io apic\n");
64 for (
uint32_t i = 0; i < maxRedirs; i++)
71 LOG_INFO(
"io apic initialized base=0x%016lx gsiBase=%u maxRedirs=%u\n", virtAddr,
83 LOG_ERR(
"multiple MADT tables found\n");
90 LOG_ERR(
"failed to initialize local apic\n");
96 LOG_ERR(
"failed to initialize ioapics\n");
109 panic(
NULL,
"apic timer used before apic initialized");
123 panic(
NULL,
"apic timer calibration used before apic initialized");
142 LOG_DEBUG(
"timer calibration ticks=%llu ticks_per_ns=%llu\n", ticks, ticksPerNs);
151 panic(
NULL,
"local apic used before apic initialized");
175 panic(
NULL,
"local apic used before apic initialized");
185 panic(
NULL,
"local apic used before apic initialized");
195 panic(
NULL,
"local apic used before apic initialized");
205 panic(
NULL,
"local apic used before apic initialized");
216 panic(
NULL,
"local apic used before apic initialized");
229 panic(
NULL,
"local apic used before apic initialized");
240 panic(
NULL,
"local apic used before apic initialized");
250 panic(
NULL,
"ioapic used before apic initialized");
262 panic(
NULL,
"ioapic used before apic initialized");
274 panic(
NULL,
"ioapic used before apic initialized");
286 panic(
NULL,
"ioapic used before apic initialized");
304 panic(
NULL,
"Failed to locate vector for gsi %d", gsi);
312 panic(
NULL,
"ioapic used before apic initialized");
317 .deliveryMode = deliveryMode,
319 .polarity = polarity,
321 .triggerMode = triggerMode,
322 .mask = enable ? 0 : 1,
332 LOG_INFO(
"ioapic redirect set gsi=%u vector=0x%02x cpu=%u enable=%d\n", gsi, vector, cpu->
id, enable);
static uint64_t lapic_init(void)
static uint64_t ioapic_all_init(void)
static uintptr_t lapicBase
static uint64_t apic_init(sdt_header_t *table)
#define assert(expression)
#define ACPI_SDT_HANDLER_REGISTER(sig, initHandler)
Macro to register an ACPI SDT handler.
#define MADT_FOR_EACH(madt, ic)
Iterate over all MADT interrupt controllers.
#define MADT_SIGNATURE
MADT table signature.
#define INTERRUPT_CONTROLLER_IO_APIC
void interrupt_disable(void)
Disable interrupts and increment the disableDepth.
void interrupt_enable(void)
Decrement the CLI depth and enable interrupts if depth reaches zero and interrupts were previously en...
interrupt_t
CPU vector identifiers.
static cpu_t * smp_self_unsafe(void)
Returns a pointer to the cpu_t structure of the current CPU.
ioapic_delivery_mode_t
IO APIC Delivery Modes.
#define IOAPIC_REG_REDIRECTION(pin, high)
Macro to get the redirection entry register for a specific pin.
ioapic_register_t
IO APIC Registers.
#define LAPIC_REG_ICR1_ID_OFFSET
The offset at which the lapic id is stored in the LAPIC_REG_ID register.
void ioapic_write(ioapic_t *ioapic, ioapic_register_t reg, uint32_t value)
Write to an IOAPIC register.
uint64_t apic_timer_ticks_per_ns(void)
Apic timer ticks per nanosecond.
ioapic_polarity_t
IO APIC Polarity Modes.
void lapic_cpu_init(void)
Initialize the local apic for the current cpu.
void lapic_eoi(void)
Send an End Of Interrupt (EOI) signal to the local apic.
void ioapic_set_redirect(interrupt_t vector, ioapic_gsi_t gsi, ioapic_delivery_mode_t deliveryMode, ioapic_polarity_t polarity, ioapic_trigger_mode_t triggerMode, cpu_t *cpu, bool enable)
Set an IOAPIC redirection entry.
void apic_timer_one_shot(interrupt_t vector, uint32_t ticks)
Configure the apic timer in one-shot mode.
void lapic_send_init(lapic_id_t id)
Send an INIT IPI to a local apic.
uint32_t ioapic_gsi_t
IO APIC Global System Interrupt type.
void lapic_send_sipi(lapic_id_t id, void *entryPoint)
Send a Startup IPI to a local apic.
ioapic_version_t ioapic_get_version(ioapic_t *ioapic)
Get the IOAPIC version.
lapic_id_t lapic_self_id(void)
Get the lapic id of the current cpu.
uint32_t ioapic_read(ioapic_t *ioapic, ioapic_register_t reg)
Read from an IOAPIC register.
#define APIC_TIMER_TICKS_FIXED_POINT_OFFSET
APIC Timer Ticks Fixed Point Offset.
ioapic_trigger_mode_t
IO APIC Trigger Modes.
uint8_t lapic_id_t
Local APIC ID type.
void lapic_send_ipi(lapic_id_t id, interrupt_t vector)
Send an Inter-Processor Interrupt (IPI) to a local apic.
ioapic_t * ioapic_from_gsi(ioapic_gsi_t gsi)
Get the IOAPIC id responsible for a given GSI.
lapic_register_t
Local APIC Registers.
uint32_t lapic_read(lapic_register_t reg)
Read from a local apic register.
void lapic_write(lapic_register_t reg, uint32_t value)
Write to a local apic register.
@ APIC_TIMER_MASKED
Timer is masked (disabled)
@ LAPIC_ICR_CLEAR_INIT_LEVEL
@ LAPIC_REG_TASK_PRIORITY
@ LAPIC_REG_TIMER_CURRENT_COUNT
@ LAPIC_REG_TIMER_INITIAL_COUNT
@ LAPIC_REG_TIMER_DIVIDER
void hpet_wait(clock_t nanoseconds)
Wait for a specified number of nanoseconds using the HPET.
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
#define LOG_ERR(format,...)
#define LOG_INFO(format,...)
#define LOG_DEBUG(format,...)
#define PML_LOWER_TO_HIGHER(addr)
Converts an address from the lower half to the higher half.
void * vmm_map(space_t *space, void *virtAddr, void *physAddr, uint64_t length, pml_flags_t flags, space_callback_func_t func, void *private)
Maps physical memory to virtual memory in a given address space.
#define PAGE_SIZE
Memory page size.
#define NULL
Pointer error value.
#define ERR
Integer error value.
static void msr_write(uint32_t msr, uint64_t value)
static uint64_t msr_read(uint32_t msr)
__UINTPTR_TYPE__ uintptr_t
uint32_t globalSystemInterruptBase
interrupt_controller_header_t header
IO APIC Version Structure.
Multiple APIC Description Table.
uint32_t localInterruptControllerAddress
IO APIC Redirection Entry Structure.
struct ioapic_redirect_entry_t::PACKED raw
#define WRITE_32(address, value)