diff --git a/src/devices/device.c b/src/devices/device.c index 40d3f5cf2d..e4e8f24344 100644 --- a/src/devices/device.c +++ b/src/devices/device.c @@ -363,35 +363,44 @@ void compute_allocate_resource( } - #if CONFIG_CONSOLE_VGA == 1 +device_t vga_pri = 0; static void allocate_vga_resource(void) { #warning "FIXME modify allocate_vga_resource so it is less pci centric!" #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; + struct device *dev, *vga, *vga_onboard; struct bus *bus; bus = 0; vga = 0; + vga_onboard = 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) { - printk_debug("Allocating VGA resource %s\n", dev_path(dev)); - vga = dev; - } - if (vga == dev) { - /* All legacy VGA cards have MEM & I/O space registers */ - dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_IO; - } else { - /* It isn't safe to enable other VGA cards */ - dev->command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO); + if (dev->on_mainboard) { + vga_onboard = dev; + } + else { + vga = dev; + } } + /* It isn't safe to enable other VGA cards */ + dev->command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO); } } - if (vga) { + + if (!vga) { + vga = vga_onboard; + } + + if (vga) { // vga is first add on card or the only onboard vga + printk_debug("Allocating VGA resource %s\n", dev_path(vga)); + vga->command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO); + vga_pri = vga; bus = vga->bus; } /* Now walk up the bridges setting the VGA enable */ @@ -402,8 +411,10 @@ static void allocate_vga_resource(void) bus = (bus == bus->dev->bus)? 0 : bus->dev->bus; } } + #endif + /** * @brief Assign the computed resources to the devices on the bus. * @@ -603,28 +614,27 @@ void dev_initialize(void) printk_info("Initializing devices...\n"); #if CONFIG_CONSOLE_VGA == 1 - for (dev = all_devices; dev; dev = dev->next) { - if ( !dev->enabled ) continue; - if (dev->enabled && !dev->initialized && - dev->ops && dev->ops->init) - { - if( !dev->on_mainboard ) continue; // process addon card in second run - else if( dev->rom_address!=0 ) continue; // onboard and it is assigned via MB Config.lb, process it later - printk_debug("%s init\n", dev_path(dev)); - dev->initialized = 1; - dev->ops->init(dev); - } - } -#endif for (dev = all_devices; dev; dev = dev->next) { if (dev->enabled && !dev->initialized && dev->ops && dev->ops->init) { + if( !dev->on_mainboard ) continue; // process addon card in second run + else if( dev->rom_address!=0 ) continue; // onboard and it is assigned via MB Config.lb, process it later printk_debug("%s init\n", dev_path(dev)); dev->initialized = 1; dev->ops->init(dev); } } +#endif + for (dev = all_devices; dev; dev = dev->next) { + if (dev->enabled && !dev->initialized && + dev->ops && dev->ops->init) + { + printk_debug("%s init\n", dev_path(dev)); + dev->initialized = 1; + dev->ops->init(dev); + } + } printk_info("Devices initialized\n"); } diff --git a/src/devices/hypertransport.c b/src/devices/hypertransport.c index e8cf432cb1..a75550cdae 100644 --- a/src/devices/hypertransport.c +++ b/src/devices/hypertransport.c @@ -67,15 +67,17 @@ static int ht_setup_link(struct prev_link *prev, device_t dev, unsigned pos) unsigned freq, old_freq; unsigned present_width, upstream_width, old_width; int reset_needed; + int linkb_to_host; /* Set the hypertransport link width and frequency */ reset_needed = 0; + linkb_to_host = pci_read_config16(dev, pos + PCI_CAP_FLAGS) & (1<<10); /* Read the capabilities */ - present_freq_cap = ht_read_freq_cap(dev, pos + PCI_HT_CAP_SLAVE_FREQ_CAP0); + present_freq_cap = ht_read_freq_cap(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ_CAP1: PCI_HT_CAP_SLAVE_FREQ_CAP0)); upstream_freq_cap = ht_read_freq_cap(prev->dev, prev->pos + prev->freq_cap_off); - present_width_cap = pci_read_config8(dev, pos + PCI_HT_CAP_SLAVE_WIDTH0); - upstream_width_cap = pci_read_config8(prev->dev, prev->pos + prev->config_off); + present_width_cap = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0)); + upstream_width_cap = pci_read_config8(prev->dev, prev->pos + prev->config_off); /* Calculate the highest useable frequency */ freq = log2(present_freq_cap & upstream_freq_cap); @@ -98,15 +100,15 @@ static int ht_setup_link(struct prev_link *prev, device_t dev, unsigned pos) present_width |= pow2_to_link_width[ln_upstream_width_out]; /* Set the current device */ - old_freq = pci_read_config8(dev, pos + PCI_HT_CAP_SLAVE_FREQ0); + old_freq = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ1:PCI_HT_CAP_SLAVE_FREQ0)); if (freq != old_freq) { - pci_write_config8(dev, pos + PCI_HT_CAP_SLAVE_FREQ0, freq); + pci_write_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ1:PCI_HT_CAP_SLAVE_FREQ0), freq); reset_needed = 1; printk_spew("HyperT FreqP old %x new %x\n",old_freq,freq); } - old_width = pci_read_config8(dev, pos + PCI_HT_CAP_SLAVE_WIDTH0 + 1); + old_width = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0) + 1); if (present_width != old_width) { - pci_write_config8(dev, pos + PCI_HT_CAP_SLAVE_WIDTH0 + 1, present_width); + pci_write_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0) + 1, present_width); reset_needed = 1; printk_spew("HyperT widthP old %x new %x\n",old_width, present_width); } @@ -129,9 +131,16 @@ static int ht_setup_link(struct prev_link *prev, device_t dev, unsigned pos) /* Remember the current link as the previous link */ prev->dev = dev; prev->pos = pos; - prev->config_off = PCI_HT_CAP_SLAVE_WIDTH1; - prev->freq_off = PCI_HT_CAP_SLAVE_FREQ1; - prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1; + if(linkb_to_host) { + prev->config_off = PCI_HT_CAP_SLAVE_WIDTH0; + prev->freq_off = PCI_HT_CAP_SLAVE_FREQ0; + prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0; + } + else { + prev->config_off = PCI_HT_CAP_SLAVE_WIDTH1; + prev->freq_off = PCI_HT_CAP_SLAVE_FREQ1; + prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1; + } return reset_needed; @@ -175,7 +184,7 @@ static void ht_collapse_early_enumeration(struct bus *bus) /* Spin through the devices and collapse any early * hypertransport enumeration. */ - for(devfn = 0; devfn <= 0xff; devfn += 8) { + for(devfn = PCI_DEVFN(1, 0); devfn <= 0xff; devfn += 8) { struct device dummy; uint32_t id; unsigned pos, flags; @@ -187,6 +196,7 @@ static void ht_collapse_early_enumeration(struct bus *bus) id == 0x0000ffff || id == 0xffff0000) { continue; } + dummy.vendor = id & 0xffff; dummy.device = (id >> 16) & 0xffff; dummy.hdr_type = pci_read_config8(&dummy, PCI_HEADER_TYPE); @@ -268,16 +278,14 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max) /* 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) - { - if (dev->enabled) { - printk_info("Disabling static device: %s\n", - dev_path(dev)); - dev->enabled = 0; - } + id == 0x0000ffff || id == 0xffff0000) { + if (dev->enabled) { + printk_info("Disabling static device: %s\n", + dev_path(dev)); + dev->enabled = 0; + } break; } } @@ -305,6 +313,7 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max) break; } + /* Update the Unitid of the current device */ flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); flags &= ~0x1f; /* mask out base Unit ID */ diff --git a/src/devices/pci_rom.c b/src/devices/pci_rom.c index 310c00f00c..92f0b0980f 100644 --- a/src/devices/pci_rom.c +++ b/src/devices/pci_rom.c @@ -57,6 +57,7 @@ static void *pci_ram_image_start = PCI_RAM_IMAGE_START; #if CONFIG_CONSOLE_VGA == 1 int vga_inited = 0; // it will be used by vga_console +extern device_t vga_pri; // The only VGA #endif struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_header) @@ -71,7 +72,7 @@ struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_heade if (PCI_CLASS_DISPLAY_VGA == (rom_data->class_hi << 16 | rom_data->class_lo)) { #if CONFIG_CONSOLE_VGA == 1 - if(vga_inited) return NULL; // only one VGA supported + if (dev != vga_pri) return NULL; // only one VGA supported printk_spew("%s, copying VGA ROM Image from %x to %x, %x bytes\n", __func__, rom_header, PCI_VGA_RAM_IMAGE_START, rom_size); memcpy(PCI_VGA_RAM_IMAGE_START, rom_header, rom_size);