i82801gx: Reserve LPC decodes.

This change makes sure that LPC controller declares resources that it
actually decodes. bd82x6x already does it but i82801gx doesn't leading
to allocator potentially allocating something else to the same range.

Change-Id: Ieca9852e54c08e31d4d41aea97f317d9a6919806
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Reviewed-on: http://review.coreboot.org/7662
Tested-by: build bot (Jenkins)
Reviewed-by: Edward O'Callaghan <edward.ocallaghan@koparo.com>
diff --git a/src/southbridge/intel/i82801gx/lpc.c b/src/southbridge/intel/i82801gx/lpc.c
index 31ea130..bf61855 100644
--- a/src/southbridge/intel/i82801gx/lpc.c
+++ b/src/southbridge/intel/i82801gx/lpc.c
@@ -579,18 +579,20 @@
 static void i82801gx_lpc_read_resources(device_t dev)
 {
 	struct resource *res;
+	u8 io_index = 0;
+	int i;
 
 	/* 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(0, 0));
+	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;
 
-	res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+	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 |
@@ -600,6 +602,20 @@
 	res->base = IO_APIC_ADDR;
 	res->size = 0x00001000;
 	res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+	/* Set IO decode ranges if required.*/
+	for (i = 0; i < 4; i++) {
+		u32 gen_dec;
+		gen_dec = pci_read_config32(dev, 0x84 + 4 * i);
+
+		if ((gen_dec & 0xFFFC) > 0x1000) {
+			res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
+			res->base = gen_dec & 0xFFFC;
+			res->size = (gen_dec >> 16) & 0xFC;
+			res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+				IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+		}
+	}
 }
 
 static void set_subsystem(device_t dev, unsigned vendor, unsigned device)