diff options
Diffstat (limited to 'src/devices')
-rw-r--r-- | src/devices/device.c | 46 | ||||
-rw-r--r-- | src/devices/hypertransport.c | 94 | ||||
-rw-r--r-- | src/devices/pci_device.c | 2 | ||||
-rw-r--r-- | src/devices/pci_rom.c | 37 |
4 files changed, 136 insertions, 43 deletions
diff --git a/src/devices/device.c b/src/devices/device.c index 303a669d9f..4ca469b191 100644 --- a/src/devices/device.c +++ b/src/devices/device.c @@ -369,7 +369,6 @@ void compute_allocate_resource( } #if CONFIG_CONSOLE_VGA == 1 - device_t vga_pri = 0; static void allocate_vga_resource(void) { @@ -377,31 +376,52 @@ static void allocate_vga_resource(void) #warning "This function knows to much about PCI stuff, it should be just a ietrator/visitor." /* FIXME handle the VGA pallette snooping */ - struct device *dev, *vga, *vga_onboard; + struct device *dev, *vga, *vga_onboard, *vga_first, *vga_last; struct bus *bus; bus = 0; vga = 0; vga_onboard = 0; + vga_first = 0; + vga_last = 0; for(dev = all_devices; dev; dev = dev->next) { if (!dev->enabled) continue; if (((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) && ((dev->class >> 8) != PCI_CLASS_DISPLAY_OTHER)) { - if (!vga) { - if (dev->on_mainboard) { - vga_onboard = dev; - } else { - vga = dev; - } - } + if (!vga_first) { + if (dev->on_mainboard) { + vga_onboard = dev; + } else { + vga_first = dev; + } + } else { + if (dev->on_mainboard) { + vga_onboard = dev; + } else { + vga_last = dev; + } + } + /* It isn't safe to enable other VGA cards */ dev->command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO); } } - if (!vga) { - vga = vga_onboard; - } + vga = vga_last; + + if(!vga) { + vga = vga_first; + } + +#if 1 + if (vga_onboard) // will use on board vga as pri +#else + if (!vga) // will use last add on adapter as pri +#endif + { + vga = vga_onboard; + } + if (vga) { /* vga is first add on card or the only onboard vga */ @@ -419,6 +439,7 @@ static void allocate_vga_resource(void) bus = (bus == bus->dev->bus)? 0 : bus->dev->bus; } } + #endif @@ -499,7 +520,6 @@ void enable_resources(struct device *dev) */ int reset_bus(struct bus *bus) { - device_t dev; if (bus && bus->dev && bus->dev->ops && bus->dev->ops->reset_bus) { bus->dev->ops->reset_bus(bus); diff --git a/src/devices/hypertransport.c b/src/devices/hypertransport.c index a30c8f6a8d..fd347083df 100644 --- a/src/devices/hypertransport.c +++ b/src/devices/hypertransport.c @@ -1,3 +1,9 @@ +/* + 2005.11 yhlu add let the real sb to use small uintid + +*/ + + #include <bitops.h> #include <console/console.h> #include <device/device.h> @@ -11,7 +17,7 @@ #define OPT_HT_LINK 0 #if OPT_HT_LINK == 1 -#include "../northbridge/amd/amdk8/cpu_rev.c" +#include <cpu/amd/model_fxx_rev.h> #endif static device_t ht_scan_get_devs(device_t *old_devices) @@ -71,12 +77,13 @@ static unsigned ht_read_freq_cap(device_t dev, unsigned pos) } /* AMD K8 Unsupported 1Ghz? */ if ((dev->vendor == PCI_VENDOR_ID_AMD) && (dev->device == 0x1100)) { -#if K8_HT_FREQ_1G_SUPPORT == 1 - if (is_cpu_pre_e0()) -#endif - { +#if K8_HT_FREQ_1G_SUPPORT == 1 + if (is_cpu_pre_e0()) { // only e0 later suupport 1GHz HT freq_cap &= ~(1 << HT_FREQ_1000Mhz); - } + } +#else + freq_cap &= ~(1 << HT_FREQ_1000Mhz); +#endif } return freq_cap; @@ -248,7 +255,7 @@ static unsigned ht_lookup_slave_capability(struct device *dev) return pos; } -static void ht_collapse_early_enumeration(struct bus *bus) +static void ht_collapse_early_enumeration(struct bus *bus, unsigned offset_unitid) { unsigned int devfn; struct ht_link prev; @@ -275,6 +282,26 @@ static void ht_collapse_early_enumeration(struct bus *bus) } } while((ctrl & (1 << 5)) == 0); + //actually, only for one HT device HT chain, and unitid is 0 +#if HT_CHAIN_UNITID_BASE == 0 + if(offset_unitid) { + return; + } +#endif + + /* Check if is already collapsed */ + if((!offset_unitid)|| (offset_unitid && (!((HT_CHAIN_END_UNITID_BASE == 0) && (HT_CHAIN_END_UNITID_BASE <HT_CHAIN_UNITID_BASE))))) { + struct device dummy; + uint32_t id; + dummy.bus = bus; + dummy.path.type = DEVICE_PATH_PCI; + dummy.path.u.pci.devfn = PCI_DEVFN(0, 0); + id = pci_read_config32(&dummy, PCI_VENDOR_ID); + if ( ! ( (id == 0xffffffff) || (id == 0x00000000) || + (id == 0x0000ffff) || (id == 0xffff0000) ) ) { + return; + } + } /* Spin through the devices and collapse any early * hypertransport enumeration. @@ -309,15 +336,25 @@ static void ht_collapse_early_enumeration(struct bus *bus) } unsigned int hypertransport_scan_chain(struct bus *bus, - unsigned min_devfn, unsigned max_devfn, unsigned int max) + unsigned min_devfn, unsigned max_devfn, unsigned int max, unsigned offset_unitid) { + //even HT_CHAIN_UNITID_BASE == 0, we still can go through this function, because of end_of_chain check, also We need it to optimize link unsigned next_unitid, last_unitid; device_t old_devices, dev, func; - unsigned min_unitid = 1; + unsigned min_unitid = (offset_unitid) ? HT_CHAIN_UNITID_BASE:1; struct ht_link prev; + device_t last_func = 0; + +#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE + //let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE + unsigned real_last_unitid; + uint8_t real_last_pos; + device_t real_last_dev; + int ht_dev_num = 0; +#endif /* Restore the hypertransport chain to it's unitialized state */ - ht_collapse_early_enumeration(bus); + ht_collapse_early_enumeration(bus, offset_unitid); /* See which static device nodes I have */ old_devices = bus->children; @@ -405,6 +442,7 @@ unsigned int hypertransport_scan_chain(struct bus *bus, func->path.u.pci.devfn += (next_unitid << 3); static_count = (func->path.u.pci.devfn >> 3) - (dev->path.u.pci.devfn >> 3) + 1; + last_func = func; } /* Compute the number of unitids consumed */ @@ -416,6 +454,14 @@ unsigned int hypertransport_scan_chain(struct bus *bus, } /* Update the Unitid of the next device */ +#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE + if(offset_unitid) { + real_last_unitid = next_unitid; + real_last_pos = pos; + real_last_dev = dev; + ht_dev_num++; + } +#endif next_unitid += count; /* Setup the hypetransport link */ @@ -442,6 +488,26 @@ unsigned int hypertransport_scan_chain(struct bus *bus, printk_debug("HyperT reset not needed\n"); } #endif + +#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE + if(offset_unitid && (ht_dev_num>0)) { + uint16_t flags; + int i; + device_t last_func = 0; + flags = pci_read_config16(real_last_dev, real_last_pos + PCI_CAP_FLAGS); + flags &= ~0x1f; + flags |= HT_CHAIN_END_UNITID_BASE & 0x1f; + pci_write_config16(real_last_dev, real_last_pos + PCI_CAP_FLAGS, flags); + + for(func = real_last_dev; func; func = func->sibling) { + func->path.u.pci.devfn -= ((real_last_unitid - HT_CHAIN_END_UNITID_BASE) << 3); + last_func = func; + } + + next_unitid = real_last_unitid; + } +#endif + if (next_unitid > 0x1f) { next_unitid = 0x1f; } @@ -454,13 +520,15 @@ unsigned int hypertransport_scan_chain(struct bus *bus, for(left = old_devices; left; left = left->sibling) { printk_debug("%s\n", dev_path(left)); } - die("Left over static devices. Check your Config.lb\n"); + printk_err("HT: Left over static devices. Check your Config.lb\n"); + if(last_func && !last_func->sibling) // put back the left over static device, and let pci_scan_bus disable it + last_func->sibling = old_devices; } - + /* Now that nothing is overlapping it is safe to scan the * children. */ - max = pci_scan_bus(bus, 0x00, (next_unitid << 3)|7, max); + max = pci_scan_bus(bus, 0x00, (next_unitid << 3)|7, max); return max; } diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c index f3f53f0688..a002d1cc35 100644 --- a/src/devices/pci_device.c +++ b/src/devices/pci_device.c @@ -1043,7 +1043,7 @@ unsigned int pci_scan_bus(struct bus *bus, for(left = old_devices; left; left = left->sibling) { printk_debug("%s\n", dev_path(left)); } - die("Left over static devices. Check your Config.lb\n"); + die("PCI: Left over static devices. Check your Config.lb\n"); } /* For all children that implement scan_bus (i.e. bridges) diff --git a/src/devices/pci_rom.c b/src/devices/pci_rom.c index 64a85bb700..fbc6130bc3 100644 --- a/src/devices/pci_rom.c +++ b/src/devices/pci_rom.c @@ -22,14 +22,15 @@ struct rom_header * pci_rom_probe(struct device *dev) } printk_debug("rom address for %s = %x\n", dev_path(dev), rom_address); + + if(!dev->on_mainboard) { + /* enable expansion ROM address decoding */ + pci_write_config32(dev, PCI_ROM_ADDRESS, + rom_address|PCI_ROM_ADDRESS_ENABLE); + } - /* enable expansion ROM address decoding */ - pci_write_config32(dev, PCI_ROM_ADDRESS, - rom_address|PCI_ROM_ADDRESS_ENABLE); - - rom_header = (struct rom_header *) rom_address; - printk_spew("PCI Expansion ROM, signature 0x%04x, \n\t" - "INIT size 0x%04x, data ptr 0x%04x\n", + rom_header = (struct rom_header *)rom_address; + printk_spew("PCI Expansion ROM, signature 0x%04x, INIT size 0x%04x, data ptr 0x%04x\n", le32_to_cpu(rom_header->signature), rom_header->size * 512, le32_to_cpu(rom_header->data)); if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) { @@ -38,7 +39,7 @@ struct rom_header * pci_rom_probe(struct device *dev) return NULL; } - rom_data = (struct pci_data *) ((unsigned char *) rom_header + le32_to_cpu(rom_header->data)); + rom_data = (unsigned char *) rom_header + le32_to_cpu(rom_header->data); printk_spew("PCI ROM Image, Vendor %04x, Device %04x,\n", rom_data->vendor, rom_data->device); if (dev->vendor != rom_data->vendor || dev->device != rom_data->device) { @@ -51,7 +52,7 @@ struct rom_header * pci_rom_probe(struct device *dev) rom_data->class_hi, rom_data->class_lo, rom_data->type); if (dev->class != ((rom_data->class_hi << 8) | rom_data->class_lo)) { - printk_err("Class Code mismatch ROM %08x, dev %08x\n", + printk_debug("Class Code mismatch ROM %08x, dev %08x\n", (rom_data->class_hi << 8) | rom_data->class_lo, dev->class); //return NULL; } @@ -59,12 +60,14 @@ struct rom_header * pci_rom_probe(struct device *dev) return rom_header; } -static void *pci_ram_image_start = PCI_RAM_IMAGE_START; +static void *pci_ram_image_start = (void *)PCI_RAM_IMAGE_START; #if CONFIG_CONSOLE_VGA == 1 -int vga_inited = 0; // used by vga_console.c +extern int vga_inited; // defined in vga_console.c +#if CONFIG_CONSOLE_VGA_MULTI == 0 extern device_t vga_pri; // the primary vga device, defined in device.c #endif +#endif struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_header) { @@ -76,8 +79,8 @@ struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_heade rom_address = pci_read_config32(dev, PCI_ROM_ADDRESS); do { - rom_header = (struct rom_header *) ((unsigned char *) rom_header + image_size); // get next image - rom_data = (struct pci_data *) ((unsigned char *) rom_header + le32_to_cpu(rom_header->data)); + rom_header = (unsigned char *) rom_header + image_size; // get next image + rom_data = (unsigned char *) rom_header + le32_to_cpu(rom_header->data); image_size = le32_to_cpu(rom_data->ilen) * 512; } while ((rom_data->type!=0) && (rom_data->indicator!=0)); // make sure we got x86 version @@ -87,7 +90,9 @@ struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_heade if (PCI_CLASS_DISPLAY_VGA == rom_data->class_hi) { #if CONFIG_CONSOLE_VGA == 1 + #if CONFIG_CONSOLE_VGA_MULTI == 0 if (dev != vga_pri) return NULL; // only one VGA supported + #endif printk_debug("copying VGA ROM Image from %x to %x, %x bytes\n", rom_header, PCI_VGA_RAM_IMAGE_START, rom_size); memcpy(PCI_VGA_RAM_IMAGE_START, rom_header, rom_size); @@ -95,11 +100,11 @@ struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_heade return (struct rom_header *) (PCI_VGA_RAM_IMAGE_START); #endif } else { - printk_spew("%s, copying non-VGA ROM Image from %x to %x, %x bytes\n", - __func__, rom_header, pci_ram_image_start, rom_size); + printk_debug("copying non-VGA ROM Image from %x to %x, %x bytes\n", + rom_header, pci_ram_image_start, rom_size); memcpy(pci_ram_image_start, rom_header, rom_size); pci_ram_image_start += rom_size; - return (struct rom_header *) pci_ram_image_start; + return (struct rom_header *) (pci_ram_image_start-rom_size); } /* disable expansion ROM address decoding */ pci_write_config32(dev, PCI_ROM_ADDRESS, rom_address & ~PCI_ROM_ADDRESS_ENABLE); |