ioapic
ioapic* next;
static ioapic* sIOAPICs = NULL;
print_ioapic(struct ioapic& ioapic)
", apic-id %u\n", ioapic.number, ioapic.global_interrupt_base,
ioapic.global_interrupt_last, ioapic.max_redirection_entry + 1,
ioapic.version, ioapic.apic_id);
static inline struct ioapic*
struct ioapic* current = sIOAPICs;
ioapic_read_32(struct ioapic& ioapic, uint8 registerSelect)
ioapic.registers->io_register_select = registerSelect;
return ioapic.registers->io_window_register;
ioapic_write_32(struct ioapic& ioapic, uint8 registerSelect, uint32 value)
ioapic.registers->io_register_select = registerSelect;
ioapic.registers->io_window_register = value;
ioapic_read_64(struct ioapic& ioapic, uint8 registerSelect)
ioapic.registers->io_register_select = registerSelect + 1;
uint64 result = ioapic.registers->io_window_register;
ioapic.registers->io_register_select = registerSelect;
result |= ioapic.registers->io_window_register;
ioapic_write_64(struct ioapic& ioapic, uint8 registerSelect, uint64 value,
ioapic.registers->io_register_select
ioapic.registers->io_window_register
ioapic.registers->io_register_select
ioapic.registers->io_window_register
ioapic_configure_pin(struct ioapic& ioapic, uint8 pin, uint8 vector,
uint64 entry = ioapic_read_64(ioapic, IO_APIC_REDIRECTION_TABLE + pin * 2);
ioapic.level_triggered_mask |= ((uint64)1 << pin);
ioapic.level_triggered_mask &= ~((uint64)1 << pin);
ioapic_write_64(ioapic, IO_APIC_REDIRECTION_TABLE + pin * 2, entry, true);
struct ioapic* ioapic = find_ioapic(gsi);
if (ioapic == NULL)
uint8 pin = gsi - ioapic->global_interrupt_base;
return (ioapic->level_triggered_mask & ((uint64)1 << pin)) != 0;
struct ioapic* ioapic = find_ioapic(gsi);
if (ioapic == NULL)
uint8 pin = gsi - ioapic->global_interrupt_base;
gsi, ioapic->number, pin, cpu, apicid);
uint64 entry = ioapic_read_64(*ioapic, IO_APIC_REDIRECTION_TABLE + pin * 2);
ioapic_write_64(*ioapic, IO_APIC_REDIRECTION_TABLE + pin * 2, entry, false);
struct ioapic* ioapic = find_ioapic(gsi);
if (ioapic == NULL)
uint8 pin = gsi - ioapic->global_interrupt_base;
" -> io-apic %u pin %u\n", gsi, ioapic->number, pin);
uint64 entry = ioapic_read_64(*ioapic, IO_APIC_REDIRECTION_TABLE + pin * 2);
ioapic_write_64(*ioapic, IO_APIC_REDIRECTION_TABLE + pin * 2, entry, false);
struct ioapic* ioapic = find_ioapic(gsi);
if (ioapic == NULL)
uint8 pin = gsi - ioapic->global_interrupt_base;
" -> io-apic %u pin %u\n", gsi, ioapic->number, pin);
uint64 entry = ioapic_read_64(*ioapic, IO_APIC_REDIRECTION_TABLE + pin * 2);
ioapic_write_64(*ioapic, IO_APIC_REDIRECTION_TABLE + pin * 2, entry, true);
struct ioapic* ioapic = find_ioapic(gsi);
if (ioapic == NULL)
uint8 pin = gsi - ioapic->global_interrupt_base;
ioapic->number, pin, config);
ioapic_configure_pin(*ioapic, pin, gsi, config,
ioapic_map_ioapic(struct ioapic& ioapic, phys_addr_t physicalAddress)
ioapic.register_area = vm_map_physical_memory(B_SYSTEM_TEAM, "io-apic",
(void**)&ioapic.registers, ioapic.registers != NULL ? B_EXACT_ADDRESS
| B_KERNEL_WRITE_AREA, physicalAddress, ioapic.registers != NULL);
if (ioapic.register_area < 0) {
panic("mapping io-apic %u failed", ioapic.number);
return ioapic.register_area;
TRACE("mapped io-apic %u to %p\n", ioapic.number, ioapic.registers);
ioapic.version = ioapic_read_32(ioapic, IO_APIC_VERSION);
if (ioapic.version == 0xffffffff) {
ioapic.number);
vm_delete_area(B_SYSTEM_TEAM, ioapic.register_area, true);
ioapic.register_area = -1;
ioapic.registers = NULL;
ioapic.max_redirection_entry
= ((ioapic.version >> IO_APIC_MAX_REDIRECTION_ENTRY_SHIFT)
if (ioapic.max_redirection_entry >= MAX_SUPPORTED_REDIRECTION_ENTRIES) {
"first %u entries\n", ioapic.number, ioapic.max_redirection_entry,
ioapic.max_redirection_entry = MAX_SUPPORTED_REDIRECTION_ENTRIES - 1;
ioapic.global_interrupt_last
= ioapic.global_interrupt_base + ioapic.max_redirection_entry;
ioapic.nmi_mask = 0;
ioapic_initialize_ioapic(struct ioapic& ioapic, uint8 targetAPIC)
ioapic_write_32(ioapic, IO_APIC_ID, ioapic.apic_id << IO_APIC_ID_SHIFT);
ioapic.level_triggered_mask = 0;
uint8 gsi = ioapic.global_interrupt_base;
for (uint8 i = 0; i <= ioapic.max_redirection_entry; i++, gsi++) {
ioapic.level_triggered_mask |= ((uint64)1 << i);
ioapic_write_64(ioapic, IO_APIC_REDIRECTION_TABLE + 2 * i, entry, true);
struct ioapic* lastIOAPIC = sIOAPICs;
struct ioapic* ioapic
= (struct ioapic*)malloc(sizeof(struct ioapic));
if (ioapic == NULL) {
ioapic->number
ioapic->apic_id = info->Id;
ioapic->global_interrupt_base = info->GlobalIrqBase;
ioapic->registers = NULL;
ioapic->next = NULL;
"\n", ioapic->number, (uint32)info->Address);
status_t status = ioapic_map_ioapic(*ioapic, info->Address);
free(ioapic);
print_ioapic(*ioapic);
sIOAPICs = ioapic;
lastIOAPIC->next = ioapic;
lastIOAPIC = ioapic;
struct ioapic* ioapic = find_ioapic(info->GlobalIrq);
if (ioapic == NULL) {
uint8 pin = info->GlobalIrq - ioapic->global_interrupt_base;
ioapic->nmi_mask |= (uint64)1 << pin;
struct ioapic* ioapic = find_ioapic(info->GlobalIrq);
if (ioapic == NULL)
uint8 pin = info->GlobalIrq - ioapic->global_interrupt_base;
ioapic_configure_pin(*ioapic, pin, info->GlobalIrq, config,
struct ioapic* ioapic = find_ioapic(gsi);
if (ioapic == NULL)
uint8 pin = gsi - ioapic->global_interrupt_base;
return (ioapic->nmi_mask & ((uint64)1 << pin)) == 0;
struct ioapic* current = sIOAPICs;