Allocating resource for Expansion ROM
authorLi-Ta Lo <ollie@lanl.gov>
Thu, 23 Dec 2004 21:48:01 +0000 (21:48 +0000)
committerLi-Ta Lo <ollie@lanl.gov>
Thu, 23 Dec 2004 21:48:01 +0000 (21:48 +0000)
More correct resource allocation for legacy VGA on K8

git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1829 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

src/devices/pci_device.c
src/devices/smbus_ops.c
src/northbridge/amd/amdk8/northbridge.c

index b16e922a33a2c0350f9cb71e6a2e2b660835df33..6062fa638700baaed613fc64ee56a1abf287b8ec 100644 (file)
@@ -37,6 +37,7 @@ static uint8_t pci_moving_config8(struct device *dev, unsigned reg)
 
        return ones ^ zeroes;
 }
+
 static uint16_t pci_moving_config16(struct device *dev, unsigned reg)
 {
        uint16_t value, ones, zeroes;
@@ -81,7 +82,7 @@ unsigned pci_find_capability(device_t dev, unsigned cap)
        if (pos > PCI_CAP_LIST_NEXT) {
                pos = pci_read_config8(dev, pos);
        }
-       while(pos != 0) {   /* loop through the linked list */
+       while (pos != 0) {   /* loop through the linked list */
                int this_cap;
                this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
                if (this_cap == cap) {
@@ -111,7 +112,7 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
 
        /* See which bits move */
        moving = pci_moving_config32(dev, index);
-       
+
        /* Initialize attr to the bits that do not move */
        attr = value & ~moving;
 
@@ -153,9 +154,8 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
         */
        if (moving == 0) {
                if (value != 0) {
-                       printk_debug(
-                               "%s register %02x(%08x), read-only ignoring it\n",
-                               dev_path(dev), index, value);
+                       printk_debug("%s register %02x(%08x), read-only ignoring it\n",
+                                    dev_path(dev), index, value);
                }
                resource->flags = 0;
        }
@@ -199,9 +199,9 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
 #if 0
        if (resource->flags) {
                printk_debug("%s %02x ->",
-                       dev_path(dev), resource->index);
+                            dev_path(dev), resource->index);
                printk_debug(" value: 0x%08Lx zeroes: 0x%08Lx ones: 0x%08Lx attr: %08lx\n",
-                       value, zeroes, ones, attr);
+                            value, zeroes, ones, attr);
                printk_debug(
                        "%s %02x -> size: 0x%08Lx max: 0x%08Lx %s%s\n ",
                        dev_path(dev),
@@ -225,7 +225,7 @@ static void pci_read_bases(struct device *dev, unsigned int howmany)
 {
        unsigned long index;
 
-       for(index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
+       for (index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
                struct resource *resource;
                resource = pci_get_resource(dev, index);
                index += (resource->flags & IORESOURCE_PCI64)?8:4;
@@ -233,11 +233,63 @@ static void pci_read_bases(struct device *dev, unsigned int howmany)
        compact_resources(dev);
 }
 
+static void pci_read_rom_resource(struct device *dev, unsigned long index)
+{
+       struct resource *resource;
+       unsigned long value, attr;
+       resource_t  moving, limit;
+
+       /* Initialize the resources to nothing */
+       resource = new_resource(dev, index);
+
+       /* Get the initial value */
+       value = pci_read_config32(dev, index);
+
+       /* See which bits move */
+       moving = pci_moving_config32(dev, index);
+       /* clear the Enable bit */
+       moving = moving & 0xffffffffe;
+
+       /* Find the resource constraints. 
+        *
+        * Start by finding the bits that move. From there:
+        * - Size is the least significant bit of the bits that move.
+        * - Limit is all of the bits that move plus all of the lower bits.
+        * See PCI Spec 6.2.5.1 ...
+        */
+       limit = 0;
+
+       if (moving) {
+               resource->size = 1;
+               resource->align = resource->gran = 0;
+               while(!(moving & resource->size)) {
+                       resource->size <<= 1;
+                       resource->align += 1;
+                       resource->gran  += 1;
+               }
+               resource->limit = limit = moving | (resource->size - 1);
+               printk_debug("%s, rom size: %x, limit: %x\n",
+                           dev_path(dev), resource->size, limit);
+       }
+
+       if (moving == 0) {
+               if (value != 0) {
+                       printk_debug("%s register %02x(%08x), read-only ignoring it\n",
+                                    dev_path(dev), index, value);
+               }
+               resource->flags = 0;
+       } else {
+               resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY;
+       }
+       compact_resources(dev);
+
+}
+
 static void pci_set_resource(struct device *dev, struct resource *resource);
 
-static void pci_record_bridge_resource(
-       struct device *dev, resource_t moving,
-       unsigned index, unsigned long mask, unsigned long type)
+static void pci_record_bridge_resource( struct device *dev, resource_t moving,
+                                       unsigned index, unsigned long mask,
+                                       unsigned long type)
 {
        /* Initiliaze the constraints on the current bus */
        struct resource *resource;
@@ -272,7 +324,6 @@ static void pci_record_bridge_resource(
        return;
 }
 
-
 static void pci_bridge_read_bases(struct device *dev)
 {
        resource_t moving_base, moving_limit, moving;
@@ -329,8 +380,7 @@ void pci_dev_read_resources(struct device *dev)
 
        pci_read_bases(dev, 6);
 
-       addr = pci_read_config32(dev, PCI_ROM_ADDRESS);
-       dev->rom_address = (addr == 0xffffffff)? 0 : addr;
+       pci_read_rom_resource(dev, PCI_ROM_ADDRESS);
 }
 
 void pci_bus_read_resources(struct device *dev)
@@ -339,9 +389,8 @@ void pci_bus_read_resources(struct device *dev)
 
        pci_bridge_read_bases(dev);
        pci_read_bases(dev, 2);
-       
-       addr = pci_read_config32(dev, PCI_ROM_ADDRESS1);
-       dev->rom_address = (addr == 0xffffffff)? 0 : addr;
+
+       pci_read_rom_resource(dev, PCI_ROM_ADDRESS1);
 }
 
 static void pci_set_resource(struct device *dev, struct resource *resource)
@@ -450,10 +499,10 @@ void pci_dev_set_resources(struct device *dev)
 
        last = &dev->resource[dev->resources];
 
-       for(resource = &dev->resource[0]; resource < last; resource++) {
+       for (resource = &dev->resource[0]; resource < last; resource++) {
                pci_set_resource(dev, resource);
        }
-       for(link = 0; link < dev->links; link++) {
+       for (link = 0; link < dev->links; link++) {
                struct bus *bus;
                bus = &dev->link[link];
                if (bus->children) {
index e721bfbfb39e9e09b8b789d9de956f9133d17a21..8d32a66b8f286ef14db85b3fb170b0ba729bb2c9 100644 (file)
@@ -7,7 +7,7 @@
 struct bus *get_pbus_smbus(device_t dev)
 {
        struct bus *pbus = dev->bus;
-       while(pbus && pbus->dev && !ops_smbus_bus(pbus)) {
+       while (pbus && pbus->dev && !ops_smbus_bus(pbus)) {
                pbus = pbus->dev->bus;
        }
        if (!pbus || !pbus->dev || !pbus->dev->ops || !pbus->dev->ops->ops_smbus_bus) {
@@ -18,9 +18,10 @@ struct bus *get_pbus_smbus(device_t dev)
        return pbus;
 }
 
-       /*multi level i2c MUX??? may need to find the first i2c device and then set link down to current dev
-                 1 store get_pbus_smbus list link
-                 2 reverse the link and call set link */
+/*multi level i2c MUX??? may need to find the first i2c device and then set link
+ * down to current dev
+  1 store get_pbus_smbus list link
+  2 reverse the link and call set link */
 
 int smbus_set_link(device_t dev)
 {
@@ -33,10 +34,10 @@ int smbus_set_link(device_t dev)
                 pbus = pbus->dev->bus;
         }
 //     printk_info("smbus_set_link: ");
-       for(i=pbus_num-1; i>=0; i--) {
+       for (i=pbus_num-1; i>=0; i--) {
 //             printk_info(" %s[%d] -> ", dev_path(pbus_a[i]->dev), pbus_a[i]->link);
-               if(ops_smbus_bus(get_pbus_smbus(pbus_a[i]->dev))) {
-                       if(pbus_a[i]->dev->ops && pbus_a[i]->dev->ops->set_link)
+               if (ops_smbus_bus(get_pbus_smbus(pbus_a[i]->dev))) {
+                       if (pbus_a[i]->dev->ops && pbus_a[i]->dev->ops->set_link)
                                pbus_a[i]->dev->ops->set_link(pbus_a[i]->dev, pbus_a[i]->link);
                }
        }
index 788d698bacf7d268a9c98cbe23d3a0a25b66cda0..7612d398aea31bb0da7971a81eed8ea442f02975 100644 (file)
@@ -424,6 +424,8 @@ static void amdk8_create_vga_resource(device_t dev, unsigned nodeid)
 {
        struct resource *resource;
        unsigned link;
+       uint32_t base, limit;
+       unsigned reg;
        for (link = 0; link < dev->links; link++) {
                if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
                        printk_info("%s: bridge on link %d has VGA device\n",
@@ -433,12 +435,29 @@ static void amdk8_create_vga_resource(device_t dev, unsigned nodeid)
                        resource =  amdk8_find_mempair(dev, nodeid, link);
                        printk_info("MEM pair register %x\n", resource->index - 0x100);
                        resource->base = 0xa0000;
-                       resource->size = 0x00000;
+                       resource->size = 0x20000;
                        resource->gran = 16;
                        resource->align = 16;
-                       resource->flags = IORESOURCE_PREFETCH | IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_ASSIGNED;
+                       resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_ASSIGNED;
                }
        }
+#if 1
+       reg  = resource->index & 0xfc;
+       base  = f1_read_config32(reg);
+       limit = f1_read_config32(reg + 0x4);
+       base  &= 0x000000f0;
+       base  |= (resource->base >> 8) & 0xffffff00;
+       base  |= 3;
+       limit &= 0x00000048;
+       limit |= ((resource->base + resource->size) >> 8) & 0xffffff00;
+       limit |= (resource->index & 3) << 4;
+       limit |= (nodeid & 7);
+       f1_write_config32(reg + 0x4, limit);
+       f1_write_config32(reg, base);
+
+       /* release the resource */
+       resource->flags = 0;
+#endif
 }
 static void amdk8_set_resources(device_t dev)
 {