Commit 80b3ada7dd56088613a446934d144a747e740fa1

Authored by pbrook
1 parent d2b59317

Implement sun4u PCI IRQ routing.

Allow multiple PCI busses and PCI-PCI bridges.
Fix bugs in Versatile PCI implementation.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2166 c046a42c-6fe2-441c-8c8c-71466251a162
hw/apb_pci.c
@@ -21,6 +21,11 @@ @@ -21,6 +21,11 @@
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE. 22 * THE SOFTWARE.
23 */ 23 */
  24 +
  25 +/* XXX This file and most of its contests are somewhat misnamed. The
  26 + Ultrasparc PCI host is called the PCI Bus Module (PBM). The APB is
  27 + the secondary PCI bridge. */
  28 +
24 #include "vl.h" 29 #include "vl.h"
25 typedef target_phys_addr_t pci_addr_t; 30 typedef target_phys_addr_t pci_addr_t;
26 #include "pci_host.h" 31 #include "pci_host.h"
@@ -179,17 +184,25 @@ static CPUReadMemoryFunc *pci_apb_ioread[] = { @@ -179,17 +184,25 @@ static CPUReadMemoryFunc *pci_apb_ioread[] = {
179 &pci_apb_ioreadl, 184 &pci_apb_ioreadl,
180 }; 185 };
181 186
  187 +/* The APB host has an IRQ line for each IRQ line of each slot. */
182 static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num) 188 static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
183 { 189 {
184 - /* ??? As mentioned below this is probably wrong. */  
185 - return irq_num; 190 + return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
  191 +}
  192 +
  193 +static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
  194 +{
  195 + int bus_offset;
  196 + if (pci_dev->devfn & 1)
  197 + bus_offset = 16;
  198 + else
  199 + bus_offset = 0;
  200 + return bus_offset + irq_num;
186 } 201 }
187 202
188 static void pci_apb_set_irq(void *pic, int irq_num, int level) 203 static void pci_apb_set_irq(void *pic, int irq_num, int level)
189 { 204 {
190 - /* ??? This is almost certainly wrong. However the rest of the sun4u  
191 - IRQ handling is missing, as is OpenBIOS support, so it wouldn't work  
192 - anyway. */ 205 + /* PCI IRQ map onto the first 32 INO. */
193 pic_set_irq_new(pic, irq_num, level); 206 pic_set_irq_new(pic, irq_num, level);
194 } 207 }
195 208
@@ -199,10 +212,12 @@ PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base, @@ -199,10 +212,12 @@ PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
199 APBState *s; 212 APBState *s;
200 PCIDevice *d; 213 PCIDevice *d;
201 int pci_mem_config, pci_mem_data, apb_config, pci_ioport; 214 int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
  215 + PCIDevice *apb;
  216 + PCIBus *secondary;
202 217
203 s = qemu_mallocz(sizeof(APBState)); 218 s = qemu_mallocz(sizeof(APBState));
204 - /* Ultrasparc APB main bus */  
205 - s->bus = pci_register_bus(pci_apb_set_irq, pci_apb_map_irq, pic, 0); 219 + /* Ultrasparc PBM main bus */
  220 + s->bus = pci_register_bus(pci_apb_set_irq, pci_pbm_map_irq, pic, 0, 32);
206 221
207 pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read, 222 pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read,
208 pci_apb_config_write, s); 223 pci_apb_config_write, s);
@@ -219,7 +234,7 @@ PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base, @@ -219,7 +234,7 @@ PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
219 cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom 234 cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom
220 235
221 d = pci_register_device(s->bus, "Advanced PCI Bus", sizeof(PCIDevice), 236 d = pci_register_device(s->bus, "Advanced PCI Bus", sizeof(PCIDevice),
222 - -1, NULL, NULL); 237 + 0, NULL, NULL);
223 d->config[0x00] = 0x8e; // vendor_id : Sun 238 d->config[0x00] = 0x8e; // vendor_id : Sun
224 d->config[0x01] = 0x10; 239 d->config[0x01] = 0x10;
225 d->config[0x02] = 0x00; // device_id 240 d->config[0x02] = 0x00; // device_id
@@ -234,7 +249,11 @@ PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base, @@ -234,7 +249,11 @@ PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
234 d->config[0x0B] = 0x06; // class_base = PCI_bridge 249 d->config[0x0B] = 0x06; // class_base = PCI_bridge
235 d->config[0x0D] = 0x10; // latency_timer 250 d->config[0x0D] = 0x10; // latency_timer
236 d->config[0x0E] = 0x00; // header_type 251 d->config[0x0E] = 0x00; // header_type
237 - return s->bus; 252 +
  253 + /* APB secondary busses */
  254 + secondary = pci_bridge_init(s->bus, 8, 0x108e5000, pci_apb_map_irq);
  255 + pci_bridge_init(s->bus, 9, 0x108e5000, pci_apb_map_irq);
  256 + return secondary;
