Commit 502a53952d574717bdb626b651b16cadacab46f4

Authored by pbrook
1 parent 4aa42531

Rearrange PCI host emulation code.

Add ARM PCI emulation.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1916 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -307,7 +307,7 @@ SOUND_HW += fmopl.o adlib.o
307 307 endif
308 308  
309 309 # USB layer
310   -VL_OBJS+= usb.o usb-hub.o usb-uhci.o usb-linux.o usb-hid.o
  310 +VL_OBJS+= usb.o usb-hub.o usb-linux.o usb-hid.o
311 311  
312 312 # PCI network cards
313 313 VL_OBJS+= ne2000.o rtl8139.o
... ... @@ -316,13 +316,15 @@ ifeq ($(TARGET_BASE_ARCH), i386)
316 316 # Hardware support
317 317 VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
318 318 VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
319   -VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o acpi.o
  319 +VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o acpi.o piix_pci.o
  320 +VL_OBJS+= usb-uhci.o
320 321 DEFINES += -DHAS_AUDIO
321 322 endif
322 323 ifeq ($(TARGET_BASE_ARCH), ppc)
323 324 VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
324 325 VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
325 326 VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o
  327 +VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o
326 328 DEFINES += -DHAS_AUDIO
327 329 endif
328 330 ifeq ($(TARGET_ARCH), mips)
... ... @@ -331,7 +333,7 @@ VL_OBJS+= mips_r4k.o dma.o vga.o serial.o i8254.o i8259.o
331 333 endif
332 334 ifeq ($(TARGET_BASE_ARCH), sparc)
333 335 ifeq ($(TARGET_ARCH), sparc64)
334   -VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o
  336 +VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o apb_pci.o
335 337 VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o
336 338 VL_OBJS+= cirrus_vga.o parallel.o
337 339 else
... ... @@ -342,6 +344,7 @@ endif
342 344 ifeq ($(TARGET_BASE_ARCH), arm)
343 345 VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
344 346 VL_OBJS+= arm_boot.o pl011.o pl050.o pl080.o pl110.o pl190.o
  347 +VL_OBJS+= versatile_pci.o
345 348 endif
346 349 ifeq ($(TARGET_BASE_ARCH), sh4)
347 350 VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
... ...
hw/acpi.c
... ... @@ -220,7 +220,7 @@ static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
220 220  
221 221 /* XXX: we still add it to the PIIX3 and we count on the fact that
222 222 OSes are smart enough to accept this strange configuration */
223   -void piix4_pm_init(PCIBus *bus)
  223 +void piix4_pm_init(PCIBus *bus, int devfn)
224 224 {
225 225 PIIX4PMState *s;
226 226 uint8_t *pci_conf;
... ... @@ -228,8 +228,7 @@ void piix4_pm_init(PCIBus *bus)
228 228  
229 229 s = (PIIX4PMState *)pci_register_device(bus,
230 230 "PM", sizeof(PIIX4PMState),
231   - ((PCIDevice *)piix3_state)->devfn + 3,
232   - NULL, NULL);
  231 + devfn, NULL, NULL);
233 232 pci_conf = s->dev.config;
234 233 pci_conf[0x00] = 0x86;
235 234 pci_conf[0x01] = 0x80;
... ...
hw/apb_pci.c 0 → 100644
  1 +/*
  2 + * QEMU Ultrasparc APB PCI host
  3 + *
  4 + * Copyright (c) 2006 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include "vl.h"
  25 +typedef target_phys_addr_t pci_addr_t;
  26 +#include "pci_host.h"
  27 +
  28 +typedef PCIHostState APBState;
  29 +
  30 +static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
  31 + uint32_t val)
  32 +{
  33 + APBState *s = opaque;
  34 + int i;
  35 +
  36 + for (i = 11; i < 32; i++) {
  37 + if ((val & (1 << i)) != 0)
  38 + break;
  39 + }
  40 + s->config_reg = (1 << 16) | (val & 0x7FC) | (i << 11);
  41 +}
  42 +
  43 +static uint32_t pci_apb_config_readl (void *opaque,
  44 + target_phys_addr_t addr)
  45 +{
  46 + APBState *s = opaque;
  47 + uint32_t val;
  48 + int devfn;
  49 +
  50 + devfn = (s->config_reg >> 8) & 0xFF;
  51 + val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
  52 + return val;
  53 +}
  54 +
  55 +static CPUWriteMemoryFunc *pci_apb_config_write[] = {
  56 + &pci_apb_config_writel,
  57 + &pci_apb_config_writel,
  58 + &pci_apb_config_writel,
  59 +};
  60 +
  61 +static CPUReadMemoryFunc *pci_apb_config_read[] = {
  62 + &pci_apb_config_readl,
  63 + &pci_apb_config_readl,
  64 + &pci_apb_config_readl,
  65 +};
  66 +
  67 +static void apb_config_writel (void *opaque, target_phys_addr_t addr,
  68 + uint32_t val)
  69 +{
  70 + //PCIBus *s = opaque;
  71 +
  72 + switch (addr & 0x3f) {
  73 + case 0x00: // Control/Status
  74 + case 0x10: // AFSR
  75 + case 0x18: // AFAR
  76 + case 0x20: // Diagnostic
  77 + case 0x28: // Target address space
  78 + // XXX
  79 + default:
  80 + break;
  81 + }
  82 +}
  83 +
  84 +static uint32_t apb_config_readl (void *opaque,
  85 + target_phys_addr_t addr)
  86 +{
  87 + //PCIBus *s = opaque;
  88 + uint32_t val;
  89 +
  90 + switch (addr & 0x3f) {
  91 + case 0x00: // Control/Status
  92 + case 0x10: // AFSR
  93 + case 0x18: // AFAR
  94 + case 0x20: // Diagnostic
  95 + case 0x28: // Target address space
  96 + // XXX
  97 + default:
  98 + val = 0;
  99 + break;
  100 + }
  101 + return val;
  102 +}
  103 +
  104 +static CPUWriteMemoryFunc *apb_config_write[] = {
  105 + &apb_config_writel,
  106 + &apb_config_writel,
  107 + &apb_config_writel,
  108 +};
  109 +
  110 +static CPUReadMemoryFunc *apb_config_read[] = {
  111 + &apb_config_readl,
  112 + &apb_config_readl,
  113 + &apb_config_readl,
  114 +};
  115 +
  116 +static CPUWriteMemoryFunc *pci_apb_write[] = {
  117 + &pci_host_data_writeb,
  118 + &pci_host_data_writew,
  119 + &pci_host_data_writel,
  120 +};
  121 +
  122 +static CPUReadMemoryFunc *pci_apb_read[] = {
  123 + &pci_host_data_readb,
  124 + &pci_host_data_readw,
  125 + &pci_host_data_readl,
  126 +};
  127 +
  128 +static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,
  129 + uint32_t val)
  130 +{
  131 + cpu_outb(NULL, addr & 0xffff, val);
  132 +}
  133 +
  134 +static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,
  135 + uint32_t val)
  136 +{
  137 + cpu_outw(NULL, addr & 0xffff, val);
  138 +}
  139 +
  140 +static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,
  141 + uint32_t val)
  142 +{
  143 + cpu_outl(NULL, addr & 0xffff, val);
  144 +}
  145 +
  146 +static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr)
  147 +{
  148 + uint32_t val;
  149 +
  150 + val = cpu_inb(NULL, addr & 0xffff);
  151 + return val;
  152 +}
  153 +
  154 +static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr)
  155 +{
  156 + uint32_t val;
  157 +
  158 + val = cpu_inw(NULL, addr & 0xffff);
  159 + return val;
  160 +}
  161 +
  162 +static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)
  163 +{
  164 + uint32_t val;
  165 +
  166 + val = cpu_inl(NULL, addr & 0xffff);
  167 + return val;
  168 +}
  169 +
  170 +static CPUWriteMemoryFunc *pci_apb_iowrite[] = {
  171 + &pci_apb_iowriteb,
  172 + &pci_apb_iowritew,
  173 + &pci_apb_iowritel,
  174 +};
  175 +
  176 +static CPUReadMemoryFunc *pci_apb_ioread[] = {
  177 + &pci_apb_ioreadb,
  178 + &pci_apb_ioreadw,
  179 + &pci_apb_ioreadl,
  180 +};
  181 +
  182 +/* ??? This is probably wrong. */
  183 +static void pci_apb_set_irq(PCIDevice *d, void *pic, int irq_num, int level)
  184 +{
  185 + pic_set_irq_new(pic, d->config[PCI_INTERRUPT_LINE], level);
  186 +}
  187 +
  188 +PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
  189 + void *pic)
  190 +{
  191 + APBState *s;
  192 + PCIDevice *d;
  193 + int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
  194 +
  195 + s = qemu_mallocz(sizeof(APBState));
  196 + /* Ultrasparc APB main bus */
  197 + s->bus = pci_register_bus(pci_apb_set_irq, pic, 0);
  198 +
  199 + pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read,
  200 + pci_apb_config_write, s);
  201 + apb_config = cpu_register_io_memory(0, apb_config_read,
  202 + apb_config_write, s);
  203 + pci_mem_data = cpu_register_io_memory(0, pci_apb_read,
  204 + pci_apb_write, s);
  205 + pci_ioport = cpu_register_io_memory(0, pci_apb_ioread,
  206 + pci_apb_iowrite, s);
  207 +
  208 + cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config);
  209 + cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10, pci_mem_config);
  210 + cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, pci_ioport);
  211 + cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom
  212 +
  213 + d = pci_register_device(s->bus, "Advanced PCI Bus", sizeof(PCIDevice),
  214 + -1, NULL, NULL);
  215 + d->config[0x00] = 0x8e; // vendor_id : Sun
  216 + d->config[0x01] = 0x10;
  217 + d->config[0x02] = 0x00; // device_id
  218 + d->config[0x03] = 0xa0;
  219 + d->config[0x04] = 0x06; // command = bus master, pci mem
  220 + d->config[0x05] = 0x00;
  221 + d->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
  222 + d->config[0x07] = 0x03; // status = medium devsel
  223 + d->config[0x08] = 0x00; // revision
  224 + d->config[0x09] = 0x00; // programming i/f
  225 + d->config[0x0A] = 0x00; // class_sub = pci host
  226 + d->config[0x0B] = 0x06; // class_base = PCI_bridge
  227 + d->config[0x0D] = 0x10; // latency_timer
  228 + d->config[0x0E] = 0x00; // header_type
  229 + return s->bus;
  230 +}
  231 +
  232 +
... ...
hw/grackle_pci.c 0 → 100644
  1 +/*
  2 + * QEMU Grackle (heathrow PPC) PCI host
  3 + *
  4 + * Copyright (c) 2006 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +
  25 +#include "vl.h"
  26 +typedef target_phys_addr_t pci_addr_t;
  27 +#include "pci_host.h"
  28 +
  29 +typedef PCIHostState GrackleState;
  30 +
  31 +static void pci_grackle_config_writel (void *opaque, target_phys_addr_t addr,
  32 + uint32_t val)
  33 +{
  34 + GrackleState *s = opaque;
  35 +#ifdef TARGET_WORDS_BIGENDIAN
  36 + val = bswap32(val);
  37 +#endif
  38 + s->config_reg = val;
  39 +}
  40 +
  41 +static uint32_t pci_grackle_config_readl (void *opaque, target_phys_addr_t addr)
  42 +{
  43 + GrackleState *s = opaque;
  44 + uint32_t val;
  45 +
  46 + val = s->config_reg;
  47 +#ifdef TARGET_WORDS_BIGENDIAN
  48 + val = bswap32(val);
  49 +#endif
  50 + return val;
  51 +}
  52 +
  53 +static CPUWriteMemoryFunc *pci_grackle_config_write[] = {
  54 + &pci_grackle_config_writel,
  55 + &pci_grackle_config_writel,
  56 + &pci_grackle_config_writel,
  57 +};
  58 +
  59 +static CPUReadMemoryFunc *pci_grackle_config_read[] = {
  60 + &pci_grackle_config_readl,
  61 + &pci_grackle_config_readl,
  62 + &pci_grackle_config_readl,
  63 +};
  64 +
  65 +static CPUWriteMemoryFunc *pci_grackle_write[] = {
  66 + &pci_host_data_writeb,
  67 + &pci_host_data_writew,
  68 + &pci_host_data_writel,
  69 +};
  70 +
  71 +static CPUReadMemoryFunc *pci_grackle_read[] = {
  72 + &pci_host_data_readb,
  73 + &pci_host_data_readw,
  74 + &pci_host_data_readl,
  75 +};
  76 +
  77 +/* XXX: we do not simulate the hardware - we rely on the BIOS to
  78 + set correctly for irq line field */
  79 +static void pci_grackle_set_irq(PCIDevice *d, void *pic, int irq_num, int level)
  80 +{
  81 + heathrow_pic_set_irq(pic, d->config[PCI_INTERRUPT_LINE], level);
  82 +}
  83 +
  84 +PCIBus *pci_grackle_init(uint32_t base, void *pic)
  85 +{
  86 + GrackleState *s;
  87 + PCIDevice *d;
  88 + int pci_mem_config, pci_mem_data;
  89 +
  90 + s = qemu_mallocz(sizeof(GrackleState));
  91 + s->bus = pci_register_bus(pci_grackle_set_irq, pic, 0);
  92 +
  93 + pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read,
  94 + pci_grackle_config_write, s);
  95 + pci_mem_data = cpu_register_io_memory(0, pci_grackle_read,
  96 + pci_grackle_write, s);
  97 + cpu_register_physical_memory(base, 0x1000, pci_mem_config);
  98 + cpu_register_physical_memory(base + 0x00200000, 0x1000, pci_mem_data);
  99 + d = pci_register_device(s->bus, "Grackle host bridge", sizeof(PCIDevice),
  100 + 0, NULL, NULL);
  101 + d->config[0x00] = 0x57; // vendor_id
  102 + d->config[0x01] = 0x10;
  103 + d->config[0x02] = 0x02; // device_id
  104 + d->config[0x03] = 0x00;
  105 + d->config[0x08] = 0x00; // revision
  106 + d->config[0x09] = 0x01;
  107 + d->config[0x0a] = 0x00; // class_sub = host
  108 + d->config[0x0b] = 0x06; // class_base = PCI_bridge
  109 + d->config[0x0e] = 0x00; // header_type
  110 +
  111 + d->config[0x18] = 0x00; // primary_bus
  112 + d->config[0x19] = 0x01; // secondary_bus
  113 + d->config[0x1a] = 0x00; // subordinate_bus
  114 + d->config[0x1c] = 0x00;
  115 + d->config[0x1d] = 0x00;
  116 +
  117 + d->config[0x20] = 0x00; // memory_base
  118 + d->config[0x21] = 0x00;
  119 + d->config[0x22] = 0x01; // memory_limit
  120 + d->config[0x23] = 0x00;
  121 +
  122 + d->config[0x24] = 0x00; // prefetchable_memory_base
  123 + d->config[0x25] = 0x00;
  124 + d->config[0x26] = 0x00; // prefetchable_memory_limit
  125 + d->config[0x27] = 0x00;
  126 +
  127 +#if 0
  128 + /* PCI2PCI bridge same values as PearPC - check this */
  129 + d->config[0x00] = 0x11; // vendor_id
  130 + d->config[0x01] = 0x10;
  131 + d->config[0x02] = 0x26; // device_id
  132 + d->config[0x03] = 0x00;
  133 + d->config[0x08] = 0x02; // revision
  134 + d->config[0x0a] = 0x04; // class_sub = pci2pci
  135 + d->config[0x0b] = 0x06; // class_base = PCI_bridge
  136 + d->config[0x0e] = 0x01; // header_type
  137 +
  138 + d->config[0x18] = 0x0; // primary_bus
  139 + d->config[0x19] = 0x1; // secondary_bus
  140 + d->config[0x1a] = 0x1; // subordinate_bus
  141 + d->config[0x1c] = 0x10; // io_base
  142 + d->config[0x1d] = 0x20; // io_limit
  143 +
  144 + d->config[0x20] = 0x80; // memory_base
  145 + d->config[0x21] = 0x80;
  146 + d->config[0x22] = 0x90; // memory_limit
  147 + d->config[0x23] = 0x80;
  148 +
  149 + d->config[0x24] = 0x00; // prefetchable_memory_base
  150 + d->config[0x25] = 0x84;
  151 + d->config[0x26] = 0x00; // prefetchable_memory_limit
  152 + d->config[0x27] = 0x85;
  153 +#endif
  154 + return s->bus;
  155 +}
  156 +
... ...
hw/ide.c
... ... @@ -2490,7 +2490,7 @@ void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
2490 2490  
2491 2491 /* hd_table must contain 4 block drivers */
2492 2492 /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
2493   -void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table)
  2493 +void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn)
2494 2494 {
2495 2495 PCIIDEState *d;
2496 2496 uint8_t *pci_conf;
... ... @@ -2498,7 +2498,7 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table)
2498 2498 /* register a function 1 of PIIX3 */
2499 2499 d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE",
2500 2500 sizeof(PCIIDEState),
2501   - ((PCIDevice *)piix3_state)->devfn + 1,
  2501 + devfn,
2502 2502 NULL, NULL);
2503 2503 d->type = IDE_TYPE_PIIX3;
2504 2504  
... ...
... ... @@ -611,6 +611,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
611 611 unsigned long bios_offset, vga_bios_offset;
612 612 int bios_size, isa_bios_size;
613 613 PCIBus *pci_bus;
  614 + int piix3_devfn;
