Allocating resource for Expansion ROM

More correct resource allocation for legacy VGA on K8


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1829 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Li-Ta Lo
2004-12-23 21:48:01 +00:00
parent a804a713a2
commit 9a5b4962a7
3 changed files with 97 additions and 28 deletions

View File

@@ -37,6 +37,7 @@ static uint8_t pci_moving_config8(struct device *dev, unsigned reg)
return ones ^ zeroes; return ones ^ zeroes;
} }
static uint16_t pci_moving_config16(struct device *dev, unsigned reg) static uint16_t pci_moving_config16(struct device *dev, unsigned reg)
{ {
uint16_t value, ones, zeroes; uint16_t value, ones, zeroes;
@@ -153,8 +154,7 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
*/ */
if (moving == 0) { if (moving == 0) {
if (value != 0) { if (value != 0) {
printk_debug( printk_debug("%s register %02x(%08x), read-only ignoring it\n",
"%s register %02x(%08x), read-only ignoring it\n",
dev_path(dev), index, value); dev_path(dev), index, value);
} }
resource->flags = 0; resource->flags = 0;
@@ -233,11 +233,63 @@ static void pci_read_bases(struct device *dev, unsigned int howmany)
compact_resources(dev); 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_set_resource(struct device *dev, struct resource *resource);
static void pci_record_bridge_resource( static void pci_record_bridge_resource( struct device *dev, resource_t moving,
struct device *dev, resource_t moving, unsigned index, unsigned long mask,
unsigned index, unsigned long mask, unsigned long type) unsigned long type)
{ {
/* Initiliaze the constraints on the current bus */ /* Initiliaze the constraints on the current bus */
struct resource *resource; struct resource *resource;
@@ -272,7 +324,6 @@ static void pci_record_bridge_resource(
return; return;
} }
static void pci_bridge_read_bases(struct device *dev) static void pci_bridge_read_bases(struct device *dev)
{ {
resource_t moving_base, moving_limit, moving; resource_t moving_base, moving_limit, moving;
@@ -329,8 +380,7 @@ void pci_dev_read_resources(struct device *dev)
pci_read_bases(dev, 6); pci_read_bases(dev, 6);
addr = pci_read_config32(dev, PCI_ROM_ADDRESS); pci_read_rom_resource(dev, PCI_ROM_ADDRESS);
dev->rom_address = (addr == 0xffffffff)? 0 : addr;
} }
void pci_bus_read_resources(struct device *dev) void pci_bus_read_resources(struct device *dev)
@@ -340,8 +390,7 @@ void pci_bus_read_resources(struct device *dev)
pci_bridge_read_bases(dev); pci_bridge_read_bases(dev);
pci_read_bases(dev, 2); pci_read_bases(dev, 2);
addr = pci_read_config32(dev, PCI_ROM_ADDRESS1); pci_read_rom_resource(dev, PCI_ROM_ADDRESS1);
dev->rom_address = (addr == 0xffffffff)? 0 : addr;
} }
static void pci_set_resource(struct device *dev, struct resource *resource) static void pci_set_resource(struct device *dev, struct resource *resource)

View File

@@ -18,7 +18,8 @@ struct bus *get_pbus_smbus(device_t dev)
return pbus; return pbus;
} }
/*multi level i2c MUX??? may need to find the first i2c device and then set link down to current dev /*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 1 store get_pbus_smbus list link
2 reverse the link and call set link */ 2 reverse the link and call set link */

View File

@@ -424,6 +424,8 @@ static void amdk8_create_vga_resource(device_t dev, unsigned nodeid)
{ {
struct resource *resource; struct resource *resource;
unsigned link; unsigned link;
uint32_t base, limit;
unsigned reg;
for (link = 0; link < dev->links; link++) { for (link = 0; link < dev->links; link++) {
if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) { if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
printk_info("%s: bridge on link %d has VGA device\n", 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); resource = amdk8_find_mempair(dev, nodeid, link);
printk_info("MEM pair register %x\n", resource->index - 0x100); printk_info("MEM pair register %x\n", resource->index - 0x100);
resource->base = 0xa0000; resource->base = 0xa0000;
resource->size = 0x00000; resource->size = 0x20000;
resource->gran = 16; resource->gran = 16;
resource->align = 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) static void amdk8_set_resources(device_t dev)
{ {