[coreboot-gerrit] Change in coreboot[master]: [draft] sb/intel/common: Automatically generate ACPI PIRQ
Tobias Diedrich (Code Review)
gerrit at coreboot.org
Sun Dec 10 21:42:56 CET 2017
Tobias Diedrich has uploaded this change for review. ( https://review.coreboot.org/22810
Change subject: [draft] sb/intel/common: Automatically generate ACPI PIRQ
......................................................................
[draft] sb/intel/common: Automatically generate ACPI PIRQ
Based on https://review.coreboot.org/#/c/22803/
This function generates PIRQ ACPI tables automatically based on the
chipset registers.
Linux 4.13.14 /proc/interrupts:
CPU0 CPU1
0: 24 0 IO-APIC 2-edge timer
8: 1 0 IO-APIC 8-edge rtc0
9: 0 0 IO-APIC 9-fasteoi acpi
19: 86 0 IO-APIC 19-fasteoi ehci_hcd:usb1
23: 0 0 IO-APIC 23-fasteoi i801_smbus
24: 0 0 PCI-MSI 458752-edge PCIe PME
25: 0 0 PCI-MSI 460800-edge PCIe PME
26: 0 0 PCI-MSI 462848-edge PCIe PME
27: 166 0 PCI-MSI 32768-edge i915
28: 3953 0 PCI-MSI 512000-edge ahci[0000:00:1f.2]
29: 656 0 PCI-MSI 409600-edge eno1
30: 83 0 PCI-MSI 442368-edge snd_hda_intel:card0
[...]
Bootlog:
PCI: 00:00.0: no pin
PCI: 00:01.0: no pin
slot=2 or pin1 out of bounds
PCI: 00:02.0: pin=1 pirq=0
PCI: 00:16.0: no pin
PCI: 00:16.1: no pin
PCI: 00:16.2: no pin
PCI: 00:16.3: no pin
PCI: 00:19.0: no pin
PCI: 00:1a.0: no pin
slot=27 reg=0x3148 val=0x1070
PCI: 00:1b.0: pin=1 pirq=1
slot=28 reg=0x3146 val=0x4351
PCI: 00:1c.0: pin=1 pirq=2
slot=28 reg=0x3146 val=0x4351
PCI: 00:1c.1: pin=2 pirq=6
slot=28 reg=0x3146 val=0x4351
PCI: 00:1c.2: pin=3 pirq=4
PCI: 00:1c.3: no pin
PCI: 00:1c.4: no pin
PCI: 00:1c.5: no pin
PCI: 00:1c.6: no pin
PCI: 00:1c.7: no pin
slot=29 reg=0x3144 val=0x6543
PCI: 00:1d.0: pin=1 pirq=4
PCI: 00:1e.0: no pin
PCI: 00:1f.0: no pin
slot=31 reg=0x3140 val=0x2071
PCI: 00:1f.2: pin=1 pirq=2
slot=31 reg=0x3140 val=0x2071
PCI: 00:1f.3: pin=2 pirq=8
PCI: 00:1f.5: no pin
PCI: 00:1f.6: no pin
slot=4 or pin1 out of bounds
PCI: 00:04.0: pin=1 pirq=0
num_devs=7
Generated _PRT:
Scope (\_SB.PCI0)
{
Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
{
If (PICM)
{
Return (Package (0x07)
{
Package (0x04)
{
0x001BFFFF,
0x00000000,
0x00000000,
0x00000010
},
Package (0x04)
{
0x001CFFFF,
0x00000000,
0x00000000,
0x00000011
},
Package (0x04)
{
0x001CFFFF,
0x00000001,
0x00000000,
0x00000015
},
Package (0x04)
{
0x001CFFFF,
0x00000002,
0x00000000,
0x00000013
},
Package (0x04)
{
0x001DFFFF,
0x00000000,
0x00000000,
0x00000013
},
Package (0x04)
{
0x001FFFFF,
0x00000000,
0x00000000,
0x00000011
},
Package (0x04)
{
0x001FFFFF,
0x00000001,
0x00000000,
0x00000017
}
})
}
Else
{
Return (Package (0x07)
{
Package (0x04)
{
0x001BFFFF,
0x00000000,
\_SB.PCI0.LPCB.LNKA,
0x00000000
},
Package (0x04)
{
0x001CFFFF,
0x00000000,
\_SB.PCI0.LPCB.LNKB,
0x00000000
},
Package (0x04)
{
0x001CFFFF,
0x00000001,
\_SB.PCI0.LPCB.LNKF,
0x00000000
},
Package (0x04)
{
0x001CFFFF,
0x00000002,
\_SB.PCI0.LPCB.LNKD,
0x00000000
},
Package (0x04)
{
0x001DFFFF,
0x00000000,
\_SB.PCI0.LPCB.LNKD,
0x00000000
},
Package (0x04)
{
0x001FFFFF,
0x00000000,
\_SB.PCI0.LPCB.LNKB,
0x00000000
},
Package (0x04)
{
0x001FFFFF,
0x00000001,
\_SB.PCI0.LPCB.LNKH,
0x00000000
}
})
}
}
}
}
Change-Id: Ic6b8ce4a9db50211a9c26221ca10105c5a0829a0
Signed-off-by: Tobias Diedrich <ranma+coreboot at tdiedrich.de>
---
M src/southbridge/intel/bd82x6x/Kconfig
M src/southbridge/intel/bd82x6x/acpi/default_irq_route.asl
M src/southbridge/intel/bd82x6x/lpc.c
M src/southbridge/intel/common/Kconfig
M src/southbridge/intel/common/Makefile.inc
A src/southbridge/intel/common/acpi_pirq_gen.c
A src/southbridge/intel/common/acpi_pirq_gen.h
7 files changed, 179 insertions(+), 61 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/10/22810/1
diff --git a/src/southbridge/intel/bd82x6x/Kconfig b/src/southbridge/intel/bd82x6x/Kconfig
index fe1ca34..2266a48 100644
--- a/src/southbridge/intel/bd82x6x/Kconfig
+++ b/src/southbridge/intel/bd82x6x/Kconfig
@@ -25,6 +25,7 @@
def_bool y
select ACPI_INTEL_HARDWARE_SLEEP_VALUES
select SOUTHBRIDGE_INTEL_COMMON
+ select SOUTHBRIDGE_INTEL_COMMON_PIRQ_ACPI_GEN
select SOUTHBRIDGE_INTEL_COMMON_SMBUS
select SOUTHBRIDGE_INTEL_COMMON_SPI
select IOAPIC
diff --git a/src/southbridge/intel/bd82x6x/acpi/default_irq_route.asl b/src/southbridge/intel/bd82x6x/acpi/default_irq_route.asl
index 0e6f960..c40f260 100644
--- a/src/southbridge/intel/bd82x6x/acpi/default_irq_route.asl
+++ b/src/southbridge/intel/bd82x6x/acpi/default_irq_route.asl
@@ -14,64 +14,4 @@
* GNU General Public License for more details.
*/
-/* PCI Interrupt Routing */
-Method(_PRT)
-{
- If (PICM) {
- Return (Package() {
- /* Onboard graphics (IGD) 0:2.0 */
- Package() { 0x0002ffff, 0, 0, 16 },/* GFX INTA -> PIRQA (MSI) */
- /* PCI Express Graphics (PEG) 0:1.0 */
- Package() { 0x0001ffff, 0, 0, 16 },/* GFX PCIe INTA -> PIRQA (MSI) */
- Package() { 0x0001ffff, 0, 0, 17 },/* GFX PCIe INTB -> PIRQB (MSI) */
- Package() { 0x0001ffff, 0, 0, 18 },/* GFX PCIe INTC -> PIRQC (MSI) */
- Package() { 0x0001ffff, 0, 0, 19 },/* GFX PCIe INTD -> PIRQD (MSI) */
- /* XHCI 0:14.0 (ivy only) */
- Package() { 0x0014ffff, 0, 0, 19 },
- /* High Definition Audio 0:1b.0 */
- Package() { 0x001bffff, 0, 0, 16 },/* D27IP_ZIP HDA INTA -> PIRQA (MSI) */
- /* PCIe Root Ports 0:1c.x */
- Package() { 0x001cffff, 0, 0, 17 },/* D28IP_P1IP PCIe INTA -> PIRQB */
- Package() { 0x001cffff, 1, 0, 21 },/* D28IP_P2IP PCIe INTB -> PIRQF */
- Package() { 0x001cffff, 2, 0, 19 },/* D28IP_P3IP PCIe INTC -> PIRQD */
- Package() { 0x001cffff, 3, 0, 20 },/* D28IP_P3IP PCIe INTD -> PIRQE */
- /* EHCI #1 0:1d.0 */
- Package() { 0x001dffff, 0, 0, 19 },/* D29IP_E1P EHCI1 INTA -> PIRQD */
- /* EHCI #2 0:1a.0 */
- Package() { 0x001affff, 0, 0, 21 },/* D26IP_E2P EHCI2 INTA -> PIRQF */
- /* LPC devices 0:1f.0 */
- Package() { 0x001fffff, 0, 0, 17 }, /* D31IP_SIP SATA INTA -> PIRQB (MSI) */
- Package() { 0x001fffff, 1, 0, 23 }, /* D31IP_SMIP SMBUS INTB -> PIRQH */
- Package() { 0x001fffff, 2, 0, 16 }, /* D31IP_TTIP THRT INTC -> PIRQA */
- Package() { 0x001fffff, 3, 0, 18 },
- })
- } Else {
- Return (Package() {
- /* Onboard graphics (IGD) 0:2.0 */
- Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
- /* PCI Express Graphics (PEG) 0:1.0 */
- Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
- Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
- Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKC, 0 },
- Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKD, 0 },
- /* XHCI 0:14.0 (ivy only) */
- Package() { 0x0014ffff, 0, \_SB.PCI0.LPCB.LNKD, 0 },
- /* High Definition Audio 0:1b.0 */
- Package() { 0x001bffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
- /* PCIe Root Ports 0:1c.x */
- Package() { 0x001cffff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
- Package() { 0x001cffff, 1, \_SB.PCI0.LPCB.LNKF, 0 },
- Package() { 0x001cffff, 2, \_SB.PCI0.LPCB.LNKD, 0 },
- Package() { 0x001cffff, 3, \_SB.PCI0.LPCB.LNKE, 0 },
- /* EHCI #1 0:1d.0 */
- Package() { 0x001dffff, 0, \_SB.PCI0.LPCB.LNKD, 0 },
- /* EHCI #2 0:1a.0 */
- Package() { 0x001affff, 0, \_SB.PCI0.LPCB.LNKF, 0 },
- /* LPC device 0:1f.0 */
- Package() { 0x001fffff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
- Package() { 0x001fffff, 1, \_SB.PCI0.LPCB.LNKH, 0 },
- Package() { 0x001fffff, 2, \_SB.PCI0.LPCB.LNKA, 0 },
- Package() { 0x001fffff, 3, \_SB.PCI0.LPCB.LNKC, 0 },
- })
- }
-}
+/* PCI Interrupt Routing is generated */
diff --git a/src/southbridge/intel/bd82x6x/lpc.c b/src/southbridge/intel/bd82x6x/lpc.c
index 2bfc1e3..5224469 100644
--- a/src/southbridge/intel/bd82x6x/lpc.c
+++ b/src/southbridge/intel/bd82x6x/lpc.c
@@ -35,6 +35,7 @@
#include "pch.h"
#include "nvs.h"
#include <southbridge/intel/common/pciehp.h>
+#include <southbridge/intel/common/acpi_pirq_gen.h>
#define NMI_OFF 0
@@ -815,12 +816,42 @@
return "LPCB";
}
+static const u32 pirq_dir_route_reg[] = {
+ D20IR, 0, D22IR, 0, 0, D25IR, D26IR, D27IR, D28IR, D29IR, 0, D31IR,
+};
+
+u8 intel_common_map_pirq(device_t dev, u8 pci_pin)
+{
+ u8 slot = PCI_SLOT(dev->path.pci.devfn);
+ u8 shift = 4 * (pci_pin - 1);
+ u8 pirq;
+ u32 reg;
+
+ if (slot < 20 || slot > 31 || pci_pin < 1 || pci_pin > 4) {
+ printk(BIOS_DEBUG, "slot=%d or pin%d out of bounds\n",
+ slot, pci_pin);
+ return 0;
+ }
+
+ reg = pirq_dir_route_reg[slot - 20];
+ printk(BIOS_DEBUG, "slot=%d reg=0x%04x val=0x%04x\n",
+ slot, reg, RCBA16(reg));
+
+ pirq = ((RCBA16(reg) >> shift) & 0xf);
+ if (pirq > 8) {
+ printk(BIOS_DEBUG, "pirq=%d out of bounds\n", pirq);
+ return 0;
+ }
+ return 1 + pirq;
+}
+
static void southbridge_fill_ssdt(device_t device)
{
device_t dev = dev_find_slot(0, PCI_DEVFN(0x1f,0));
config_t *chip = dev->chip_info;
intel_acpi_pcie_hotplug_generator(chip->pcie_hotplug_map, 8);
+ intel_acpi_gen_def_acpi_pirq(dev);
}
static void lpc_final(struct device *dev)
diff --git a/src/southbridge/intel/common/Kconfig b/src/southbridge/intel/common/Kconfig
index 6ce6b33..f6a0180 100644
--- a/src/southbridge/intel/common/Kconfig
+++ b/src/southbridge/intel/common/Kconfig
@@ -15,6 +15,9 @@
config HAVE_INTEL_CHIPSET_LOCKDOWN
def_bool n
+config SOUTHBRIDGE_INTEL_COMMON_PIRQ_ACPI_GEN
+ def_bool n
+
config INTEL_CHIPSET_LOCKDOWN
depends on HAVE_INTEL_CHIPSET_LOCKDOWN && HAVE_SMI_HANDLER && !CHROMEOS
#ChromeOS's payload seems to handle finalization on its on.
diff --git a/src/southbridge/intel/common/Makefile.inc b/src/southbridge/intel/common/Makefile.inc
index 0128505..13150d9 100644
--- a/src/southbridge/intel/common/Makefile.inc
+++ b/src/southbridge/intel/common/Makefile.inc
@@ -33,4 +33,6 @@
smm-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_SPI) += spi.c
endif
+ramstage-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_PIRQ_ACPI_GEN) += acpi_pirq_gen.c
+
endif
diff --git a/src/southbridge/intel/common/acpi_pirq_gen.c b/src/southbridge/intel/common/acpi_pirq_gen.c
new file mode 100644
index 0000000..17d9d09
--- /dev/null
+++ b/src/southbridge/intel/common/acpi_pirq_gen.c
@@ -0,0 +1,119 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Arthur Heymans <arthur at aheymans.xyz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/acpigen.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/pci_def.h>
+#include <string.h>
+
+#include "acpi_pirq_gen.h"
+
+enum emit_type {
+ EMIT_NONE,
+ EMIT_APIC,
+ EMIT_PICM,
+};
+
+static int enumerate_root_pci_pins(enum emit_type emit, const char *lpcb_path)
+{
+ static char buffer[DEVICE_PATH_MAX];
+ device_t dev;
+ u8 prev_int_pin = 0;
+ u8 prev_pci_dev = 0;
+ int num_devs = 0;
+
+ for (dev = all_devices; dev; dev = dev->next) {
+ u8 pci_dev;
+ u8 int_pin;
+ u8 pirq;
+
+ if (dev->path.type != DEVICE_PATH_PCI ||
+ dev->bus->secondary != 0)
+ continue;
+
+ pci_dev = PCI_SLOT(dev->path.pci.devfn);
+ int_pin = pci_read_config8(dev, PCI_INTERRUPT_PIN);
+
+ if (int_pin == 0 || int_pin > 4) {
+ printk(BIOS_DEBUG, "%s: no pin\n", dev_path(dev));
+ continue;
+ }
+
+ pirq = intel_common_map_pirq(dev, int_pin);
+
+ printk(BIOS_DEBUG, "%s: pin=%d pirq=%d\n",
+ dev_path(dev), int_pin, pirq);
+
+ if (pirq == 0)
+ continue;
+
+ /* Avoid duplicate entries */
+ if (prev_pci_dev == pci_dev && prev_int_pin == int_pin) {
+ continue;
+ } else {
+ prev_int_pin = int_pin;
+ prev_pci_dev = pci_dev;
+ }
+ if (emit != EMIT_NONE) {
+ acpigen_write_package(4);
+ acpigen_write_dword((pci_dev << 16) | 0xffff);
+ acpigen_write_dword(int_pin - 1);
+ if (emit == EMIT_APIC) {
+ acpigen_write_dword(0);
+ acpigen_write_dword(16 + (pirq - 1));
+ } else {
+ snprintf(buffer, sizeof(buffer),
+ "%s.LNK%c", lpcb_path, 'A' + pirq - 1);
+ printk(BIOS_DEBUG, "path=%s\n", buffer);
+ acpigen_emit_namestring(buffer);
+ acpigen_write_dword(0);
+ }
+ acpigen_pop_len();
+ }
+ num_devs++;
+ }
+ return num_devs;
+}
+
+void intel_acpi_gen_def_acpi_pirq(device_t dev)
+{
+ const char *lpcb_path = acpi_device_path(dev);
+ int num_devs = enumerate_root_pci_pins(EMIT_NONE, lpcb_path);
+
+ if (!lpcb_path) {
+ printk(BIOS_ERR, "Missing LPCB ACPI path\n");
+ return;
+ }
+ printk(BIOS_INFO, "num_devs=%d\n", num_devs);
+
+ acpigen_write_scope("\\_SB.PCI0");
+ acpigen_write_method("_PRT", 0);
+ acpigen_write_if();
+ acpigen_emit_namestring("PICM");
+ acpigen_emit_byte(RETURN_OP);
+ acpigen_write_package(num_devs);
+ enumerate_root_pci_pins(EMIT_APIC, lpcb_path);
+ acpigen_pop_len(); /* package */
+ acpigen_pop_len(); /* if PICM */
+ acpigen_write_else();
+ acpigen_emit_byte(RETURN_OP);
+ acpigen_write_package(num_devs);
+ enumerate_root_pci_pins(EMIT_PICM, lpcb_path);
+ acpigen_pop_len(); /* package */
+ acpigen_pop_len(); /* else PICM */
+ acpigen_pop_len(); /* _PRT */
+ acpigen_pop_len(); /* \_SB */
+}
diff --git a/src/southbridge/intel/common/acpi_pirq_gen.h b/src/southbridge/intel/common/acpi_pirq_gen.h
new file mode 100644
index 0000000..d5c68f7
--- /dev/null
+++ b/src/southbridge/intel/common/acpi_pirq_gen.h
@@ -0,0 +1,22 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Arthur Heymans <arthur at aheymans.xyz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef INTEL_COMMON_ACPI_PIRQ_GEN_H
+#define INTEL_COMMON_ACPI_PIRQ_GEN_H
+
+void intel_acpi_gen_def_acpi_pirq(device_t dev);
+u8 intel_common_map_pirq(device_t dev, u8 int_pin);
+
+#endif
--
To view, visit https://review.coreboot.org/22810
To unsubscribe, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic6b8ce4a9db50211a9c26221ca10105c5a0829a0
Gerrit-Change-Number: 22810
Gerrit-PatchSet: 1
Gerrit-Owner: Tobias Diedrich <ranma+coreboot at tdiedrich.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20171210/5aec5ced/attachment-0001.html>
More information about the coreboot-gerrit
mailing list