614 615 CPUState *env;
615 616 NICInfo *nd;
616 617  
... ... @@ -741,7 +742,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
741 742  
742 743 if (pci_enabled) {
743 744 pci_bus = i440fx_init();
744   - piix3_init(pci_bus);
  745 + piix3_devfn = piix3_init(pci_bus);
745 746 } else {
746 747 pci_bus = NULL;
747 748 }
... ... @@ -813,7 +814,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
813 814 }
814 815  
815 816 if (pci_enabled) {
816   - pci_piix3_ide_init(pci_bus, bs_table);
  817 + pci_piix3_ide_init(pci_bus, bs_table, piix3_devfn + 1);
817 818 } else {
818 819 for(i = 0; i < 2; i++) {
819 820 isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
... ... @@ -832,12 +833,12 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
832 833 cmos_init(ram_size, boot_device, bs_table);
833 834  
834 835 if (pci_enabled && usb_enabled) {
835   - usb_uhci_init(pci_bus, usb_root_ports);
  836 + usb_uhci_init(pci_bus, usb_root_ports, piix3_devfn + 2);
836 837 usb_attach(usb_root_ports[0], vm_usb_hub);
837 838 }
838 839  
839 840 if (pci_enabled && acpi_enabled) {
840   - piix4_pm_init(pci_bus);
  841 + piix4_pm_init(pci_bus, piix3_devfn + 3);
841 842 }
842 843 /* must be done after all PCI devices are instanciated */
843 844 /* XXX: should be done in the Bochs BIOS */
... ...
hw/pci.c
... ... @@ -25,25 +25,10 @@
25 25  
26 26 //#define DEBUG_PCI
27 27  
28   -#define PCI_VENDOR_ID 0x00 /* 16 bits */
29   -#define PCI_DEVICE_ID 0x02 /* 16 bits */
30   -#define PCI_COMMAND 0x04 /* 16 bits */
31   -#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
32   -#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
33   -#define PCI_CLASS_DEVICE 0x0a /* Device class */
34   -#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
35   -#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
36   -#define PCI_MIN_GNT 0x3e /* 8 bits */
37   -#define PCI_MAX_LAT 0x3f /* 8 bits */
38   -
39   -/* just used for simpler irq handling. */
40   -#define PCI_DEVICES_MAX 64
41   -#define PCI_IRQ_WORDS ((PCI_DEVICES_MAX + 31) / 32)
42   -
43 28 struct PCIBus {
44 29 int bus_num;
45 30 int devfn_min;
46   - void (*set_irq)(PCIDevice *pci_dev, int irq_num, int level);
  31 + pci_set_irq_fn set_irq;
47 32 uint32_t config_reg; /* XXX: suppress */
48 33 /* low level pic */
49 34 SetIRQFunc *low_set_irq;
... ... @@ -53,17 +38,24 @@ struct PCIBus {
53 38  
54 39 target_phys_addr_t pci_mem_base;
55 40 static int pci_irq_index;
56   -static uint32_t pci_irq_levels[4][PCI_IRQ_WORDS];
57 41 static PCIBus *first_bus;
58 42  
59   -static PCIBus *pci_register_bus(void)
  43 +PCIBus *pci_register_bus(pci_set_irq_fn set_irq, void *pic, int devfn_min)
60 44 {
61 45 PCIBus *bus;
62 46 bus = qemu_mallocz(sizeof(PCIBus));
  47 + bus->set_irq = set_irq;
  48 + bus->irq_opaque = pic;
  49 + bus->devfn_min = devfn_min;
63 50 first_bus = bus;
64 51 return bus;
65 52 }
66 53  
  54 +int pci_bus_num(PCIBus *s)
  55 +{
  56 + return s->bus_num;
  57 +}
  58 +
67 59 void generic_pci_save(QEMUFile* f, void *opaque)
68 60 {
69 61 PCIDevice* s=(PCIDevice*)opaque;
... ... @@ -141,16 +133,9 @@ void pci_register_io_region(PCIDevice *pci_dev, int region_num,
141 133 *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
142 134 }
143 135  
144   -static void pci_addr_writel(void* opaque, uint32_t addr, uint32_t val)
145   -{
146   - PCIBus *s = opaque;
147   - s->config_reg = val;
148   -}
149   -
150   -static uint32_t pci_addr_readl(void* opaque, uint32_t addr)
  136 +target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
151 137 {
152   - PCIBus *s = opaque;
153   - return s->config_reg;
  138 + return addr + pci_mem_base;
154 139 }
155 140  
156 141 static void pci_update_mappings(PCIDevice *d)
... ... @@ -218,7 +203,7 @@ static void pci_update_mappings(PCIDevice *d)
218 203 isa_unassign_ioport(r->addr, r->size);
219 204 }
220 205 } else {
221   - cpu_register_physical_memory(r->addr + pci_mem_base,
  206 + cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
222 207 r->size,
223 208 IO_MEM_UNASSIGNED);
224 209 }
... ... @@ -346,8 +331,7 @@ void pci_default_write_config(PCIDevice *d,
346 331 }
347 332 }
348 333  
349   -static void pci_data_write(void *opaque, uint32_t addr,
350   - uint32_t val, int len)
  334 +void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
351 335 {
352 336 PCIBus *s = opaque;
353 337 PCIDevice *pci_dev;
... ... @@ -355,18 +339,15 @@ static void pci_data_write(void *opaque, uint32_t addr,
355 339  
356 340 #if defined(DEBUG_PCI) && 0
357 341 printf("pci_data_write: addr=%08x val=%08x len=%d\n",
358   - s->config_reg, val, len);
  342 + addr, val, len);
359 343 #endif
360   - if (!(s->config_reg & (1 << 31))) {
361   - return;
362   - }
363   - bus_num = (s->config_reg >> 16) & 0xff;
  344 + bus_num = (addr >> 16) & 0xff;
364 345 if (bus_num != 0)
365 346 return;
366   - pci_dev = s->devices[(s->config_reg >> 8) & 0xff];
  347 + pci_dev = s->devices[(addr >> 8) & 0xff];
367 348 if (!pci_dev)
368 349 return;
369   - config_addr = (s->config_reg & 0xfc) | (addr & 3);
  350 + config_addr = addr & 0xff;
370 351 #if defined(DEBUG_PCI)
371 352 printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
372 353 pci_dev->name, config_addr, val, len);
... ... @@ -374,20 +355,17 @@ static void pci_data_write(void *opaque, uint32_t addr,
374 355 pci_dev->config_write(pci_dev, config_addr, val, len);
375 356 }
376 357  
377   -static uint32_t pci_data_read(void *opaque, uint32_t addr,
378   - int len)
  358 +uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
379 359 {
380 360 PCIBus *s = opaque;
381 361 PCIDevice *pci_dev;
382 362 int config_addr, bus_num;
383 363 uint32_t val;
384 364  
385   - if (!(s->config_reg & (1 << 31)))
386   - goto fail;
387   - bus_num = (s->config_reg >> 16) & 0xff;
  365 + bus_num = (addr >> 16) & 0xff;
388 366 if (bus_num != 0)
389 367 goto fail;
390   - pci_dev = s->devices[(s->config_reg >> 8) & 0xff];
  368 + pci_dev = s->devices[(addr >> 8) & 0xff];
391 369 if (!pci_dev) {
392 370 fail:
393 371 switch(len) {
... ... @@ -404,7 +382,7 @@ static uint32_t pci_data_read(void *opaque, uint32_t addr,
404 382 }
405 383 goto the_end;
406 384 }
407   - config_addr = (s->config_reg & 0xfc) | (addr & 3);
  385 + config_addr = addr & 0xff;
408 386 val = pci_dev->config_read(pci_dev, config_addr, len);
409 387 #if defined(DEBUG_PCI)
410 388 printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
... ... @@ -413,1431 +391,87 @@ static uint32_t pci_data_read(void *opaque, uint32_t addr,
413 391 the_end:
414 392 #if defined(DEBUG_PCI) && 0
415 393 printf("pci_data_read: addr=%08x val=%08x len=%d\n",
416   - s->config_reg, val, len);
  394 + addr, val, len);
417 395 #endif
418 396 return val;
419 397 }
420 398  
421   -static void pci_data_writeb(void* opaque, uint32_t addr, uint32_t val)
422   -{
423   - pci_data_write(opaque, addr, val, 1);
424   -}
425   -
426   -static void pci_data_writew(void* opaque, uint32_t addr, uint32_t val)
427   -{
428   - pci_data_write(opaque, addr, val, 2);
429   -}
430   -
431   -static void pci_data_writel(void* opaque, uint32_t addr, uint32_t val)
432   -{
433   - pci_data_write(opaque, addr, val, 4);
434   -}
435   -
436   -static uint32_t pci_data_readb(void* opaque, uint32_t addr)
437   -{
438   - return pci_data_read(opaque, addr, 1);
439   -}
440   -
441   -static uint32_t pci_data_readw(void* opaque, uint32_t addr)
442   -{
443   - return pci_data_read(opaque, addr, 2);
444   -}
445   -
446   -static uint32_t pci_data_readl(void* opaque, uint32_t addr)
447   -{
448   - return pci_data_read(opaque, addr, 4);
449   -}
450   -
451   -/* i440FX PCI bridge */
452   -
453   -static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level);
  399 +/***********************************************************/
  400 +/* generic PCI irq support */
454 401  
455   -PCIBus *i440fx_init(void)
  402 +/* 0 <= irq_num <= 3. level must be 0 or 1 */
  403 +void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
456 404 {
457   - PCIBus *s;
458   - PCIDevice *d;
459   -
460   - s = pci_register_bus();
461   - s->set_irq = piix3_set_irq;
462   -
463   - register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s);
464   - register_ioport_read(0xcf8, 4, 4, pci_addr_readl, s);
465   -
466   - register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s);
467   - register_ioport_write(0xcfc, 4, 2, pci_data_writew, s);
468   - register_ioport_write(0xcfc, 4, 4, pci_data_writel, s);
469   - register_ioport_read(0xcfc, 4, 1, pci_data_readb, s);
470   - register_ioport_read(0xcfc, 4, 2, pci_data_readw, s);
471   - register_ioport_read(0xcfc, 4, 4, pci_data_readl, s);
472   -
473   - d = pci_register_device(s, "i440FX", sizeof(PCIDevice), 0,
474   - NULL, NULL);
475   -
476   - d->config[0x00] = 0x86; // vendor_id
477   - d->config[0x01] = 0x80;
478   - d->config[0x02] = 0x37; // device_id
479   - d->config[0x03] = 0x12;
480   - d->config[0x08] = 0x02; // revision
481   - d->config[0x0a] = 0x00; // class_sub = host2pci
482   - d->config[0x0b] = 0x06; // class_base = PCI_bridge
483   - d->config[0x0e] = 0x00; // header_type
484   - return s;
  405 + PCIBus *bus = pci_dev->bus;
  406 + bus->set_irq(pci_dev, bus->irq_opaque, irq_num, level);
485 407 }
486 408  
487   -/* PIIX3 PCI to ISA bridge */
488   -
489   -typedef struct PIIX3State {
490   - PCIDevice dev;
491   -} PIIX3State;
492   -
493   -PIIX3State *piix3_state;
  409 +/***********************************************************/
  410 +/* monitor info on PCI */
494 411  
495   -/* return the global irq number corresponding to a given device irq
496   - pin. We could also use the bus number to have a more precise
497   - mapping. */
498   -static inline int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
  412 +static void pci_info_device(PCIDevice *d)
499 413 {
500   - int slot_addend;
501   - slot_addend = (pci_dev->devfn >> 3) - 1;
502   - return (irq_num + slot_addend) & 3;
503   -}
  414 + int i, class;
  415 + PCIIORegion *r;
