[coreboot-gerrit] Change in coreboot[master]: sb/intel/common: Add function to automatically generate ACPI PIRQ

Arthur Heymans (Code Review) gerrit at coreboot.org
Sun Dec 10 15:13:48 CET 2017


Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/22803


Change subject: sb/intel/common: Add function to automatically generate ACPI PIRQ
......................................................................

sb/intel/common: Add function to automatically generate ACPI PIRQ

With the RCBA DxxIR registers on reset default the pins are mapped
quite straightforwardly namely pinA -> linkA, pinB -> linkB, pinC ->
linkC, pinD -> linkD. Although this might not be optimal for
performance, it does provide a good working default.

This function generates PIRQ ACPI tables automatically based on the
previous assumption.

Change-Id: I2b5d68adabf0840162c6f295af8d10d8d3007a34
Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
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
4 files changed, 145 insertions(+), 0 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/03/22803/1

diff --git a/src/southbridge/intel/common/Kconfig b/src/southbridge/intel/common/Kconfig
index 304ecbf..8ea8c77 100644
--- a/src/southbridge/intel/common/Kconfig
+++ b/src/southbridge/intel/common/Kconfig
@@ -11,6 +11,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 5810394..aae5c83 100644
--- a/src/southbridge/intel/common/Makefile.inc
+++ b/src/southbridge/intel/common/Makefile.inc
@@ -28,4 +28,6 @@
 romstage-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS) += smbus.c
 ramstage-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS) += smbus.c
 
+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..d5a17d7
--- /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 <device/pci_def.h>
+
+#include "acpi_pirq_gen.h"
+
+static int count_different_pirq(void)
+{
+	device_t irq_dev;
+	u8 prev_int_pin = 0;
+	u32 prev_pci_dev = 0;
+	int num_devs = 0;
+
+	for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
+		u8 int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
+		u32 pci_dev = (irq_dev->path.pci.devfn >> 3) & 0x1f;
+
+		if (irq_dev->bus->secondary != 0)
+			continue;
+		if (int_pin == 0 || int_pin > 4)
+			continue;
+		/* Avoid dublicate entries */
+		if (prev_pci_dev == pci_dev && prev_int_pin == int_pin) {
+			continue;
+		} else {
+			prev_int_pin = int_pin;
+			prev_pci_dev = pci_dev;
+		}
+		num_devs++;
+	}
+	return num_devs;
+}
+
+void gen_def_acpi_pirq(void)
+{
+	device_t irq_dev;
+	u8 prev_int_pin = 0;
+	u32 prev_pci_dev = 0;
+	int num_devs = count_different_pirq();
+	const char *link_list[4] = {"\\_SB.PCI0.LPCB.LNKA",
+				    "\\_SB.PCI0.LPCB.LNKB",
+				    "\\_SB.PCI0.LPCB.LNKC",
+				    "\\_SB.PCI0.LPCB.LNKD"};
+
+	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);
+	for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
+		u8 int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
+		u32 pci_dev = (irq_dev->path.pci.devfn >> 3) & 0x1f;
+
+		if (irq_dev->bus->secondary != 0)
+			continue;
+		if (int_pin == 0 || int_pin > 4)
+			continue;
+		/* Avoid dublicate entries */
+		if (prev_pci_dev == pci_dev && prev_int_pin == int_pin) {
+			continue;
+		} else {
+			prev_int_pin = int_pin;
+			prev_pci_dev = pci_dev;
+		}
+		acpigen_write_package(4);
+		acpigen_write_dword((pci_dev << 16) | 0xffff);
+		acpigen_write_dword(int_pin - 1);
+		acpigen_write_dword(0);
+		acpigen_write_dword(16 + (int_pin - 1));
+		acpigen_pop_len();
+	}
+	acpigen_pop_len(); /* package */
+	acpigen_pop_len(); /* if PICM */
+ 	acpigen_write_else();
+	acpigen_emit_byte(RETURN_OP);
+	acpigen_write_package(num_devs);
+	for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
+		u8 int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
+		u32 pci_dev = (irq_dev->path.pci.devfn >> 3) & 0x1f;
+
+		if (irq_dev->bus->secondary != 0)
+			continue;
+		if (int_pin == 0 || int_pin > 4)
+			continue;
+		/* Avoid dublicate entries */
+		if (prev_pci_dev == pci_dev && prev_int_pin == int_pin) {
+			continue;
+		} else {
+			prev_int_pin = int_pin;
+			prev_pci_dev = pci_dev;
+		}
+		acpigen_write_package(4);
+		acpigen_write_dword((pci_dev << 16) | 0xffff);
+ 		acpigen_write_dword(int_pin - 1);
+ 		acpigen_emit_namestring(link_list[int_pin - 1]);
+ 		acpigen_write_dword(0);
+ 		acpigen_pop_len();
+ 	}
+ 	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..a3f0609
--- /dev/null
+++ b/src/southbridge/intel/common/acpi_pirq_gen.h
@@ -0,0 +1,21 @@
+/*
+ * 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 gen_def_acpi_pirq(void);
+
+#endif

-- 
To view, visit https://review.coreboot.org/22803
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I2b5d68adabf0840162c6f295af8d10d8d3007a34
Gerrit-Change-Number: 22803
Gerrit-PatchSet: 1
Gerrit-Owner: Arthur Heymans <arthur at aheymans.xyz>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20171210/34021710/attachment.html>


More information about the coreboot-gerrit mailing list