- First stab at running linuxbios without the old static device tree.
Things are close but not quite there yet. git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1681 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
@@ -4,4 +4,3 @@ object device_util.o
|
||||
object pci_device.o
|
||||
object pnp_device.o
|
||||
object hypertransport.o
|
||||
object chip.o
|
||||
|
@@ -1,232 +0,0 @@
|
||||
/* chips are arbitrary chips (superio, southbridge, etc.)
|
||||
* They have private structures that define chip resources and default
|
||||
* settings. They have four externally visible functions for control.
|
||||
* They have a generic component which applies to all chips for
|
||||
* path, etc.
|
||||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
#include <device/chip.h>
|
||||
#include <device/pci.h>
|
||||
|
||||
/**
|
||||
* @brief Configure static devices
|
||||
*
|
||||
* Starting from the static device 'root', walk the tree and configure each
|
||||
* device by calling the device specific chip_control::enable().
|
||||
*
|
||||
* This function is only an iterator, the exact definition of 'configure'
|
||||
* depends on the device specific implementation of chip_control::enable().
|
||||
*
|
||||
* @param root root of the static device tree to be configured.
|
||||
* @param pass pass of the configuration operation to be perfromed.
|
||||
*
|
||||
* @see chip_pass
|
||||
* @see chip_control::enable
|
||||
*/
|
||||
void chip_configure(struct chip *root, enum chip_pass pass)
|
||||
{
|
||||
struct chip *c;
|
||||
|
||||
for (c = root; c; c = c->next) {
|
||||
if (c->control && c->control->enable)
|
||||
c->control->enable(c, pass);
|
||||
}
|
||||
|
||||
for (c = root; c; c = c->next) {
|
||||
if (c->children)
|
||||
chip_configure(c->children, pass);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert static device structures to dynamic structures.
|
||||
*
|
||||
* A static device may contain one or more dynamic devices. Dynamic device
|
||||
* structures of these devices have to be generated before the enumeration
|
||||
* of dynamic devices. This function converts a static chip structure to a
|
||||
* set of dynamic device structures.
|
||||
*
|
||||
* This function is the generic method called by enumerate_static_device_chain()
|
||||
* for static devices. Devices extend this default behavior by defining their
|
||||
* own chip_controll::enumerate(). Generally, device specific
|
||||
* chip_control::enumerate() method calls this function as its last operation.
|
||||
*
|
||||
* @param chip static chip structure to be converted.
|
||||
*
|
||||
*/
|
||||
void chip_enumerate(struct chip *chip)
|
||||
{
|
||||
struct chip *child;
|
||||
device_t dev;
|
||||
int link;
|
||||
int i;
|
||||
|
||||
dev = 0;
|
||||
link = 0;
|
||||
|
||||
if (chip->control && chip->control->name) {
|
||||
printk_debug("Enumerating: %s\n", chip->control->name);
|
||||
}
|
||||
|
||||
for(i = 0; i < MAX_CHIP_PATHS; i++) {
|
||||
int identical_paths;
|
||||
identical_paths =
|
||||
(i > 0) &&
|
||||
(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:
|
||||
/* no dynamic device associated */
|
||||
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(parent, &chip->path[i].path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
link += 1;
|
||||
}
|
||||
|
||||
if (dev) {
|
||||
struct chip_resource *res, *res_limit;
|
||||
printk_spew("path (%p) %s %s",
|
||||
dev, dev_path(dev), identical_paths?"identical":"");
|
||||
printk_spew(" parent: (%p):%d %s\n",
|
||||
dev->bus->dev, dev->bus->link,
|
||||
dev_path(dev->bus->dev));
|
||||
dev->chip = chip;
|
||||
dev->enabled = chip->path[i].enabled;
|
||||
dev->links = link + 1;
|
||||
for(child = chip->children; child; child = child->next) {
|
||||
if (!child->bus && child->link == i) {
|
||||
child->bus = &dev->link[link];
|
||||
}
|
||||
}
|
||||
res = &chip->path[i].resource[0];
|
||||
res_limit = &chip->path[i].resource[MAX_RESOURCES];
|
||||
for(; res < res_limit; res++) {
|
||||
if (res->flags) {
|
||||
struct resource *resource;
|
||||
resource = new_resource(dev, res->index);
|
||||
resource->flags = res->flags | IORESOURCE_FIXED | IORESOURCE_ASSIGNED;
|
||||
resource->base = res->base;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dev && !chip->dev) {
|
||||
chip->dev = dev;
|
||||
}
|
||||
}
|
||||
if (chip->children && !chip->dev) {
|
||||
die("No device but children?");
|
||||
}
|
||||
for(child = chip->children; child; child = child->next) {
|
||||
if (!child->bus) {
|
||||
child->bus = &chip->dev->link[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enumerate a static device tree.
|
||||
*
|
||||
* A static device chain is a linked list of static device structures which are
|
||||
* on the same branch of the static device tree. This function does not only
|
||||
* enumerate the devices on a single chain, as its name suggest, it also walks
|
||||
* into the subordinary chains by recursion. It calls the device specific
|
||||
* chip_control::enumerate() of the device if one exists or calls the generic
|
||||
* chip_enumerate().
|
||||
*
|
||||
* This function is only an iterator, the exact definition of 'enumerate'
|
||||
* depends on the implementation of the generic chip_enumerate() and/or device
|
||||
* specific chip_control::enumerate().
|
||||
*
|
||||
* @param root static chip structure to start with.
|
||||
*
|
||||
* @see chip_control::enumerate()
|
||||
*/
|
||||
static void enumerate_static_device_chain(struct chip *root)
|
||||
{
|
||||
struct chip *chip;
|
||||
for(chip = root; chip; chip = chip->next) {
|
||||
void (*enumerate)(struct chip *chip);
|
||||
enumerate = chip_enumerate;
|
||||
if (chip->control && chip->control->enumerate) {
|
||||
enumerate = chip->control->enumerate;
|
||||
}
|
||||
enumerate(chip);
|
||||
}
|
||||
|
||||
for(chip = root; chip; chip = chip->next) {
|
||||
if (chip->children) {
|
||||
enumerate_static_device_chain(chip->children);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enumerate static devices in the system.
|
||||
*
|
||||
* Static device is . Static devices are actually enumerated or "listed" in
|
||||
* the Config.lb config file and the corresponding data structures are
|
||||
* generated by config tool in the static.c.
|
||||
*
|
||||
* \note The definition of 'enumerate' is not clear in this context. Does it
|
||||
* mean probe ?
|
||||
*
|
||||
* \note How do we determine the existence of the static devices ? Static
|
||||
* devices are listed in the config file and generated at compile time by config
|
||||
* tool. This function is called at certain point in the early stage of
|
||||
* LinuxBIOS. It uses the chip_enumerate() function to convert the static
|
||||
* structures into dynamic ones. What if the static devices listed in the config
|
||||
* file does actually not exist in the system ? Is there any side effect of
|
||||
* these 'phantom' device structures
|
||||
*
|
||||
* The static device does not necesarry conform to the dynamic device tree in
|
||||
* the system.
|
||||
*/
|
||||
void enumerate_static_devices(void)
|
||||
{
|
||||
struct chip *child;
|
||||
int i;
|
||||
printk_info("Enumerating static devices...\n");
|
||||
static_root.dev = &dev_root;
|
||||
dev_root.links = MAX_LINKS;
|
||||
for(i = 0; i < MAX_LINKS; i++) {
|
||||
dev_root.link[i].link = i;
|
||||
dev_root.link[i].dev = &dev_root;
|
||||
for(child = static_root.children; child; child = child->next) {
|
||||
if (!child->bus && child->link == i) {
|
||||
child->bus = &dev_root.link[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
for(child = static_root.children; child; child = child->next) {
|
||||
if (!child->bus) {
|
||||
child->bus = &dev_root.link[0];
|
||||
}
|
||||
}
|
||||
enumerate_static_device_chain(&static_root);
|
||||
}
|
@@ -27,7 +27,7 @@
|
||||
/** Linked list of ALL devices */
|
||||
struct device *all_devices = &dev_root;
|
||||
/** Pointer to the last device */
|
||||
static struct device **last_dev_p = &dev_root.next;
|
||||
extern struct device **last_dev_p;
|
||||
|
||||
/** The upper limit of MEM resource of the devices.
|
||||
* Reserve 20M for the system */
|
||||
@@ -504,6 +504,9 @@ void dev_enumerate(void)
|
||||
unsigned subordinate;
|
||||
printk_info("Enumerating buses...\n");
|
||||
root = &dev_root;
|
||||
if (root->chip_ops && root->chip_ops->enable_dev) {
|
||||
root->chip_ops->enable_dev(root);
|
||||
}
|
||||
if (!root->ops || !root->ops->scan_bus) {
|
||||
printk_err("dev_root missing scan_bus operation");
|
||||
return;
|
||||
|
@@ -133,6 +133,14 @@ const char *dev_path(device_t dev)
|
||||
sprintf(buffer, "APIC: %02x",
|
||||
dev->path.u.apic.apic_id);
|
||||
break;
|
||||
case DEVICE_PATH_PCI_DOMAIN:
|
||||
sprintf(buffer, "PCI_DOMAIN: %04x",
|
||||
dev->path.u.pci_domain.domain);
|
||||
break;
|
||||
case DEVICE_PATH_APIC_CLUSTER:
|
||||
sprintf(buffer, "APIC_CLUSTER: %01x",
|
||||
dev->path.u.apic_cluster.cluster);
|
||||
break;
|
||||
default:
|
||||
printk_err("Unknown device path type: %d\n", dev->path.type);
|
||||
break;
|
||||
@@ -155,8 +163,7 @@ int path_eq(struct device_path *path1, struct device_path *path2)
|
||||
equal = 1;
|
||||
break;
|
||||
case DEVICE_PATH_PCI:
|
||||
equal = (path1->u.pci.bus == path2->u.pci.bus) &&
|
||||
(path1->u.pci.devfn == path2->u.pci.devfn);
|
||||
equal = (path1->u.pci.devfn == path2->u.pci.devfn);
|
||||
break;
|
||||
case DEVICE_PATH_PNP:
|
||||
equal = (path1->u.pnp.port == path2->u.pnp.port) &&
|
||||
@@ -168,6 +175,12 @@ int path_eq(struct device_path *path1, struct device_path *path2)
|
||||
case DEVICE_PATH_APIC:
|
||||
equal = (path1->u.apic.apic_id == path2->u.apic.apic_id);
|
||||
break;
|
||||
case DEVICE_PATH_PCI_DOMAIN:
|
||||
equal = (path1->u.pci_domain.domain == path2->u.pci_domain.domain);
|
||||
break;
|
||||
case DEVICE_PATH_APIC_CLUSTER:
|
||||
equal = (path1->u.apic_cluster.cluster == path2->u.apic_cluster.cluster);
|
||||
break;
|
||||
default:
|
||||
printk_err("Uknown device type: %d\n", path1->type);
|
||||
break;
|
||||
|
@@ -5,7 +5,6 @@
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <device/hypertransport.h>
|
||||
#include <device/chip.h>
|
||||
#include <part/hard_reset.h>
|
||||
#include <part/fallback_boot.h>
|
||||
|
||||
@@ -263,8 +262,8 @@ 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 sequence for the device */
|
||||
if (dev->chip && dev->chip->control && dev->chip->control->enable_dev) {
|
||||
dev->chip->control->enable_dev(dev);
|
||||
if (dev->chip_ops && dev->chip_ops->enable_dev) {
|
||||
dev->chip_ops->enable_dev(dev);
|
||||
}
|
||||
/* Now read the vendor and device id */
|
||||
id = pci_read_config32(dev, PCI_VENDOR_ID);
|
||||
|
@@ -18,7 +18,6 @@
|
||||
#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>
|
||||
#include <delay.h>
|
||||
@@ -486,7 +485,7 @@ void pci_dev_enable_resources(struct device *dev)
|
||||
|
||||
/* Set the subsystem vendor and device id for mainboard devices */
|
||||
ops = ops_pci(dev);
|
||||
if (dev->chip && ops && ops->set_subsystem) {
|
||||
if (dev->chip_ops && ops && ops->set_subsystem) {
|
||||
printk_debug("%s subsystem <- %02x/%02x\n",
|
||||
dev_path(dev),
|
||||
MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
|
||||
@@ -740,10 +739,9 @@ unsigned int pci_scan_bus(struct bus *bus,
|
||||
* it may be absent and enable_dev must cope.
|
||||
*
|
||||
*/
|
||||
if ( dev->chip && dev->chip->control &&
|
||||
dev->chip->control->enable_dev)
|
||||
if (dev->chip_ops && dev->chip_ops->enable_dev)
|
||||
{
|
||||
dev->chip->control->enable_dev(dev);
|
||||
dev->chip_ops->enable_dev(dev);
|
||||
}
|
||||
/* Now read the vendor and device id */
|
||||
id = pci_read_config32(dev, PCI_VENDOR_ID);
|
||||
|
@@ -185,22 +185,24 @@ static void get_resources(device_t dev, struct pnp_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
void pnp_enumerate(struct chip *chip, unsigned functions,
|
||||
struct device_operations *ops, struct pnp_info *info)
|
||||
void pnp_enable_devices(device_t base_dev, struct device_operations *ops,
|
||||
unsigned functions, struct pnp_info *info)
|
||||
{
|
||||
struct device_path path;
|
||||
device_t dev;
|
||||
int i;
|
||||
|
||||
chip_enumerate(chip);
|
||||
|
||||
path.type = DEVICE_PATH_PNP;
|
||||
path.u.pnp.port = chip->dev->path.u.pnp.port;
|
||||
path.u.pnp.port = base_dev->path.u.pnp.port;
|
||||
|
||||
/* Setup the ops and resources on the newly allocated devices */
|
||||
for(i = 0; i < functions; i++) {
|
||||
path.u.pnp.device = info[i].function;
|
||||
dev = alloc_find_dev(chip->bus, &path);
|
||||
dev = alloc_find_dev(base_dev->bus, &path);
|
||||
|
||||
/* Don't initialize a device multiple times */
|
||||
if (dev->ops)
|
||||
continue;
|
||||
|
||||
if (info[i].ops == 0) {
|
||||
dev->ops = ops;
|
||||
|
@@ -76,6 +76,9 @@ unsigned int scan_static_bus(device_t bus, unsigned int max)
|
||||
|
||||
for(link = 0; link < bus->links; link++) {
|
||||
for(child = bus->link[link].children; child; child = child->sibling) {
|
||||
if (child->chip_ops && child->chip_ops->enable_dev) {
|
||||
child->chip_ops->enable_dev(child);
|
||||
}
|
||||
if (child->ops && child->ops->enable) {
|
||||
child->ops->enable(child);
|
||||
}
|
||||
@@ -142,7 +145,6 @@ unsigned int root_dev_scan_bus(device_t root, unsigned int max)
|
||||
|
||||
void root_dev_init(device_t root)
|
||||
{
|
||||
initialize_cpus(root);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,9 +171,4 @@ struct device_operations default_dev_ops_root = {
|
||||
* This is the root of the dynamic device tree. A PCI tree always has
|
||||
* one bus, bus 0. Bus 0 contains devices and bridges.
|
||||
*/
|
||||
struct device dev_root = {
|
||||
.ops = &default_dev_ops_root,
|
||||
.bus = &dev_root.link[0],
|
||||
.path = { .type = DEVICE_PATH_ROOT },
|
||||
.enabled = 1,
|
||||
};
|
||||
extern struct device dev_root;
|
||||
|
Reference in New Issue
Block a user