504 416  
505   -static inline int get_pci_irq_level(int irq_num)
506   -{
507   - int pic_level;
508   -#if (PCI_IRQ_WORDS == 2)
509   - pic_level = ((pci_irq_levels[irq_num][0] |
510   - pci_irq_levels[irq_num][1]) != 0);
511   -#else
512   - {
513   - int i;
514   - pic_level = 0;
515   - for(i = 0; i < PCI_IRQ_WORDS; i++) {
516   - if (pci_irq_levels[irq_num][i]) {
517   - pic_level = 1;
518   - break;
519   - }
520   - }
  417 + term_printf(" Bus %2d, device %3d, function %d:\n",
  418 + d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
  419 + class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
  420 + term_printf(" ");
  421 + switch(class) {
  422 + case 0x0101:
  423 + term_printf("IDE controller");
  424 + break;
  425 + case 0x0200:
  426 + term_printf("Ethernet controller");
  427 + break;
  428 + case 0x0300:
  429 + term_printf("VGA controller");
  430 + break;
  431 + default:
  432 + term_printf("Class %04x", class);
  433 + break;
521 434 }
522   -#endif
523   - return pic_level;
524   -}
525   -
526   -static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level)
527   -{
528   - int irq_index, shift, pic_irq, pic_level;
529   - uint32_t *p;
530   -
531   - irq_num = pci_slot_get_pirq(pci_dev, irq_num);
532   - irq_index = pci_dev->irq_index;
533   - p = &pci_irq_levels[irq_num][irq_index >> 5];
534   - shift = (irq_index & 0x1f);
535   - *p = (*p & ~(1 << shift)) | (level << shift);
  435 + term_printf(": PCI device %04x:%04x\n",
  436 + le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
  437 + le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
536 438  
537   - /* now we change the pic irq level according to the piix irq mappings */
538   - /* XXX: optimize */
539   - pic_irq = piix3_state->dev.config[0x60 + irq_num];
540   - if (pic_irq < 16) {
541   - /* the pic level is the logical OR of all the PCI irqs mapped
542   - to it */
543   - pic_level = 0;
544   - if (pic_irq == piix3_state->dev.config[0x60])
545   - pic_level |= get_pci_irq_level(0);
546   - if (pic_irq == piix3_state->dev.config[0x61])
547   - pic_level |= get_pci_irq_level(1);
548   - if (pic_irq == piix3_state->dev.config[0x62])
549   - pic_level |= get_pci_irq_level(2);
550   - if (pic_irq == piix3_state->dev.config[0x63])
551   - pic_level |= get_pci_irq_level(3);
552   - pic_set_irq(pic_irq, pic_level);
  439 + if (d->config[PCI_INTERRUPT_PIN] != 0) {
  440 + term_printf(" IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);
553 441 }
554   -}
555   -
556   -static void piix3_reset(PIIX3State *d)
557   -{
558   - uint8_t *pci_conf = d->dev.config;
559   -
560   - pci_conf[0x04] = 0x07; // master, memory and I/O
561   - pci_conf[0x05] = 0x00;
562   - pci_conf[0x06] = 0x00;
563   - pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
564   - pci_conf[0x4c] = 0x4d;
565   - pci_conf[0x4e] = 0x03;
566   - pci_conf[0x4f] = 0x00;
567   - pci_conf[0x60] = 0x80;
568   - pci_conf[0x69] = 0x02;
569   - pci_conf[0x70] = 0x80;
570   - pci_conf[0x76] = 0x0c;
571   - pci_conf[0x77] = 0x0c;
572   - pci_conf[0x78] = 0x02;
573   - pci_conf[0x79] = 0x00;
574   - pci_conf[0x80] = 0x00;
575   - pci_conf[0x82] = 0x00;
576   - pci_conf[0xa0] = 0x08;
577   - pci_conf[0xa0] = 0x08;
578   - pci_conf[0xa2] = 0x00;
579   - pci_conf[0xa3] = 0x00;
580   - pci_conf[0xa4] = 0x00;
581   - pci_conf[0xa5] = 0x00;
582   - pci_conf[0xa6] = 0x00;
583   - pci_conf[0xa7] = 0x00;
584   - pci_conf[0xa8] = 0x0f;
585   - pci_conf[0xaa] = 0x00;
586   - pci_conf[0xab] = 0x00;
587   - pci_conf[0xac] = 0x00;
588   - pci_conf[0xae] = 0x00;
589   -}
590   -
591   -void piix3_init(PCIBus *bus)
592   -{
593   - PIIX3State *d;
594   - uint8_t *pci_conf;
595   -
596   - d = (PIIX3State *)pci_register_device(bus, "PIIX3", sizeof(PIIX3State),
597   - -1, NULL, NULL);
598   - register_savevm("PIIX3", 0, 1, generic_pci_save, generic_pci_load, d);
599   -
600   - piix3_state = d;
601   - pci_conf = d->dev.config;
602   -
603   - pci_conf[0x00] = 0x86; // Intel
604   - pci_conf[0x01] = 0x80;
605   - pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
606   - pci_conf[0x03] = 0x70;
607   - pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA
608   - pci_conf[0x0b] = 0x06; // class_base = PCI_bridge
609   - pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
610   -
611   - piix3_reset(d);
612   -}
613   -
614   -/* PREP pci init */
615   -
616   -static inline void set_config(PCIBus *s, target_phys_addr_t addr)
617   -{
618   - int devfn, i;
619   -
620   - for(i = 0; i < 11; i++) {
621   - if ((addr & (1 << (11 + i))) != 0)
622   - break;
  442 + for(i = 0;i < PCI_NUM_REGIONS; i++) {
  443 + r = &d->io_regions[i];
  444 + if (r->size != 0) {
  445 + term_printf(" BAR%d: ", i);
  446 + if (r->type & PCI_ADDRESS_SPACE_IO) {
  447 + term_printf("I/O at 0x%04x [0x%04x].\n",
  448 + r->addr, r->addr + r->size - 1);
  449 + } else {
  450 + term_printf("32 bit memory at 0x%08x [0x%08x].\n",
  451 + r->addr, r->addr + r->size - 1);
  452 + }
  453 + }
623 454 }
624   - devfn = ((addr >> 8) & 7) | (i << 3);
625   - s->config_reg = 0x80000000 | (addr & 0xfc) | (devfn << 8);
626   -}
627   -
628   -static void PPC_PCIIO_writeb (void *opaque, target_phys_addr_t addr, uint32_t val)
629   -{
630   - PCIBus *s = opaque;
631   - set_config(s, addr);
632   - pci_data_write(s, addr, val, 1);
633   -}
634   -
635   -static void PPC_PCIIO_writew (void *opaque, target_phys_addr_t addr, uint32_t val)
636   -{
637   - PCIBus *s = opaque;
638   - set_config(s, addr);
639   -#ifdef TARGET_WORDS_BIGENDIAN
640   - val = bswap16(val);
641   -#endif
642   - pci_data_write(s, addr, val, 2);
643   -}
644   -
645   -static void PPC_PCIIO_writel (void *opaque, target_phys_addr_t addr, uint32_t val)
646   -{
647   - PCIBus *s = opaque;
648   - set_config(s, addr);
649   -#ifdef TARGET_WORDS_BIGENDIAN
650   - val = bswap32(val);
651   -#endif
652   - pci_data_write(s, addr, val, 4);
653   -}
654   -
655   -static uint32_t PPC_PCIIO_readb (void *opaque, target_phys_addr_t addr)
656   -{
657   - PCIBus *s = opaque;
658   - uint32_t val;
659   - set_config(s, addr);
660   - val = pci_data_read(s, addr, 1);
661   - return val;
662   -}
663   -
664   -static uint32_t PPC_PCIIO_readw (void *opaque, target_phys_addr_t addr)
665   -{
666   - PCIBus *s = opaque;
667   - uint32_t val;
668   - set_config(s, addr);
669   - val = pci_data_read(s, addr, 2);
670   -#ifdef TARGET_WORDS_BIGENDIAN
671   - val = bswap16(val);
672   -#endif
673   - return val;
674   -}
675   -
676   -static uint32_t PPC_PCIIO_readl (void *opaque, target_phys_addr_t addr)
677   -{
678   - PCIBus *s = opaque;
679   - uint32_t val;
680   - set_config(s, addr);
681   - val = pci_data_read(s, addr, 4);
682   -#ifdef TARGET_WORDS_BIGENDIAN
683   - val = bswap32(val);
684   -#endif
685   - return val;
686   -}
687   -
688   -static CPUWriteMemoryFunc *PPC_PCIIO_write[] = {
689   - &PPC_PCIIO_writeb,
690   - &PPC_PCIIO_writew,
691   - &PPC_PCIIO_writel,
692   -};
693   -
694   -static CPUReadMemoryFunc *PPC_PCIIO_read[] = {
695   - &PPC_PCIIO_readb,
696   - &PPC_PCIIO_readw,
697   - &PPC_PCIIO_readl,
698   -};
699   -
700   -static void prep_set_irq(PCIDevice *d, int irq_num, int level)
701   -{
702   - /* XXX: we do not simulate the hardware - we rely on the BIOS to
703   - set correctly for irq line field */
704   - pic_set_irq(d->config[PCI_INTERRUPT_LINE], level);
705   -}
706   -
707   -PCIBus *pci_prep_init(void)
708   -{
709   - PCIBus *s;
710   - PCIDevice *d;
711   - int PPC_io_memory;
712   -
713   - s = pci_register_bus();
714   - s->set_irq = prep_set_irq;
715   -
716   - register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s);
717   - register_ioport_read(0xcf8, 4, 4, pci_addr_readl, s);
718   -
719   - register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s);
720   - register_ioport_write(0xcfc, 4, 2, pci_data_writew, s);
721   - register_ioport_write(0xcfc, 4, 4, pci_data_writel, s);
722   - register_ioport_read(0xcfc, 4, 1, pci_data_readb, s);
723   - register_ioport_read(0xcfc, 4, 2, pci_data_readw, s);
724   - register_ioport_read(0xcfc, 4, 4, pci_data_readl, s);
725   -
726   - PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read,
727   - PPC_PCIIO_write, s);
728   - cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);
729   -
730   - /* PCI host bridge */
731   - d = pci_register_device(s, "PREP Host Bridge - Motorola Raven",
732   - sizeof(PCIDevice), 0, NULL, NULL);
733   - d->config[0x00] = 0x57; // vendor_id : Motorola
734   - d->config[0x01] = 0x10;
735   - d->config[0x02] = 0x01; // device_id : Raven
736   - d->config[0x03] = 0x48;
737   - d->config[0x08] = 0x00; // revision
738   - d->config[0x0A] = 0x00; // class_sub = pci host
739   - d->config[0x0B] = 0x06; // class_base = PCI_bridge
740   - d->config[0x0C] = 0x08; // cache_line_size
741   - d->config[0x0D] = 0x10; // latency_timer
742   - d->config[0x0E] = 0x00; // header_type
743   - d->config[0x34] = 0x00; // capabilities_pointer
744   -
745   - return s;
746   -}
747   -
748   -
749   -/* Grackle PCI host */
750   -static void pci_grackle_config_writel (void *opaque, target_phys_addr_t addr,
751   - uint32_t val)
752   -{
753   - PCIBus *s = opaque;
754   -#ifdef TARGET_WORDS_BIGENDIAN
755   - val = bswap32(val);
756   -#endif
757   - s->config_reg = val;
758   -}
759   -
760   -static uint32_t pci_grackle_config_readl (void *opaque, target_phys_addr_t addr)
761   -{
762   - PCIBus *s = opaque;
763   - uint32_t val;
764   -
765   - val = s->config_reg;
766   -#ifdef TARGET_WORDS_BIGENDIAN
767   - val = bswap32(val);
768   -#endif
769   - return val;
770   -}
771   -
772   -static CPUWriteMemoryFunc *pci_grackle_config_write[] = {
773   - &pci_grackle_config_writel,
774   - &pci_grackle_config_writel,
775   - &pci_grackle_config_writel,
776   -};
777   -
778   -static CPUReadMemoryFunc *pci_grackle_config_read[] = {
779   - &pci_grackle_config_readl,
780   - &pci_grackle_config_readl,
781   - &pci_grackle_config_readl,
782   -};
783   -
784   -static void pci_grackle_writeb (void *opaque, target_phys_addr_t addr,
785   - uint32_t val)
786   -{
787   - PCIBus *s = opaque;
788   - pci_data_write(s, addr, val, 1);
789   -}
790   -
791   -static void pci_grackle_writew (void *opaque, target_phys_addr_t addr,
792   - uint32_t val)
793   -{
794   - PCIBus *s = opaque;
795   -#ifdef TARGET_WORDS_BIGENDIAN
796   - val = bswap16(val);
797   -#endif
798   - pci_data_write(s, addr, val, 2);
799   -}
800   -
801   -static void pci_grackle_writel (void *opaque, target_phys_addr_t addr,
802   - uint32_t val)
803   -{
804   - PCIBus *s = opaque;
805   -#ifdef TARGET_WORDS_BIGENDIAN
806   - val = bswap32(val);
807   -#endif
808   - pci_data_write(s, addr, val, 4);
809   -}
810   -
811   -static uint32_t pci_grackle_readb (void *opaque, target_phys_addr_t addr)
812   -{
813   - PCIBus *s = opaque;
814   - uint32_t val;
815   - val = pci_data_read(s, addr, 1);
816   - return val;
817   -}
818   -
819   -static uint32_t pci_grackle_readw (void *opaque, target_phys_addr_t addr)
820   -{
821   - PCIBus *s = opaque;
822   - uint32_t val;
823   - val = pci_data_read(s, addr, 2);
824   -#ifdef TARGET_WORDS_BIGENDIAN
825   - val = bswap16(val);
826   -#endif
827   - return val;
828   -}
829   -
830   -static uint32_t pci_grackle_readl (void *opaque, target_phys_addr_t addr)
831   -{
832   - PCIBus *s = opaque;
833   - uint32_t val;
834   -
835   - val = pci_data_read(s, addr, 4);
836   -#ifdef TARGET_WORDS_BIGENDIAN
837   - val = bswap32(val);
838   -#endif
839   - return val;
840   -}
841   -
842   -static CPUWriteMemoryFunc *pci_grackle_write[] = {
843   - &pci_grackle_writeb,
844   - &pci_grackle_writew,
845   - &pci_grackle_writel,
846   -};
847   -
848   -static CPUReadMemoryFunc *pci_grackle_read[] = {
849   - &pci_grackle_readb,
850   - &pci_grackle_readw,
851   - &pci_grackle_readl,
852   -};
853   -
854   -void pci_set_pic(PCIBus *bus, SetIRQFunc *set_irq, void *irq_opaque)
855   -{
856   - bus->low_set_irq = set_irq;
857   - bus->irq_opaque = irq_opaque;
858   -}
859   -
860   -/* XXX: we do not simulate the hardware - we rely on the BIOS to
861   - set correctly for irq line field */
862   -static void pci_set_irq_simple(PCIDevice *d, int irq_num, int level)
863   -{
864   - PCIBus *s = d->bus;
865   - s->low_set_irq(s->irq_opaque, d->config[PCI_INTERRUPT_LINE], level);
866 455 }
867 456  
868   -PCIBus *pci_grackle_init(uint32_t base)
  457 +void pci_for_each_device(void (*fn)(PCIDevice *d))
869 458 {
870   - PCIBus *s;
  459 + PCIBus *bus = first_bus;
871 460 PCIDevice *d;
872   - int pci_mem_config, pci_mem_data;
873   -
874   - s = pci_register_bus();
875   - s->set_irq = pci_set_irq_simple;
876   -
877   - pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read,
878   - pci_grackle_config_write, s);
879   - pci_mem_data = cpu_register_io_memory(0, pci_grackle_read,
880   - pci_grackle_write, s);
881   - cpu_register_physical_memory(base, 0x1000, pci_mem_config);
882   - cpu_register_physical_memory(base + 0x00200000, 0x1000, pci_mem_data);
883   - d = pci_register_device(s, "Grackle host bridge", sizeof(PCIDevice),
884   - 0, NULL, NULL);
885   - d->config[0x00] = 0x57; // vendor_id
886   - d->config[0x01] = 0x10;
887   - d->config[0x02] = 0x02; // device_id
888   - d->config[0x03] = 0x00;
889   - d->config[0x08] = 0x00; // revision
890   - d->config[0x09] = 0x01;
891   - d->config[0x0a] = 0x00; // class_sub = host
892   - d->config[0x0b] = 0x06; // class_base = PCI_bridge
893   - d->config[0x0e] = 0x00; // header_type
894   -
895   - d->config[0x18] = 0x00; // primary_bus
896   - d->config[0x19] = 0x01; // secondary_bus
897   - d->config[0x1a] = 0x00; // subordinate_bus
898   - d->config[0x1c] = 0x00;
899   - d->config[0x1d] = 0x00;
900   -
901   - d->config[0x20] = 0x00; // memory_base
902   - d->config[0x21] = 0x00;
903   - d->config[0x22] = 0x01; // memory_limit
904   - d->config[0x23] = 0x00;
905   -
906   - d->config[0x24] = 0x00; // prefetchable_memory_base
907   - d->config[0x25] = 0x00;
908   - d->config[0x26] = 0x00; // prefetchable_memory_limit
909   - d->config[0x27] = 0x00;
910   -
911   -#if 0
912   - /* PCI2PCI bridge same values as PearPC - check this */
913   - d->config[0x00] = 0x11; // vendor_id
914   - d->config[0x01] = 0x10;
915   - d->config[0x02] = 0x26; // device_id
916   - d->config[0x03] = 0x00;
917   - d->config[0x08] = 0x02; // revision
918   - d->config[0x0a] = 0x04; // class_sub = pci2pci
919   - d->config[0x0b] = 0x06; // class_base = PCI_bridge
920   - d->config[0x0e] = 0x01; // header_type
921   -
922   - d->config[0x18] = 0x0; // primary_bus
923   - d->config[0x19] = 0x1; // secondary_bus
924   - d->config[0x1a] = 0x1; // subordinate_bus
925   - d->config[0x1c] = 0x10; // io_base
926   - d->config[0x1d] = 0x20; // io_limit
927   -
928   - d->config[0x20] = 0x80; // memory_base
929   - d->config[0x21] = 0x80;
930   - d->config[0x22] = 0x90; // memory_limit
931   - d->config[0x23] = 0x80;
  461 + int devfn;
932 462  
933   - d->config[0x24] = 0x00; // prefetchable_memory_base
934   - d->config[0x25] = 0x84;
935   - d->config[0x26] = 0x00; // prefetchable_memory_limit
936   - d->config[0x27] = 0x85;
937   -#endif
938   - return s;
939   -}
940   -
941   -/* Uninorth PCI host (for all Mac99 and newer machines */
942   -static void pci_unin_main_config_writel (void *opaque, target_phys_addr_t addr,
943   - uint32_t val)
944   -{
945   - PCIBus *s = opaque;
946   - int i;
947   -
948   -#ifdef TARGET_WORDS_BIGENDIAN
949   - val = bswap32(val);
950   -#endif
951   -
952   - for (i = 11; i < 32; i++) {
953   - if ((val & (1 << i)) != 0)
954   - break;
  463 + if (bus) {
  464 + for(devfn = 0; devfn < 256; devfn++) {
  465 + d = bus->devices[devfn];
  466 + if (d)
  467 + fn(d);
  468 + }
955 469 }
956   -#if 0
957   - s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11);
958   -#else
959   - s->config_reg = 0x80000000 | (0 << 16) | (val & 0x7FC) | (i << 11);
960   -#endif
961 470 }
962 471  
963   -static uint32_t pci_unin_main_config_readl (void *opaque,
964   - target_phys_addr_t addr)
  472 +void pci_info(void)