238 } 257 }
239 258
240 259
hw/grackle_pci.c
@@ -92,7 +92,8 @@ PCIBus *pci_grackle_init(uint32_t base, void *pic) @@ -92,7 +92,8 @@ PCIBus *pci_grackle_init(uint32_t base, void *pic)
92 int pci_mem_config, pci_mem_data; 92 int pci_mem_config, pci_mem_data;
93 93
94 s = qemu_mallocz(sizeof(GrackleState)); 94 s = qemu_mallocz(sizeof(GrackleState));
95 - s->bus = pci_register_bus(pci_grackle_set_irq, pci_grackle_map_irq, pic, 0); 95 + s->bus = pci_register_bus(pci_grackle_set_irq, pci_grackle_map_irq,
  96 + pic, 0, 0);
96 97
97 pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read, 98 pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read,
98 pci_grackle_config_write, s); 99 pci_grackle_config_write, s);
hw/pci.c
@@ -35,9 +35,11 @@ struct PCIBus { @@ -35,9 +35,11 @@ struct PCIBus {
35 SetIRQFunc *low_set_irq; 35 SetIRQFunc *low_set_irq;
36 void *irq_opaque; 36 void *irq_opaque;
37 PCIDevice *devices[256]; 37 PCIDevice *devices[256];
  38 + PCIDevice *parent_dev;
  39 + PCIBus *next;
38 /* The bus IRQ state is the logical OR of the connected devices. 40 /* The bus IRQ state is the logical OR of the connected devices.
39 Keep a count of the number of devices with raised IRQs. */ 41 Keep a count of the number of devices with raised IRQs. */
40 - int irq_count[4]; 42 + int irq_count[];
41 }; 43 };
42 44
43 static void pci_update_mappings(PCIDevice *d); 45 static void pci_update_mappings(PCIDevice *d);
@@ -47,19 +49,29 @@ static int pci_irq_index; @@ -47,19 +49,29 @@ static int pci_irq_index;
47 static PCIBus *first_bus; 49 static PCIBus *first_bus;
48 50
49 PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, 51 PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
50 - void *pic, int devfn_min) 52 + void *pic, int devfn_min, int nirq)
51 { 53 {
52 PCIBus *bus; 54 PCIBus *bus;
53 - bus = qemu_mallocz(sizeof(PCIBus)); 55 + bus = qemu_mallocz(sizeof(PCIBus) + (nirq * sizeof(int)));
54 bus->set_irq = set_irq; 56 bus->set_irq = set_irq;
55 bus->map_irq = map_irq; 57 bus->map_irq = map_irq;
56 bus->irq_opaque = pic; 58 bus->irq_opaque = pic;
57 bus->devfn_min = devfn_min; 59 bus->devfn_min = devfn_min;
58 - memset(bus->irq_count, 0, sizeof(bus->irq_count));  
59 first_bus = bus; 60 first_bus = bus;
60 return bus; 61 return bus;
61 } 62 }
62 63
  64 +PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq)
  65 +{
  66 + PCIBus *bus;
  67 + bus = qemu_mallocz(sizeof(PCIBus));
  68 + bus->map_irq = map_irq;
  69 + bus->parent_dev = dev;
  70 + bus->next = dev->bus->next;
  71 + dev->bus->next = bus;
  72 + return bus;
  73 +}
  74 +
