the following patch was just integrated into master:
commit 0f5cf5e45b78d2e6a91d978bb86de5a4ff07c4d5
Author: Mike Loptien <loptienm(a)gmail.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>
Reviewed-on: http://review.coreboot.org/5734
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marc.jones(a)se-eng.com>
Reviewed-by: Mike Loptien <mike.loptien(a)se-eng.com>
See http://review.coreboot.org/5734 for details.
-gerrit
the following patch was just integrated into master:
commit 433659ad1e864808ec30e90a62ecfd711559c5a9
Author: Martin Roth <gaumless(a)gmail.com>
Date: Mon May 12 21:55:00 2014 -0600
fsp_baytrail: Add the FSP version of Intel's Bay Trail-I chip
While similar to the Bay Trail-M/D code based on the MRC, there are
many differences as well:
- Obviously, uses the FSP instead of the MRC binaries.
- FSP does additional hardware setup, so coreboot doesn't need to.
- Different microcode & microcode loading method
- Uses the cache_as_ram.inc from the FSP Driver
- Various other changes in support of the FSP
Additional changes that don't have to to with the FSP vs MRC:
- Updated IRQ Routing
- Different FADT implementation.
This was validated with FSP:
BAYTRAIL_FSP_GOLD_002_10-JANUARY-2014.fd
SHA256: d29eefbb33454bd5314bfaa38fb055d592a757de7b348ed7096cd8c2d65908a5
MD5: 9360cd915f0d3e4116bbc782233d7b91
Change-Id: Iadadf8cd6cf444ba840e0f76d3aed7825cd7aee4
Signed-off-by: Martin Roth <gaumless(a)gmail.com>
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
Reviewed-on: http://review.coreboot.org/5791
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer(a)coreboot.org>
See http://review.coreboot.org/5791 for details.
-gerrit
Martin Roth (gaumless(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5734
-gerrit
commit 12523e206e456290c7f7012dfa24627a63f828cc
Author: Mike Loptien <loptienm(a)gmail.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 | 151 +++++++++++++++++++++++++++++++++++++++++++++++
src/include/device/pci.h | 2 +
2 files changed, 153 insertions(+)
diff --git a/src/device/pci_device.c b/src/device/pci_device.c
index f09fcaa..3a54c2d 100644
--- a/src/device/pci_device.c
+++ b/src/device/pci_device.c
@@ -12,6 +12,7 @@
* (Written by Yinghai Lu <yhlu(a)tyan.com> for Tyan)
* Copyright (C) 2005-2009 coresystems GmbH
* (Written by Stefan Reinauer <stepan(a)coresystems.de> for coresystems GmbH)
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC.
*/
/*
@@ -1303,6 +1304,156 @@ 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 corresponding to the pin number or "Invalid"
+ */
+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 + 1
+ * where PIN A = 1 ... PIN_D = 4
+ *
+ * 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
+ */
+static int swizzle_irq_pins(device_t dev, device_t *parent_bridge)
+{
+ device_t parent; /* Our current device's parent device */
+ device_t child; /* The child device of the parent */
+ uint8_t parent_bus = 0; /* Parent Bus number */
+ uint16_t parent_devfn = 0; /* Parent Device and Function number */
+ uint16_t child_devfn = 0; /* Child Device and Function number */
+ uint8_t 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_bridge = 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 get 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.
+ * Errors: -1 is returned if the device is not enabled
+ * -2 is returned if a parent bridge could not be found.
+ */
+int get_pci_irq_pins(device_t dev, device_t *parent_bdg)
+{
+ uint8_t bus = 0; /* The bus this device is on */
+ uint16_t devfn = 0; /* This device's device and function numbers */
+ uint8_t int_pin = 0; /* Interrupt pin used by the device */
+ uint8_t target_pin = 0; /* Interrupt pin we want to assign an IRQ to */
+
+ /* Make sure this device is enabled */
+ if (!(dev->enabled && (dev->path.type == DEVICE_PATH_PCI)))
+ return -1;
+
+ bus = dev->bus->secondary;
+ devfn = dev->path.pci.devfn;
+
+ /* Get and validate the interrupt pin used. 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:%02X.%02X 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..8175970 100644
--- a/src/include/device/pci.h
+++ b/src/include/device/pci.h
@@ -82,6 +82,8 @@ 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_pci_irq_pins(device_t dev, device_t *parent_bdg);
void pci_assign_irqs(unsigned bus, unsigned slot,
const unsigned char pIntAtoD[4]);
the following patch was just integrated into master:
commit 2a9b2ed3ff5411d0efdbde3b9ba1d1de06ab09aa
Author: Martin Roth <gaumless(a)gmail.com>
Date: Mon May 19 15:30:00 2014 -0600
drivers/intel/fsp: update enable_mrc_cache with fast boot
When going from a configuration with fast boot disabled to one with
it enabled, ENABLE_MRC_CACHE was not being enabled properly. This
forces it on with ENABLE_FSP_FAST_BOOT.
Change-Id: If7b6374e0c0a1d5403a50a1b0a958cea6f96cc88
Signed-off-by: Martin Roth <gaumless(a)gmail.com>
Reviewed-on: http://review.coreboot.org/5794
Tested-by: build bot (Jenkins)
Reviewed-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Reviewed-by: Stefan Reinauer <stefan.reinauer(a)coreboot.org>
See http://review.coreboot.org/5794 for details.
-gerrit
the following patch was just integrated into master:
commit 7312c54dc684099a6d85ae13f3de097754ced0f0
Author: Martin Roth <gaumless(a)gmail.com>
Date: Mon May 12 21:52:54 2014 -0600
add rtc_init() to romstage
The FSP clears the bit that tells us whether or not the RTC has lost
power when it sets up memory. Because of this, we need to initialize
the RTC in romstage instead of ramstage.
Change-Id: I158e4339fc539d32cfb2428042df6156d312a5f4
Signed-off-by: Martin Roth <gaumless(a)gmail.com>
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
Reviewed-on: http://review.coreboot.org/5735
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marc.jones(a)se-eng.com>
See http://review.coreboot.org/5735 for details.
-gerrit
Martin Roth (gaumless(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5735
-gerrit
commit 4ba47f88dc3326f870be443f43837463662f468f
Author: Martin Roth <gaumless(a)gmail.com>
Date: Mon May 12 21:52:54 2014 -0600
add rtc_init() to romstage
The FSP clears the bit that tells us whether or not the RTC has lost
power when it sets up memory. Because of this, we need to initialize
the RTC in romstage instead of ramstage.
Change-Id: I158e4339fc539d32cfb2428042df6156d312a5f4
Signed-off-by: Martin Roth <gaumless(a)gmail.com>
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
---
src/drivers/pc80/Makefile.inc | 1 +
src/drivers/pc80/mc146818rtc.c | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/drivers/pc80/Makefile.inc b/src/drivers/pc80/Makefile.inc
index 4d0a280..d216e2c 100644
--- a/src/drivers/pc80/Makefile.inc
+++ b/src/drivers/pc80/Makefile.inc
@@ -1,3 +1,4 @@
+romstage-y += mc146818rtc.c
ramstage-y += mc146818rtc.c
ramstage-y += isa-dma.c
ramstage-y += i8254.c
diff --git a/src/drivers/pc80/mc146818rtc.c b/src/drivers/pc80/mc146818rtc.c
index 51cd6c3..6f8a4eb 100644
--- a/src/drivers/pc80/mc146818rtc.c
+++ b/src/drivers/pc80/mc146818rtc.c
@@ -71,6 +71,7 @@ void rtc_init(int invalid)
unsigned char x;
#endif
+#ifndef __PRE_RAM__
#if CONFIG_HAVE_ACPI_RESUME
/*
* Avoid clearing pending interrupts and resetting the RTC control
@@ -80,7 +81,8 @@ void rtc_init(int invalid)
*/
if (acpi_slp_type == 3)
return;
-#endif
+#endif /* CONFIG_HAVE_ACPI_RESUME */
+#endif /* __PRE_RAM__ */
printk(BIOS_DEBUG, "RTC Init\n");
Martin Roth (gaumless(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5735
-gerrit
commit c12d1625e24bd0f6c7d5ef474b81455aca08cbf8
Author: Martin Roth <gaumless(a)gmail.com>
Date: Mon May 12 21:52:54 2014 -0600
add rtc_init() to romstage
The FSP clears the bit that tells us whether or not the RTC has lost
power when it sets up memory. Because of this, we need to initialize
the RTC in romstage instead of ramstage.
Change-Id: I158e4339fc539d32cfb2428042df6156d312a5f4
Signed-off-by: Martin Roth <gaumless(a)gmail.com>
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
---
src/drivers/pc80/Makefile.inc | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/drivers/pc80/Makefile.inc b/src/drivers/pc80/Makefile.inc
index 4d0a280..d216e2c 100644
--- a/src/drivers/pc80/Makefile.inc
+++ b/src/drivers/pc80/Makefile.inc
@@ -1,3 +1,4 @@
+romstage-y += mc146818rtc.c
ramstage-y += mc146818rtc.c
ramstage-y += isa-dma.c
ramstage-y += i8254.c