965 473 {
966   - PCIBus *s = opaque;
967   - uint32_t val;
968   - int devfn;
969   -
970   - devfn = (s->config_reg >> 8) & 0xFF;
971   - val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
972   -#ifdef TARGET_WORDS_BIGENDIAN
973   - val = bswap32(val);
974   -#endif
975   -
976   - return val;
977   -}
978   -
979   -static CPUWriteMemoryFunc *pci_unin_main_config_write[] = {
980   - &pci_unin_main_config_writel,
981   - &pci_unin_main_config_writel,
982   - &pci_unin_main_config_writel,
983   -};
984   -
985   -static CPUReadMemoryFunc *pci_unin_main_config_read[] = {
986   - &pci_unin_main_config_readl,
987   - &pci_unin_main_config_readl,
988   - &pci_unin_main_config_readl,
989   -};
990   -
991   -static void pci_unin_main_writeb (void *opaque, target_phys_addr_t addr,
992   - uint32_t val)
993   -{
994   - PCIBus *s = opaque;
995   - pci_data_write(s, addr & 7, val, 1);
996   -}
997   -
998   -static void pci_unin_main_writew (void *opaque, target_phys_addr_t addr,
999   - uint32_t val)
1000   -{
1001   - PCIBus *s = opaque;
1002   -#ifdef TARGET_WORDS_BIGENDIAN
1003   - val = bswap16(val);
1004   -#endif
1005   - pci_data_write(s, addr & 7, val, 2);
1006   -}
1007   -
1008   -static void pci_unin_main_writel (void *opaque, target_phys_addr_t addr,
1009   - uint32_t val)
1010   -{
1011   - PCIBus *s = opaque;
1012   -#ifdef TARGET_WORDS_BIGENDIAN
1013   - val = bswap32(val);
1014   -#endif
1015   - pci_data_write(s, addr & 7, val, 4);
1016   -}
1017   -
1018   -static uint32_t pci_unin_main_readb (void *opaque, target_phys_addr_t addr)
1019   -{
1020   - PCIBus *s = opaque;
1021   - uint32_t val;
1022   -
1023   - val = pci_data_read(s, addr & 7, 1);
1024   -
1025   - return val;
1026   -}
1027   -
1028   -static uint32_t pci_unin_main_readw (void *opaque, target_phys_addr_t addr)
1029   -{
1030   - PCIBus *s = opaque;
1031   - uint32_t val;
1032   -
1033   - val = pci_data_read(s, addr & 7, 2);
1034   -#ifdef TARGET_WORDS_BIGENDIAN
1035   - val = bswap16(val);
1036   -#endif
1037   -
1038   - return val;
1039   -}
1040   -
1041   -static uint32_t pci_unin_main_readl (void *opaque, target_phys_addr_t addr)
1042   -{
1043   - PCIBus *s = opaque;
1044   - uint32_t val;
1045   -
1046   - val = pci_data_read(s, addr, 4);
1047   -#ifdef TARGET_WORDS_BIGENDIAN
1048   - val = bswap32(val);
1049   -#endif
1050   -
1051   - return val;
1052   -}
1053   -
1054   -static CPUWriteMemoryFunc *pci_unin_main_write[] = {
1055   - &pci_unin_main_writeb,
1056   - &pci_unin_main_writew,
1057   - &pci_unin_main_writel,
1058   -};
1059   -
1060   -static CPUReadMemoryFunc *pci_unin_main_read[] = {
1061   - &pci_unin_main_readb,
1062   - &pci_unin_main_readw,
1063   - &pci_unin_main_readl,
1064   -};
1065   -
1066   -#if 0
1067   -
1068   -static void pci_unin_config_writel (void *opaque, target_phys_addr_t addr,
1069   - uint32_t val)
1070   -{
1071   - PCIBus *s = opaque;
1072   -
1073   -#ifdef TARGET_WORDS_BIGENDIAN
1074   - val = bswap32(val);
1075   -#endif
1076   - s->config_reg = 0x80000000 | (val & ~0x00000001);
1077   -}
1078   -
1079   -static uint32_t pci_unin_config_readl (void *opaque,
1080   - target_phys_addr_t addr)
1081   -{
1082   - PCIBus *s = opaque;
1083   - uint32_t val;
1084   -
1085   - val = (s->config_reg | 0x00000001) & ~0x80000000;
1086   -#ifdef TARGET_WORDS_BIGENDIAN
1087   - val = bswap32(val);
1088   -#endif
1089   -
1090   - return val;
1091   -}
1092   -
1093   -static CPUWriteMemoryFunc *pci_unin_config_write[] = {
1094   - &pci_unin_config_writel,
1095   - &pci_unin_config_writel,
1096   - &pci_unin_config_writel,
1097   -};
1098   -
1099   -static CPUReadMemoryFunc *pci_unin_config_read[] = {
1100   - &pci_unin_config_readl,
1101   - &pci_unin_config_readl,
1102   - &pci_unin_config_readl,
1103   -};
1104   -
1105   -static void pci_unin_writeb (void *opaque, target_phys_addr_t addr,
1106   - uint32_t val)
1107   -{
1108   - PCIBus *s = opaque;
1109   - pci_data_write(s, addr & 3, val, 1);
1110   -}
1111   -
1112   -static void pci_unin_writew (void *opaque, target_phys_addr_t addr,
1113   - uint32_t val)
1114   -{
1115   - PCIBus *s = opaque;
1116   -#ifdef TARGET_WORDS_BIGENDIAN
1117   - val = bswap16(val);
1118   -#endif
1119   - pci_data_write(s, addr & 3, val, 2);
1120   -}
1121   -
1122   -static void pci_unin_writel (void *opaque, target_phys_addr_t addr,
1123   - uint32_t val)
1124   -{
1125   - PCIBus *s = opaque;
1126   -#ifdef TARGET_WORDS_BIGENDIAN
1127   - val = bswap32(val);
1128   -#endif
1129   - pci_data_write(s, addr & 3, val, 4);
1130   -}
1131   -
1132   -static uint32_t pci_unin_readb (void *opaque, target_phys_addr_t addr)
1133   -{
1134   - PCIBus *s = opaque;
1135   - uint32_t val;
1136   -
1137   - val = pci_data_read(s, addr & 3, 1);
1138   -
1139   - return val;
1140   -}
1141   -
1142   -static uint32_t pci_unin_readw (void *opaque, target_phys_addr_t addr)
1143   -{
1144   - PCIBus *s = opaque;
1145   - uint32_t val;
1146   -
1147   - val = pci_data_read(s, addr & 3, 2);
1148   -#ifdef TARGET_WORDS_BIGENDIAN
1149   - val = bswap16(val);
1150   -#endif
1151   -
1152   - return val;
1153   -}
1154   -
1155   -static uint32_t pci_unin_readl (void *opaque, target_phys_addr_t addr)
1156   -{
1157   - PCIBus *s = opaque;
1158   - uint32_t val;
1159   -
1160   - val = pci_data_read(s, addr & 3, 4);
1161   -#ifdef TARGET_WORDS_BIGENDIAN
1162   - val = bswap32(val);
1163   -#endif
1164   -
1165   - return val;
1166   -}
1167   -
1168   -static CPUWriteMemoryFunc *pci_unin_write[] = {
1169   - &pci_unin_writeb,
1170   - &pci_unin_writew,
1171   - &pci_unin_writel,
1172   -};
1173   -
1174   -static CPUReadMemoryFunc *pci_unin_read[] = {
1175   - &pci_unin_readb,
1176   - &pci_unin_readw,
1177   - &pci_unin_readl,
1178   -};
1179   -#endif
1180   -
1181   -PCIBus *pci_pmac_init(void)
1182   -{
1183   - PCIBus *s;
1184   - PCIDevice *d;
1185   - int pci_mem_config, pci_mem_data;
1186   -
1187   - /* Use values found on a real PowerMac */
1188   - /* Uninorth main bus */
1189   - s = pci_register_bus();
1190   - s->set_irq = pci_set_irq_simple;
1191   -
1192   - pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read,
1193   - pci_unin_main_config_write, s);
1194   - pci_mem_data = cpu_register_io_memory(0, pci_unin_main_read,
1195   - pci_unin_main_write, s);
1196   - cpu_register_physical_memory(0xf2800000, 0x1000, pci_mem_config);
1197   - cpu_register_physical_memory(0xf2c00000, 0x1000, pci_mem_data);
1198   - s->devfn_min = 11 << 3;
1199   - d = pci_register_device(s, "Uni-north main", sizeof(PCIDevice),
1200   - 11 << 3, NULL, NULL);
1201   - d->config[0x00] = 0x6b; // vendor_id : Apple
1202   - d->config[0x01] = 0x10;
1203   - d->config[0x02] = 0x1F; // device_id
1204   - d->config[0x03] = 0x00;
1205   - d->config[0x08] = 0x00; // revision
1206   - d->config[0x0A] = 0x00; // class_sub = pci host
1207   - d->config[0x0B] = 0x06; // class_base = PCI_bridge
1208   - d->config[0x0C] = 0x08; // cache_line_size
1209   - d->config[0x0D] = 0x10; // latency_timer
1210   - d->config[0x0E] = 0x00; // header_type
1211   - d->config[0x34] = 0x00; // capabilities_pointer
1212   -
1213   -#if 0 // XXX: not activated as PPC BIOS doesn't handle mutiple buses properly
1214   - /* pci-to-pci bridge */
1215   - d = pci_register_device("Uni-north bridge", sizeof(PCIDevice), 0, 13 << 3,
1216   - NULL, NULL);
1217   - d->config[0x00] = 0x11; // vendor_id : TI
1218   - d->config[0x01] = 0x10;
1219   - d->config[0x02] = 0x26; // device_id
1220   - d->config[0x03] = 0x00;
1221   - d->config[0x08] = 0x05; // revision
1222   - d->config[0x0A] = 0x04; // class_sub = pci2pci
1223   - d->config[0x0B] = 0x06; // class_base = PCI_bridge
1224   - d->config[0x0C] = 0x08; // cache_line_size
1225   - d->config[0x0D] = 0x20; // latency_timer
1226   - d->config[0x0E] = 0x01; // header_type
1227   -
1228   - d->config[0x18] = 0x01; // primary_bus
1229   - d->config[0x19] = 0x02; // secondary_bus
1230   - d->config[0x1A] = 0x02; // subordinate_bus
1231   - d->config[0x1B] = 0x20; // secondary_latency_timer
1232   - d->config[0x1C] = 0x11; // io_base
1233   - d->config[0x1D] = 0x01; // io_limit
1234   - d->config[0x20] = 0x00; // memory_base
1235   - d->config[0x21] = 0x80;
1236   - d->config[0x22] = 0x00; // memory_limit
1237   - d->config[0x23] = 0x80;
1238   - d->config[0x24] = 0x01; // prefetchable_memory_base
1239   - d->config[0x25] = 0x80;
1240   - d->config[0x26] = 0xF1; // prefectchable_memory_limit
1241   - d->config[0x27] = 0x7F;
1242   - // d->config[0x34] = 0xdc // capabilities_pointer
1243   -#endif
1244   -#if 0 // XXX: not needed for now
1245   - /* Uninorth AGP bus */
1246   - s = &pci_bridge[1];
1247   - pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
1248   - pci_unin_config_write, s);
1249   - pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
1250   - pci_unin_write, s);
1251   - cpu_register_physical_memory(0xf0800000, 0x1000, pci_mem_config);
1252   - cpu_register_physical_memory(0xf0c00000, 0x1000, pci_mem_data);
1253   -
1254   - d = pci_register_device("Uni-north AGP", sizeof(PCIDevice), 0, 11 << 3,
1255   - NULL, NULL);
1256   - d->config[0x00] = 0x6b; // vendor_id : Apple
1257   - d->config[0x01] = 0x10;
1258   - d->config[0x02] = 0x20; // device_id
1259   - d->config[0x03] = 0x00;
1260   - d->config[0x08] = 0x00; // revision
1261   - d->config[0x0A] = 0x00; // class_sub = pci host
1262   - d->config[0x0B] = 0x06; // class_base = PCI_bridge
1263   - d->config[0x0C] = 0x08; // cache_line_size
1264   - d->config[0x0D] = 0x10; // latency_timer
1265   - d->config[0x0E] = 0x00; // header_type
1266   - // d->config[0x34] = 0x80; // capabilities_pointer
1267   -#endif
1268   -
1269   -#if 0 // XXX: not needed for now
1270   - /* Uninorth internal bus */
1271   - s = &pci_bridge[2];
1272   - pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
1273   - pci_unin_config_write, s);
1274   - pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
1275   - pci_unin_write, s);
1276   - cpu_register_physical_memory(0xf4800000, 0x1000, pci_mem_config);
1277   - cpu_register_physical_memory(0xf4c00000, 0x1000, pci_mem_data);
1278   -
1279   - d = pci_register_device("Uni-north internal", sizeof(PCIDevice),
1280   - 3, 11 << 3, NULL, NULL);
1281   - d->config[0x00] = 0x6b; // vendor_id : Apple
1282   - d->config[0x01] = 0x10;
1283   - d->config[0x02] = 0x1E; // device_id
1284   - d->config[0x03] = 0x00;
1285   - d->config[0x08] = 0x00; // revision
1286   - d->config[0x0A] = 0x00; // class_sub = pci host
1287   - d->config[0x0B] = 0x06; // class_base = PCI_bridge
1288   - d->config[0x0C] = 0x08; // cache_line_size
1289   - d->config[0x0D] = 0x10; // latency_timer
1290   - d->config[0x0E] = 0x00; // header_type
1291   - d->config[0x34] = 0x00; // capabilities_pointer
1292   -#endif
1293   - return s;
1294   -}
1295   -
1296   -/* Ultrasparc APB PCI host */
1297   -static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
1298   - uint32_t val)
1299   -{
1300   - PCIBus *s = opaque;
1301   - int i;
1302   -
1303   - for (i = 11; i < 32; i++) {
1304   - if ((val & (1 << i)) != 0)
1305   - break;
1306   - }
1307   - s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11);
1308   -}
1309   -
1310   -static uint32_t pci_apb_config_readl (void *opaque,
1311   - target_phys_addr_t addr)
1312   -{
1313   - PCIBus *s = opaque;
1314   - uint32_t val;
1315   - int devfn;
1316   -
1317   - devfn = (s->config_reg >> 8) & 0xFF;
1318   - val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
1319   - return val;
1320   -}
1321   -
1322   -static CPUWriteMemoryFunc *pci_apb_config_write[] = {
1323   - &pci_apb_config_writel,
1324   - &pci_apb_config_writel,
1325   - &pci_apb_config_writel,
1326   -};
1327   -
1328   -static CPUReadMemoryFunc *pci_apb_config_read[] = {
1329   - &pci_apb_config_readl,
1330   - &pci_apb_config_readl,
1331   - &pci_apb_config_readl,
1332   -};
1333   -
1334   -static void apb_config_writel (void *opaque, target_phys_addr_t addr,
1335   - uint32_t val)
1336   -{
1337   - //PCIBus *s = opaque;
1338   -
1339   - switch (addr & 0x3f) {
1340   - case 0x00: // Control/Status
1341   - case 0x10: // AFSR
1342   - case 0x18: // AFAR
1343   - case 0x20: // Diagnostic
1344   - case 0x28: // Target address space
1345   - // XXX
1346   - default:
1347   - break;
1348   - }
1349   -}
1350   -
1351   -static uint32_t apb_config_readl (void *opaque,
1352   - target_phys_addr_t addr)
1353   -{
1354   - //PCIBus *s = opaque;
1355   - uint32_t val;
1356   -
1357   - switch (addr & 0x3f) {
1358   - case 0x00: // Control/Status
1359   - case 0x10: // AFSR
1360   - case 0x18: // AFAR
1361   - case 0x20: // Diagnostic
1362   - case 0x28: // Target address space
1363   - // XXX
1364   - default:
1365   - val = 0;
1366   - break;
1367   - }
1368   - return val;
1369   -}
1370   -
1371   -static CPUWriteMemoryFunc *apb_config_write[] = {
1372   - &apb_config_writel,
1373   - &apb_config_writel,
1374   - &apb_config_writel,
1375   -};
1376   -
1377   -static CPUReadMemoryFunc *apb_config_read[] = {
1378   - &apb_config_readl,
1379   - &apb_config_readl,
1380   - &apb_config_readl,
1381   -};
1382   -
1383   -static void pci_apb_writeb (void *opaque, target_phys_addr_t addr,
1384   - uint32_t val)
1385   -{
1386   - PCIBus *s = opaque;
1387   -
1388   - pci_data_write(s, addr & 7, val, 1);
1389   -}
1390   -
1391   -static void pci_apb_writew (void *opaque, target_phys_addr_t addr,
1392   - uint32_t val)
1393   -{
1394   - PCIBus *s = opaque;
1395   -
1396   - pci_data_write(s, addr & 7, val, 2);
1397   -}
1398   -
1399   -static void pci_apb_writel (void *opaque, target_phys_addr_t addr,
1400   - uint32_t val)
1401   -{
1402   - PCIBus *s = opaque;
1403   -
1404   - pci_data_write(s, addr & 7, val, 4);
1405   -}
1406   -
1407   -static uint32_t pci_apb_readb (void *opaque, target_phys_addr_t addr)
1408   -{
1409   - PCIBus *s = opaque;
1410   - uint32_t val;
1411   -
1412   - val = pci_data_read(s, addr & 7, 1);
1413   - return val;
1414   -}
1415   -
1416   -static uint32_t pci_apb_readw (void *opaque, target_phys_addr_t addr)
1417   -{
1418   - PCIBus *s = opaque;
1419   - uint32_t val;
1420   -
1421   - val = pci_data_read(s, addr & 7, 2);
1422   - return val;
1423   -}
1424   -
1425   -static uint32_t pci_apb_readl (void *opaque, target_phys_addr_t addr)
1426   -{
1427   - PCIBus *s = opaque;
1428   - uint32_t val;
1429   -
1430   - val = pci_data_read(s, addr, 4);
1431   - return val;
1432   -}
1433   -
1434   -static CPUWriteMemoryFunc *pci_apb_write[] = {
1435   - &pci_apb_writeb,
1436   - &pci_apb_writew,
1437   - &pci_apb_writel,
1438   -};
1439   -
1440   -static CPUReadMemoryFunc *pci_apb_read[] = {
1441   - &pci_apb_readb,
1442   - &pci_apb_readw,
1443   - &pci_apb_readl,
1444   -};
1445   -
1446   -static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,
1447   - uint32_t val)
1448   -{
1449   - cpu_outb(NULL, addr & 0xffff, val);
1450   -}
1451   -
1452   -static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,
1453   - uint32_t val)
1454   -{
1455   - cpu_outw(NULL, addr & 0xffff, val);
1456   -}
1457   -
1458   -static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,
1459   - uint32_t val)
1460   -{
1461   - cpu_outl(NULL, addr & 0xffff, val);
1462   -}
1463   -
1464   -static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr)
1465   -{
1466   - uint32_t val;
1467   -
1468   - val = cpu_inb(NULL, addr & 0xffff);
1469   - return val;
1470   -}
1471   -
1472   -static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr)
1473   -{
1474   - uint32_t val;
1475   -
1476   - val = cpu_inw(NULL, addr & 0xffff);
1477   - return val;
1478   -}
1479   -
1480   -static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)
1481   -{
1482   - uint32_t val;
1483   -
1484   - val = cpu_inl(NULL, addr & 0xffff);
1485   - return val;
1486   -}
1487   -
1488   -static CPUWriteMemoryFunc *pci_apb_iowrite[] = {
1489   - &pci_apb_iowriteb,
1490   - &pci_apb_iowritew,
1491   - &pci_apb_iowritel,
1492   -};
1493   -
1494   -static CPUReadMemoryFunc *pci_apb_ioread[] = {
1495   - &pci_apb_ioreadb,
1496   - &pci_apb_ioreadw,
1497   - &pci_apb_ioreadl,
1498   -};
1499   -
1500   -PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base)
1501   -{
1502   - PCIBus *s;
1503   - PCIDevice *d;
1504   - int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
1505   -
1506   - /* Ultrasparc APB main bus */
1507   - s = pci_register_bus();
1508   - s->set_irq = pci_set_irq_simple;
1509   -
1510   - pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read,
1511   - pci_apb_config_write, s);
1512   - apb_config = cpu_register_io_memory(0, apb_config_read,
1513   - apb_config_write, s);
1514   - pci_mem_data = cpu_register_io_memory(0, pci_apb_read,
1515   - pci_apb_write, s);
1516   - pci_ioport = cpu_register_io_memory(0, pci_apb_ioread,
1517   - pci_apb_iowrite, s);
1518   -
1519   - cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config);
1520   - cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10, pci_mem_config);
1521   - cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, pci_ioport);
1522   - cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom
1523   -
1524   - d = pci_register_device(s, "Advanced PCI Bus", sizeof(PCIDevice),
1525   - -1, NULL, NULL);
1526   - d->config[0x00] = 0x8e; // vendor_id : Sun
1527   - d->config[0x01] = 0x10;
1528   - d->config[0x02] = 0x00; // device_id
1529   - d->config[0x03] = 0xa0;
1530   - d->config[0x04] = 0x06; // command = bus master, pci mem
1531   - d->config[0x05] = 0x00;
1532   - d->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
1533   - d->config[0x07] = 0x03; // status = medium devsel
1534   - d->config[0x08] = 0x00; // revision
1535   - d->config[0x09] = 0x00; // programming i/f
1536   - d->config[0x0A] = 0x00; // class_sub = pci host
1537   - d->config[0x0B] = 0x06; // class_base = PCI_bridge
1538   - d->config[0x0D] = 0x10; // latency_timer
1539   - d->config[0x0E] = 0x00; // header_type
1540   - return s;
1541   -}
1542   -
1543   -/***********************************************************/
1544   -/* generic PCI irq support */
1545   -
1546   -/* 0 <= irq_num <= 3. level must be 0 or 1 */
1547   -void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
1548   -{
1549   - PCIBus *bus = pci_dev->bus;
1550   - bus->set_irq(pci_dev, irq_num, level);
1551   -}
1552   -
1553   -/***********************************************************/
1554   -/* monitor info on PCI */
1555   -
1556   -static void pci_info_device(PCIDevice *d)
1557   -{
1558   - int i, class;
1559   - PCIIORegion *r;
1560   -
1561   - term_printf(" Bus %2d, device %3d, function %d:\n",
1562   - d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
1563   - class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
1564   - term_printf(" ");
1565   - switch(class) {
1566   - case 0x0101:
1567   - term_printf("IDE controller");
1568   - break;
1569   - case 0x0200:
1570   - term_printf("Ethernet controller");
1571   - break;
1572   - case 0x0300:
1573   - term_printf("VGA controller");
1574   - break;
1575   - default:
1576   - term_printf("Class %04x", class);
1577   - break;
1578   - }
1579   - term_printf(": PCI device %04x:%04x\n",
1580   - le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
1581   - le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
1582   -
1583   - if (d->config[PCI_INTERRUPT_PIN] != 0) {
1584   - term_printf(" IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);
1585   - }
1586   - for(i = 0;i < PCI_NUM_REGIONS; i++) {
1587   - r = &d->io_regions[i];
1588   - if (r->size != 0) {
1589   - term_printf(" BAR%d: ", i);
1590   - if (r->type & PCI_ADDRESS_SPACE_IO) {
1591   - term_printf("I/O at 0x%04x [0x%04x].\n",
1592   - r->addr, r->addr + r->size - 1);
1593   - } else {
1594   - term_printf("32 bit memory at 0x%08x [0x%08x].\n",
1595   - r->addr, r->addr + r->size - 1);
1596   - }
1597   - }
1598   - }
1599   -}
1600   -
1601   -void pci_info(void)
1602   -{
1603   - PCIBus *bus = first_bus;
1604   - PCIDevice *d;
1605   - int devfn;
1606   -
1607   - if (bus) {
1608   - for(devfn = 0; devfn < 256; devfn++) {
1609   - d = bus->devices[devfn];
1610   - if (d)
1611   - pci_info_device(d);
1612   - }
1613   - }
1614   -}
1615   -
1616   -/***********************************************************/
1617   -/* XXX: the following should be moved to the PC BIOS */
1618   -
1619   -static __attribute__((unused)) uint32_t isa_inb(uint32_t addr)
1620   -{
1621   - return cpu_inb(NULL, addr);
1622   -}
1623   -
1624   -static void isa_outb(uint32_t val, uint32_t addr)
1625   -{
1626   - cpu_outb(NULL, addr, val);
1627   -}
1628   -
1629   -static __attribute__((unused)) uint32_t isa_inw(uint32_t addr)
1630   -{
1631   - return cpu_inw(NULL, addr);
1632   -}
1633   -
1634   -static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr)
1635   -{
1636   - cpu_outw(NULL, addr, val);
1637   -}
1638   -
1639   -static __attribute__((unused)) uint32_t isa_inl(uint32_t addr)
1640   -{
1641   - return cpu_inl(NULL, addr);
1642   -}
1643   -
1644   -static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr)
1645   -{
1646   - cpu_outl(NULL, addr, val);
1647   -}
1648   -
1649   -static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
1650   -{
1651   - PCIBus *s = d->bus;
1652   - s->config_reg = 0x80000000 | (s->bus_num << 16) |
1653   - (d->devfn << 8) | addr;
1654   - pci_data_write(s, 0, val, 4);
1655   -}
1656   -
1657   -static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
1658   -{
1659   - PCIBus *s = d->bus;
1660   - s->config_reg = 0x80000000 | (s->bus_num << 16) |
1661   - (d->devfn << 8) | (addr & ~3);
1662   - pci_data_write(s, addr & 3, val, 2);
1663   -}
1664   -
1665   -static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
1666   -{
1667   - PCIBus *s = d->bus;
1668   - s->config_reg = 0x80000000 | (s->bus_num << 16) |
1669   - (d->devfn << 8) | (addr & ~3);
1670   - pci_data_write(s, addr & 3, val, 1);
1671   -}
1672   -
1673   -static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
1674   -{
1675   - PCIBus *s = d->bus;
1676   - s->config_reg = 0x80000000 | (s->bus_num << 16) |
1677   - (d->devfn << 8) | addr;
1678   - return pci_data_read(s, 0, 4);
1679   -}
1680   -
1681   -static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
1682   -{
1683   - PCIBus *s = d->bus;
1684   - s->config_reg = 0x80000000 | (s->bus_num << 16) |
1685   - (d->devfn << 8) | (addr & ~3);
1686   - return pci_data_read(s, addr & 3, 2);
1687   -}
1688   -
1689   -static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
1690   -{
1691   - PCIBus *s = d->bus;
1692   - s->config_reg = 0x80000000 | (s->bus_num << 16) |
1693   - (d->devfn << 8) | (addr & ~3);
1694   - return pci_data_read(s, addr & 3, 1);
1695   -}
1696   -
1697   -static uint32_t pci_bios_io_addr;
1698   -static uint32_t pci_bios_mem_addr;
1699   -/* host irqs corresponding to PCI irqs A-D */
1700   -static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
1701   -
1702   -static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
1703   -{
1704   - PCIIORegion *r;
1705   - uint16_t cmd;
1706   - uint32_t ofs;
1707   -
1708   - if ( region_num == PCI_ROM_SLOT ) {
1709   - ofs = 0x30;
1710   - }else{
1711   - ofs = 0x10 + region_num * 4;
1712   - }
1713   -
1714   - pci_config_writel(d, ofs, addr);
1715   - r = &d->io_regions[region_num];
1716   -
1717   - /* enable memory mappings */
1718   - cmd = pci_config_readw(d, PCI_COMMAND);
1719   - if ( region_num == PCI_ROM_SLOT )
1720   - cmd |= 2;
1721   - else if (r->type & PCI_ADDRESS_SPACE_IO)
1722   - cmd |= 1;
1723   - else
1724   - cmd |= 2;
1725   - pci_config_writew(d, PCI_COMMAND, cmd);
1726   -}
1727   -
1728   -static void pci_bios_init_device(PCIDevice *d)
1729   -{
1730   - int class;
1731   - PCIIORegion *r;
1732   - uint32_t *paddr;
1733   - int i, pin, pic_irq, vendor_id, device_id;
1734   -
1735   - class = pci_config_readw(d, PCI_CLASS_DEVICE);
1736   - vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
1737   - device_id = pci_config_readw(d, PCI_DEVICE_ID);
1738   - switch(class) {
1739   - case 0x0101:
1740   - if (vendor_id == 0x8086 && device_id == 0x7010) {
1741   - /* PIIX3 IDE */
1742   - pci_config_writew(d, 0x40, 0x8000); // enable IDE0
1743   - pci_config_writew(d, 0x42, 0x8000); // enable IDE1
1744   - goto default_map;
1745   - } else {
1746   - /* IDE: we map it as in ISA mode */
1747   - pci_set_io_region_addr(d, 0, 0x1f0);
1748   - pci_set_io_region_addr(d, 1, 0x3f4);
1749   - pci_set_io_region_addr(d, 2, 0x170);
1750   - pci_set_io_region_addr(d, 3, 0x374);
1751   - }
1752   - break;
1753   - case 0x0300:
1754   - if (vendor_id != 0x1234)
1755   - goto default_map;
1756   - /* VGA: map frame buffer to default Bochs VBE address */
1757   - pci_set_io_region_addr(d, 0, 0xE0000000);
1758   - break;
1759   - case 0x0800:
1760   - /* PIC */
1761   - vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
1762   - device_id = pci_config_readw(d, PCI_DEVICE_ID);
1763   - if (vendor_id == 0x1014) {
1764   - /* IBM */
1765   - if (device_id == 0x0046 || device_id == 0xFFFF) {
1766   - /* MPIC & MPIC2 */
1767   - pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
1768   - }
1769   - }
1770   - break;
1771   - case 0xff00:
1772   - if (vendor_id == 0x0106b &&
1773   - (device_id == 0x0017 || device_id == 0x0022)) {
1774   - /* macio bridge */
1775   - pci_set_io_region_addr(d, 0, 0x80800000);
1776   - }
1777   - break;
1778   - default:
1779   - default_map:
1780   - /* default memory mappings */
1781   - for(i = 0; i < PCI_NUM_REGIONS; i++) {
1782   - r = &d->io_regions[i];
1783   - if (r->size) {
1784   - if (r->type & PCI_ADDRESS_SPACE_IO)
1785   - paddr = &pci_bios_io_addr;
1786   - else
1787   - paddr = &pci_bios_mem_addr;
1788   - *paddr = (*paddr + r->size - 1) & ~(r->size - 1);
1789   - pci_set_io_region_addr(d, i, *paddr);
1790   - *paddr += r->size;
1791   - }
1792   - }
1793   - break;
1794   - }
1795   -
1796   - /* map the interrupt */
1797   - pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
1798   - if (pin != 0) {
1799   - pin = pci_slot_get_pirq(d, pin - 1);
1800   - pic_irq = pci_irqs[pin];
1801   - pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
1802   - }
1803   -}
1804   -
1805   -/*
1806   - * This function initializes the PCI devices as a normal PCI BIOS
1807   - * would do. It is provided just in case the BIOS has no support for
1808   - * PCI.
1809   - */
1810   -void pci_bios_init(void)
1811   -{
1812   - PCIBus *bus;
1813   - PCIDevice *d;
1814   - int devfn, i, irq;
1815   - uint8_t elcr[2];
1816   -
1817   - pci_bios_io_addr = 0xc000;
1818   - pci_bios_mem_addr = 0xf0000000;
1819   -
1820   - /* activate IRQ mappings */
1821   - elcr[0] = 0x00;
1822   - elcr[1] = 0x00;
1823   - for(i = 0; i < 4; i++) {
1824   - irq = pci_irqs[i];
1825   - /* set to trigger level */
1826   - elcr[irq >> 3] |= (1 << (irq & 7));
1827   - /* activate irq remapping in PIIX */
1828   - pci_config_writeb((PCIDevice *)piix3_state, 0x60 + i, irq);
1829   - }
1830   - isa_outb(elcr[0], 0x4d0);
1831   - isa_outb(elcr[1], 0x4d1);
1832   -
1833   - bus = first_bus;
1834   - if (bus) {
1835   - for(devfn = 0; devfn < 256; devfn++) {
1836   - d = bus->devices[devfn];
1837   - if (d)
1838   - pci_bios_init_device(d);
1839   - }
1840   - }
  474 + pci_for_each_device(pci_info_device);
1841 475 }
1842 476  
1843 477 /* Initialize a PCI NIC. */
... ...
hw/pci_host.h 0 → 100644
  1 +/*
  2 + * QEMU Common PCI Host bridge configuration data space access routines.
  3 + *
  4 + * Copyright (c) 2006 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +
  25 +/* Worker routines for a PCI host controller that uses an {address,data}
  26 + register pair to access PCI configuration space. */
  27 +
  28 +typedef struct {
  29 + uint32_t config_reg;
  30 + PCIBus *bus;
  31 +} PCIHostState;
  32 +
  33 +static void pci_host_data_writeb(void* opaque, pci_addr_t addr, uint32_t val)
  34 +{
  35 + PCIHostState *s = opaque;
  36 + if (s->config_reg & (1u << 31))
  37 + pci_data_write(s->bus, s->config_reg | (addr & 3), val, 1);
  38 +}
  39 +
  40 +static void pci_host_data_writew(void* opaque, pci_addr_t addr, uint32_t val)
  41 +{
  42 + PCIHostState *s = opaque;
  43 +#ifdef TARGET_WORDS_BIGENDIAN
  44 + val = bswap16(val);
  45 +#endif
  46 + if (s->config_reg & (1u << 31))
  47 + pci_data_write(s->bus, s->config_reg | (addr & 3), val, 2);
  48 +}
  49 +
  50 +static void pci_host_data_writel(void* opaque, pci_addr_t addr, uint32_t val)
  51 +{
  52 + PCIHostState *s = opaque;
  53 +#ifdef TARGET_WORDS_BIGENDIAN
  54 + val = bswap32(val);
  55 +#endif
  56 + if (s->config_reg & (1u << 31))
  57 + pci_data_write(s->bus, s->config_reg, val, 4);
  58 +}
  59 +
  60 +static uint32_t pci_host_data_readb(void* opaque, pci_addr_t addr)
  61 +{
  62 + PCIHostState *s = opaque;
  63 + if (!(s->config_reg & (1 << 31)))
  64 + return 0xff;
  65 + return pci_data_read(s->bus, s->config_reg | (addr & 3), 1);
  66 +}
  67 +
  68 +static uint32_t pci_host_data_readw(void* opaque, pci_addr_t addr)
  69 +{
  70 + PCIHostState *s = opaque;
  71 + uint32_t val;
  72 + if (!(s->config_reg & (1 << 31)))
  73 + return 0xffff;
  74 + val = pci_data_read(s->bus, s->config_reg | (addr & 3), 2);
  75 +#ifdef TARGET_WORDS_BIGENDIAN
  76 + val = bswap16(val);
  77 +#endif
  78 + return val;
  79 +}
  80 +
  81 +static uint32_t pci_host_data_readl(void* opaque, pci_addr_t addr)
  82 +{
  83 + PCIHostState *s = opaque;
  84 + uint32_t val;
  85 + if (!(s->config_reg & (1 << 31)))
  86 + return 0xffffffff;
  87 + val = pci_data_read(s->bus, s->config_reg | (addr & 3), 4);
  88 +#ifdef TARGET_WORDS_BIGENDIAN
  89 + val = bswap32(val);
  90 +#endif
  91 + return val;
  92 +}
  93 +
... ...
hw/piix_pci.c 0 → 100644
  1 +/*
  2 + * QEMU i440FX/PIIX3 PCI Bridge Emulation
  3 + *
  4 + * Copyright (c) 2006 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +
  25 +#include "vl.h"
  26 +typedef uint32_t pci_addr_t;
  27 +#include "pci_host.h"
  28 +
  29 +typedef PCIHostState I440FXState;
  30 +
  31 +static void i440fx_addr_writel(void* opaque, uint32_t addr, uint32_t val)
  32 +{
  33 + I440FXState *s = opaque;
  34 + s->config_reg = val;
  35 +}
  36 +
  37 +static uint32_t i440fx_addr_readl(void* opaque, uint32_t addr)
  38 +{
  39 + I440FXState *s = opaque;
  40 + return s->config_reg;
  41 +}
  42 +
  43 +static void piix3_set_irq(PCIDevice *pci_dev, void *pic, int irq_num, int level);
  44 +
  45 +PCIBus *i440fx_init(void)
  46 +{
  47 + PCIBus *b;
  48 + PCIDevice *d;
  49 + I440FXState *s;
  50 +
  51 + s = qemu_mallocz(sizeof(I440FXState));
  52 + b = pci_register_bus(piix3_set_irq, NULL, 0);
  53 + s->bus = b;
  54 +
  55 + register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s);
  56 + register_ioport_read(0xcf8, 4, 4, i440fx_addr_readl, s);
  57 +
  58 + register_ioport_write(0xcfc, 4, 1, pci_host_data_writeb, s);
  59 + register_ioport_write(0xcfc, 4, 2, pci_host_data_writew, s);
  60 + register_ioport_write(0xcfc, 4, 4, pci_host_data_writel, s);
  61 + register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s);
  62 + register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);
  63 + register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
  64 +
  65 + d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0,
  66 + NULL, NULL);
  67 +
  68 + d->config[0x00] = 0x86; // vendor_id
  69 + d->config[0x01] = 0x80;
  70 + d->config[0x02] = 0x37; // device_id
  71 + d->config[0x03] = 0x12;
  72 + d->config[0x08] = 0x02; // revision
  73 + d->config[0x0a] = 0x00; // class_sub = host2pci
  74 + d->config[0x0b] = 0x06; // class_base = PCI_bridge
  75 + d->config[0x0e] = 0x00; // header_type
  76 + return b;
  77 +}
  78 +
  79 +/* PIIX3 PCI to ISA bridge */
  80 +
  81 +static PCIDevice *piix3_dev;
  82 +
  83 +/* just used for simpler irq handling. */
  84 +#define PCI_IRQ_WORDS ((PCI_DEVICES_MAX + 31) / 32)
  85 +
  86 +static uint32_t pci_irq_levels[4][PCI_IRQ_WORDS];
  87 +
  88 +/* return the global irq number corresponding to a given device irq
  89 + pin. We could also use the bus number to have a more precise
  90 + mapping. */
  91 +static inline int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
  92 +{
  93 + int slot_addend;
  94 + slot_addend = (pci_dev->devfn >> 3) - 1;
  95 + return (irq_num + slot_addend) & 3;
  96 +}
  97 +
  98 +static inline int get_pci_irq_level(int irq_num)
  99 +{
  100 + int pic_level;
  101 +#if (PCI_IRQ_WORDS == 2)
  102 + pic_level = ((pci_irq_levels[irq_num][0] |
  103 + pci_irq_levels[irq_num][1]) != 0);
  104 +#else
  105 + {
  106 + int i;
  107 + pic_level = 0;
  108 + for(i = 0; i < PCI_IRQ_WORDS; i++) {
  109 + if (pci_irq_levels[irq_num][i]) {
  110 + pic_level = 1;
  111 + break;
  112 + }
  113 + }
  114 + }
  115 +#endif
  116 + return pic_level;
  117 +}
  118 +
  119 +static void piix3_set_irq(PCIDevice *pci_dev, void *pic, int irq_num, int level)
  120 +{
  121 + int irq_index, shift, pic_irq, pic_level;
  122 + uint32_t *p;
  123 +
  124 + irq_num = pci_slot_get_pirq(pci_dev, irq_num);
  125 + irq_index = pci_dev->irq_index;
  126 + p = &pci_irq_levels[irq_num][irq_index >> 5];
  127 + shift = (irq_index & 0x1f);
  128 + *p = (*p & ~(1 << shift)) | (level << shift);
  129 +
  130 + /* now we change the pic irq level according to the piix irq mappings */
  131 + /* XXX: optimize */
  132 + pic_irq = piix3_dev->config[0x60 + irq_num];
  133 + if (pic_irq < 16) {
  134 + /* the pic level is the logical OR of all the PCI irqs mapped
  135 + to it */
  136 + pic_level = 0;
  137 + if (pic_irq == piix3_dev->config[0x60])
  138 + pic_level |= get_pci_irq_level(0);
  139 + if (pic_irq == piix3_dev->config[0x61])
  140 + pic_level |= get_pci_irq_level(1);
  141 + if (pic_irq == piix3_dev->config[0x62])
  142 + pic_level |= get_pci_irq_level(2);
  143 + if (pic_irq == piix3_dev->config[0x63])
  144 + pic_level |= get_pci_irq_level(3);
  145 + pic_set_irq(pic_irq, pic_level);
  146 + }
  147 +}
  148 +
  149 +static void piix3_reset(PCIDevice *d)
  150 +{
  151 + uint8_t *pci_conf = d->config;
  152 +
  153 + pci_conf[0x04] = 0x07; // master, memory and I/O
  154 + pci_conf[0x05] = 0x00;
  155 + pci_conf[0x06] = 0x00;
  156 + pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
  157 + pci_conf[0x4c] = 0x4d;
  158 + pci_conf[0x4e] = 0x03;
  159 + pci_conf[0x4f] = 0x00;
  160 + pci_conf[0x60] = 0x80;
  161 + pci_conf[0x69] = 0x02;
  162 + pci_conf[0x70] = 0x80;
  163 + pci_conf[0x76] = 0x0c;
  164 + pci_conf[0x77] = 0x0c;
  165 + pci_conf[0x78] = 0x02;
  166 + pci_conf[0x79] = 0x00;
  167 + pci_conf[0x80] = 0x00;
  168 + pci_conf[0x82] = 0x00;
  169 + pci_conf[0xa0] = 0x08;
  170 + pci_conf[0xa0] = 0x08;
  171 + pci_conf[0xa2] = 0x00;
  172 + pci_conf[0xa3] = 0x00;
  173 + pci_conf[0xa4] = 0x00;
  174 + pci_conf[0xa5] = 0x00;
  175 + pci_conf[0xa6] = 0x00;
  176 + pci_conf[0xa7] = 0x00;
  177 + pci_conf[0xa8] = 0x0f;
  178 + pci_conf[0xaa] = 0x00;
  179 + pci_conf[0xab] = 0x00;
  180 + pci_conf[0xac] = 0x00;
  181 + pci_conf[0xae] = 0x00;
  182 +}
  183 +
  184 +int piix3_init(PCIBus *bus)
  185 +{
  186 + PCIDevice *d;
  187 + uint8_t *pci_conf;
  188 +
  189 + d = pci_register_device(bus, "PIIX3", sizeof(PCIDevice),
  190 + -1, NULL, NULL);
  191 + register_savevm("PIIX3", 0, 1, generic_pci_save, generic_pci_load, d);
  192 +
  193 + piix3_dev = d;
  194 + pci_conf = d->config;
  195 +
  196 + pci_conf[0x00] = 0x86; // Intel
  197 + pci_conf[0x01] = 0x80;
  198 + pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
  199 + pci_conf[0x03] = 0x70;
  200 + pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA
  201 + pci_conf[0x0b] = 0x06; // class_base = PCI_bridge
  202 + pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
  203 +
  204 + piix3_reset(d);
  205 + return d->devfn;
  206 +}
  207 +
  208 +/***********************************************************/
  209 +/* XXX: the following should be moved to the PC BIOS */
  210 +
  211 +static __attribute__((unused)) uint32_t isa_inb(uint32_t addr)
  212 +{
  213 + return cpu_inb(NULL, addr);
  214 +}
  215 +
  216 +static void isa_outb(uint32_t val, uint32_t addr)
  217 +{
  218 + cpu_outb(NULL, addr, val);
  219 +}
  220 +
  221 +static __attribute__((unused)) uint32_t isa_inw(uint32_t addr)
  222 +{
  223 + return cpu_inw(NULL, addr);
  224 +}
  225 +
  226 +static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr)
  227 +{
  228 + cpu_outw(NULL, addr, val);
  229 +}
  230 +
  231 +static __attribute__((unused)) uint32_t isa_inl(uint32_t addr)
  232 +{
  233 + return cpu_inl(NULL, addr);
  234 +}
  235 +
  236 +static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr)
  237 +{
  238 + cpu_outl(NULL, addr, val);
  239 +}
  240 +
  241 +static uint32_t pci_bios_io_addr;
  242 +static uint32_t pci_bios_mem_addr;
  243 +/* host irqs corresponding to PCI irqs A-D */
  244 +static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
  245 +
  246 +static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
  247 +{
  248 + PCIBus *s = d->bus;
  249 + addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
  250 + pci_data_write(s, addr, val, 4);
  251 +}
  252 +
  253 +static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
  254 +{
  255 + PCIBus *s = d->bus;
  256 + addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
  257 + pci_data_write(s, addr, val, 2);
  258 +}
  259 +
  260 +static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
  261 +{
  262 + PCIBus *s = d->bus;
  263 + addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
  264 + pci_data_write(s, addr, val, 1);
  265 +}
  266 +
  267 +static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
  268 +{
  269 + PCIBus *s = d->bus;
  270 + addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
  271 + return pci_data_read(s, addr, 4);
  272 +}
  273 +
  274 +static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
  275 +{
  276 + PCIBus *s = d->bus;
  277 + addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
  278 + return pci_data_read(s, addr, 2);
  279 +}
  280 +
  281 +static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
  282 +{
  283 + PCIBus *s = d->bus;
  284 + addr |= (pci_bus_num(s) << 16) | (d->devfn << 8);
  285 + return pci_data_read(s, addr, 1);
  286 +}
  287 +
  288 +static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
  289 +{
  290 + PCIIORegion *r;
  291 + uint16_t cmd;
  292 + uint32_t ofs;
  293 +
  294 + if ( region_num == PCI_ROM_SLOT ) {
  295 + ofs = 0x30;
  296 + }else{
  297 + ofs = 0x10 + region_num * 4;
  298 + }
  299 +
  300 + pci_config_writel(d, ofs, addr);
  301 + r = &d->io_regions[region_num];
  302 +
  303 + /* enable memory mappings */
  304 + cmd = pci_config_readw(d, PCI_COMMAND);
  305 + if ( region_num == PCI_ROM_SLOT )
  306 + cmd |= 2;
  307 + else if (r->type & PCI_ADDRESS_SPACE_IO)
  308 + cmd |= 1;
  309 + else
  310 + cmd |= 2;
  311 + pci_config_writew(d, PCI_COMMAND, cmd);
  312 +}
  313 +
  314 +static void pci_bios_init_device(PCIDevice *d)
  315 +{
  316 + int class;
  317 + PCIIORegion *r;
  318 + uint32_t *paddr;
  319 + int i, pin, pic_irq, vendor_id, device_id;
  320 +
  321 + class = pci_config_readw(d, PCI_CLASS_DEVICE);
  322 + vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
  323 + device_id = pci_config_readw(d, PCI_DEVICE_ID);
  324 + switch(class) {
  325 + case 0x0101:
  326 + if (vendor_id == 0x8086 && device_id == 0x7010) {
  327 + /* PIIX3 IDE */
  328 + pci_config_writew(d, 0x40, 0x8000); // enable IDE0
  329 + pci_config_writew(d, 0x42, 0x8000); // enable IDE1
  330 + goto default_map;
  331 + } else {
  332 + /* IDE: we map it as in ISA mode */
  333 + pci_set_io_region_addr(d, 0, 0x1f0);
  334 + pci_set_io_region_addr(d, 1, 0x3f4);
  335 + pci_set_io_region_addr(d, 2, 0x170);
  336 + pci_set_io_region_addr(d, 3, 0x374);
  337 + }
  338 + break;
  339 + case 0x0300:
  340 + if (vendor_id != 0x1234)
  341 + goto default_map;
  342 + /* VGA: map frame buffer to default Bochs VBE address */
  343 + pci_set_io_region_addr(d, 0, 0xE0000000);
  344 + break;
  345 + case 0x0800:
  346 + /* PIC */
  347 + vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
  348 + device_id = pci_config_readw(d, PCI_DEVICE_ID);
  349 + if (vendor_id == 0x1014) {
  350 + /* IBM */
  351 + if (device_id == 0x0046 || device_id == 0xFFFF) {
  352 + /* MPIC & MPIC2 */
  353 + pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
  354 + }
  355 + }
  356 + break;
  357 + case 0xff00:
  358 + if (vendor_id == 0x0106b &&
  359 + (device_id == 0x0017 || device_id == 0x0022)) {
  360 + /* macio bridge */
  361 + pci_set_io_region_addr(d, 0, 0x80800000);
  362 + }
  363 + break;
  364 + default:
  365 + default_map:
  366 + /* default memory mappings */
  367 + for(i = 0; i < PCI_NUM_REGIONS; i++) {
  368 + r = &d->io_regions[i];
  369 + if (r->size) {
  370 + if (r->type & PCI_ADDRESS_SPACE_IO)
  371 + paddr = &pci_bios_io_addr;
  372 + else
  373 + paddr = &pci_bios_mem_addr;
  374 + *paddr = (*paddr + r->size - 1) & ~(r->size - 1);
  375 + pci_set_io_region_addr(d, i, *paddr);
  376 + *paddr += r->size;
  377 + }
  378 + }
  379 + break;
  380 + }
  381 +
  382 + /* map the interrupt */
  383 + pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
  384 + if (pin != 0) {
  385 + pin = pci_slot_get_pirq(d, pin - 1);
  386 + pic_irq = pci_irqs[pin];
  387 + pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
  388 + }
  389 +}
  390 +
  391 +/*
  392 + * This function initializes the PCI devices as a normal PCI BIOS
  393 + * would do. It is provided just in case the BIOS has no support for
  394 + * PCI.
  395 + */
  396 +void pci_bios_init(void)
  397 +{
  398 + int i, irq;
  399 + uint8_t elcr[2];
  400 +
  401 + pci_bios_io_addr = 0xc000;
  402 + pci_bios_mem_addr = 0xf0000000;
  403 +
  404 + /* activate IRQ mappings */
  405 + elcr[0] = 0x00;
  406 + elcr[1] = 0x00;
  407 + for(i = 0; i < 4; i++) {
  408 + irq = pci_irqs[i];
  409 + /* set to trigger level */
  410 + elcr[irq >> 3] |= (1 << (irq & 7));
  411 + /* activate irq remapping in PIIX */
  412 + pci_config_writeb(piix3_dev, 0x60 + i, irq);
  413 + }
  414 + isa_outb(elcr[0], 0x4d0);
  415 + isa_outb(elcr[1], 0x4d1);
  416 +
  417 + pci_for_each_device(pci_bios_init_device);
  418 +}
  419 +