63 int pci_bus_num(PCIBus *s) 75 int pci_bus_num(PCIBus *s)
64 { 76 {
65 return s->bus_num; 77 return s->bus_num;
@@ -351,7 +363,9 @@ void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len) @@ -351,7 +363,9 @@ void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
351 addr, val, len); 363 addr, val, len);
352 #endif 364 #endif
353 bus_num = (addr >> 16) & 0xff; 365 bus_num = (addr >> 16) & 0xff;
354 - if (bus_num != 0) 366 + while (s && s->bus_num != bus_num)
  367 + s = s->next;
  368 + if (!s)
355 return; 369 return;
356 pci_dev = s->devices[(addr >> 8) & 0xff]; 370 pci_dev = s->devices[(addr >> 8) & 0xff];
357 if (!pci_dev) 371 if (!pci_dev)
@@ -372,7 +386,9 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len) @@ -372,7 +386,9 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
372 uint32_t val; 386 uint32_t val;
373 387
374 bus_num = (addr >> 16) & 0xff; 388 bus_num = (addr >> 16) & 0xff;
375 - if (bus_num != 0) 389 + while (s && s->bus_num != bus_num)
  390 + s= s->next;
  391 + if (!s)
376 goto fail; 392 goto fail;
377 pci_dev = s->devices[(addr >> 8) & 0xff]; 393 pci_dev = s->devices[(addr >> 8) & 0xff];
378 if (!pci_dev) { 394 if (!pci_dev) {
@@ -411,11 +427,21 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len) @@ -411,11 +427,21 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
411 /* 0 <= irq_num <= 3. level must be 0 or 1 */ 427 /* 0 <= irq_num <= 3. level must be 0 or 1 */
412 void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level) 428 void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
413 { 429 {
414 - PCIBus *bus = pci_dev->bus; 430 + PCIBus *bus;
  431 + int change;
  432 +
  433 + change = level - pci_dev->irq_state[irq_num];
  434 + if (!change)
  435 + return;
415 436
416 - irq_num = bus->map_irq(pci_dev, irq_num);  
417 - bus->irq_count[irq_num] += level - pci_dev->irq_state[irq_num];  
418 pci_dev->irq_state[irq_num] = level; 437 pci_dev->irq_state[irq_num] = level;
  438 + bus = pci_dev->bus;
  439 + while (!bus->set_irq) {
  440 + irq_num = bus->map_irq(pci_dev, irq_num);
  441 + pci_dev = bus->parent_dev;
  442 + bus = pci_dev->bus;
  443 + }
  444 + bus->irq_count[irq_num] += change;
419 bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0); 445 bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
420 } 446 }
421 447
@@ -465,6 +491,9 @@ static void pci_info_device(PCIDevice *d) @@ -465,6 +491,9 @@ static void pci_info_device(PCIDevice *d)
465 if (d->config[PCI_INTERRUPT_PIN] != 0) { 491 if (d->config[PCI_INTERRUPT_PIN] != 0) {
466 term_printf(" IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]); 492 term_printf(" IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);
467 } 493 }
  494 + if (class == 0x0604) {
  495 + term_printf(" BUS %d.\n", d->config[0x19]);
  496 + }
468 for(i = 0;i < PCI_NUM_REGIONS; i++) { 497 for(i = 0;i < PCI_NUM_REGIONS; i++) {
469 r = &d->io_regions[i]; 498 r = &d->io_regions[i];
470 if (r->size != 0) { 499 if (r->size != 0) {
@@ -478,14 +507,19 @@ static void pci_info_device(PCIDevice *d) @@ -478,14 +507,19 @@ static void pci_info_device(PCIDevice *d)
478 } 507 }
479 } 508 }
480 } 509 }
  510 + if (class == 0x0604 && d->config[0x19] != 0) {
  511 + pci_for_each_device(d->config[0x19], pci_info_device);
  512 + }
