- O2, enums, and switch statements work in romcc
- Support for compiling romcc on non x86 platforms - new romc options -msse and -mmmx for specifying extra registers to use - Bug fixes to device the device disable/enable framework and an amd8111 implementation - Move the link specification to the chip specification instead of the path - Allow specifying devices with internal bridges. - Initial via epia support - Opteron errata fixes git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1200 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
@@ -46,16 +46,33 @@ void chip_enumerate(struct chip *chip)
|
||||
int identical_paths;
|
||||
identical_paths =
|
||||
(i > 0) &&
|
||||
(path_eq(&chip->path[i - 1].path, &chip->path[i].path)) &&
|
||||
(chip->path[i - 1].channel == chip->path[i].channel);
|
||||
(path_eq(&chip->path[i - 1].path, &chip->path[i].path));
|
||||
if (!identical_paths) {
|
||||
struct bus *parent;
|
||||
int bus;
|
||||
link = 0;
|
||||
dev = 0;
|
||||
parent = chip->bus;
|
||||
switch(chip->path[i].path.type) {
|
||||
case DEVICE_PATH_NONE:
|
||||
break;
|
||||
case DEVICE_PATH_PCI:
|
||||
bus = chip->path[i].path.u.pci.bus;
|
||||
if (bus != 0) {
|
||||
device_t dev;
|
||||
int i = 1;
|
||||
dev = chip->dev;
|
||||
while(dev && (i != bus)) {
|
||||
dev = dev->next;
|
||||
i++;
|
||||
}
|
||||
if ((i == bus) && dev) {
|
||||
parent = &dev->link[0];
|
||||
}
|
||||
}
|
||||
/* Fall through */
|
||||
default:
|
||||
dev = alloc_dev(chip->bus, &chip->path[i].path);
|
||||
dev = alloc_dev(parent, &chip->path[i].path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -63,12 +80,13 @@ void chip_enumerate(struct chip *chip)
|
||||
link += 1;
|
||||
}
|
||||
if (dev) {
|
||||
printk_spew("path %s %s\n", dev_path(dev), identical_paths?"identical":"");
|
||||
printk_spew("path (%p) %s %s", dev, dev_path(dev), identical_paths?"identical":"");
|
||||
printk_spew(" parent: (%p) %s\n",dev->bus->dev, dev_path(dev->bus->dev));
|
||||
dev->chip = chip;
|
||||
dev->enable = chip->path[i].enable;
|
||||
dev->links = link + 1;
|
||||
for(child = chip->children; child; child = child->next) {
|
||||
if (!child->bus &&
|
||||
child->path[0].channel == i) {
|
||||
if (!child->bus && child->link == i) {
|
||||
child->bus = &dev->link[link];
|
||||
}
|
||||
}
|
||||
|
@@ -115,6 +115,9 @@ static void read_resources(struct bus *bus)
|
||||
dev_path(curdev));
|
||||
continue;
|
||||
}
|
||||
if (!curdev->enable) {
|
||||
continue;
|
||||
}
|
||||
curdev->ops->read_resources(curdev);
|
||||
/* Read in subtractive resources behind the current device */
|
||||
links = 0;
|
||||
@@ -251,16 +254,12 @@ void compute_allocate_resource(
|
||||
min_align = 0;
|
||||
base = bridge->base;
|
||||
|
||||
printk_spew("%s: bus %p, bridge %p, type_mask 0x%x, type 0x%x\n",
|
||||
__FUNCTION__,
|
||||
bus, bridge, type_mask, type);
|
||||
printk_spew("vendor 0x%x device 0x%x class 0x%x \n",
|
||||
bus->dev->vendor, bus->dev->device, bus->dev->class);
|
||||
printk_spew("%s compute_allocate_%s: base: %08lx size: %08lx align: %d gran: %d\n",
|
||||
dev_path(bus->dev),
|
||||
(bridge->flags & IORESOURCE_IO)? "io":
|
||||
(bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem",
|
||||
base, bridge->size, bridge->align, bridge->gran);
|
||||
printk_spew("%s compute_allocate_%s: base: %08lx size: %08lx align: %d gran: %d\n",
|
||||
dev_path(bus->dev),
|
||||
(bridge->flags & IORESOURCE_IO)? "io":
|
||||
(bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem",
|
||||
base, bridge->size, bridge->align, bridge->gran);
|
||||
|
||||
|
||||
/* We want different minimum alignments for different kinds of
|
||||
* resources. These minimums are not device type specific
|
||||
@@ -406,6 +405,9 @@ void assign_resources(struct bus *bus)
|
||||
dev_path(curdev));
|
||||
continue;
|
||||
}
|
||||
if (!curdev->enable) {
|
||||
continue;
|
||||
}
|
||||
curdev->ops->set_resources(curdev);
|
||||
}
|
||||
printk_debug("ASSIGNED RESOURCES, bus %d\n", bus->secondary);
|
||||
@@ -422,6 +424,9 @@ void enable_resources(struct device *dev)
|
||||
dev_path(dev));
|
||||
return;
|
||||
}
|
||||
if (!dev->enable) {
|
||||
return;
|
||||
}
|
||||
dev->ops->enable_resources(dev);
|
||||
}
|
||||
|
||||
@@ -444,13 +449,12 @@ void dev_enumerate(void)
|
||||
void dev_configure(void)
|
||||
{
|
||||
struct device *root = &dev_root;
|
||||
printk_info("%s: Allocating resources...", __FUNCTION__);
|
||||
printk_info("Allocating resources...");
|
||||
printk_debug("\n");
|
||||
|
||||
|
||||
root->ops->read_resources(root);
|
||||
|
||||
printk_spew("%s: done reading resources...\n", __FUNCTION__);
|
||||
/* Make certain the io devices are allocated somewhere
|
||||
* safe.
|
||||
*/
|
||||
@@ -465,10 +469,8 @@ void dev_configure(void)
|
||||
root->resource[1].flags |= IORESOURCE_SET;
|
||||
// now just set things into registers ... we hope ...
|
||||
root->ops->set_resources(root);
|
||||
printk_spew("%s: done setting resources...\n", __FUNCTION__);
|
||||
|
||||
allocate_vga_resource();
|
||||
printk_spew("%s: done vga resources...\n", __FUNCTION__);
|
||||
|
||||
printk_info("done.\n");
|
||||
}
|
||||
@@ -494,7 +496,7 @@ void dev_initialize(void)
|
||||
|
||||
printk_info("Initializing devices...\n");
|
||||
for (dev = all_devices; dev; dev = dev->next) {
|
||||
if (dev->ops && dev->ops->init) {
|
||||
if (dev->enable && dev->ops && dev->ops->init) {
|
||||
printk_debug("%s init\n", dev_path(dev));
|
||||
dev->ops->init(dev);
|
||||
}
|
||||
|
@@ -30,15 +30,17 @@ device_t alloc_find_dev(struct bus *parent, struct device_path *path)
|
||||
*/
|
||||
struct device *dev_find_slot(unsigned int bus, unsigned int devfn)
|
||||
{
|
||||
struct device *dev;
|
||||
struct device *dev, *result;
|
||||
|
||||
result = 0;
|
||||
for (dev = all_devices; dev; dev = dev->next) {
|
||||
if ((dev->bus->secondary == bus) &&
|
||||
(dev->path.u.pci.devfn == devfn)) {
|
||||
result = dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return dev;
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Find a device of a given vendor and type
|
||||
@@ -88,6 +90,9 @@ const char *dev_path(device_t dev)
|
||||
}
|
||||
else {
|
||||
switch(dev->path.type) {
|
||||
case DEVICE_PATH_ROOT:
|
||||
memcpy(buffer, "Root Device", 12);
|
||||
break;
|
||||
case DEVICE_PATH_PCI:
|
||||
sprintf(buffer, "PCI: %02x:%02x.%01x",
|
||||
dev->bus->secondary,
|
||||
@@ -116,8 +121,12 @@ int path_eq(struct device_path *path1, struct device_path *path2)
|
||||
switch(path1->type) {
|
||||
case DEVICE_PATH_NONE:
|
||||
break;
|
||||
case DEVICE_PATH_ROOT:
|
||||
equal = 1;
|
||||
break;
|
||||
case DEVICE_PATH_PCI:
|
||||
equal = path1->u.pci.devfn == path2->u.pci.devfn;
|
||||
equal = (path1->u.pci.bus == path2->u.pci.bus) &&
|
||||
(path1->u.pci.devfn == path2->u.pci.devfn);
|
||||
break;
|
||||
case DEVICE_PATH_PNP:
|
||||
equal = (path1->u.pnp.port == path2->u.pnp.port) &&
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include <device/path.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/hypertransport.h>
|
||||
#include <device/chip.h>
|
||||
#include <part/hard_reset.h>
|
||||
#include <part/fallback_boot.h>
|
||||
|
||||
@@ -243,11 +244,19 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
|
||||
/* Add this device to the pci bus chain */
|
||||
*chain_last = dev;
|
||||
/* Run the magice enable/disable sequence for the device */
|
||||
if (dev->ops && dev->ops->enable) {
|
||||
dev->ops->enable(dev);
|
||||
if (dev->chip && dev->chip->control && dev->chip->control->enable_dev) {
|
||||
dev->chip->control->enable_dev(dev);
|
||||
}
|
||||
/* Now read the vendor and device id */
|
||||
id = pci_read_config32(dev, PCI_VENDOR_ID);
|
||||
|
||||
/* If the chain is fully enumerated quit */
|
||||
if (id == 0xffffffff || id == 0x00000000 ||
|
||||
id == 0x0000ffff || id == 0xffff0000) {
|
||||
printk_err("Missing static device: %s\n",
|
||||
dev_path(dev));
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Update the device chain tail */
|
||||
for(func = dev; func; func = func->sibling) {
|
||||
@@ -268,7 +277,8 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
|
||||
/* Find the hypertransport link capability */
|
||||
pos = ht_lookup_slave_capability(dev);
|
||||
if (pos == 0) {
|
||||
printk_err("Hypertransport link capability not found");
|
||||
printk_err("%s Hypertransport link capability not found",
|
||||
dev_path(dev));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <device/chip.h>
|
||||
#include <part/hard_reset.h>
|
||||
#include <part/fallback_boot.h>
|
||||
|
||||
@@ -175,7 +176,6 @@ static void pci_bridge_read_bases(struct device *dev)
|
||||
|
||||
/* FIXME handle bridges without some of the optional resources */
|
||||
|
||||
printk_spew("%s: path %s\n", __FUNCTION__, dev_path(dev));
|
||||
/* Initialize the io space constraints on the current bus */
|
||||
dev->resource[reg].base = 0;
|
||||
dev->resource[reg].size = 0;
|
||||
@@ -215,7 +215,6 @@ static void pci_bridge_read_bases(struct device *dev)
|
||||
reg++;
|
||||
|
||||
dev->resources = reg;
|
||||
printk_spew("DONE %s: path %s\n", __FUNCTION__, dev_path(dev));
|
||||
}
|
||||
|
||||
|
||||
@@ -455,11 +454,13 @@ static void set_pci_ops(struct device *dev)
|
||||
break;
|
||||
default:
|
||||
bad:
|
||||
printk_err("%s [%04x/%04x/%06x] has unknown header "
|
||||
"type %02x, ignoring.\n",
|
||||
dev_path(dev),
|
||||
dev->vendor, dev->device,
|
||||
dev->class >> 8, dev->hdr_type);
|
||||
if (dev->enable) {
|
||||
printk_err("%s [%04x/%04x/%06x] has unknown header "
|
||||
"type %02x, ignoring.\n",
|
||||
dev_path(dev),
|
||||
dev->vendor, dev->device,
|
||||
dev->class >> 8, dev->hdr_type);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -556,17 +557,16 @@ unsigned int pci_scan_bus(struct bus *bus,
|
||||
}
|
||||
else {
|
||||
/* Run the magic enable/disable sequence for the device */
|
||||
if (dev->ops && dev->ops->enable) {
|
||||
dev->ops->enable(dev);
|
||||
if (dev->chip && dev->chip->control && dev->chip->control->enable_dev) {
|
||||
dev->chip->control->enable_dev(dev);
|
||||
}
|
||||
/* Now read the vendor and device id */
|
||||
id = pci_read_config32(dev, PCI_VENDOR_ID);
|
||||
}
|
||||
|
||||
/* Read the rest of the pci configuration information */
|
||||
hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
|
||||
class = pci_read_config32(dev, PCI_CLASS_REVISION);
|
||||
|
||||
|
||||
/* Store the interesting information in the device structure */
|
||||
dev->vendor = id & 0xffff;
|
||||
dev->device = (id >> 16) & 0xffff;
|
||||
@@ -576,20 +576,19 @@ unsigned int pci_scan_bus(struct bus *bus,
|
||||
|
||||
/* Look at the vendor and device id, or at least the
|
||||
* header type and class and figure out which set of configuration
|
||||
* methods to use.
|
||||
* methods to use. Unless we already have some pci ops.
|
||||
*/
|
||||
if (!dev->ops) {
|
||||
set_pci_ops(dev);
|
||||
/* Error if we don't have some pci operations for it */
|
||||
if (!dev->ops) {
|
||||
printk_err("%s No device operations\n",
|
||||
dev_path(dev));
|
||||
continue;
|
||||
}
|
||||
/* Now run the magic enable/disable sequence for the device */
|
||||
if (dev->ops && dev->ops->enable) {
|
||||
dev->ops->enable(dev);
|
||||
}
|
||||
set_pci_ops(dev);
|
||||
/* Error if we don't have some pci operations for it */
|
||||
if (dev->enable && !dev->ops) {
|
||||
printk_err("%s No device operations\n",
|
||||
dev_path(dev));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Now run the magic enable/disable sequence for the device */
|
||||
if (dev->ops && dev->ops->enable) {
|
||||
dev->ops->enable(dev);
|
||||
}
|
||||
|
||||
printk_debug("%s [%04x/%04x] %s\n",
|
||||
@@ -632,8 +631,7 @@ unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
|
||||
struct bus *bus;
|
||||
uint32_t buses;
|
||||
uint16_t cr;
|
||||
|
||||
printk_spew("%s: dev %p, max %d\n", __FUNCTION__, dev, max);
|
||||
|
||||
bus = &dev->link[0];
|
||||
dev->links = 1;
|
||||
|
||||
@@ -707,7 +705,6 @@ static void pci_level_irq(unsigned char intNum)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This function assigns IRQs for all functions contained within
|
||||
the indicated device address. If the device does not exist or does
|
||||
|
@@ -123,6 +123,8 @@ struct device_operations default_dev_ops_root = {
|
||||
struct device dev_root = {
|
||||
.ops = &default_dev_ops_root,
|
||||
.bus = &dev_root.link[0],
|
||||
.path = { .type = DEVICE_PATH_ROOT },
|
||||
.enable = 1,
|
||||
.links = 1,
|
||||
.link = {
|
||||
[0] = {
|
||||
|
Reference in New Issue
Block a user