... ...
hw/ppc_chrp.c
... ... @@ -415,19 +415,18 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
415 415  
416 416 if (is_heathrow) {
417 417 isa_mem_base = 0x80000000;
418   - pci_bus = pci_grackle_init(0xfec00000);
419 418  
420 419 /* Register 2 MB of ISA IO space */
421 420 PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL);
422 421 cpu_register_physical_memory(0xfe000000, 0x00200000, PPC_io_memory);
423 422  
424 423 /* init basic PC hardware */
  424 + pic = heathrow_pic_init(&heathrow_pic_mem_index);
  425 + set_irq = heathrow_pic_set_irq;
  426 + pci_bus = pci_grackle_init(0xfec00000, pic);
425 427 vga_initialize(pci_bus, ds, phys_ram_base + ram_size,
426 428 ram_size, vga_ram_size,
427 429 vga_bios_offset, vga_bios_size);
428   - pic = heathrow_pic_init(&heathrow_pic_mem_index);
429   - set_irq = heathrow_pic_set_irq;
430   - pci_set_pic(pci_bus, set_irq, pic);
431 430  
432 431 /* XXX: suppress that */
433 432 isa_pic = pic_init(pic_irq_request, NULL);
... ... @@ -462,7 +461,6 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
462 461 arch_name = "HEATHROW";
463 462 } else {
464 463 isa_mem_base = 0x80000000;
465   - pci_bus = pci_pmac_init();
466 464  
467 465 /* Register 8 MB of ISA IO space */
468 466 PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL);
... ... @@ -472,13 +470,13 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
472 470 unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL);
473 471 cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory);
474 472  
  473 + pic = openpic_init(NULL, &openpic_mem_index, 1, &env);
  474 + set_irq = openpic_set_irq;
  475 + pci_bus = pci_pmac_init(pic);