481 } 513 }
482 514
483 -void pci_for_each_device(void (*fn)(PCIDevice *d)) 515 +void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d))
484 { 516 {
485 PCIBus *bus = first_bus; 517 PCIBus *bus = first_bus;
486 PCIDevice *d; 518 PCIDevice *d;
487 int devfn; 519 int devfn;
488 520
  521 + while (bus && bus->bus_num != bus_num)
  522 + bus = bus->next;
489 if (bus) { 523 if (bus) {
490 for(devfn = 0; devfn < 256; devfn++) { 524 for(devfn = 0; devfn < 256; devfn++) {
491 d = bus->devices[devfn]; 525 d = bus->devices[devfn];
@@ -497,7 +531,7 @@ void pci_for_each_device(void (*fn)(PCIDevice *d)) @@ -497,7 +531,7 @@ void pci_for_each_device(void (*fn)(PCIDevice *d))
497 531
498 void pci_info(void) 532 void pci_info(void)
499 { 533 {
500 - pci_for_each_device(pci_info_device); 534 + pci_for_each_device(0, pci_info_device);
501 } 535 }
502 536
503 /* Initialize a PCI NIC. */ 537 /* Initialize a PCI NIC. */
@@ -515,3 +549,50 @@ void pci_nic_init(PCIBus *bus, NICInfo *nd) @@ -515,3 +549,50 @@ void pci_nic_init(PCIBus *bus, NICInfo *nd)
515 } 549 }
516 } 550 }
517 551
  552 +typedef struct {
  553 + PCIDevice dev;
  554 + PCIBus *bus;
  555 +} PCIBridge;
  556 +
  557 +void pci_bridge_write_config(PCIDevice *d,
  558 + uint32_t address, uint32_t val, int len)
  559 +{
  560 + PCIBridge *s = (PCIBridge *)d;
  561 +
  562 + if (address == 0x19 || (address == 0x18 && len > 1)) {
  563 + if (address == 0x19)
  564 + s->bus->bus_num = val & 0xff;
  565 + else
  566 + s->bus->bus_num = (val >> 8) & 0xff;
  567 +#if defined(DEBUG_PCI)
  568 + printf ("pci-bridge: %s: Assigned bus %d\n", d->name, s->bus->bus_num);
  569 +#endif
  570 + }
  571 + pci_default_write_config(d, address, val, len);
  572 +}
  573 +
  574 +PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
  575 + pci_map_irq_fn map_irq, const char *name)
  576 +{
  577 + PCIBridge *s;
  578 + s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge),
  579 + devfn, NULL, pci_bridge_write_config);
  580 + s->dev.config[0x00] = id >> 16;
  581 + s->dev.config[0x01] = id > 24;
  582 + s->dev.config[0x02] = id; // device_id
  583 + s->dev.config[0x03] = id >> 8;
  584 + s->dev.config[0x04] = 0x06; // command = bus master, pci mem
  585 + s->dev.config[0x05] = 0x00;
  586 + s->dev.config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
  587 + s->dev.config[0x07] = 0x00; // status = fast devsel
  588 + s->dev.config[0x08] = 0x00; // revision
  589 + s->dev.config[0x09] = 0x00; // programming i/f
  590 + s->dev.config[0x0A] = 0x04; // class_sub = PCI to PCI bridge
  591 + s->dev.config[0x0B] = 0x06; // class_base = PCI_bridge
  592 + s->dev.config[0x0D] = 0x10; // latency_timer
  593 + s->dev.config[0x0E] = 0x81; // header_type
  594 + s->dev.config[0x1E] = 0xa0; // secondary status
  595 +
  596 + s->bus = pci_register_secondary_bus(&s->dev, map_irq);
  597 + return s->bus;
  598 +}
hw/piix_pci.c
@@ -59,7 +59,7 @@ PCIBus *i440fx_init(void) @@ -59,7 +59,7 @@ PCIBus *i440fx_init(void)
59 I440FXState *s; 59 I440FXState *s;
60 60
61 s = qemu_mallocz(sizeof(I440FXState)); 61 s = qemu_mallocz(sizeof(I440FXState));
62 - b = pci_register_bus(piix3_set_irq, pci_slot_get_pirq, NULL, 0); 62 + b = pci_register_bus(piix3_set_irq, pci_slot_get_pirq, NULL, 0, 4);
63 s->bus = b; 63 s->bus = b;
64 64
65 register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s); 65 register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s);
@@ -226,6 +226,7 @@ static uint32_t pci_bios_io_addr; @@ -226,6 +226,7 @@ static uint32_t pci_bios_io_addr;
226 static uint32_t pci_bios_mem_addr; 226 static uint32_t pci_bios_mem_addr;
227 /* host irqs corresponding to PCI irqs A-D */ 227 /* host irqs corresponding to PCI irqs A-D */
228 static uint8_t pci_irqs[4] = { 11, 9, 11, 9 }; 228 static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
  229 +static int pci_bios_next_bus;
