/* StarForth — Steady-State Virtual Machine Runtime Copyright (c) 2023–2025 Robert A. James All rights reserved. This file is part of the StarForth project. Licensed under the StarForth License, Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: https://github.com/star.4th@proton.me/StarForth/LICENSE.txt This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. See the License for the specific language governing permissions and limitations under the License. */ /** * ioapic.h - I/O APIC interface (amd64 only) * * Item 4.3.5 (FABRIC.md §27.5): no I/O APIC driver existed anywhere in this * tree before this item. The Local APIC (apic.h) self-interrupts for the * timer and needs no routing; any *legacy* IRQ (i8042 keyboard's IRQ1 * included) requires the I/O APIC to redirect it to a Local APIC vector. */ #ifndef STARKERNEL_IOAPIC_H #define STARKERNEL_IOAPIC_H #include /** * Locate and map the I/O APIC via the ACPI MADT (parsed from @p acpi_rsdp). * Also captures any Interrupt Source Override entries so legacy ISA IRQs * with a non-default GSI/polarity/trigger mapping route correctly. * * @param acpi_rsdp BootInfo->acpi_table (RSDP), or NULL. * @return 0 on success, -1 if no MADT/I/O APIC entry was found. */ int ioapic_init(void *acpi_rsdp); /** * Program a redirection entry for a legacy ISA IRQ, initially masked. * Honors an Interrupt Source Override for @p isa_irq if the MADT had one * (different GSI, polarity, or trigger mode); otherwise uses the ISA * default (GSI == isa_irq, active-high, edge-triggered) per the ACPI * specification's "conforms to bus" default. * * @param isa_irq Legacy IRQ number (0-15). * @param vector IDT vector to deliver (e.g. 0x21). * @param dest_apic_id Destination Local APIC ID (see apic_id()). * @return 0 on success, -1 if ioapic_init() has not succeeded. */ int ioapic_route_legacy_irq(uint8_t isa_irq, uint8_t vector, uint8_t dest_apic_id); /** * Clear the mask bit on a previously routed legacy IRQ's redirection entry. * Call only after ioapic_route_legacy_irq() has programmed it. */ void ioapic_unmask_legacy_irq(uint8_t isa_irq); #endif /* STARKERNEL_IOAPIC_H */