475 476 /* init basic PC hardware */
476 477 vga_initialize(pci_bus, ds, phys_ram_base + ram_size,
477 478 ram_size, vga_ram_size,
478 479 vga_bios_offset, vga_bios_size);
479   - pic = openpic_init(NULL, &openpic_mem_index, 1, &env);
480   - set_irq = openpic_set_irq;
481   - pci_set_pic(pci_bus, set_irq, pic);
482 480  
483 481 /* XXX: suppress that */
484 482 isa_pic = pic_init(pic_irq_request, NULL);
... ...
hw/prep_pci.c 0 → 100644
  1 +/*
  2 + * QEMU PREP PCI host
  3 + *
  4 + * Copyright (c) 2006 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +
  25 +#include "vl.h"
  26 +typedef uint32_t pci_addr_t;
  27 +#include "pci_host.h"
  28 +
  29 +typedef PCIHostState PREPPCIState;
  30 +
  31 +static void pci_prep_addr_writel(void* opaque, uint32_t addr, uint32_t val)
  32 +{
  33 + PREPPCIState *s = opaque;
  34 + s->config_reg = val;
  35 +}
  36 +
  37 +static uint32_t pci_prep_addr_readl(void* opaque, uint32_t addr)
  38 +{
  39 + PREPPCIState *s = opaque;
  40 + return s->config_reg;
  41 +}
  42 +
  43 +static inline uint32_t PPC_PCIIO_config(target_phys_addr_t addr)
  44 +{
  45 + int i;
  46 +
  47 + for(i = 0; i < 11; i++) {
  48 + if ((addr & (1 << (11 + i))) != 0)
  49 + break;
  50 + }
  51 + return (addr & 0x7ff) | (i << 11);
  52 +}
  53 +
  54 +static void PPC_PCIIO_writeb (void *opaque, target_phys_addr_t addr, uint32_t val)
  55 +{
  56 + PREPPCIState *s = opaque;
  57 + pci_data_write(s->bus, PPC_PCIIO_config(addr), val, 1);
  58 +}
  59 +
  60 +static void PPC_PCIIO_writew (void *opaque, target_phys_addr_t addr, uint32_t val)
  61 +{
  62 + PREPPCIState *s = opaque;
  63 +#ifdef TARGET_WORDS_BIGENDIAN
  64 + val = bswap16(val);
  65 +#endif
  66 + pci_data_write(s->bus, PPC_PCIIO_config(addr), val, 2);
  67 +}
  68 +
  69 +static void PPC_PCIIO_writel (void *opaque, target_phys_addr_t addr, uint32_t val)
  70 +{
  71 + PREPPCIState *s = opaque;
  72 +#ifdef TARGET_WORDS_BIGENDIAN
  73 + val = bswap32(val);
  74 +#endif
  75 + pci_data_write(s->bus, PPC_PCIIO_config(addr), val, 4);
  76 +}
  77 +
  78 +static uint32_t PPC_PCIIO_readb (void *opaque, target_phys_addr_t addr)
  79 +{
  80 + PREPPCIState *s = opaque;
  81 + uint32_t val;
  82 + val = pci_data_read(s->bus, PPC_PCIIO_config(addr), 1);
  83 + return val;
  84 +}
  85 +
  86 +static uint32_t PPC_PCIIO_readw (void *opaque, target_phys_addr_t addr)
  87 +{
  88 + PREPPCIState *s = opaque;
  89 + uint32_t val;
  90 + val = pci_data_read(s->bus, PPC_PCIIO_config(addr), 2);
  91 +#ifdef TARGET_WORDS_BIGENDIAN
  92 + val = bswap16(val);
  93 +#endif
  94 + return val;
  95 +}
  96 +
  97 +static uint32_t PPC_PCIIO_readl (void *opaque, target_phys_addr_t addr)
  98 +{
  99 + PREPPCIState *s = opaque;
  100 + uint32_t val;
  101 + val = pci_data_read(s->bus, PPC_PCIIO_config(addr), 4);
  102 +#ifdef TARGET_WORDS_BIGENDIAN
  103 + val = bswap32(val);
  104 +#endif
  105 + return val;
  106 +}
  107 +
  108 +static CPUWriteMemoryFunc *PPC_PCIIO_write[] = {
  109 + &PPC_PCIIO_writeb,
  110 + &PPC_PCIIO_writew,
  111 + &PPC_PCIIO_writel,
  112 +};
  113 +
  114 +static CPUReadMemoryFunc *PPC_PCIIO_read[] = {
  115 + &PPC_PCIIO_readb,
  116 + &PPC_PCIIO_readw,
  117 + &PPC_PCIIO_readl,
  118 +};
  119 +
  120 +static void prep_set_irq(PCIDevice *d, void *pic, int irq_num, int level)
  121 +{
  122 + /* XXX: we do not simulate the hardware - we rely on the BIOS to
  123 + set correctly for irq line field */
  124 + pic_set_irq(d->config[PCI_INTERRUPT_LINE], level);
  125 +}
  126 +
  127 +PCIBus *pci_prep_init(void)
  128 +{
  129 + PREPPCIState *s;
  130 + PCIDevice *d;
  131 + int PPC_io_memory;
  132 +
  133 + s = qemu_mallocz(sizeof(PREPPCIState));
  134 + s->bus = pci_register_bus(prep_set_irq, NULL, 0);
  135 +
  136 + register_ioport_write(0xcf8, 4, 4, pci_prep_addr_writel, s);
  137 + register_ioport_read(0xcf8, 4, 4, pci_prep_addr_readl, s);
  138 +
  139 + register_ioport_write(0xcfc, 4, 1, pci_host_data_writeb, s);
  140 + register_ioport_write(0xcfc, 4, 2, pci_host_data_writew, s);
  141 + register_ioport_write(0xcfc, 4, 4, pci_host_data_writel, s);
  142 + register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s);
  143 + register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);
  144 + register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
  145 +
  146 + PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read,
  147 + PPC_PCIIO_write, s);
  148 + cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);
  149 +
  150 + /* PCI host bridge */
  151 + d = pci_register_device(s->bus, "PREP Host Bridge - Motorola Raven",
  152 + sizeof(PCIDevice), 0, NULL, NULL);
  153 + d->config[0x00] = 0x57; // vendor_id : Motorola
  154 + d->config[0x01] = 0x10;
  155 + d->config[0x02] = 0x01; // device_id : Raven
  156 + d->config[0x03] = 0x48;
  157 + d->config[0x08] = 0x00; // revision
  158 + d->config[0x0A] = 0x00; // class_sub = pci host
  159 + d->config[0x0B] = 0x06; // class_base = PCI_bridge
  160 + d->config[0x0C] = 0x08; // cache_line_size
  161 + d->config[0x0D] = 0x10; // latency_timer
  162 + d->config[0x0E] = 0x00; // header_type
  163 + d->config[0x34] = 0x00; // capabilities_pointer
  164 +
  165 + return s->bus;
  166 +}
  167 +
