Martin Roth (martin.roth(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5734
-gerrit
commit d1ce947b01fd89147ed37d425982902bcacab250
Author: Mike Loptien <mike.loptien(a)se-eng.com>
Date: Mon May 12 21:46:31 2014 -0600
PCI IRQs: Swizzle PCI IRQs for PCI bridges
The PCI Specification states that devices that implement
a bridge and a secondary bus must swizzle (rotate) the
interrupt pins according to the table below:
Child Dev # Child PIN Parent PIN
0,4,8,12... A/B/C/D A/B/C/D
1,5,9,13... A/B/C/D B/C/D/A
2,6,10,14.. A/B/C/D C/D/A/B
3,7,11,15.. A/B/C/D D/A/B/C
Which is also described by this equation:
PIN_parent = (Pin_child + Dev_child) % 4
When a device is found and its bus number is greater than 0,
it is on a bridge and needs to be swizzled. Following the
string of parents up to the root bus and swizzling as we go
gives us the desired swizzling result. When BIOS_SPEW is
defined, it will print out each step of the swizzling process.
Change-Id: Icafeadd01983282c86e25f560c831c9482c74e68
Signed-off-by: Martin Roth <gaumless(a)gmail.com>
---
src/device/pci_device.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++
src/include/device/pci.h | 3 +
2 files changed, 144 insertions(+)
diff --git a/src/device/pci_device.c b/src/device/pci_device.c
index f09fcaa..588e297 100644
--- a/src/device/pci_device.c
+++ b/src/device/pci_device.c
@@ -1303,6 +1303,147 @@ unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
return max;
}
+/**
+ * Take an INT_PIN number (0, 1 - 4) and convert
+ * it to a string ("NO PIN", "PIN A" - "PIN D")
+ *
+ * @param pin PCI Interrupt Pin number (0, 1 - 4)
+ * @return A string ("NO PIN", "PIN A" - "PIN D") corresponding to the pin number
+ */
+const char * pin_to_str(int pin)
+{
+ const char * str[5] = {
+ "NO PIN",
+ "PIN A",
+ "PIN B",
+ "PIN C",
+ "PIN D",
+ };
+
+ if (pin >= 0 || pin <= 4)
+ return str[pin];
+ else
+ return "Invalid PIN, not 0 - 4";
+}
+
+/**
+ * Get the PCI INT_PIN swizzle for a device defined as:
+ * pin_parent = (pin_child + devn_child) % 4
+ * where PIN A = 0 ... PIN_D = 3
+ *
+ * Given a PCI device structure 'dev', find the interrupt pin
+ * that will be triggered on its parent bridge device when
+ * generating an interrupt. For example: Device 1:3.2 may
+ * use INT_PIN A but will trigger PIN D on its parent bridge
+ * device. In this case, this function will return 4 (PIN D).
+ *
+ * @param dev A PCI device structure to swizzle interrupt pins for
+ * @param *parent_bdg The PCI device structure for the bridge
+ * device 'dev' is attached to
+ * @return The interrupt pin number (1 - 4) that 'dev' will
+ * trigger when generating an interrupt
+ */
+int swizzle_irq_pins(device_t dev, device_t *parent_bdg)
+{
+ device_t parent; /* Our current devices parent device */
+ device_t child; /* The child device of the parent */
+ int parent_bus = 0; /* Parent Bus number */
+ int parent_devfn = 0; /* Parent Device and Function number */
+ int child_devfn = 0; /* Child Device and Function number */
+ int swizzled_pin = 0; /* Pin swizzled across a bridge */
+
+ /* Start with PIN A = 0 ... D = 3 */
+ swizzled_pin = pci_read_config8(dev, PCI_INTERRUPT_PIN) - 1;
+
+ /* While our current device has parent devices */
+ child = dev;
+ for (parent = child->bus->dev; parent; parent = parent->bus->dev) {
+ parent_bus = parent->bus->secondary;
+ parent_devfn = parent->path.pci.devfn;
+ child_devfn = child->path.pci.devfn;
+
+ /* Swizzle the INT_PIN for any bridges not on root bus */
+ swizzled_pin = (PCI_SLOT(child_devfn) + swizzled_pin) % 4;
+ printk(BIOS_SPEW, "\tWith INT_PIN swizzled to %s\n"
+ "\tAttached to bridge device %01X:%02Xh.%02Xh\n",
+ pin_to_str(swizzled_pin + 1), parent_bus,
+ PCI_SLOT(parent_devfn), PCI_FUNC(parent_devfn));
+
+ /* Continue until we find the root bus */
+ if (parent_bus > 0) {
+ /* We will go on to the next parent so this parent becomes the child */
+ child = parent;
+ continue;
+ } else {
+ /* Found the root bridge device, fill in the structure and exit */
+ *parent_bdg = parent;
+ break;
+ }
+ }
+
+ /* End with PIN A = 1 ... D = 4 */
+ return swizzled_pin + 1;
+}
+
+/**
+ * Given a device structure 'dev', find its interrupt pin
+ * and its parent bridge 'parent_bdg' device structure.
+ * If it is behind a bridge, it will return the interrupt
+ * pin number (1 - 4) of the parent bridge that the device
+ * interrupt pin has been swizzled to, otherwise it will
+ * return the interrupt pin that is programmed into the
+ * PCI config space of the target device. If 'dev' is
+ * behind a bridge, it will fill in 'parent_bdg' with the
+ * device structure of the bridge it is behind, otherwise
+ * it will copy 'dev' into 'parent_bdg'.
+ *
+ * @param dev A PCI device structure to swizzle interrupt pins for.
+ * @param *parent_bdg The PCI device structure for the bridge
+ * device 'dev' is attached to.
+ * @return The interrupt pin number (1 - 4) that 'dev' will
+ * trigger when generating an interrupt.
+ */
+int get_irq_pins(device_t dev, device_t *parent_bdg)
+{
+ int bus = 0; /* The bus this device is on */
+ int devfn = 0; /* This device's device and function numbers */
+ int int_pin = 0; /* Interrupt pin used by the device */
+ int target_pin = 0; /* Interrupt pin we want to assign an IRQ to */
+
+ bus = dev->bus->secondary;
+ devfn = dev->path.pci.devfn;
+
+ /* Make sure this device is enabled and has a valid INT_PIN */
+ if (!(dev->enabled && (dev->path.type == DEVICE_PATH_PCI)))
+ return -1;
+
+ /* Get the interrupt pin that this dev uses, only 1-4 are allowed */
+ int_pin = pci_read_config8(dev, PCI_INTERRUPT_PIN);
+ if (int_pin < 1 || int_pin > 4)
+ return -1;
+
+ printk(BIOS_SPEW, "PCI IRQ: Found device %01X:%02Xh.%02Xh using %s\n",
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pin_to_str(int_pin));
+
+ /* If this device is on a bridge, swizzle its INT_PIN */
+ if (bus) {
+ /* Swizzle its INT_PINs */
+ target_pin = swizzle_irq_pins(dev, parent_bdg);
+
+ /* Make sure the swizzle returned valid structures */
+ if (parent_bdg == NULL) {
+ printk(BIOS_WARNING, "Warning: Could not find parent bridge for this device!\n");
+ return -2;
+ }
+ } else { /* Device is not behind a bridge */
+ target_pin = int_pin; /* Return its own interrupt pin */
+ *parent_bdg = dev; /* Return its own structure */
+ }
+
+ /* Target pin is the interrupt pin we want to assign an IRQ to */
+ return target_pin;
+}
+
#if CONFIG_PC80_SYSTEM
/**
* Assign IRQ numbers.
diff --git a/src/include/device/pci.h b/src/include/device/pci.h
index 5594d29..f4dcd4d 100644
--- a/src/include/device/pci.h
+++ b/src/include/device/pci.h
@@ -82,6 +82,9 @@ void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device);
void pci_dev_init(struct device *dev);
unsigned int pci_match_simple_dev(device_t dev, pci_devfn_t sdev);
+const char * pin_to_str(int pin);
+int get_irq_pins(device_t dev, device_t *parent_bdg);
+int swizzle_irq_pins(device_t dev, device_t *parent_bdg);
void pci_assign_irqs(unsigned bus, unsigned slot,
const unsigned char pIntAtoD[4]);
Martin Roth (martin.roth(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5733
-gerrit
commit bc2748eb000163d91fa9a84a0e1ed57b083498ce
Author: Mike Loptien <mike.loptien(a)se-eng.com>
Date: Mon May 12 21:39:04 2014 -0600
ACPI: Move irqhelper.h and irqroute.asl to arch/x86
These files end up being exactly the same for every platform
so they can be moved up to arch/x86 so that they are not
duplicated for every mainboard.
These are used for all of the Intel FSP platforms, the MRC-based
Bay Trail platform can be modified slightly to use this and AMD
platform support will be brought in shortly.
Change-Id: I2ee56c1acf9ad66c2c76f1cca00d99e8bc14eab1
Signed-off-by: Martin Roth <gaumless(a)gmail.com>
---
src/arch/x86/acpi/irq_helper.h | 55 ++++++++++++++++++++++++++++++++++++++++++
src/arch/x86/acpi/irqroute.asl | 43 +++++++++++++++++++++++++++++++++
2 files changed, 98 insertions(+)
diff --git a/src/arch/x86/acpi/irq_helper.h b/src/arch/x86/acpi/irq_helper.h
new file mode 100644
index 0000000..e3a23d8
--- /dev/null
+++ b/src/arch/x86/acpi/irq_helper.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 Sage Electronics Engineering, LLC.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * This file will use arch/x86/acpi/irqroute.asl and mainboard/irqroute.h
+ * to generate the ACPI IRQ routing for the mainboard being compiled.
+ * This method uses #defines in irqroute.h along with the macros contained
+ * in this file to generate an IRQ routing for each PCI device in the system.
+ */
+#undef PCI_DEV_PIRQ_ROUTES
+#undef ACPI_DEV_IRQ
+#undef PCI_DEV_PIRQ_ROUTE
+#undef PIRQ_PIC_ROUTES
+#undef PIRQ_PIC
+
+#if defined(PIC_MODE)
+
+#define ACPI_DEV_IRQ(dev_, pin_, pin_name_) \
+ Package() { ## dev_ ## ffff, pin_, \_SB.PCI0.LPCB.LNK ## pin_name_, 0 }
+
+#else /* defined(PIC_MODE) */
+
+#define ACPI_DEV_IRQ(dev_, pin_, pin_name_) \
+ Package() { ## dev_ ## ffff, pin_, 0, PIRQ ## pin_name_ ## _APIC_IRQ }
+
+#endif
+
+#define PCI_DEV_PIRQ_ROUTE(dev_, a_, b_, c_, d_) \
+ ACPI_DEV_IRQ(dev_, 0, a_), \
+ ACPI_DEV_IRQ(dev_, 1, b_), \
+ ACPI_DEV_IRQ(dev_, 2, c_), \
+ ACPI_DEV_IRQ(dev_, 3, d_)
+
+/* Empty PIRQ_PIC definition. */
+#define PIRQ_PIC(pirq_, pic_irq_)
+
+/* Include the mainboard irq route definition */
+#include "irqroute.h"
diff --git a/src/arch/x86/acpi/irqroute.asl b/src/arch/x86/acpi/irqroute.asl
new file mode 100644
index 0000000..24f4d54
--- /dev/null
+++ b/src/arch/x86/acpi/irqroute.asl
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2013 Google Inc.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+// PCI Interrupt Routing
+Method(_PRT)
+{
+ /*
+ * PICM comes from _PIC, which returns the following:
+ * 0 – PIC mode
+ * 1 – APIC mode
+ * 2 – SAPIC mode
+ */
+ If (PICM) {
+ Return (Package() {
+ #undef PIC_MODE
+ #include <arch/x86/acpi/irq_helper.h>
+ PCI_DEV_PIRQ_ROUTES
+ })
+ } Else {
+ Return (Package() {
+ #define PIC_MODE
+ #include <arch/x86/acpi/irq_helper.h>
+ PCI_DEV_PIRQ_ROUTES
+ })
+ }
+}
Martin Roth (martin.roth(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5732
-gerrit
commit af21eb3e3767816c6ef03331938c8f3522e052fc
Author: Martin Roth <gaumless(a)gmail.com>
Date: Mon May 12 17:38:59 2014 -0600
device_romstage: Add a way to move to the next device
When trying to loop through all the devices in romstage, there was
no function to just go from one to the next.
This gives an easy way to go all the way down the chain of devices.
Change-Id: Id205b24610d75de060b0d48fa283a2ab92d1df0a
Signed-off-by: Martin Roth <gaumless(a)gmail.com>
---
src/device/device_romstage.c | 22 ++++++++++++++++++++++
src/include/device/device.h | 2 ++
2 files changed, 24 insertions(+)
diff --git a/src/device/device_romstage.c b/src/device/device_romstage.c
index 591cf88..d37dd8e 100644
--- a/src/device/device_romstage.c
+++ b/src/device/device_romstage.c
@@ -55,6 +55,28 @@ ROMSTAGE_CONST struct device *dev_find_slot(unsigned int bus,
}
/**
+ * Given a device pointer, find the next pci device.
+ *
+ * @param previous_dev A pointer to a PCI device structure.
+ * @return Pointer to the next device structure (if found), 0 otherwise.
+ */
+ROMSTAGE_CONST struct device *dev_find_next_device(
+ ROMSTAGE_CONST struct device *previous_dev)
+{
+ ROMSTAGE_CONST struct device *dev, *result;
+
+ result = 0;
+
+ for (dev = previous_dev->next; dev; dev = dev->next) {
+ if (dev->path.type == DEVICE_PATH_PCI) {
+ result = dev;
+ break;
+ }
+ }
+ return result;
+}
+
+/**
* Given an SMBus bus and a device number, find the device structure.
*
* @param bus The bus number.
diff --git a/src/include/device/device.h b/src/include/device/device.h
index dfebeaa..90fcc7c 100644
--- a/src/include/device/device.h
+++ b/src/include/device/device.h
@@ -238,6 +238,8 @@ u32 find_pci_tolm(struct bus *bus);
ROMSTAGE_CONST struct device * dev_find_slot (unsigned int bus,
unsigned int devfn);
+ROMSTAGE_CONST struct device *dev_find_next_device(
+ ROMSTAGE_CONST struct device *previous_dev);
ROMSTAGE_CONST struct device * dev_find_slot_on_smbus (unsigned int bus,
unsigned int addr);
the following patch was just integrated into master:
commit a823f9b545b4a172c1c0f778b773f9ca13f0791e
Author: Zaolin <zaolin(a)das-labor.org>
Date: Tue May 6 21:31:45 2014 +0200
mainboard/lenovo: Add Lenovo Thinkpad T520 support
Short list of known issues for this patchset:
* Suspend/Resume - does not work
* Combi pci card for SD/MMC card reader with IEEE1394 - not found
* Shutdown - sometimes does not work as expected
* At least mysterious harddrive i/o
Change-Id: Iaba8d1f5e471cfeca20d82f4e1b416641e1f2ae9
Signed-off-by: Philipp Deppenwiese <zaolin(a)das-labor.org>
Reviewed-on: http://review.coreboot.org/5672
Tested-by: build bot (Jenkins)
Reviewed-by: Idwer Vollering <vidwer(a)gmail.com>
See http://review.coreboot.org/5672 for details.
-gerrit
the following patch was just integrated into master:
commit 3d68b1a62af20894fc0137a9658587f12b84e004
Author: Zaolin <zaolin(a)das-labor.org>
Date: Tue May 6 21:30:54 2014 +0200
cpu/intel: Add CPU socket rPGA988B
Used by the Lenovo ThinkPad T520
Change-Id: I1009616cc4c18ebd0e3be7ceb50398617b49e3a3
Signed-off-by: Philipp Deppenwiese <zaolin(a)das-labor.org>
Reviewed-on: http://review.coreboot.org/5671
Reviewed-by: Idwer Vollering <vidwer(a)gmail.com>
Tested-by: build bot (Jenkins)
See http://review.coreboot.org/5671 for details.
-gerrit
the following patch was just integrated into master:
commit 107b71c3a3101c307acadb75c1e1e2f7b96c5015
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Jan 9 14:35:41 2014 -0600
baytrail: reboot with EC in S0 with no MRC cache and EC in RW
This improves boot time in 2 ways for a firmware upgrade:
1. Normally MRC would detect the S0 state without an MRC cache
even though it's told to the S5 path. When it observes this
state a cold reset occurs. The cold reset stays in S5 for
at least 4 seconds which is time observed by the end user.
2. As the EC was running RW code before the reset after firmware
upgrade it will still be running the older RW code. Vboot will
then reboot the EC and the whole system to put the EC into RO
mode so it can handle the RW update.
The issues are mitigated by detecting the system is in S0 with
no MRC cache and the EC isn't in RO mode. Therefore we can do the
reboot without waiting the 4 secs and the EC is running RO so
the 2nd reboot is not necessary.
BUG=chrome-os-partner:24133
BRANCH=rambi,squawks
TEST=Booted. Updated firmware while in OS. Rebooted. Noted the
EC reboot before MRC execution.
Change-Id: I1c53d334a5e18c237a74ffbe96f263a7540cd8fe
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/182061
Reviewed-by: Duncan Laurie <dlaurie(a)chromium.org>
Reviewed-on: http://review.coreboot.org/5040
Tested-by: build bot (Jenkins)
Reviewed-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
See http://review.coreboot.org/5040 for details.
-gerrit
the following patch was just integrated into master:
commit 9f1a7cffabacdb6022e4579a6229eb5d29e9bcf4
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Jan 9 14:28:05 2014 -0600
chromeec: add function to reboot on unexpected image
It's helpful to have a generic function that will tell
the EC to reboot if the EC isn't running a specified
image. Add that and implement google_chromeec_early_init()
to utilize the new function still maintaing its semantics
of if recvoery mode is enabled the EC should be running its
RO image. There is a slight change in that no communication
is done with the EC if not in recovery mode.
BUG=chrome-os-partner:24133
BRANCH=rambi,squawks
TEST=Built and boot with recovery request. Noted EC reboot.
Change-Id: I22240f6a11231e39c33fd79796a52ec76b119397
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/182060
Reviewed-by: Duncan Laurie <dlaurie(a)chromium.org>
Reviewed-on: http://review.coreboot.org/5039
Tested-by: build bot (Jenkins)
Reviewed-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
See http://review.coreboot.org/5039 for details.
-gerrit
the following patch was just integrated into master:
commit b376ea632f1498174d86fa8f8b78848607492055
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Thu Jan 9 10:10:15 2014 -0800
baytrail: dptf: Add disable trip point methods
Added a method in each temp sensor to disable the aux trip points
and then a wrapper function to call this method for each enabled
temperature sensor.
The event handler function is changed to not use a switch statement
so it does not need to be serialized. This was causing issues
with nested locking between the global lock and the EC PATM mutex.
Some unused code in temp sensors that was added earlier is removed
and instead a critical threshold is specified in _CRT.
The top level DPTF device _OSC method is expanded to check for the
passive policy UUID and initialize thermal devices. This is done
for both enable and disable steps to ensure that the EC thermal
thresholds are reset in both cases.
Additionally the priority based _TRT is specified with TRTR=1.
BUG=chrome-os-partner:17279
BRANCH=rambi
TEST=build and boot on rambi, load esif_lf kernel drivers and start
esif_uf application. Observe that temperature thresholds are set
properly when running 'appstart Dptf' and that they are disabled
after running 'appstop Dptf'
Change-Id: Ia15824ca42164dadae2011d4e364b70905e36f85
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/182024
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Reviewed-on: http://review.coreboot.org/5037
Tested-by: build bot (Jenkins)
Reviewed-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
See http://review.coreboot.org/5037 for details.
-gerrit
the following patch was just integrated into master:
commit dec0148100cb05f5675c4f5127753cd32035930d
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Thu Jan 9 10:10:51 2014 -0800
rambi: dptf: Set critical thresholds
Set critical temperature thresdholds to 70C. This will cause DPTF
framework to shut down the system so it may need to be higher or
lower but will need some testing.
BUG=chrome-os-partner:17279
BRANCH=rambi
TEST=build and boot on rambi, start DPTF framework and observe it
using specified critical thresholds.
Change-Id: Ibbf6d814295eb5ff006cb879676b7613f5eb56a3
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/182025
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Reviewed-on: http://review.coreboot.org/5038
Tested-by: build bot (Jenkins)
Reviewed-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
See http://review.coreboot.org/5038 for details.
-gerrit