drivers/generic/ioapic: Drop poor implementation

This disables MP table generation for the affected boards
since interrupt routing entries would now be completely missing.

The mechanism itself is flawed and redundant. The mapping
of integrated PCI devices' INTx pins to IOAPIC pins is
dependent of configuration registers and needs not appear
in the devicetree.cb files at all.

The write_smp_table implementation would skip writing
any entry delivering to destination IOAPIC ID 0. This
does not follow MP table specification.

There were duplicate calls to register_new_ioapic_gsi0(),
with another present under southbridge LPC device.

Change-Id: I383d55ba2bc0800423617215e0bfdfad5136e9ac
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/69488
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
Kyösti Mälkki 2021-06-08 08:06:06 +03:00
parent 9202cab661
commit ca5a793ec3
14 changed files with 25 additions and 303 deletions

View File

@ -795,9 +795,9 @@ config ACPI_NHLT
menu "System tables"
config GENERATE_MP_TABLE
prompt "Generate an MP table" if HAVE_MP_TABLE || DRIVERS_GENERIC_IOAPIC
prompt "Generate an MP table" if HAVE_MP_TABLE
bool
default HAVE_MP_TABLE || DRIVERS_GENERIC_IOAPIC
default HAVE_MP_TABLE
help
Generate an MP table (conforming to the Intel MultiProcessor
specification 1.4) for this board.

View File