... ...
hw/sun4m.c
... ... @@ -183,6 +183,11 @@ void pic_set_irq(int irq, int level)
183 183 slavio_pic_set_irq(slavio_intctl, irq, level);
184 184 }
185 185  
  186 +void pic_set_irq_new(void *opaque, int irq, int level)
  187 +{
  188 + pic_set_irq(irq, level);
  189 +}
  190 +
186 191 void pic_set_irq_cpu(int irq, int level, unsigned int cpu)
187 192 {
188 193 slavio_pic_set_irq_cpu(slavio_intctl, irq, level, cpu);
... ...
hw/sun4u.c
... ... @@ -329,7 +329,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
329 329 }
330 330 }
331 331 }
332   - pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE);
  332 + pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, NULL);
333 333 isa_mem_base = VGA_BASE;
334 334 vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size,
335 335 vga_ram_size, 0, 0);
... ...
hw/unin_pci.c 0 → 100644
  1 +/*
  2 + * QEMU Uninorth PCI host (for all Mac99 and newer machines)
  3 + *
  4 + * Copyright (c) 2006 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include "vl.h"
  25 +typedef target_phys_addr_t pci_addr_t;
  26 +#include "pci_host.h"
  27 +
  28 +typedef PCIHostState UNINState;
  29 +
  30 +static void pci_unin_main_config_writel (void *opaque, target_phys_addr_t addr,
  31 + uint32_t val)
  32 +{
  33 + UNINState *s = opaque;
  34 + int i;
  35 +
  36 +#ifdef TARGET_WORDS_BIGENDIAN
  37 + val = bswap32(val);
  38 +#endif
  39 +
  40 + for (i = 11; i < 32; i++) {
  41 + if ((val & (1 << i)) != 0)
  42 + break;
  43 + }
  44 +#if 0
  45 + s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11);
  46 +#else
  47 + s->config_reg = 0x80000000 | (0 << 16) | (val & 0x7FC) | (i << 11);
  48 +#endif
  49 +}
  50 +
  51 +static uint32_t pci_unin_main_config_readl (void *opaque,
  52 + target_phys_addr_t addr)
  53 +{
  54 + UNINState *s = opaque;
  55 + uint32_t val;
  56 + int devfn;
  57 +
  58 + devfn = (s->config_reg >> 8) & 0xFF;
  59 + val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
  60 +#ifdef TARGET_WORDS_BIGENDIAN
  61 + val = bswap32(val);
  62 +#endif
  63 +
  64 + return val;
  65 +}
  66 +
  67 +static CPUWriteMemoryFunc *pci_unin_main_config_write[] = {
  68 + &pci_unin_main_config_writel,
  69 + &pci_unin_main_config_writel,
  70 + &pci_unin_main_config_writel,
  71 +};
  72 +
  73 +static CPUReadMemoryFunc *pci_unin_main_config_read[] = {
  74 + &pci_unin_main_config_readl,
  75 + &pci_unin_main_config_readl,
  76 + &pci_unin_main_config_readl,
  77 +};
  78 +
  79 +static CPUWriteMemoryFunc *pci_unin_main_write[] = {
  80 + &pci_host_data_writeb,
  81 + &pci_host_data_writew,
  82 + &pci_host_data_writel,
  83 +};
  84 +
  85 +static CPUReadMemoryFunc *pci_unin_main_read[] = {
  86 + &pci_host_data_readb,
  87 + &pci_host_data_readw,
  88 + &pci_host_data_readl,
  89 +};
  90 +
  91 +#if 0
  92 +
  93 +static void pci_unin_config_writel (void *opaque, target_phys_addr_t addr,
  94 + uint32_t val)
  95 +{
  96 + UNINState *s = opaque;
  97 +
  98 +#ifdef TARGET_WORDS_BIGENDIAN
  99 + val = bswap32(val);
  100 +#endif
  101 + s->config_reg = 0x80000000 | (val & ~0x00000001);
  102 +}
  103 +
  104 +static uint32_t pci_unin_config_readl (void *opaque,
  105 + target_phys_addr_t addr)
  106 +{
  107 + UNINState *s = opaque;
  108 + uint32_t val;
  109 +
  110 + val = (s->config_reg | 0x00000001) & ~0x80000000;
  111 +#ifdef TARGET_WORDS_BIGENDIAN
  112 + val = bswap32(val);
  113 +#endif
  114 +
  115 + return val;
  116 +}
  117 +
  118 +static CPUWriteMemoryFunc *pci_unin_config_write[] = {
  119 + &pci_unin_config_writel,
  120 + &pci_unin_config_writel,
  121 + &pci_unin_config_writel,
  122 +};
  123 +
  124 +static CPUReadMemoryFunc *pci_unin_config_read[] = {
  125 + &pci_unin_config_readl,
  126 + &pci_unin_config_readl,
  127 + &pci_unin_config_readl,
  128 +};
  129 +
  130 +static CPUWriteMemoryFunc *pci_unin_write[] = {
  131 + &pci_host_pci_writeb,
  132 + &pci_host_pci_writew,
  133 + &pci_host_pci_writel,
  134 +};
  135 +
  136 +static CPUReadMemoryFunc *pci_unin_read[] = {
  137 + &pci_host_pci_readb,
  138 + &pci_host_pci_readw,
  139 + &pci_host_pci_readl,
  140 +};
  141 +#endif
  142 +
  143 +static void pci_unin_set_irq(PCIDevice *d, void *pic, int irq_num, int level)
  144 +{
  145 + openpic_set_irq(pic, d->config[PCI_INTERRUPT_LINE], level);
  146 +}
  147 +
  148 +PCIBus *pci_pmac_init(void *pic)
  149 +{
  150 + UNINState *s;
  151 + PCIDevice *d;
  152 + int pci_mem_config, pci_mem_data;
  153 +
  154 + /* Use values found on a real PowerMac */
  155 + /* Uninorth main bus */
  156 + s = qemu_mallocz(sizeof(UNINState));
  157 + s->bus = pci_register_bus(pci_unin_set_irq, NULL, 11 << 3);
  158 +
  159 + pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read,
  160 + pci_unin_main_config_write, s);
  161 + pci_mem_data = cpu_register_io_memory(0, pci_unin_main_read,
  162 + pci_unin_main_write, s);
  163 + cpu_register_physical_memory(0xf2800000, 0x1000, pci_mem_config);
  164 + cpu_register_physical_memory(0xf2c00000, 0x1000, pci_mem_data);
  165 + d = pci_register_device(s->bus, "Uni-north main", sizeof(PCIDevice),
  166 + 11 << 3, NULL, NULL);
  167 + d->config[0x00] = 0x6b; // vendor_id : Apple
  168 + d->config[0x01] = 0x10;
  169 + d->config[0x02] = 0x1F; // device_id
  170 + d->config[0x03] = 0x00;
  171 + d->config[0x08] = 0x00; // revision
  172 + d->config[0x0A] = 0x00; // class_sub = pci host
  173 + d->config[0x0B] = 0x06; // class_base = PCI_bridge
  174 + d->config[0x0C] = 0x08; // cache_line_size
  175 + d->config[0x0D] = 0x10; // latency_timer
  176 + d->config[0x0E] = 0x00; // header_type
  177 + d->config[0x34] = 0x00; // capabilities_pointer
  178 +
  179 +#if 0 // XXX: not activated as PPC BIOS doesn't handle mutiple buses properly
  180 + /* pci-to-pci bridge */
  181 + d = pci_register_device("Uni-north bridge", sizeof(PCIDevice), 0, 13 << 3,
  182 + NULL, NULL);
  183 + d->config[0x00] = 0x11; // vendor_id : TI
  184 + d->config[0x01] = 0x10;
  185 + d->config[0x02] = 0x26; // device_id
  186 + d->config[0x03] = 0x00;
  187 + d->config[0x08] = 0x05; // revision
  188 + d->config[0x0A] = 0x04; // class_sub = pci2pci
  189 + d->config[0x0B] = 0x06; // class_base = PCI_bridge
  190 + d->config[0x0C] = 0x08; // cache_line_size
  191 + d->config[0x0D] = 0x20; // latency_timer
  192 + d->config[0x0E] = 0x01; // header_type
  193 +
  194 + d->config[0x18] = 0x01; // primary_bus
  195 + d->config[0x19] = 0x02; // secondary_bus
  196 + d->config[0x1A] = 0x02; // subordinate_bus
  197 + d->config[0x1B] = 0x20; // secondary_latency_timer
  198 + d->config[0x1C] = 0x11; // io_base
  199 + d->config[0x1D] = 0x01; // io_limit
  200 + d->config[0x20] = 0x00; // memory_base
  201 + d->config[0x21] = 0x80;
  202 + d->config[0x22] = 0x00; // memory_limit
  203 + d->config[0x23] = 0x80;
  204 + d->config[0x24] = 0x01; // prefetchable_memory_base
  205 + d->config[0x25] = 0x80;
  206 + d->config[0x26] = 0xF1; // prefectchable_memory_limit
  207 + d->config[0x27] = 0x7F;
  208 + // d->config[0x34] = 0xdc // capabilities_pointer
  209 +#endif
  210 +#if 0 // XXX: not needed for now
  211 + /* Uninorth AGP bus */
  212 + s = &pci_bridge[1];
  213 + pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
  214 + pci_unin_config_write, s);
  215 + pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
  216 + pci_unin_write, s);
  217 + cpu_register_physical_memory(0xf0800000, 0x1000, pci_mem_config);
  218 + cpu_register_physical_memory(0xf0c00000, 0x1000, pci_mem_data);
  219 +
  220 + d = pci_register_device("Uni-north AGP", sizeof(PCIDevice), 0, 11 << 3,
  221 + NULL, NULL);
  222 + d->config[0x00] = 0x6b; // vendor_id : Apple
  223 + d->config[0x01] = 0x10;
  224 + d->config[0x02] = 0x20; // device_id
  225 + d->config[0x03] = 0x00;
  226 + d->config[0x08] = 0x00; // revision
  227 + d->config[0x0A] = 0x00; // class_sub = pci host
  228 + d->config[0x0B] = 0x06; // class_base = PCI_bridge
  229 + d->config[0x0C] = 0x08; // cache_line_size
  230 + d->config[0x0D] = 0x10; // latency_timer
  231 + d->config[0x0E] = 0x00; // header_type
  232 + // d->config[0x34] = 0x80; // capabilities_pointer
  233 +#endif
  234 +
  235 +#if 0 // XXX: not needed for now
  236 + /* Uninorth internal bus */
  237 + s = &pci_bridge[2];
  238 + pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
  239 + pci_unin_config_write, s);
  240 + pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
  241 + pci_unin_write, s);
  242 + cpu_register_physical_memory(0xf4800000, 0x1000, pci_mem_config);
  243 + cpu_register_physical_memory(0xf4c00000, 0x1000, pci_mem_data);
  244 +
  245 + d = pci_register_device("Uni-north internal", sizeof(PCIDevice),
  246 + 3, 11 << 3, NULL, NULL);
  247 + d->config[0x00] = 0x6b; // vendor_id : Apple
  248 + d->config[0x01] = 0x10;
  249 + d->config[0x02] = 0x1E; // device_id
  250 + d->config[0x03] = 0x00;
  251 + d->config[0x08] = 0x00; // revision
  252 + d->config[0x0A] = 0x00; // class_sub = pci host
  253 + d->config[0x0B] = 0x06; // class_base = PCI_bridge
  254 + d->config[0x0C] = 0x08; // cache_line_size
  255 + d->config[0x0D] = 0x10; // latency_timer
  256 + d->config[0x0E] = 0x00; // header_type
  257 + d->config[0x34] = 0x00; // capabilities_pointer
  258 +#endif
  259 + return s->bus;
  260 +}
  261 +
... ...
hw/usb-uhci.c
... ... @@ -638,7 +638,7 @@ static void uhci_map(PCIDevice *pci_dev, int region_num,
638 638 register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
639 639 }
640 640  
641   -void usb_uhci_init(PCIBus *bus, USBPort **usb_ports)
  641 +void usb_uhci_init(PCIBus *bus, USBPort **usb_ports, int devfn)
642 642 {
643 643 UHCIState *s;
644 644 uint8_t *pci_conf;
... ... @@ -647,8 +647,7 @@ void usb_uhci_init(PCIBus *bus, USBPort **usb_ports)
647 647  
648 648 s = (UHCIState *)pci_register_device(bus,
649 649 "USB-UHCI", sizeof(UHCIState),
650   - ((PCIDevice *)piix3_state)->devfn + 2,
651   - NULL, NULL);
  650 + devfn, NULL, NULL);
652 651 pci_conf = s->dev.config;
653 652 pci_conf[0x00] = 0x86;
654 653 pci_conf[0x01] = 0x80;
... ...
hw/usb.h
... ... @@ -155,7 +155,7 @@ int set_usb_string(uint8_t *buf, const char *str);
155 155 USBDevice *usb_hub_init(USBPort **usb_ports, int nb_ports);
156 156  
157 157 /* usb-uhci.c */
158   -void usb_uhci_init(PCIBus *bus, USBPort **usb_ports);
  158 +void usb_uhci_init(PCIBus *bus, USBPort **usb_ports, int devfn);