229 230
230 static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val) 231 static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
231 { 232 {
@@ -320,6 +321,14 @@ static void pci_bios_init_device(PCIDevice *d) @@ -320,6 +321,14 @@ static void pci_bios_init_device(PCIDevice *d)
320 pci_set_io_region_addr(d, 3, 0x374); 321 pci_set_io_region_addr(d, 3, 0x374);
321 } 322 }
322 break; 323 break;
  324 + case 0x0604:
  325 + /* PCI to PCI bridge. Assign bus ID and recurse to configure
  326 + devices on the secondary bus. */
  327 + i = pci_bios_next_bus++;
  328 + pci_config_writeb(d, 0x18, pci_bus_num(d->bus));
  329 + pci_config_writeb(d, 0x19, i);
  330 + pci_for_each_device(i, pci_bios_init_device);
  331 + break;
323 case 0x0300: 332 case 0x0300:
324 if (vendor_id != 0x1234) 333 if (vendor_id != 0x1234)
325 goto default_map; 334 goto default_map;
@@ -398,6 +407,7 @@ void pci_bios_init(void) @@ -398,6 +407,7 @@ void pci_bios_init(void)
398 isa_outb(elcr[0], 0x4d0); 407 isa_outb(elcr[0], 0x4d0);
399 isa_outb(elcr[1], 0x4d1); 408 isa_outb(elcr[1], 0x4d1);
400 409
401 - pci_for_each_device(pci_bios_init_device); 410 + pci_bios_next_bus = 1;
  411 + pci_for_each_device(0, pci_bios_init_device);
