diff --git a/src/boot/hardwaremain.c b/src/boot/hardwaremain.c index bdbd4a3791..08f972e612 100644 --- a/src/boot/hardwaremain.c +++ b/src/boot/hardwaremain.c @@ -37,6 +37,15 @@ it with the version available from LANL. #include #include +/** + * @brief Main function of the DRAM part of LinuxBIOS. + * + * LinuxBIOS is divided into Pre-DRAM part and DRAM part. + * + * + * Device Enumeration: + * In the dev_enumerate() phase, + */ void hardwaremain(int boot_complete) { struct lb_memory *lb_mem; @@ -48,8 +57,8 @@ void hardwaremain(int boot_complete) post_code(0x39); printk_notice("LinuxBIOS-%s%s %s %s...\n", - linuxbios_version, linuxbios_extra_version, linuxbios_build, - (boot_complete)?"rebooting":"booting"); + linuxbios_version, linuxbios_extra_version, linuxbios_build, + (boot_complete)?"rebooting":"booting"); post_code(0x40); diff --git a/src/devices/device.c b/src/devices/device.c index 87e627d52c..d974a1930d 100644 --- a/src/devices/device.c +++ b/src/devices/device.c @@ -56,10 +56,12 @@ device_t alloc_dev(struct bus *parent, struct device_path *path) int link; spin_lock(&dev_lock); + /* Find the last child of our parent */ - for(child = parent->children; child && child->sibling; ) { + for (child = parent->children; child && child->sibling; ) { child = child->sibling; } + dev = malloc(sizeof(*dev)); if (dev == 0) { die("DEV: out of memory.\n"); @@ -67,13 +69,12 @@ device_t alloc_dev(struct bus *parent, struct device_path *path) memset(dev, 0, sizeof(*dev)); memcpy(&dev->path, path, sizeof(*path)); - /* Initialize the back pointers in the link fields */ - for(link = 0; link < MAX_LINKS; link++) { + for (link = 0; link < MAX_LINKS; link++) { dev->link[link].dev = dev; dev->link[link].link = link; } - + /* By default devices are enabled */ dev->enabled = 1; @@ -118,10 +119,10 @@ static void read_resources(struct bus *bus) struct device *curdev; printk_spew("%s read_resources bus %d link: %d\n", - dev_path(bus->dev), bus->secondary, bus->link); + dev_path(bus->dev), bus->secondary, bus->link); /* Walk through all of the devices and find which resources they need. */ - for(curdev = bus->children; curdev; curdev = curdev->sibling) { + for (curdev = bus->children; curdev; curdev = curdev->sibling) { unsigned links; int i; if (curdev->have_resources) { @@ -139,7 +140,7 @@ static void read_resources(struct bus *bus) curdev->have_resources = 1; /* Read in subtractive resources behind the current device */ links = 0; - for(i = 0; i < curdev->resources; i++) { + for (i = 0; i < curdev->resources; i++) { struct resource *resource; unsigned link; resource = &curdev->resource[i]; @@ -148,7 +149,7 @@ static void read_resources(struct bus *bus) link = IOINDEX_SUBTRACTIVE_LINK(resource->index); if (link > MAX_LINKS) { printk_err("%s subtractive index on link: %d\n", - dev_path(curdev), link); + dev_path(curdev), link); continue; } if (!(links & (1 << link))) { @@ -159,7 +160,7 @@ static void read_resources(struct bus *bus) } } printk_spew("%s read_resources bus %d link: %d done\n", - dev_path(bus->dev), bus->secondary, bus->link); + dev_path(bus->dev), bus->secondary, bus->link); } struct pick_largest_state { @@ -190,9 +191,9 @@ static void pick_largest_resource(void *gp, return; } if (!state->result || - (state->result->align < resource->align) || - ((state->result->align == resource->align) && - (state->result->size < resource->size))) { + (state->result->align < resource->align) || + ((state->result->align == resource->align) && + (state->result->size < resource->size))) { state->result_dev = dev; state->result = resource; } @@ -257,11 +258,10 @@ void compute_allocate_resource( base = bridge->base; 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); - + 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 @@ -283,14 +283,13 @@ void compute_allocate_resource( /* Walk through all the devices on the current bus and * compute the addresses. */ - while((dev = largest_resource(bus, &resource, type_mask, type))) { + while ((dev = largest_resource(bus, &resource, type_mask, type))) { resource_t size; /* Do NOT I repeat do not ignore resources which have zero size. * If they need to be ignored dev->read_resources should not even * return them. Some resources must be set even when they have * no size. PCI bridge resources are a good example of this. */ - /* Propogate the resource alignment to the bridge register */ if (resource->align > bridge->align) { bridge->align = resource->align; @@ -339,14 +338,13 @@ void compute_allocate_resource( resource->flags &= ~IORESOURCE_STORED; base += size; - printk_spew( - "%s %02x * [0x%08Lx - 0x%08Lx] %s\n", - dev_path(dev), - resource->index, - resource->base, - resource->base + resource->size - 1, - (resource->flags & IORESOURCE_IO)? "io": - (resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem"); + printk_spew("%s %02x * [0x%08Lx - 0x%08Lx] %s\n", + dev_path(dev), + resource->index, + resource->base, + resource->base + resource->size - 1, + (resource->flags & IORESOURCE_IO)? "io": + (resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem"); } } /* A pci bridge resource does not need to be a power @@ -358,10 +356,10 @@ void compute_allocate_resource( bridge->size = round(base, bridge->gran) - bridge->base; printk_spew("%s compute_allocate_%s: base: %08Lx size: %08Lx align: %d gran: %d done\n", - dev_path(bus->dev), - (bridge->flags & IORESOURCE_IO)? "io": - (bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem", - base, bridge->size, bridge->align, bridge->gran); + dev_path(bus->dev), + (bridge->flags & IORESOURCE_IO)? "io": + (bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem", + base, bridge->size, bridge->align, bridge->gran); } @@ -380,10 +378,6 @@ static void allocate_vga_resource(void) if (((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) && ((dev->class >> 8) != PCI_CLASS_DISPLAY_OTHER)) { if (!vga) { - printk_debug("Allocating VGA resource %s\n", - dev_path(dev)); - printk_debug("parent of the vga device %s\n", - dev_path(dev->bus->dev)); vga = dev; } if (vga == dev) { @@ -400,8 +394,6 @@ static void allocate_vga_resource(void) } /* Now walk up the bridges setting the VGA enable */ while (bus) { - printk_info("Enabling VGA forward on bus connect to %s\n", - dev_path(bus->dev)); bus->bridge_ctrl |= PCI_BRIDGE_CTL_VGA; bus = (bus == bus->dev->bus)? 0 : bus->dev->bus; } @@ -545,7 +537,7 @@ void dev_configure(void) printk_info("Reading resources...\n"); root->ops->read_resources(root); - printk_info("Done\n"); + printk_info("Done reading resources.\n"); /* Get the resources */ io = &root->resource[0]; @@ -567,13 +559,13 @@ void dev_configure(void) /* Store the computed resource allocations into device registers ... */ printk_info("Setting resources...\n"); root->ops->set_resources(root); - printk_info("Done\n"); + printk_info("Done setting resources.\n"); #if 0 mem->flags |= IORESOURCE_STORED; report_resource_stored(root, mem, ""); #endif - printk_info("done.\n"); + printk_info("Done allocating resources.\n"); } /** diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c index a32c3a675f..b16e922a33 100644 --- a/src/devices/pci_device.c +++ b/src/devices/pci_device.c @@ -117,7 +117,7 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index) /* If it is a 64bit resource look at the high half as well */ if (((attr & PCI_BASE_ADDRESS_SPACE_IO) == 0) && - ((attr & PCI_BASE_ADDRESS_MEM_LIMIT_MASK) == PCI_BASE_ADDRESS_MEM_LIMIT_64)) + ((attr & PCI_BASE_ADDRESS_MEM_LIMIT_MASK) == PCI_BASE_ADDRESS_MEM_LIMIT_64)) { /* Find the high bits that move */ moving |= ((resource_t)pci_moving_config32(dev, index + 4)) << 32; @@ -611,13 +611,14 @@ static void set_pci_ops(struct device *dev) * @brief See if we have already allocated a device structure for a given devfn. * * Given a linked list of PCI device structures and a devfn number, find the - * device structure correspond to the devfn, if present. + * device structure correspond to the devfn, if present. This function also + * removes the device structure from the linked list. * * @param list the device structure list * @param devfn a device/function number * - * @return pointer to the device structure found or null of we have not allocated - * a device for this devfn yet. + * @return pointer to the device structure found or null of we have not + * allocated a device for this devfn yet. */ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn) { @@ -626,7 +627,7 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn) for(; *list; list = &(*list)->sibling) { if ((*list)->path.type != DEVICE_PATH_PCI) { printk_err("child %s not a pci device\n", - dev_path(*list)); + dev_path(*list)); continue; } if ((*list)->path.u.pci.devfn == devfn) { @@ -637,15 +638,15 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn) break; } } - /* Just like alloc_dev add the device to the - * list of device on the bus. When the list of devices was formed - * we removed all of the parents children, and now we are interleaving - * static and dynamic devices in order on the bus. + /* Just like alloc_dev add the device to the list of device on the bus. + * When the list of devices was formed we removed all of the parents + * children, and now we are interleaving static and dynamic devices in + * order on the bus. */ if (dev) { device_t child; /* Find the last child of our parent */ - for(child = dev->bus->children; child && child->sibling; ) { + for (child = dev->bus->children; child && child->sibling; ) { child = child->sibling; } /* Place the device on the list of children of it's parent. */ @@ -854,6 +855,8 @@ unsigned int pci_scan_bridge(struct device *dev, unsigned int max) uint32_t buses; uint16_t cr; + printk_spew("%s for %s\n", __func__, dev_path(dev)); + bus = &dev->link[0]; bus->dev = dev; dev->links = 1; @@ -882,15 +885,15 @@ unsigned int pci_scan_bridge(struct device *dev, unsigned int max) */ buses &= 0xff000000; buses |= (((unsigned int) (dev->bus->secondary) << 0) | - ((unsigned int) (bus->secondary) << 8) | - ((unsigned int) (bus->subordinate) << 16)); + ((unsigned int) (bus->secondary) << 8) | + ((unsigned int) (bus->subordinate) << 16)); pci_write_config32(dev, PCI_PRIMARY_BUS, buses); - + /* Now we can scan all subordinate buses * i.e. the bus behind the bridge. */ max = pci_scan_bus(bus, 0x00, 0xff, max); - + /* We know the number of buses behind this bridge. Set the subordinate * bus number to its real value. */ @@ -899,7 +902,7 @@ unsigned int pci_scan_bridge(struct device *dev, unsigned int max) ((unsigned int) (bus->subordinate) << 16); pci_write_config32(dev, PCI_PRIMARY_BUS, buses); pci_write_config16(dev, PCI_COMMAND, cr); - + printk_spew("%s returns max %d\n", __func__, max); return max; } diff --git a/src/devices/root_device.c b/src/devices/root_device.c index a02fe7a060..2c641a2260 100644 --- a/src/devices/root_device.c +++ b/src/devices/root_device.c @@ -89,9 +89,8 @@ unsigned int scan_static_bus(device_t root, unsigned int max) if (child->ops && child->ops->enable) { child->ops->enable(child); } - printk_debug("%s %s\n", - dev_path(child), - child->enabled?"enabled": "disabled"); + printk_debug("%s %s\n", dev_path(child), + child->enabled?"enabled": "disabled"); } } for (link = 0; link < root->links; link++) { diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c index 464e66c51f..788d698bac 100644 --- a/src/northbridge/amd/amdk8/northbridge.c +++ b/src/northbridge/amd/amdk8/northbridge.c @@ -22,7 +22,7 @@ static device_t __f1_dev[FX_DEVS]; static void debug_fx_devs(void) { int i; - for(i = 0; i < FX_DEVS; i++) { + for (i = 0; i < FX_DEVS; i++) { device_t dev; dev = __f0_dev[i]; if (dev) { @@ -44,7 +44,7 @@ static void get_fx_devs(void) if (__f1_dev[0]) { return; } - for(i = 0; i < FX_DEVS; i++) { + for (i = 0; i < FX_DEVS; i++) { __f0_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 0)); __f1_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 1)); } @@ -63,7 +63,7 @@ static void f1_write_config32(unsigned reg, uint32_t value) { int i; get_fx_devs(); - for(i = 0; i < FX_DEVS; i++) { + for (i = 0; i < FX_DEVS; i++) { device_t dev; dev = __f1_dev[i]; if (dev && dev->enabled) { @@ -84,9 +84,9 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max) nodeid = amdk8_nodeid(dev); #if 0 printk_debug("%s amdk8_scan_chains max: %d starting...\n", - dev_path(dev), max); + dev_path(dev), max); #endif - for(link = 0; link < dev->links; link++) { + for (link = 0; link < dev->links; link++) { uint32_t link_type; uint32_t busses, config_busses; unsigned free_reg, config_reg; @@ -103,9 +103,10 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max) if (!(link_type & NonCoherent)) { continue; } - /* See if there is an available configuration space mapping register in function 1. */ + /* See if there is an available configuration space mapping + * register in function 1. */ free_reg = 0; - for(config_reg = 0xe0; config_reg <= 0xec; config_reg += 4) { + for (config_reg = 0xe0; config_reg <= 0xec; config_reg += 4) { uint32_t config; config = f1_read_config32(config_reg); if (!free_reg && ((config & 3) == 0)) { @@ -113,22 +114,23 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max) continue; } if (((config & 3) == 3) && - (((config >> 4) & 7) == nodeid) && - (((config >> 8) & 3) == link)) { + (((config >> 4) & 7) == nodeid) && + (((config >> 8) & 3) == link)) { break; } } if (free_reg && (config_reg > 0xec)) { config_reg = free_reg; } - /* If we can't find an available configuration space mapping register skip this bus */ + /* If we can't find an available configuration space mapping + * register skip this bus */ if (config_reg > 0xec) { continue; } - /* Set up the primary, secondary and subordinate bus numbers. We have - * no idea how many busses are behind this bridge yet, so we set the subordinate - * bus number to 0xff for the moment. + /* Set up the primary, secondary and subordinate bus numbers. + * We have no idea how many busses are behind this bridge yet, + * so we set the subordinate bus number to 0xff for the moment. */ dev->link[link].secondary = ++max; dev->link[link].subordinate = 0xff; @@ -138,15 +140,15 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max) */ busses = pci_read_config32(dev, dev->link[link].cap + 0x14); config_busses = f1_read_config32(config_reg); - + /* Configure the bus numbers for this bridge: the configuration - * transactions will not be propagates by the bridge if it is not - * correctly configured + * transactions will not be propagates by the bridge if it is + * not correctly configured */ busses &= 0xff000000; busses |= (((unsigned int)(dev->bus->secondary) << 0) | - ((unsigned int)(dev->link[link].secondary) << 8) | - ((unsigned int)(dev->link[link].subordinate) << 16)); + ((unsigned int)(dev->link[link].secondary) << 8) | + ((unsigned int)(dev->link[link].subordinate) << 16)); pci_write_config32(dev, dev->link[link].cap + 0x14, busses); config_busses &= 0x000fc88; @@ -161,29 +163,31 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max) #if 0 printk_debug("%s Hyper transport scan link: %d max: %d\n", dev_path(dev), link, max); -#endif - /* Now we can scan all of the subordinate busses i.e. the chain on the hypertranport link */ +#endif + /* Now we can scan all of the subordinate busses i.e. the + * chain on the hypertranport link */ max = hypertransport_scan_chain(&dev->link[link], max); #if 0 printk_debug("%s Hyper transport scan link: %d new max: %d\n", dev_path(dev), link, max); -#endif +#endif - /* We know the number of busses behind this bridge. Set the subordinate - * bus number to it's real value + /* We know the number of busses behind this bridge. Set the + * subordinate bus number to it's real value */ dev->link[link].subordinate = max; busses = (busses & 0xff00ffff) | ((unsigned int) (dev->link[link].subordinate) << 16); pci_write_config32(dev, dev->link[link].cap + 0x14, busses); - config_busses = (config_busses & 0x00ffffff) | (dev->link[link].subordinate << 24); + config_busses = (config_busses & 0x00ffffff) | + (dev->link[link].subordinate << 24); f1_write_config32(config_reg, config_busses); #if 0 printk_debug("%s Hypertransport scan link: %d done\n", dev_path(dev), link); -#endif +#endif } #if 0 printk_debug("%s amdk8_scan_chains max: %d done\n", @@ -199,39 +203,38 @@ static int reg_useable(unsigned reg, unsigned nodeid, link; int result; res = 0; - for(nodeid = 0; !res && (nodeid < 8); nodeid++) { + for (nodeid = 0; !res && (nodeid < 8); nodeid++) { device_t dev; dev = __f0_dev[nodeid]; - for(link = 0; !res && (link < 3); link++) { + for (link = 0; !res && (link < 3); link++) { res = probe_resource(dev, 0x100 + (reg | link)); } } result = 2; if (res) { result = 0; - if ( (goal_link == (link - 1)) && - (goal_nodeid == (nodeid - 1)) && - (res->flags <= 1)) { + if ((goal_link == (link - 1)) && + (goal_nodeid == (nodeid - 1)) && + (res->flags <= 1)) { result = 1; } } #if 0 printk_debug("reg: %02x result: %d gnodeid: %u glink: %u nodeid: %u link: %u\n", - reg, result, - goal_nodeid, goal_link, - nodeid, link); + reg, result, + goal_nodeid, goal_link, + nodeid, link); #endif return result; } - static struct resource *amdk8_find_iopair(device_t dev, unsigned nodeid, unsigned link) { struct resource *resource; unsigned free_reg, reg; resource = 0; free_reg = 0; - for(reg = 0xc0; reg <= 0xd8; reg += 0x8) { + for (reg = 0xc0; reg <= 0xd8; reg += 0x8) { int result; result = reg_useable(reg, dev, nodeid, link); if (result == 1) { @@ -258,7 +261,7 @@ static struct resource *amdk8_find_mempair(device_t dev, unsigned nodeid, unsign unsigned free_reg, reg; resource = 0; free_reg = 0; - for(reg = 0x80; reg <= 0xb8; reg += 0x8) { + for (reg = 0x80; reg <= 0xb8; reg += 0x8) { int result; result = reg_useable(reg, dev, nodeid, link); if (result == 1) { @@ -278,6 +281,7 @@ static struct resource *amdk8_find_mempair(device_t dev, unsigned nodeid, unsign } return resource; } + static void amdk8_link_read_bases(device_t dev, unsigned nodeid, unsigned link) { struct resource *resource; @@ -328,7 +332,7 @@ static void amdk8_read_resources(device_t dev) { unsigned nodeid, link; nodeid = amdk8_nodeid(dev); - for(link = 0; link < dev->links; link++) { + for (link = 0; link < dev->links; link++) { if (dev->link[link].children) { amdk8_link_read_bases(dev, nodeid, link); } @@ -416,6 +420,26 @@ static void amdk8_set_resource(device_t dev, struct resource *resource, unsigned report_resource_stored(dev, resource, buf); } +static void amdk8_create_vga_resource(device_t dev, unsigned nodeid) +{ + struct resource *resource; + unsigned link; + 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", + dev_path(dev), link); + printk_info("creating MEM pair for VGA memory\n"); + /* Initialize the io space constraints on the current bus */ + resource = amdk8_find_mempair(dev, nodeid, link); + printk_info("MEM pair register %x\n", resource->index - 0x100); + resource->base = 0xa0000; + resource->size = 0x00000; + resource->gran = 16; + resource->align = 16; + resource->flags = IORESOURCE_PREFETCH | IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_ASSIGNED; + } + } +} static void amdk8_set_resources(device_t dev) { unsigned nodeid, link; @@ -424,8 +448,10 @@ static void amdk8_set_resources(device_t dev) /* Find the nodeid */ nodeid = amdk8_nodeid(dev); + amdk8_create_vga_resource(dev, nodeid); + /* Set each resource we have found */ - for(i = 0; i < dev->resources; i++) { + for (i = 0; i < dev->resources; i++) { amdk8_set_resource(dev, &dev->resource[i], nodeid); } diff --git a/src/southbridge/amd/amd8111/amd8111_lpc.c b/src/southbridge/amd/amd8111/amd8111_lpc.c index 5d3fc44a1b..65c1ccb013 100644 --- a/src/southbridge/amd/amd8111/amd8111_lpc.c +++ b/src/southbridge/amd/amd8111/amd8111_lpc.c @@ -84,7 +84,7 @@ static void setup_ioapic(void) return; } printk_spew("for IRQ, reg 0x%08x value 0x%08x 0x%08x\n", - a->reg, a->value_low, a->value_high); + a->reg, a->value_low, a->value_high); } } @@ -176,15 +176,16 @@ static void amd8111_lpc_enable_resources(device_t dev) enable_childrens_resources(dev); } - static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device) { pci_write_config32(dev, 0x70, - ((device & 0xffff) << 16) | (vendor & 0xffff)); + ((device & 0xffff) << 16) | (vendor & 0xffff)); } + static struct pci_operations lops_pci = { .set_subsystem = lpci_set_subsystem, }; + static struct device_operations lpc_ops = { .read_resources = amd8111_lpc_read_resources, .set_resources = pci_dev_set_resources,