159 159  
160 160 /* usb-linux.c */
161 161 USBDevice *usb_host_device_open(const char *devname);
... ...
hw/versatile_pci.c 0 → 100644
  1 +/*
  2 + * ARM Versatile/PB PCI host controller
  3 + *
  4 + * Copyright (c) 2006 CodeSourcery.
  5 + * Written by Paul Brook
  6 + *
  7 + * This code is licenced under the LGPL.
  8 + */
  9 +
  10 +#include "vl.h"
  11 +
  12 +static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr)
  13 +{
  14 + return addr & 0xf8ff;
  15 +}
  16 +
  17 +static void pci_vpb_config_writeb (void *opaque, target_phys_addr_t addr,
  18 + uint32_t val)
  19 +{
  20 + pci_data_write(opaque, vpb_pci_config_addr (addr), val, 1);
  21 +}
  22 +
  23 +static void pci_vpb_config_writew (void *opaque, target_phys_addr_t addr,
  24 + uint32_t val)
  25 +{
  26 +#ifdef TARGET_WORDS_BIGENDIAN
  27 + val = bswap16(val);
  28 +#endif
  29 + pci_data_write(opaque, vpb_pci_config_addr (addr), val, 2);
  30 +}
  31 +
  32 +static void pci_vpb_config_writel (void *opaque, target_phys_addr_t addr,
  33 + uint32_t val)
  34 +{
  35 +#ifdef TARGET_WORDS_BIGENDIAN
  36 + val = bswap32(val);
  37 +#endif
  38 + pci_data_write(opaque, vpb_pci_config_addr (addr), val, 4);
  39 +}
  40 +
  41 +static uint32_t pci_vpb_config_readb (void *opaque, target_phys_addr_t addr)
  42 +{
  43 + uint32_t val;
  44 + val = pci_data_read(opaque, vpb_pci_config_addr (addr), 1);
  45 + return val;
  46 +}
  47 +
  48 +static uint32_t pci_vpb_config_readw (void *opaque, target_phys_addr_t addr)
  49 +{
  50 + uint32_t val;
  51 + val = pci_data_read(opaque, vpb_pci_config_addr (addr), 2);
  52 +#ifdef TARGET_WORDS_BIGENDIAN
  53 + val = bswap16(val);
  54 +#endif
  55 + return val;
  56 +}
  57 +
  58 +static uint32_t pci_vpb_config_readl (void *opaque, target_phys_addr_t addr)
  59 +{
  60 + uint32_t val;
  61 + val = pci_data_read(opaque, vpb_pci_config_addr (addr), 4);
  62 +#ifdef TARGET_WORDS_BIGENDIAN
  63 + val = bswap32(val);
  64 +#endif
  65 + return val;
  66 +}
  67 +
  68 +static CPUWriteMemoryFunc *pci_vpb_config_write[] = {
  69 + &pci_vpb_config_writeb,
  70 + &pci_vpb_config_writew,
  71 + &pci_vpb_config_writel,
  72 +};
  73 +
  74 +static CPUReadMemoryFunc *pci_vpb_config_read[] = {
  75 + &pci_vpb_config_readb,
  76 + &pci_vpb_config_readw,
  77 + &pci_vpb_config_readl,
  78 +};
  79 +
  80 +static void pci_vpb_set_irq(PCIDevice *d, void *pic, int irq_num, int level)
  81 +{
  82 + pic_set_irq_new(pic, 27 + irq_num, level);
  83 +}
  84 +
  85 +PCIBus *pci_vpb_init(void *pic)
  86 +{
  87 + PCIBus *s;
  88 + PCIDevice *d;
  89 + int mem_config;
  90 +
  91 + s = pci_register_bus(pci_vpb_set_irq, pic, 11 << 3);
  92 + /* ??? Register memory space. */
  93 +
  94 + mem_config = cpu_register_io_memory(0, pci_vpb_config_read,
  95 + pci_vpb_config_write, s);
  96 + /* Selfconfig area. */
  97 + cpu_register_physical_memory(0x41000000, 0x10000, mem_config);
  98 + /* Normal config area. */
  99 + cpu_register_physical_memory(0x42000000, 0x10000, mem_config);
  100 +
  101 + d = pci_register_device(s, "Versatile/PB PCI Controller",
  102 + sizeof(PCIDevice), -1, NULL, NULL);
  103 + d->config[0x00] = 0xee; // vendor_id
  104 + d->config[0x01] = 0x10;
  105 + d->config[0x02] = 0x00; // device_id
  106 + d->config[0x03] = 0x03;
  107 + d->config[0x04] = 0x00;
  108 + d->config[0x05] = 0x00;
  109 + d->config[0x06] = 0x20;
  110 + d->config[0x07] = 0x02;
  111 + d->config[0x08] = 0x00; // revision
  112 + d->config[0x09] = 0x00; // programming i/f
  113 + d->config[0x0A] = 0x40; // class_sub = pci host
  114 + d->config[0x0B] = 0x0b; // class_base = PCI_bridge
  115 + d->config[0x0D] = 0x10; // latency_timer
  116 +
  117 + return s;
  118 +}
  119 +
... ...
hw/versatilepb.c
... ... @@ -10,6 +10,8 @@
10 10 #include "vl.h"
11 11 #include "arm_pic.h"
12 12  
  13 +#define LOCK_VALUE 0xa05f
  14 +
13 15 /* Primary interrupt controller. */
14 16  
15 17 typedef struct vpb_sic_state
... ... @@ -145,6 +147,188 @@ static vpb_sic_state *vpb_sic_init(uint32_t base, void *parent, int irq)
145 147 return s;
146 148 }
147 149  
  150 +/* System controller. */
  151 +
  152 +typedef struct {
  153 + uint32_t base;
  154 + uint32_t leds;
  155 + uint16_t lockval;
  156 + uint32_t cfgdata1;
  157 + uint32_t cfgdata2;
  158 + uint32_t flags;
  159 + uint32_t nvflags;
  160 + uint32_t resetlevel;
  161 +} vpb_sys_state;
  162 +
  163 +static uint32_t vpb_sys_read(void *opaque, target_phys_addr_t offset)
  164 +{
  165 + vpb_sys_state *s = (vpb_sys_state *)opaque;
  166 +
  167 + offset -= s->base;
  168 + switch (offset) {
  169 + case 0x00: /* ID */
  170 + return 0x41007004;
  171 + case 0x04: /* SW */
  172 + /* General purpose hardware switches.
  173 + We don't have a useful way of exposing these to the user. */
  174 + return 0;
  175 + case 0x08: /* LED */
  176 + return s->leds;
  177 + case 0x20: /* LOCK */
  178 + return s->lockval;
  179 + case 0x0c: /* OSC0 */
  180 + case 0x10: /* OSC1 */
  181 + case 0x14: /* OSC2 */
  182 + case 0x18: /* OSC3 */
  183 + case 0x1c: /* OSC4 */
  184 + case 0x24: /* 100HZ */
  185 + /* ??? Implement these. */
  186 + return 0;
  187 + case 0x28: /* CFGDATA1 */
  188 + return s->cfgdata1;
  189 + case 0x2c: /* CFGDATA2 */
  190 + return s->cfgdata2;
  191 + case 0x30: /* FLAGS */
  192 + return s->flags;
  193 + case 0x38: /* NVFLAGS */
  194 + return s->nvflags;
  195 + case 0x40: /* RESETCTL */
  196 + return s->resetlevel;
  197 + case 0x44: /* PCICTL */
  198 + return 1;
  199 + case 0x48: /* MCI */
  200 + return 0;
  201 + case 0x4c: /* FLASH */
  202 + return 0;
  203 + case 0x50: /* CLCD */
  204 + return 0x1000;
  205 + case 0x54: /* CLCDSER */
  206 + return 0;
  207 + case 0x58: /* BOOTCS */
  208 + return 0;
  209 + case 0x5c: /* 24MHz */
  210 + /* ??? not implemented. */
  211 + return 0;
  212 + case 0x60: /* MISC */
  213 + return 0;
  214 + case 0x64: /* DMAPSR0 */
  215 + case 0x68: /* DMAPSR1 */
  216 + case 0x6c: /* DMAPSR2 */
  217 + case 0x8c: /* OSCRESET0 */
  218 + case 0x90: /* OSCRESET1 */
  219 + case 0x94: /* OSCRESET2 */
  220 + case 0x98: /* OSCRESET3 */
  221 + case 0x9c: /* OSCRESET4 */
  222 + case 0xc0: /* SYS_TEST_OSC0 */
  223 + case 0xc4: /* SYS_TEST_OSC1 */
  224 + case 0xc8: /* SYS_TEST_OSC2 */
  225 + case 0xcc: /* SYS_TEST_OSC3 */
  226 + case 0xd0: /* SYS_TEST_OSC4 */
  227 + return 0;
  228 + default:
  229 + printf ("vpb_sys_read: Bad register offset 0x%x\n", offset);
  230 + return 0;
  231 + }
  232 +}
  233 +
  234 +static void vpb_sys_write(void *opaque, target_phys_addr_t offset,
  235 + uint32_t val)
  236 +{
  237 + vpb_sys_state *s = (vpb_sys_state *)opaque;
  238 + offset -= s->base;
  239 +
  240 + switch (offset) {
  241 + case 0x08: /* LED */
  242 + s->leds = val;
  243 + case 0x0c: /* OSC0 */
  244 + case 0x10: /* OSC1 */
  245 + case 0x14: /* OSC2 */
  246 + case 0x18: /* OSC3 */
  247 + case 0x1c: /* OSC4 */
  248 + /* ??? */
  249 + break;
  250 + case 0x20: /* LOCK */
  251 + if (val == LOCK_VALUE)
  252 + s->lockval = val;
  253 + else
  254 + s->lockval = val & 0x7fff;
  255 + break;
  256 + case 0x28: /* CFGDATA1 */
  257 + /* ??? Need to implement this. */
  258 + s->cfgdata1 = val;
  259 + break;
  260 + case 0x2c: /* CFGDATA2 */
  261 + /* ??? Need to implement this. */
  262 + s->cfgdata2 = val;
  263 + break;
  264 + case 0x30: /* FLAGSSET */
  265 + s->flags |= val;
  266 + break;
  267 + case 0x34: /* FLAGSCLR */
  268 + s->flags &= ~val;
  269 + break;
  270 + case 0x38: /* NVFLAGSSET */
  271 + s->nvflags |= val;
  272 + break;
  273 + case 0x3c: /* NVFLAGSCLR */
  274 + s->nvflags &= ~val;
  275 + break;
  276 + case 0x40: /* RESETCTL */
  277 + if (s->lockval == LOCK_VALUE) {
  278 + s->resetlevel = val;
  279 + if (val & 0x100)
  280 + cpu_abort(cpu_single_env, "Board reset\n");
  281 + }
  282 + break;
  283 + case 0x44: /* PCICTL */
  284 + /* nothing to do. */
  285 + break;
  286 + case 0x4c: /* FLASH */
  287 + case 0x50: /* CLCD */
  288 + case 0x54: /* CLCDSER */
  289 + case 0x64: /* DMAPSR0 */
  290 + case 0x68: /* DMAPSR1 */
  291 + case 0x6c: /* DMAPSR2 */
  292 + case 0x8c: /* OSCRESET0 */
  293 + case 0x90: /* OSCRESET1 */
  294 + case 0x94: /* OSCRESET2 */
  295 + case 0x98: /* OSCRESET3 */
  296 + case 0x9c: /* OSCRESET4 */
  297 + break;
  298 + default:
  299 + printf ("vpb_sys_write: Bad register offset 0x%x\n", offset);
  300 + return;
  301 + }
  302 +}
  303 +
  304 +static CPUReadMemoryFunc *vpb_sys_readfn[] = {
  305 + vpb_sys_read,
  306 + vpb_sys_read,
  307 + vpb_sys_read
  308 +};
  309 +
  310 +static CPUWriteMemoryFunc *vpb_sys_writefn[] = {
  311 + vpb_sys_write,
  312 + vpb_sys_write,
  313 + vpb_sys_write
  314 +};
  315 +
  316 +static vpb_sys_state *vpb_sys_init(uint32_t base)
  317 +{
  318 + vpb_sys_state *s;
  319 + int iomemtype;
  320 +
  321 + s = (vpb_sys_state *)qemu_mallocz(sizeof(vpb_sys_state));
  322 + if (!s)
  323 + return NULL;
  324 + s->base = base;
  325 + iomemtype = cpu_register_io_memory(0, vpb_sys_readfn,
  326 + vpb_sys_writefn, s);
  327 + cpu_register_physical_memory(base, 0x00000fff, iomemtype);
  328 + /* ??? Save/restore. */
  329 + return s;
  330 +}
  331 +
148 332 /* Board init. */
149 333  
150 334 /* The AB and PB boards both use the same core, just with different
... ... @@ -159,6 +343,10 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
159 343 CPUState *env;
160 344 void *pic;
161 345 void *sic;
  346 + PCIBus *pci_bus;
  347 + NICInfo *nd;
  348 + int n;
  349 + int done_smc = 0;
162 350  
163 351 env = cpu_init();
164 352 cpu_arm_set_model(env, ARM_CPUID_ARM926);
... ... @@ -166,20 +354,24 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
166 354 /* SDRAM at address zero. */
167 355 cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
168 356  
  357 + vpb_sys_init(0x10000000);
169 358 pic = arm_pic_init_cpu(env);
170 359 pic = pl190_init(0x10140000, pic, ARM_PIC_CPU_IRQ, ARM_PIC_CPU_FIQ);
171 360 sic = vpb_sic_init(0x10003000, pic, 31);
172 361 pl050_init(0x10006000, sic, 3, 0);
173 362 pl050_init(0x10007000, sic, 4, 1);
174 363  
175   - /* TODO: Init PCI NICs. */
176   - if (nd_table[0].vlan) {
177   - if (nd_table[0].model == NULL
178   - || strcmp(nd_table[0].model, "smc91c111") == 0) {
179   - smc91c111_init(&nd_table[0], 0x10010000, sic, 25);
  364 + pci_bus = pci_vpb_init(sic);
  365 + /* The Versatile PCI bridge does not provide access to PCI IO space,
  366 + so many of the qemu PCI devices are not useable. */
  367 + for(n = 0; n < nb_nics; n++) {
  368 + nd = &nd_table[n];
  369 + if (!nd->model)
  370 + nd->model = done_smc ? "rtl8139" : "smc91c111";
  371 + if (strcmp(nd->model, "smc91c111") == 0) {
  372 + smc91c111_init(nd, 0x10010000, sic, 25);
180 373 } else {
181   - fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
182   - exit (1);
  374 + pci_nic_init(pci_bus, nd);
183 375 }
184 376 }
185 377  
... ...
... ... @@ -593,6 +593,20 @@ typedef struct PCIIORegion {
593 593  
594 594 #define PCI_ROM_SLOT 6
595 595 #define PCI_NUM_REGIONS 7
  596 +
  597 +#define PCI_DEVICES_MAX 64
  598 +
  599 +#define PCI_VENDOR_ID 0x00 /* 16 bits */
  600 +#define PCI_DEVICE_ID 0x02 /* 16 bits */
  601 +#define PCI_COMMAND 0x04 /* 16 bits */
  602 +#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
  603 +#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
  604 +#define PCI_CLASS_DEVICE 0x0a /* Device class */
  605 +#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
  606 +#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
  607 +#define PCI_MIN_GNT 0x3e /* 8 bits */
  608 +#define PCI_MAX_LAT 0x3f /* 8 bits */
  609 +
596 610 struct PCIDevice {
597 611 /* PCI config space */
598 612 uint8_t config[256];
... ... @@ -606,6 +620,7 @@ struct PCIDevice {
606 620 /* do not access the following fields */
607 621 PCIConfigReadFunc *config_read;
608 622 PCIConfigWriteFunc *config_write;
  623 + /* ??? This is a PC-specific hack, and should be removed. */
609 624 int irq_index;
610 625 };
611 626  
... ... @@ -627,21 +642,37 @@ void pci_default_write_config(PCIDevice *d,
627 642 void generic_pci_save(QEMUFile* f, void *opaque);
628 643 int generic_pci_load(QEMUFile* f, void *opaque, int version_id);
629 644  
630   -extern struct PIIX3State *piix3_state;
  645 +typedef void (*pci_set_irq_fn)(PCIDevice *pci_dev, void *pic,
  646 + int irq_num, int level);
  647 +PCIBus *pci_register_bus(pci_set_irq_fn set_irq, void *pic, int devfn_min);
  648 +
  649 +void pci_nic_init(PCIBus *bus, NICInfo *nd);
  650 +void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len);
  651 +uint32_t pci_data_read(void *opaque, uint32_t addr, int len);
  652 +int pci_bus_num(PCIBus *s);
  653 +void pci_for_each_device(void (*fn)(PCIDevice *d));
631 654  
632   -PCIBus *i440fx_init(void);
633   -void piix3_init(PCIBus *bus);
634   -void pci_bios_init(void);
635 655 void pci_info(void);
636 656  
637   -/* temporary: will be moved in platform specific file */
638   -void pci_set_pic(PCIBus *bus, SetIRQFunc *set_irq, void *irq_opaque);
  657 +/* prep_pci.c */
639 658 PCIBus *pci_prep_init(void);
640   -PCIBus *pci_grackle_init(uint32_t base);
641   -PCIBus *pci_pmac_init(void);
642   -PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base);
643 659  
644   -void pci_nic_init(PCIBus *bus, NICInfo *nd);
  660 +/* grackle_pci.c */
  661 +PCIBus *pci_grackle_init(uint32_t base, void *pic);
  662 +
  663 +/* unin_pci.c */
  664 +PCIBus *pci_pmac_init(void *pic);
  665 +
  666 +/* apb_pci.c */
  667 +PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
  668 + void *pic);
  669 +
  670 +PCIBus *pci_vpb_init(void *pic);
  671 +
  672 +/* piix_pci.c */
  673 +PCIBus *i440fx_init(void);
  674 +int piix3_init(PCIBus *bus);
  675 +void pci_bios_init(void);
645 676  
646 677 /* openpic.c */
647 678 typedef struct openpic_t openpic_t;
... ... @@ -726,7 +757,7 @@ void isa_ide_init(int iobase, int iobase2, int irq,
726 757 BlockDriverState *hd0, BlockDriverState *hd1);
727 758 void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
728 759 int secondary_ide_enabled);
729   -void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table);
  760 +void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn);
730 761 int pmac_ide_init (BlockDriverState **hd_table,
731 762 SetIRQFunc *set_irq, void *irq_opaque, int irq);
732 763  
... ... @@ -843,7 +874,7 @@ int pcspk_audio_init(AudioState *);
843 874  
844 875 /* acpi.c */
845 876 extern int acpi_enabled;
846   -void piix4_pm_init(PCIBus *bus);
  877 +void piix4_pm_init(PCIBus *bus, int devfn);
847 878 void acpi_bios_init(void);
848 879  
849 880 /* pc.c */
... ...