diff --git a/src/arch/x86/include/arch/ioapic.h b/src/arch/x86/include/arch/ioapic.h index 33f15240d6..bdbcfbf415 100644 --- a/src/arch/x86/include/arch/ioapic.h +++ b/src/arch/x86/include/arch/ioapic.h @@ -9,7 +9,7 @@ #ifndef __ACPI__ -#include +#include #define ALL (0xff << 24) #define NONE (0) @@ -31,6 +31,9 @@ void io_apic_write(void *ioapic_base, u32 reg, u32 value); void set_ioapic_id(void *ioapic_base, u8 ioapic_id); void setup_ioapic(void *ioapic_base, u8 ioapic_id); void clear_ioapic(void *ioapic_base); + +void setup_ioapic_helper(void *ioapic_base, u8 ioapic_id, bool irq_on_fsb, + bool enable_virtual_wire); #endif #endif diff --git a/src/arch/x86/ioapic.c b/src/arch/x86/ioapic.c index 3b814ad834..c148534351 100644 --- a/src/arch/x86/ioapic.c +++ b/src/arch/x86/ioapic.c @@ -109,11 +109,14 @@ void set_ioapic_id(void *ioapic_base, u8 ioapic_id) } -static void load_vectors(void *ioapic_base) +void setup_ioapic_helper(void *ioapic_base, u8 ioapic_id, bool irq_on_fsb, + bool enable_virtual_wire) { - int first = 1, last; + int first = 0, last; - if (CONFIG(IOAPIC_INTERRUPTS_ON_FSB)) { + set_ioapic_id(ioapic_base, ioapic_id); + + if (irq_on_fsb) { /* * For the Pentium 4 and above APICs deliver their interrupts * on the front side bus, enable that. @@ -121,20 +124,24 @@ static void load_vectors(void *ioapic_base) printk(BIOS_DEBUG, "IOAPIC: Enabling interrupts on FSB\n"); io_apic_write(ioapic_base, 0x03, io_apic_read(ioapic_base, 0x03) | (1 << 0)); - } else if (CONFIG(IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS)) { + } else { printk(BIOS_DEBUG, "IOAPIC: Enabling interrupts on APIC serial bus\n"); io_apic_write(ioapic_base, 0x03, 0); } - route_i8259_irq0(ioapic_base); + if (enable_virtual_wire) { + route_i8259_irq0(ioapic_base); + first = 1; + } last = ioapic_interrupt_count(ioapic_base) - 1; clear_vectors(ioapic_base, first, last); } + void setup_ioapic(void *ioapic_base, u8 ioapic_id) { - set_ioapic_id(ioapic_base, ioapic_id); - load_vectors(ioapic_base); + setup_ioapic_helper(ioapic_base, ioapic_id, + CONFIG(IOAPIC_INTERRUPTS_ON_FSB), true); } diff --git a/src/drivers/generic/ioapic/ioapic.c b/src/drivers/generic/ioapic/ioapic.c index e33d58483e..708d9a1a7e 100644 --- a/src/drivers/generic/ioapic/ioapic.c +++ b/src/drivers/generic/ioapic/ioapic.c @@ -9,76 +9,12 @@ static void ioapic_init(struct device *dev) { struct drivers_generic_ioapic_config *config = dev->chip_info; - u32 bsp_lapicid = lapicid(); - u32 low, high; - u32 i, ioapic_interrupts; - void *ioapic_base; - u8 ioapic_id; if (!dev->enabled || !config) return; - ioapic_base = config->base; - ioapic_id = config->apicid; - - printk(BIOS_DEBUG, "IOAPIC: Initializing IOAPIC at %p\n", - ioapic_base); - printk(BIOS_DEBUG, "IOAPIC: Bootstrap Processor Local APIC = 0x%02x\n", - bsp_lapicid); - - if (ioapic_id) { - printk(BIOS_DEBUG, "IOAPIC: ID = 0x%02x\n", ioapic_id); - /* Set IOAPIC ID if it has been specified. */ - io_apic_write(ioapic_base, 0x00, - (io_apic_read(ioapic_base, 0x00) & 0xf0ffffff) | - (ioapic_id << 24)); - } - - /* Read the available number of interrupts. */ - ioapic_interrupts = (io_apic_read(ioapic_base, 0x01) >> 16) & 0xff; - if (!ioapic_interrupts || ioapic_interrupts == 0xff) - ioapic_interrupts = 24; - printk(BIOS_DEBUG, "IOAPIC: %d interrupts\n", ioapic_interrupts); - - if (config->irq_on_fsb) { - /* - * For the Pentium 4 and above APICs deliver their interrupts - * on the front side bus, enable that. - */ - printk(BIOS_DEBUG, "IOAPIC: Enabling interrupts on FSB\n"); - io_apic_write(ioapic_base, 0x03, - io_apic_read(ioapic_base, 0x03) | (1 << 0)); - } else { - printk(BIOS_DEBUG, "IOAPIC: Enabling interrupts on APIC serial bus\n"); - io_apic_write(ioapic_base, 0x03, 0); - } - - if (config->enable_virtual_wire) { - /* Enable Virtual Wire Mode. */ - low = INT_ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT; - high = bsp_lapicid << (56 - 32); - - io_apic_write(ioapic_base, 0x10, low); - io_apic_write(ioapic_base, 0x11, high); - - if (io_apic_read(ioapic_base, 0x10) == 0xffffffff) { - printk(BIOS_WARNING, "IOAPIC not responding.\n"); - return; - } - - printk(BIOS_SPEW, "IOAPIC: reg 0x%08x value 0x%08x 0x%08x\n", 0, - high, low); - } - low = INT_DISABLED; - high = NONE; - - for (i = 1; i < ioapic_interrupts; i++) { - io_apic_write(ioapic_base, i * 2 + 0x10, low); - io_apic_write(ioapic_base, i * 2 + 0x11, high); - - printk(BIOS_SPEW, "IOAPIC: reg 0x%08x value 0x%08x 0x%08x\n", - i, high, low); - } + setup_ioapic_helper(config->base, config->apicid, config->irq_on_fsb, + config->enable_virtual_wire); } static void ioapic_read_resources(struct device *dev)