coreboot-kgpe-d16/src/devices/chip.c

213 lines
6.1 KiB
C
Raw Normal View History

/* 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) {
- Moved hlt() to it's own header. - Reworked pnp superio device support. Now complete superio support is less than 100 lines. - Added support for hard coding resource assignments in Config.lb - Minor bug fixes to romcc - Initial support for catching the x86 processor BIST error codes. I've only seen this trigger once in production during a very suspcious reset but... - added raminit_test to test the code paths in raminit.c for the Opteron - Removed the IORESOURCE_SET bit and added IORESOURCE_ASSIGNED and IORESOURCE_STORED so we can tell what we have really done. - Added generic AGP/IOMMU setting code to x86 - Added an implementation of memmove and removed reserved identifiers from memcpy - Added minimal support for booting on pre b3 stepping K8 cores - Moved the checksum on amd8111 boards because our default location was on top of extended RTC registers - On the Hdama added support for enabling i2c hub so we can get at the temperature sensors. Not that i2c bus was implemented well enough to make that useful. - Redid the Opteron port so we should only need one reset and most of memory initialization is done in cpu_fixup. This is much, much faster. - Attempted to make the VGA IO region assigment work. The code seems to work now... - Redid the error handling in amdk8/raminit.c to distinguish between a bad value and a smbus error, and moved memory clearing out to cpufixup. - Removed CONFIG_KEYBOARD as it was useless. See pc87360/superio.c for how to setup a legacy keyboard properly. - Reworked the register values for standard hardware, moving the defintions from chip.h into the headers of the initialization routines. This is much saner and is actually implemented. - Made the hdama port an under clockers BIOS. I debuged so many interesting problems. - On amd8111_lpc added setup of architectural/legacy hardware - Enabled PCI error reporting as much as possible. - Enhanded build_opt_tbl to generate a header of the cmos option locations so that romcc compiled code can query the cmos options. - In romcc gracefully handle function names that degenerate into function pointers - Bumped the version to 1.1.6 as we are getting closer to 2.0 TODO finish optimizing the HT links of non dual boards TODO make all Opteron board work again TODO convert all superio devices to use the new helpers TODO convert the via/epia to freebios2 conventions TODO cpu fixup/setup by cpu type git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1390 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2004-03-11 16:01:31 +01:00
struct chip_resource *res, *res_limit;
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->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];
}
}
- Moved hlt() to it's own header. - Reworked pnp superio device support. Now complete superio support is less than 100 lines. - Added support for hard coding resource assignments in Config.lb - Minor bug fixes to romcc - Initial support for catching the x86 processor BIST error codes. I've only seen this trigger once in production during a very suspcious reset but... - added raminit_test to test the code paths in raminit.c for the Opteron - Removed the IORESOURCE_SET bit and added IORESOURCE_ASSIGNED and IORESOURCE_STORED so we can tell what we have really done. - Added generic AGP/IOMMU setting code to x86 - Added an implementation of memmove and removed reserved identifiers from memcpy - Added minimal support for booting on pre b3 stepping K8 cores - Moved the checksum on amd8111 boards because our default location was on top of extended RTC registers - On the Hdama added support for enabling i2c hub so we can get at the temperature sensors. Not that i2c bus was implemented well enough to make that useful. - Redid the Opteron port so we should only need one reset and most of memory initialization is done in cpu_fixup. This is much, much faster. - Attempted to make the VGA IO region assigment work. The code seems to work now... - Redid the error handling in amdk8/raminit.c to distinguish between a bad value and a smbus error, and moved memory clearing out to cpufixup. - Removed CONFIG_KEYBOARD as it was useless. See pc87360/superio.c for how to setup a legacy keyboard properly. - Reworked the register values for standard hardware, moving the defintions from chip.h into the headers of the initialization routines. This is much saner and is actually implemented. - Made the hdama port an under clockers BIOS. I debuged so many interesting problems. - On amd8111_lpc added setup of architectural/legacy hardware - Enabled PCI error reporting as much as possible. - Enhanded build_opt_tbl to generate a header of the cmos option locations so that romcc compiled code can query the cmos options. - In romcc gracefully handle function names that degenerate into function pointers - Bumped the version to 1.1.6 as we are getting closer to 2.0 TODO finish optimizing the HT links of non dual boards TODO make all Opteron board work again TODO convert all superio devices to use the new helpers TODO convert the via/epia to freebios2 conventions TODO cpu fixup/setup by cpu type git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1390 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2004-03-11 16:01:31 +01:00
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 = get_resource(dev, res->index);
resource->flags = res->flags | IORESOURCE_FIXED | IORESOURCE_ASSIGNED;
resource->base = res->base;
}
}
}
if (dev && !chip->dev) {
chip->dev = dev;
}
}
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)
{
printk_info("Enumerating static devices...\n");
enumerate_static_device_chain(&static_root);
}