402 } 412 }
403 413
hw/prep_pci.c
@@ -120,18 +120,12 @@ static CPUReadMemoryFunc *PPC_PCIIO_read[] = { @@ -120,18 +120,12 @@ static CPUReadMemoryFunc *PPC_PCIIO_read[] = {
120 /* Don't know if this matches real hardware, but it agrees with OHW. */ 120 /* Don't know if this matches real hardware, but it agrees with OHW. */
121 static int prep_map_irq(PCIDevice *pci_dev, int irq_num) 121 static int prep_map_irq(PCIDevice *pci_dev, int irq_num)
122 { 122 {
123 - return (irq_num + (pci_dev->devfn >> 3)) & 3; 123 + return (irq_num + (pci_dev->devfn >> 3)) & 1;
124 } 124 }
125 125
126 -static int prep_irq_levels[4];  
127 -  
128 static void prep_set_irq(void *pic, int irq_num, int level) 126 static void prep_set_irq(void *pic, int irq_num, int level)
129 { 127 {
130 - int pic_irq_num;  
131 - prep_irq_levels[irq_num] = level;  
132 - level |= prep_irq_levels[irq_num ^ 2];  
133 - pic_irq_num = (irq_num == 0 || irq_num == 2) ? 9 : 11;  
134 - pic_set_irq(pic_irq_num, level); 128 + pic_set_irq(irq_num ? 11 : 9, level);
135 } 129 }
136 130
137 PCIBus *pci_prep_init(void) 131 PCIBus *pci_prep_init(void)
@@ -141,7 +135,7 @@ PCIBus *pci_prep_init(void) @@ -141,7 +135,7 @@ PCIBus *pci_prep_init(void)
141 int PPC_io_memory; 135 int PPC_io_memory;
142 136
143 s = qemu_mallocz(sizeof(PREPPCIState)); 137 s = qemu_mallocz(sizeof(PREPPCIState));
144 - s->bus = pci_register_bus(prep_set_irq, prep_map_irq, NULL, 0); 138 + s->bus = pci_register_bus(prep_set_irq, prep_map_irq, NULL, 0, 2);
145 139
146 register_ioport_write(0xcf8, 4, 4, pci_prep_addr_writel, s); 140 register_ioport_write(0xcf8, 4, 4, pci_prep_addr_writel, s);
147 register_ioport_read(0xcf8, 4, 4, pci_prep_addr_readl, s); 141 register_ioport_read(0xcf8, 4, 4, pci_prep_addr_readl, s);
hw/unin_pci.c
@@ -161,7 +161,7 @@ PCIBus *pci_pmac_init(void *pic) @@ -161,7 +161,7 @@ PCIBus *pci_pmac_init(void *pic)
161 /* Uninorth main bus */ 161 /* Uninorth main bus */
162 s = qemu_mallocz(sizeof(UNINState)); 162 s = qemu_mallocz(sizeof(UNINState));
163 s->bus = pci_register_bus(pci_unin_set_irq, pci_unin_map_irq, 163 s->bus = pci_register_bus(pci_unin_set_irq, pci_unin_map_irq,
164 - pic, 11 << 3); 164 + pic, 11 << 3, 4);
165 165
166 pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read, 166 pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read,
167 pci_unin_main_config_write, s); 167 pci_unin_main_config_write, s);
hw/versatile_pci.c
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 11
12 static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr) 12 static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr)
13 { 13 {
14 - return addr & 0xf8ff; 14 + return addr & 0xffffff;
15 } 15 }
16 16
17 static void pci_vpb_config_writeb (void *opaque, target_phys_addr_t addr, 17 static void pci_vpb_config_writeb (void *opaque, target_phys_addr_t addr,
@@ -105,15 +105,15 @@ PCIBus *pci_vpb_init(void *pic, int irq, int realview) @@ -105,15 +105,15 @@ PCIBus *pci_vpb_init(void *pic, int irq, int realview)
105 base = 0x40000000; 105 base = 0x40000000;
106 name = "Versatile/PB PCI Controller"; 106 name = "Versatile/PB PCI Controller";
107 } 107 }
108 - s = pci_register_bus(pci_vpb_set_irq, pci_vpb_map_irq, pic, 11 << 3); 108 + s = pci_register_bus(pci_vpb_set_irq, pci_vpb_map_irq, pic, 11 << 3, 4);
109 /* ??? Register memory space. */ 109 /* ??? Register memory space. */
110 110
111 mem_config = cpu_register_io_memory(0, pci_vpb_config_read, 111 mem_config = cpu_register_io_memory(0, pci_vpb_config_read,
112 pci_vpb_config_write, s); 112 pci_vpb_config_write, s);
113 /* Selfconfig area. */ 113 /* Selfconfig area. */
114 - cpu_register_physical_memory(base + 0x01000000, 0x10000, mem_config); 114 + cpu_register_physical_memory(base + 0x01000000, 0x1000000, mem_config);
115 /* Normal config area. */ 115 /* Normal config area. */
116 - cpu_register_physical_memory(base + 0x02000000, 0x10000, mem_config); 116 + cpu_register_physical_memory(base + 0x02000000, 0x1000000, mem_config);
117 117
118 d = pci_register_device(s, name, sizeof(PCIDevice), -1, NULL, NULL); 118 d = pci_register_device(s, name, sizeof(PCIDevice), -1, NULL, NULL);
119 119
@@ -759,15 +759,17 @@ int pci_device_load(PCIDevice *s, QEMUFile *f); @@ -759,15 +759,17 @@ int pci_device_load(PCIDevice *s, QEMUFile *f);
759 typedef void (*pci_set_irq_fn)(void *pic, int irq_num, int level); 759 typedef void (*pci_set_irq_fn)(void *pic, int irq_num, int level);
760 typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); 760 typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
761 PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, 761 PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
762 - void *pic, int devfn_min); 762 + void *pic, int devfn_min, int nirq);
763 763
764 void pci_nic_init(PCIBus *bus, NICInfo *nd); 764 void pci_nic_init(PCIBus *bus, NICInfo *nd);
765 void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len); 765 void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len);
766 uint32_t pci_data_read(void *opaque, uint32_t addr, int len); 766 uint32_t pci_data_read(void *opaque, uint32_t addr, int len);
767 int pci_bus_num(PCIBus *s); 767 int pci_bus_num(PCIBus *s);
768 -void pci_for_each_device(void (*fn)(PCIDevice *d)); 768 +void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
769 769
770 void pci_info(void); 770 void pci_info(void);
  771 +PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
  772 + pci_map_irq_fn map_irq, const char *name);
771 773
772 /* prep_pci.c */ 774 /* prep_pci.c */
773 PCIBus *pci_prep_init(void); 775 PCIBus *pci_prep_init(void);