@ -9,7 +9,6 @@
#include <device/device.h>
#include <device/path.h>
#include <device/pci_ids.h>
#include <drivers/generic/ioapic/chip.h>
#include <stdint.h>
#include <string.h>
@ -509,34 +508,11 @@ void *mptable_finalize(struct mp_config_table *mc)
return smp_next_mpe_entry(mc);
}
static const struct device *find_next_ioapic(unsigned int last_ioapic_id)
{
const struct device *dev;
const struct device *result = NULL;
unsigned int ioapic_id = MAX_APICS;
for (dev = all_devices; dev; dev = dev->next) {
if (dev->path.type == DEVICE_PATH_IOAPIC &&
dev->path.ioapic.ioapic_id > last_ioapic_id &&
dev->path.ioapic.ioapic_id <= ioapic_id) {
result = dev;
}
}
return result;
}
unsigned long __weak write_smp_table(unsigned long addr)
{
struct drivers_generic_ioapic_config *ioapic_config;
struct mp_config_table *mc;
int isa_bus, pin, parentpin;
const struct device *dev;
const struct device *parent;
const struct device *oldparent;
int isa_bus;
void *tmp, *v;
int isaioapic = -1, have_fixed_entries;
const struct pci_irq_info *pci_irq_info;
unsigned int ioapic_id = 0;
v = smp_write_floating_table(addr, 0);
mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
@ -547,99 +523,6 @@ unsigned long __weak write_smp_table(unsigned long addr)
mptable_write_buses(mc, NULL, &isa_bus);
while ((dev = find_next_ioapic(ioapic_id))) {
ioapic_config = dev->chip_info;
if (!ioapic_config) {
printk(BIOS_ERR, "%s has no config, ignoring\n",
dev_path(dev));
ioapic_id++;
continue;
}
ioapic_id = dev->path.ioapic.ioapic_id;
smp_write_ioapic(mc, ioapic_id,
ioapic_config->version,
ioapic_config->base);
if (ioapic_config->have_isa_interrupts) {
if (isaioapic >= 0)
printk(BIOS_ERR,
"More than one IOAPIC with ISA interrupts?\n");
else
isaioapic = dev->path.ioapic.ioapic_id;
}
}
if (isaioapic >= 0) {
/* Legacy Interrupts */
printk(BIOS_DEBUG, "Writing ISA IRQs\n");
mptable_add_isa_interrupts(mc, isa_bus, isaioapic, 0);
}
for (dev = all_devices; dev; dev = dev->next) {
if (!is_enabled_pci(dev))
continue;
have_fixed_entries = 0;
for (pin = 0; pin < 4; pin++) {
if (dev->pci_irq_info[pin].ioapic_dst_id) {
printk(BIOS_DEBUG,
"fixed IRQ entry for: %s: INT%c# -> IOAPIC %d PIN %d\n",
dev_path(dev),
pin + 'A',
dev->pci_irq_info[pin].ioapic_dst_id,
dev->pci_irq_info[pin].ioapic_irq_pin);
smp_write_intsrc(mc, mp_INT,
dev->pci_irq_info[pin].ioapic_flags,
dev->bus->secondary,
((dev->path.pci.devfn & 0xf8) >> 1)
| pin,
dev->pci_irq_info[pin].ioapic_dst_id,
dev->pci_irq_info[pin].ioapic_irq_pin);
have_fixed_entries = 1;
}
}
if (!have_fixed_entries) {
pin = (dev->path.pci.devfn & 7) % 4;
oldparent = parent = dev;
while ((parent = parent->bus->dev)) {
parentpin = (oldparent->path.pci.devfn >> 3)
+ (oldparent->path.pci.devfn & 7);
parentpin += dev->path.pci.devfn & 7;
parentpin += dev->path.pci.devfn >> 3;
parentpin %= 4;
pci_irq_info = &parent->pci_irq_info[parentpin];
if (pci_irq_info->ioapic_dst_id) {
printk(BIOS_DEBUG,
"automatic IRQ entry for %s: INT%c# -> IOAPIC %d PIN %d\n",
dev_path(dev), pin + 'A',
pci_irq_info->ioapic_dst_id,
pci_irq_info->ioapic_irq_pin);
smp_write_intsrc(mc, mp_INT,
pci_irq_info->ioapic_flags,
dev->bus->secondary,
((dev->path.pci.devfn & 0xf8)
>> 1) | pin,
pci_irq_info->ioapic_dst_id,
pci_irq_info->ioapic_irq_pin);
break;
}
if (parent->path.type == DEVICE_PATH_DOMAIN) {
printk(BIOS_WARNING,
"no IRQ found for %s\n",
dev_path(dev));
break;
}
oldparent = parent;
}
}
}
mptable_lintsrc(mc, isa_bus);
tmp = mptable_finalize(mc);
printk(BIOS_INFO, "MPTABLE len: %d\n", (unsigned int)((uintptr_t)tmp -

View File

@ -1,2 +0,0 @@
config DRIVERS_GENERIC_IOAPIC
bool

View File

@ -1 +0,0 @@
ramstage-$(CONFIG_DRIVERS_GENERIC_IOAPIC) += ioapic.c

View File

@ -1,13 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef DRIVERS_GENERIC_IOAPIC_CHIP_H
#define DRIVERS_GENERIC_IOAPIC_CHIP_H
typedef struct drivers_generic_ioapic_config {
u32 version;
u8 apicid;
u8 have_isa_interrupts;
void *base;
} ioapic_config_t;
#endif

View File

@ -1,42 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <device/device.h>
#include "chip.h"
#include <arch/ioapic.h>
static void ioapic_init(struct device *dev)
{
struct drivers_generic_ioapic_config *config = dev->chip_info;
if (!dev->enabled || !config)
return;
setup_ioapic(config->base, config->apicid);
}
static void ioapic_read_resources(struct device *dev)
{
struct drivers_generic_ioapic_config *config = (struct drivers_generic_ioapic_config *)dev->chip_info;
struct resource *res;
res = new_resource(dev, 0);
res->base = (resource_t)(uintptr_t)config->base;
res->size = 0x1000;
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
}
static struct device_operations ioapic_operations = {
.read_resources = ioapic_read_resources,
.set_resources = noop_set_resources,
.init = ioapic_init,
};
static void enable_dev(struct device *dev)
{
dev->ops = &ioapic_operations;
}
struct chip_operations drivers_generic_ioapic_ops = {
CHIP_NAME("IOAPIC")
.enable_dev = enable_dev,
};

View File

@ -12,8 +12,6 @@ config BOARD_SPECIFIC_OPTIONS
select H8_HAS_BAT_THRESHOLDS_IMPL
select BOARD_ROMSIZE_KB_8192 if !BOARD_LENOVO_R500
select BOARD_ROMSIZE_KB_4096 if BOARD_LENOVO_R500
select DRIVERS_GENERIC_IOAPIC
select HAVE_MP_TABLE
select HAVE_ACPI_TABLES
select EC_ACPI
select HAVE_OPTION_TABLE

View File

@ -34,7 +34,6 @@ chip northbridge/intel/gm45
device pci 01.0 on end # PCIe Bridge for discrete graphics
device pci 02.0 on # VGA
subsystemid 0x17aa 0x20e4
ioapic_irq 2 INTA 0x10
end
device pci 02.1 on
subsystemid 0x17aa 0x20e4
@ -85,27 +84,21 @@ chip northbridge/intel/gm45
device pci 19.0 on end # LAN
device pci 1a.0 on # UHCI
subsystemid 0x17aa 0x20f0
ioapic_irq 2 INTA 0x10
end
device pci 1a.1 on # UHCI
subsystemid 0x17aa 0x20f0
ioapic_irq 2 INTB 0x11
end
device pci 1a.2 on # UHCI
subsystemid 0x17aa 0x20f0
ioapic_irq 2 INTC 0x12
end
device pci 1a.7 on # EHCI
subsystemid 0x17aa 0x20f1
ioapic_irq 2 INTC 0x12
end
device pci 1b.0 on # HD Audio
subsystemid 0x17aa 0x20f2
ioapic_irq 2 INTA 0x10
end
device pci 1c.0 on # PCIe Port #1
subsystemid 0x17aa 0x20f3 # WWAN
ioapic_irq 2 INTA 0x10
end
device pci 1c.1 on
subsystemid 0x17aa 0x20f3 # WLAN
@ -121,19 +114,15 @@ chip northbridge/intel/gm45
device pci 1c.5 off end # PCIe Port #6
device pci 1d.0 on # UHCI
subsystemid 0x17aa 0x20f0
ioapic_irq 2 INTA 0x10
end
device pci 1d.1 on # UHCI
subsystemid 0x17aa 0x20f0
ioapic_irq 2 INTB 0x11
end
device pci 1d.2 on # UHCI
subsystemid 0x17aa 0x20f0
ioapic_irq 2 INTC 0x12
end
device pci 1d.7 on # EHCI
subsystemid 0x17aa 0x20f1
ioapic_irq 2 INTA 0x10
end
device pci 1e.0 on # PCI
subsystemid 0x17aa 0x20f4
@ -141,12 +130,6 @@ chip northbridge/intel/gm45
device pci 1f.0 on # LPC bridge
subsystemid 0x17aa 0x20f5
chip drivers/generic/ioapic
register "have_isa_interrupts" = "1"
register "base" = "(void *)0xfec00000"
device ioapic 2 on end
end
chip ec/lenovo/pmh7
device pnp ff.1 on end # dummy
register "backlight_enable" = "0x01"
@ -217,7 +200,6 @@ chip northbridge/intel/gm45
end
device pci 1f.2 on # SATA/IDE 1
subsystemid 0x17aa 0x20f8
ioapic_irq 2 INTB 0x11
end
device pci 1f.3 on end # SMBus
device pci 1f.5 off end # SATA/IDE 2

View File

@ -11,8 +11,6 @@ config BOARD_SPECIFIC_OPTIONS
select H8_HAS_BAT_THRESHOLDS_IMPL
select NO_UART_ON_SUPERIO
select BOARD_ROMSIZE_KB_8192
select DRIVERS_GENERIC_IOAPIC
select HAVE_MP_TABLE
select HAVE_ACPI_TABLES
select EC_ACPI
select HAVE_OPTION_TABLE

View File

@ -33,7 +33,6 @@ chip northbridge/intel/gm45
end # host bridge
device pci 02.0 on # VGA
subsystemid 0x17aa 0x20e4
ioapic_irq 2 INTA 0x10
end
device pci 02.1 on
subsystemid 0x17aa 0x20e4
@ -78,27 +77,21 @@ chip northbridge/intel/gm45
device pci 19.0 on end # LAN
device pci 1a.0 on # UHCI
subsystemid 0x17aa 0x20f0
ioapic_irq 2 INTA 0x10
end
device pci 1a.1 on # UHCI
subsystemid 0x17aa 0x20f0
ioapic_irq 2 INTB 0x11
end
device pci 1a.2 on # UHCI
subsystemid 0x17aa 0x20f0
ioapic_irq 2 INTC 0x12
end
device pci 1a.7 on # EHCI
subsystemid 0x17aa 0x20f1
ioapic_irq 2 INTC 0x12
end
device pci 1b.0 on # HD Audio
subsystemid 0x17aa 0x20f2
ioapic_irq 2 INTA 0x10
end
device pci 1c.0 on # PCIe Port #1
subsystemid 0x17aa 0x20f3 # WWAN
ioapic_irq 2 INTA 0x10
end
device pci 1c.1 on
subsystemid 0x17aa 0x20f3 # WLAN
@ -111,19 +104,15 @@ chip northbridge/intel/gm45
device pci 1c.5 off end # PCIe Port #6
device pci 1d.0 on # UHCI
subsystemid 0x17aa 0x20f0
ioapic_irq 2 INTA 0x10
end
device pci 1d.1 on # UHCI
subsystemid 0x17aa 0x20f0
ioapic_irq 2 INTB 0x11
end
device pci 1d.2 on # UHCI
subsystemid 0x17aa 0x20f0
ioapic_irq 2 INTC 0x12
end
device pci 1d.7 on # EHCI
subsystemid 0x17aa 0x20f1
ioapic_irq 2 INTA 0x10
end
device pci 1e.0 on # PCI
subsystemid 0x17aa 0x20f4
@ -131,12 +120,6 @@ chip northbridge/intel/gm45
device pci 1f.0 on # LPC bridge
subsystemid 0x17aa 0x20f5
chip drivers/generic/ioapic
register "have_isa_interrupts" = "1"
register "base" = "(void *)0xfec00000"
device ioapic 2 on end
end
chip ec/lenovo/pmh7
device pnp ff.1 on end # dummy
register "backlight_enable" = "0x01"
@ -180,11 +163,9 @@ chip northbridge/intel/gm45
end
device pci 1f.2 on # SATA/IDE 1
subsystemid 0x17aa 0x20f8
ioapic_irq 2 INTB 0x11
end
device pci 1f.3 on # SMBus
subsystemid 0x17aa 0x20f9
ioapic_irq 2 INTC 0x12
# eeprom, 8 virtual devices, same chip
chip drivers/i2c/at24rf08c
device i2c 54 on end

View File

@ -8,8 +8,6 @@ config BOARD_SPECIFIC_OPTIONS
select SOUTHBRIDGE_INTEL_I82801IX
select SUPERIO_SMSC_LPC47N227
select BOARD_ROMSIZE_KB_4096
select DRIVERS_GENERIC_IOAPIC
select HAVE_MP_TABLE
select CARDBUS_PLUGIN_SUPPORT
select HAVE_ACPI_TABLES
select HAVE_ACPI_RESUME

View File

@ -23,9 +23,7 @@ chip northbridge/intel/gm45
device domain 0 on
subsystemid 0x4352 0x8986
device pci 00.0 on end # host bridge
device pci 02.0 on # VGA
ioapic_irq 2 INTA 0x10
end
device pci 02.0 on end # VGA
device pci 02.1 on end # Display
device pci 03.0 off end # ME
device pci 03.1 off end # ME
@ -69,62 +67,32 @@ chip northbridge/intel/gm45
register "gen1_dec" = "0x000c0601"
device pci 19.0 off end # LAN
device pci 1a.0 on # UHCI
ioapic_irq 2 INTA 0x10
end
device pci 1a.1 on # UHCI
ioapic_irq 2 INTB 0x11
end
device pci 1a.2 on # UHCI
ioapic_irq 2 INTC 0x12
end
device pci 1a.7 on # EHCI
ioapic_irq 2 INTC 0x12
end
device pci 1b.0 on # HD Audio
ioapic_irq 2 INTA 0x10
end
device pci 1c.0 on # PCIe Port #1
ioapic_irq 2 INTA 0x10
end
device pci 1a.0 on end # UHCI
device pci 1a.1 on end # UHCI
device pci 1a.2 on end # UHCI
device pci 1a.7 on end # EHCI
device pci 1b.0 on end # HD Audio
device pci 1c.0 on end # PCIe Port #1
device pci 1c.1 off end # PCIe Port #2
device pci 1c.2 off end # PCIe Port #3
device pci 1c.3 off end # PCIe Port #4
device pci 1c.4 on # PCIe Port #5
ioapic_irq 2 INTA 0x10
device pci 00.0 on end # Realtek 8168B
end
device pci 1c.5 off end # PCIe Port #6
device pci 1d.0 on # UHCI
ioapic_irq 2 INTA 0x10
end
device pci 1d.1 on # UHCI
ioapic_irq 2 INTB 0x11
end
device pci 1d.2 on # UHCI
ioapic_irq 2 INTC 0x12
end
device pci 1d.7 on # EHCI
ioapic_irq 2 INTA 0x10
end
device pci 1d.0 on end # UHCI
device pci 1d.1 on end # UHCI
device pci 1d.2 on end # UHCI
device pci 1d.7 on end # EHCI
device pci 1e.0 on # PCI
device pci 03.0 on # TI Cardbus
ioapic_irq 2 INTA 0x10
end
device pci 03.1 on # TI Cardbus
ioapic_irq 2 INTB 0x11
end
# device 03 INTA 0x10, INTB 0x11
device pci 03.0 on end # TI Cardbus
device pci 03.1 on end # TI Cardbus
device pci 03.2 off end # TI FireWire OHC
device pci 03.3 off end # unconnected FlashMedia
device pci 03.4 off end # unconnected SD-Card
end
device pci 1f.0 on # LPC bridge
chip drivers/generic/ioapic
register "have_isa_interrupts" = "1"
register "base" = "(void *)0xfec00000"
device ioapic 2 on end
end
chip superio/smsc/lpc47n227
device pnp 2e.1 on # Parallel port
io 0x60 = 0x378
@ -142,12 +110,8 @@ chip northbridge/intel/gm45
end
end
end
device pci 1f.2 on # SATA/IDE 1
ioapic_irq 2 INTB 0x11
end
device pci 1f.3 on # SMBus
ioapic_irq 2 INTC 0x12
end
device pci 1f.2 on end # SATA/IDE 1
device pci 1f.3 on end # SMBus
device pci 1f.5 off end # SATA/IDE 2
device pci 1f.6 off end # Thermal
end

View File

@ -21,7 +21,6 @@ config BOARD_SPECIFIC_OPTIONS
# LPC47N207 selected for external LPC card
# not on board, should be made selectable.
select SUPERIO_SMSC_LPC47N207
select DRIVERS_GENERIC_IOAPIC
select INTEL_INT15
select SANDYBRIDGE_VBOOT_IN_ROMSTAGE
select HAVE_SPD_IN_CBFS

View File

@ -32,10 +32,6 @@ chip northbridge/intel/sandybridge
end
device domain 0 on
ioapic_irq 4 INTA 0x10
ioapic_irq 4 INTB 0x11
ioapic_irq 4 INTC 0x12
ioapic_irq 4 INTD 0x13
subsystemid 0x1ae0 0xc000 inherit
device pci 00.0 on end # host bridge
device pci 02.0 on end # vga controller
@ -61,28 +57,19 @@ chip northbridge/intel/sandybridge
device pci 16.2 off end # Management Engine IDE-R
device pci 16.3 off end # Management Engine KT
device pci 19.0 off end # Intel Gigabit Ethernet
device pci 1a.0 on # USB2 EHCI #2
ioapic_irq 4 INTA 0x11
end
device pci 1b.0 on # High Definition Audio
ioapic_irq 4 INTA 0x16
end
device pci 1a.0 on end # USB2 EHCI #2
device pci 1b.0 on end # High Definition Audio
device pci 1c.0 on end # PCIe Port #1 (WLAN)
device pci 1c.1 off end # PCIe Port #2
device pci 1c.2 off end # PCIe Port #3
device pci 1c.3 on # PCIe Port #4 (LAN)
# ioapic_irq 4 INTA 0x13
end
device pci 1c.3 on end # PCIe Port #4 (LAN)
device pci 1c.4 off end # PCIe Port #5
device pci 1c.5 off end # PCIe Port #6
device pci 1c.6 off end # PCIe Port #7
device pci 1c.7 off end # PCIe Port #8
device pci 1d.0 on # USB2 EHCI #1
ioapic_irq 4 INTA 0x13
end
device pci 1d.0 on end # USB2 EHCI #1
device pci 1e.0 off end # PCI bridge
device pci 1f.0 on # LPC bridge
ioapic_irq 4 INTA 0x10
chip superio/smsc/mec1308
device pnp 2e.1 on # PM1
io 0x60 = 0xb00
@ -104,22 +91,12 @@ chip northbridge/intel/sandybridge
register "mailbox_port" = "0xa00"
device pnp ff.1 off end
end
chip drivers/generic/ioapic
register "have_isa_interrupts" = "1"
register "base" = "(void *)0xfec00000"
device ioapic 4 on end
end
chip drivers/pc80/tpm
device pnp 0c31.0 on end
end
end
device pci 1f.2 on # SATA Controller 1
ioapic_irq 4 INTA 0x10
end
device pci 1f.3 on # SMBus
ioapic_irq 4 INTC 0x17
end
device pci 1f.2 on end # SATA Controller 1
device pci 1f.3 on end # SMBus
device pci 1f.5 off end # SATA Controller 2
device pci 1f.6 on end # Thermal
end