[coreboot] Patch set updated for coreboot: f7b7845 lynxpoint: lpc resource reservations
Stefan Reinauer (stefan.reinauer@coreboot.org)
gerrit at coreboot.org
Wed Mar 13 01:09:14 CET 2013
Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2682
-gerrit
commit f7b78458911d5179642c80356f5615c0ab5d2848
Author: Aaron Durbin <adurbin at chromium.org>
Date: Wed Dec 19 14:38:01 2012 -0600
lynxpoint: lpc resource reservations
This commit updates the Lynx Point resource reservations before
the coreboot allocator assigns resources. There is no need to mark
anything as subtractive decode because there are no devices/buses
linked to the LPC device.
The I/O range reservations consists of claiming the first 4KiB
of I/O space. The PMBASE, GPIOBASE, and LPC generic I/O decode
ranges are checked against the default claimed range. If those
ranges overlap or fall outside of the default range then those
resources are added.
The MMIO range reservations consist of claiming everything from
the I/O APIC to 4GiB. The RCBA and the LPC Generic Memory range
register are then conditionally added if they fall outside of
the default MMIO range.
Change-Id: I0f560a03814a2b15961fdbe61e4164cd54cff7a5
Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
src/southbridge/intel/lynxpoint/lpc.c | 167 +++++++++++++++++++++++-----------
src/southbridge/intel/lynxpoint/pch.h | 1 +
2 files changed, 113 insertions(+), 55 deletions(-)
diff --git a/src/southbridge/intel/lynxpoint/lpc.c b/src/southbridge/intel/lynxpoint/lpc.c
index a44d80f..facea7c 100644
--- a/src/southbridge/intel/lynxpoint/lpc.c
+++ b/src/southbridge/intel/lynxpoint/lpc.c
@@ -574,74 +574,131 @@ static void lpc_init(struct device *dev)
pch_fixups(dev);
}
-static void pch_lpc_read_resources(device_t dev)
+static void pch_lpc_add_mmio_resources(device_t dev)
{
+ u32 reg;
struct resource *res;
- config_t *config = dev->chip_info;
- u8 io_index = 0;
-
- /* Get the normal PCI resources of this device. */
- pci_dev_read_resources(dev);
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+ const u32 default_decode_base = IO_APIC_ADDR;
- /* GPIOBASE */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
- res->base = DEFAULT_GPIOBASE;
- res->size = DEFAULT_GPIOSIZE;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, io_index++); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
+ /*
+ * Just report all resources from IO-APIC base to 4GiB. Don't mark
+ * them reserved as that may upset the OS if this range is marked
+ * as reserved in the e820.
+ */
+ res = new_resource(dev, OIC);
+ res->base = default_decode_base;
+ res->size = 0 - default_decode_base;
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
- /* Set PCH IO decode ranges if required.*/
- if ((config->gen1_dec & 0xFFFC) > 0x1000) {
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
- res->base = config->gen1_dec & 0xFFFC;
- res->size = (config->gen1_dec >> 16) & 0xFC;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+ /* RCBA */
+ if (DEFAULT_RCBA < default_decode_base) {
+ res = new_resource(dev, RCBA);
+ res->base = DEFAULT_RCBA;
+ res->size = 16 * 1024;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED |
+ IORESOURCE_FIXED | IORESOURCE_RESERVE;
}
- if ((config->gen2_dec & 0xFFFC) > 0x1000) {
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
- res->base = config->gen2_dec & 0xFFFC;
- res->size = (config->gen2_dec >> 16) & 0xFC;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+ /* Check LPC Memory Decode register. */
+ reg = pci_read_config32(dev, LGMR);
+ if (reg & 1) {
+ reg &= ~0xffff;
+ if (reg < default_decode_base) {
+ res = new_resource(dev, LGMR);
+ res->base = reg;
+ res->size = 16 * 1024;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED |
+ IORESOURCE_FIXED | IORESOURCE_RESERVE;
+ }
}
+}
- if ((config->gen3_dec & 0xFFFC) > 0x1000) {
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
- res->base = config->gen3_dec & 0xFFFC;
- res->size = (config->gen3_dec >> 16) & 0xFC;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
- }
+/* Default IO range claimed by the LPC device. The upper bound is exclusive. */
+#define LPC_DEFAULT_IO_RANGE_LOWER 0
+#define LPC_DEFAULT_IO_RANGE_UPPER 0x1000
+
+static inline int pch_io_range_in_default(u16 base, u16 size)
+{
+ /* Does it start above the range? */
+ if (base >= LPC_DEFAULT_IO_RANGE_UPPER)
+ return 0;
+
+ /* Is it entirely contained? */
+ if (base >= LPC_DEFAULT_IO_RANGE_LOWER &&
+ (base + size) < LPC_DEFAULT_IO_RANGE_UPPER)
+ return 1;
+
+ /* This will return not in range for partial overlaps. */
+ return 0;
+}
+
+/*
+ * Note: this function assumes there is no overlap with the default LPC device's
+ * claimed range: LPC_DEFAULT_IO_RANGE_LOWER -> LPC_DEFAULT_IO_RANGE_UPPER.
+ */
+static void pch_lpc_add_io_resource(device_t dev, u16 base, u16 size, int index)
+{
+ struct resource *res;
+
+ if (pch_io_range_in_default(base, size))
+ return;
- if ((config->gen4_dec & 0xFFFC) > 0x1000) {
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
- res->base = config->gen4_dec & 0xFFFC;
- res->size = (config->gen4_dec >> 16) & 0xFC;
- res->flags = IORESOURCE_IO| IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+ res = new_resource(dev, index);
+ res->base = base;
+ res->size = size;
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void pch_lpc_add_gen_io_resources(device_t dev, int reg_value, int index)
+{
+ /*
+ * Check if the register is enabled. If so and the base exceeds the
+ * device's deafult claim range add the resoure.
+ */
+ if (reg_value & 1) {
+ u16 base = reg_value & 0xfffc;
+ u16 size = (0x3 | ((reg_value >> 16) & 0xfc)) + 1;
+ pch_lpc_add_io_resource(dev, base, size, index);
}
}
+static void pch_lpc_add_io_resources(device_t dev)
+{
+ struct resource *res;
+ config_t *config = dev->chip_info;
+
+ /* Add the default claimed IO range for the LPC device. */
+ res = new_resource(dev, 0);
+ res->base = LPC_DEFAULT_IO_RANGE_LOWER;
+ res->size = LPC_DEFAULT_IO_RANGE_UPPER - LPC_DEFAULT_IO_RANGE_LOWER;
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ /* GPIOBASE */
+ pch_lpc_add_io_resource(dev, DEFAULT_GPIOBASE, DEFAULT_GPIOSIZE,
+ GPIO_BASE);
+
+ /* PMBASE */
+ pch_lpc_add_io_resource(dev, DEFAULT_PMBASE, 128, PMBASE);
+
+ /* LPC Generic IO Decode range. */
+ pch_lpc_add_gen_io_resources(dev, config->gen1_dec, LPC_GEN1_DEC);
+ pch_lpc_add_gen_io_resources(dev, config->gen2_dec, LPC_GEN2_DEC);
+ pch_lpc_add_gen_io_resources(dev, config->gen3_dec, LPC_GEN3_DEC);
+ pch_lpc_add_gen_io_resources(dev, config->gen4_dec, LPC_GEN4_DEC);
+}
+
+static void pch_lpc_read_resources(device_t dev)
+{
+ /* Get the normal PCI resources of this device. */
+ pci_dev_read_resources(dev);
+
+ /* Add non-standard MMIO resources. */
+ pch_lpc_add_mmio_resources(dev);
+
+ /* Add IO resources. */
+ pch_lpc_add_io_resources(dev);
+}
+
static void pch_lpc_enable_resources(device_t dev)
{
pch_decode_init(dev);
diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h
index 4da2c62..eea3465 100644
--- a/src/southbridge/intel/lynxpoint/pch.h
+++ b/src/southbridge/intel/lynxpoint/pch.h
@@ -227,6 +227,7 @@ unsigned get_gpios(const int *gpio_num_array);
#define LPC_GEN2_DEC 0x88 /* LPC IF Generic Decode Range 2 */
#define LPC_GEN3_DEC 0x8c /* LPC IF Generic Decode Range 3 */
#define LPC_GEN4_DEC 0x90 /* LPC IF Generic Decode Range 4 */
+#define LGMR 0x98 /* LPC Generic Memory Range */
/* PCI Configuration Space (D31:F1): IDE */
#define PCH_IDE_DEV PCI_DEV(0, 0x1f, 1)
More information about the coreboot
mailing list