[coreboot] New patch to review for coreboot: 58b355f lynxpoint: lpc resource reservations

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Tue Mar 12 22:51:19 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 58b355faa757643845bd320a773e7dd8be32894f
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