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,7 +307,7 @@ SOUND_HW += fmopl.o adlib.o
307 endif 307 endif
308 308
309 # USB layer 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 # PCI network cards 312 # PCI network cards
313 VL_OBJS+= ne2000.o rtl8139.o 313 VL_OBJS+= ne2000.o rtl8139.o
@@ -316,13 +316,15 @@ ifeq ($(TARGET_BASE_ARCH), i386) @@ -316,13 +316,15 @@ ifeq ($(TARGET_BASE_ARCH), i386)
316 # Hardware support 316 # Hardware support
317 VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) 317 VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
318 VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o 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 DEFINES += -DHAS_AUDIO 321 DEFINES += -DHAS_AUDIO
321 endif 322 endif
322 ifeq ($(TARGET_BASE_ARCH), ppc) 323 ifeq ($(TARGET_BASE_ARCH), ppc)
323 VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) 324 VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
324 VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o 325 VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
325 VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o 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 DEFINES += -DHAS_AUDIO 328 DEFINES += -DHAS_AUDIO
327 endif 329 endif
328 ifeq ($(TARGET_ARCH), mips) 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,7 +333,7 @@ VL_OBJS+= mips_r4k.o dma.o vga.o serial.o i8254.o i8259.o
331 endif 333 endif
332 ifeq ($(TARGET_BASE_ARCH), sparc) 334 ifeq ($(TARGET_BASE_ARCH), sparc)
333 ifeq ($(TARGET_ARCH), sparc64) 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 VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o 337 VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o
336 VL_OBJS+= cirrus_vga.o parallel.o 338 VL_OBJS+= cirrus_vga.o parallel.o
337 else 339 else
@@ -342,6 +344,7 @@ endif @@ -342,6 +344,7 @@ endif
342 ifeq ($(TARGET_BASE_ARCH), arm) 344 ifeq ($(TARGET_BASE_ARCH), arm)
343 VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o 345 VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
344 VL_OBJS+= arm_boot.o pl011.o pl050.o pl080.o pl110.o pl190.o 346 VL_OBJS+= arm_boot.o pl011.o pl050.o pl080.o pl110.o pl190.o
  347 +VL_OBJS+= versatile_pci.o
345 endif 348 endif
346 ifeq ($(TARGET_BASE_ARCH), sh4) 349 ifeq ($(TARGET_BASE_ARCH), sh4)
347 VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o 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,7 +220,7 @@ static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
220 220
221 /* XXX: we still add it to the PIIX3 and we count on the fact that 221 /* XXX: we still add it to the PIIX3 and we count on the fact that
222 OSes are smart enough to accept this strange configuration */ 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 PIIX4PMState *s; 225 PIIX4PMState *s;
226 uint8_t *pci_conf; 226 uint8_t *pci_conf;
@@ -228,8 +228,7 @@ void piix4_pm_init(PCIBus *bus) @@ -228,8 +228,7 @@ void piix4_pm_init(PCIBus *bus)
228 228
229 s = (PIIX4PMState *)pci_register_device(bus, 229 s = (PIIX4PMState *)pci_register_device(bus,
230 "PM", sizeof(PIIX4PMState), 230 "PM", sizeof(PIIX4PMState),
231 - ((PCIDevice *)piix3_state)->devfn + 3,  
232 - NULL, NULL); 231 + devfn, NULL, NULL);
233 pci_conf = s->dev.config; 232 pci_conf = s->dev.config;
234 pci_conf[0x00] = 0x86; 233 pci_conf[0x00] = 0x86;
235 pci_conf[0x01] = 0x80; 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,7 +2490,7 @@ void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
2490 2490
2491 /* hd_table must contain 4 block drivers */ 2491 /* hd_table must contain 4 block drivers */
2492 /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */ 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 PCIIDEState *d; 2495 PCIIDEState *d;
2496 uint8_t *pci_conf; 2496 uint8_t *pci_conf;
@@ -2498,7 +2498,7 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table) @@ -2498,7 +2498,7 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table)
2498 /* register a function 1 of PIIX3 */ 2498 /* register a function 1 of PIIX3 */
2499 d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE", 2499 d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE",
2500 sizeof(PCIIDEState), 2500 sizeof(PCIIDEState),
2501 - ((PCIDevice *)piix3_state)->devfn + 1, 2501 + devfn,
2502 NULL, NULL); 2502 NULL, NULL);
2503 d->type = IDE_TYPE_PIIX3; 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,6 +611,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
611 unsigned long bios_offset, vga_bios_offset; 611 unsigned long bios_offset, vga_bios_offset;
612 int bios_size, isa_bios_size; 612 int bios_size, isa_bios_size;
613 PCIBus *pci_bus; 613 PCIBus *pci_bus;
  614 + int piix3_devfn;
614 CPUState *env; 615 CPUState *env;
615 NICInfo *nd; 616 NICInfo *nd;
616 617
@@ -741,7 +742,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device, @@ -741,7 +742,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
741 742
742 if (pci_enabled) { 743 if (pci_enabled) {
743 pci_bus = i440fx_init(); 744 pci_bus = i440fx_init();
744 - piix3_init(pci_bus); 745 + piix3_devfn = piix3_init(pci_bus);
745 } else { 746 } else {
746 pci_bus = NULL; 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,7 +814,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
813 } 814 }
814 815
815 if (pci_enabled) { 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 } else { 818 } else {
818 for(i = 0; i < 2; i++) { 819 for(i = 0; i < 2; i++) {
819 isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], 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,12 +833,12 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
832 cmos_init(ram_size, boot_device, bs_table); 833 cmos_init(ram_size, boot_device, bs_table);
833 834
834 if (pci_enabled && usb_enabled) { 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 usb_attach(usb_root_ports[0], vm_usb_hub); 837 usb_attach(usb_root_ports[0], vm_usb_hub);
837 } 838 }
838 839
839 if (pci_enabled && acpi_enabled) { 840 if (pci_enabled && acpi_enabled) {
840 - piix4_pm_init(pci_bus); 841 + piix4_pm_init(pci_bus, piix3_devfn + 3);
841 } 842 }
842 /* must be done after all PCI devices are instanciated */ 843 /* must be done after all PCI devices are instanciated */
843 /* XXX: should be done in the Bochs BIOS */ 844 /* XXX: should be done in the Bochs BIOS */
hw/pci.c
@@ -25,25 +25,10 @@ @@ -25,25 +25,10 @@
25 25
26 //#define DEBUG_PCI 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 struct PCIBus { 28 struct PCIBus {
44 int bus_num; 29 int bus_num;
45 int devfn_min; 30 int devfn_min;
46 - void (*set_irq)(PCIDevice *pci_dev, int irq_num, int level); 31 + pci_set_irq_fn set_irq;
47 uint32_t config_reg; /* XXX: suppress */ 32 uint32_t config_reg; /* XXX: suppress */
48 /* low level pic */ 33 /* low level pic */
49 SetIRQFunc *low_set_irq; 34 SetIRQFunc *low_set_irq;
@@ -53,17 +38,24 @@ struct PCIBus { @@ -53,17 +38,24 @@ struct PCIBus {
53 38
54 target_phys_addr_t pci_mem_base; 39 target_phys_addr_t pci_mem_base;
55 static int pci_irq_index; 40 static int pci_irq_index;
56 -static uint32_t pci_irq_levels[4][PCI_IRQ_WORDS];  
57 static PCIBus *first_bus; 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 PCIBus *bus; 45 PCIBus *bus;
62 bus = qemu_mallocz(sizeof(PCIBus)); 46 bus = qemu_mallocz(sizeof(PCIBus));
  47 + bus->set_irq = set_irq;
  48 + bus->irq_opaque = pic;
  49 + bus->devfn_min = devfn_min;
63 first_bus = bus; 50 first_bus = bus;
64 return bus; 51 return bus;
65 } 52 }
66 53
  54 +int pci_bus_num(PCIBus *s)
  55 +{
  56 + return s->bus_num;
  57 +}
  58 +
67 void generic_pci_save(QEMUFile* f, void *opaque) 59 void generic_pci_save(QEMUFile* f, void *opaque)
68 { 60 {
69 PCIDevice* s=(PCIDevice*)opaque; 61 PCIDevice* s=(PCIDevice*)opaque;
@@ -141,16 +133,9 @@ void pci_register_io_region(PCIDevice *pci_dev, int region_num, @@ -141,16 +133,9 @@ void pci_register_io_region(PCIDevice *pci_dev, int region_num,
141 *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type); 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 static void pci_update_mappings(PCIDevice *d) 141 static void pci_update_mappings(PCIDevice *d)
@@ -218,7 +203,7 @@ static void pci_update_mappings(PCIDevice *d) @@ -218,7 +203,7 @@ static void pci_update_mappings(PCIDevice *d)
218 isa_unassign_ioport(r->addr, r->size); 203 isa_unassign_ioport(r->addr, r->size);
219 } 204 }
220 } else { 205 } else {
221 - cpu_register_physical_memory(r->addr + pci_mem_base, 206 + cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
222 r->size, 207 r->size,
223 IO_MEM_UNASSIGNED); 208 IO_MEM_UNASSIGNED);
224 } 209 }
@@ -346,8 +331,7 @@ void pci_default_write_config(PCIDevice *d, @@ -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 PCIBus *s = opaque; 336 PCIBus *s = opaque;
353 PCIDevice *pci_dev; 337 PCIDevice *pci_dev;
@@ -355,18 +339,15 @@ static void pci_data_write(void *opaque, uint32_t addr, @@ -355,18 +339,15 @@ static void pci_data_write(void *opaque, uint32_t addr,
355 339
356 #if defined(DEBUG_PCI) && 0 340 #if defined(DEBUG_PCI) && 0
357 printf("pci_data_write: addr=%08x val=%08x len=%d\n", 341 printf("pci_data_write: addr=%08x val=%08x len=%d\n",
358 - s->config_reg, val, len); 342 + addr, val, len);
359 #endif 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 if (bus_num != 0) 345 if (bus_num != 0)
365 return; 346 return;
366 - pci_dev = s->devices[(s->config_reg >> 8) & 0xff]; 347 + pci_dev = s->devices[(addr >> 8) & 0xff];
367 if (!pci_dev) 348 if (!pci_dev)
368 return; 349 return;
369 - config_addr = (s->config_reg & 0xfc) | (addr & 3); 350 + config_addr = addr & 0xff;
370 #if defined(DEBUG_PCI) 351 #if defined(DEBUG_PCI)
371 printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n", 352 printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
372 pci_dev->name, config_addr, val, len); 353 pci_dev->name, config_addr, val, len);
@@ -374,20 +355,17 @@ static void pci_data_write(void *opaque, uint32_t addr, @@ -374,20 +355,17 @@ static void pci_data_write(void *opaque, uint32_t addr,
374 pci_dev->config_write(pci_dev, config_addr, val, len); 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 PCIBus *s = opaque; 360 PCIBus *s = opaque;
381 PCIDevice *pci_dev; 361 PCIDevice *pci_dev;
382 int config_addr, bus_num; 362 int config_addr, bus_num;
383 uint32_t val; 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 if (bus_num != 0) 366 if (bus_num != 0)
389 goto fail; 367 goto fail;
390 - pci_dev = s->devices[(s->config_reg >> 8) & 0xff]; 368 + pci_dev = s->devices[(addr >> 8) & 0xff];
391 if (!pci_dev) { 369 if (!pci_dev) {
392 fail: 370 fail:
393 switch(len) { 371 switch(len) {
@@ -404,7 +382,7 @@ static uint32_t pci_data_read(void *opaque, uint32_t addr, @@ -404,7 +382,7 @@ static uint32_t pci_data_read(void *opaque, uint32_t addr,
404 } 382 }
405 goto the_end; 383 goto the_end;
406 } 384 }
407 - config_addr = (s->config_reg & 0xfc) | (addr & 3); 385 + config_addr = addr & 0xff;
408 val = pci_dev->config_read(pci_dev, config_addr, len); 386 val = pci_dev->config_read(pci_dev, config_addr, len);
409 #if defined(DEBUG_PCI) 387 #if defined(DEBUG_PCI)
410 printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n", 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,1431 +391,87 @@ static uint32_t pci_data_read(void *opaque, uint32_t addr,
413 the_end: 391 the_end:
414 #if defined(DEBUG_PCI) && 0 392 #if defined(DEBUG_PCI) && 0
415 printf("pci_data_read: addr=%08x val=%08x len=%d\n", 393 printf("pci_data_read: addr=%08x val=%08x len=%d\n",
416 - s->config_reg, val, len); 394 + addr, val, len);
417 #endif 395 #endif
418 return val; 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 PCIDevice *d; 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 /* Initialize a PCI NIC. */ 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,19 +415,18 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
415 415
416 if (is_heathrow) { 416 if (is_heathrow) {
417 isa_mem_base = 0x80000000; 417 isa_mem_base = 0x80000000;
418 - pci_bus = pci_grackle_init(0xfec00000);  
419 418
420 /* Register 2 MB of ISA IO space */ 419 /* Register 2 MB of ISA IO space */
421 PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL); 420 PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL);
422 cpu_register_physical_memory(0xfe000000, 0x00200000, PPC_io_memory); 421 cpu_register_physical_memory(0xfe000000, 0x00200000, PPC_io_memory);
423 422
424 /* init basic PC hardware */ 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 vga_initialize(pci_bus, ds, phys_ram_base + ram_size, 427 vga_initialize(pci_bus, ds, phys_ram_base + ram_size,
426 ram_size, vga_ram_size, 428 ram_size, vga_ram_size,
427 vga_bios_offset, vga_bios_size); 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 /* XXX: suppress that */ 431 /* XXX: suppress that */
433 isa_pic = pic_init(pic_irq_request, NULL); 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,7 +461,6 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
462 arch_name = "HEATHROW"; 461 arch_name = "HEATHROW";
463 } else { 462 } else {
464 isa_mem_base = 0x80000000; 463 isa_mem_base = 0x80000000;
465 - pci_bus = pci_pmac_init();  
466 464
467 /* Register 8 MB of ISA IO space */ 465 /* Register 8 MB of ISA IO space */
468 PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL); 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,13 +470,13 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
472 unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL); 470 unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL);
473 cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory); 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 /* init basic PC hardware */ 476 /* init basic PC hardware */
476 vga_initialize(pci_bus, ds, phys_ram_base + ram_size, 477 vga_initialize(pci_bus, ds, phys_ram_base + ram_size,
477 ram_size, vga_ram_size, 478 ram_size, vga_ram_size,
478 vga_bios_offset, vga_bios_size); 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 /* XXX: suppress that */ 481 /* XXX: suppress that */
484 isa_pic = pic_init(pic_irq_request, NULL); 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,6 +183,11 @@ void pic_set_irq(int irq, int level)
183 slavio_pic_set_irq(slavio_intctl, irq, level); 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 void pic_set_irq_cpu(int irq, int level, unsigned int cpu) 191 void pic_set_irq_cpu(int irq, int level, unsigned int cpu)
187 { 192 {
188 slavio_pic_set_irq_cpu(slavio_intctl, irq, level, cpu); 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,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 isa_mem_base = VGA_BASE; 333 isa_mem_base = VGA_BASE;
334 vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, 334 vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size,
335 vga_ram_size, 0, 0); 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,7 +638,7 @@ static void uhci_map(PCIDevice *pci_dev, int region_num,
638 register_ioport_read(addr, 32, 1, uhci_ioport_readb, s); 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 UHCIState *s; 643 UHCIState *s;
644 uint8_t *pci_conf; 644 uint8_t *pci_conf;
@@ -647,8 +647,7 @@ void usb_uhci_init(PCIBus *bus, USBPort **usb_ports) @@ -647,8 +647,7 @@ void usb_uhci_init(PCIBus *bus, USBPort **usb_ports)
647 647
648 s = (UHCIState *)pci_register_device(bus, 648 s = (UHCIState *)pci_register_device(bus,
649 "USB-UHCI", sizeof(UHCIState), 649 "USB-UHCI", sizeof(UHCIState),
650 - ((PCIDevice *)piix3_state)->devfn + 2,  
651 - NULL, NULL); 650 + devfn, NULL, NULL);
652 pci_conf = s->dev.config; 651 pci_conf = s->dev.config;
653 pci_conf[0x00] = 0x86; 652 pci_conf[0x00] = 0x86;
654 pci_conf[0x01] = 0x80; 653 pci_conf[0x01] = 0x80;
hw/usb.h
@@ -155,7 +155,7 @@ int set_usb_string(uint8_t *buf, const char *str); @@ -155,7 +155,7 @@ int set_usb_string(uint8_t *buf, const char *str);
155 USBDevice *usb_hub_init(USBPort **usb_ports, int nb_ports); 155 USBDevice *usb_hub_init(USBPort **usb_ports, int nb_ports);
156 156
157 /* usb-uhci.c */ 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 /* usb-linux.c */ 160 /* usb-linux.c */
161 USBDevice *usb_host_device_open(const char *devname); 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,6 +10,8 @@
10 #include "vl.h" 10 #include "vl.h"
11 #include "arm_pic.h" 11 #include "arm_pic.h"
12 12
  13 +#define LOCK_VALUE 0xa05f
  14 +
13 /* Primary interrupt controller. */ 15 /* Primary interrupt controller. */
14 16
15 typedef struct vpb_sic_state 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,6 +147,188 @@ static vpb_sic_state *vpb_sic_init(uint32_t base, void *parent, int irq)
145 return s; 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 /* Board init. */ 332 /* Board init. */
149 333
150 /* The AB and PB boards both use the same core, just with different 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,6 +343,10 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
159 CPUState *env; 343 CPUState *env;
160 void *pic; 344 void *pic;
161 void *sic; 345 void *sic;
  346 + PCIBus *pci_bus;
  347 + NICInfo *nd;
  348 + int n;
  349 + int done_smc = 0;
162 350
163 env = cpu_init(); 351 env = cpu_init();
164 cpu_arm_set_model(env, ARM_CPUID_ARM926); 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,20 +354,24 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
166 /* SDRAM at address zero. */ 354 /* SDRAM at address zero. */
167 cpu_register_physical_memory(0, ram_size, IO_MEM_RAM); 355 cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
168 356
  357 + vpb_sys_init(0x10000000);
169 pic = arm_pic_init_cpu(env); 358 pic = arm_pic_init_cpu(env);
170 pic = pl190_init(0x10140000, pic, ARM_PIC_CPU_IRQ, ARM_PIC_CPU_FIQ); 359 pic = pl190_init(0x10140000, pic, ARM_PIC_CPU_IRQ, ARM_PIC_CPU_FIQ);
171 sic = vpb_sic_init(0x10003000, pic, 31); 360 sic = vpb_sic_init(0x10003000, pic, 31);
172 pl050_init(0x10006000, sic, 3, 0); 361 pl050_init(0x10006000, sic, 3, 0);
173 pl050_init(0x10007000, sic, 4, 1); 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 } else { 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,6 +593,20 @@ typedef struct PCIIORegion {
593 593
594 #define PCI_ROM_SLOT 6 594 #define PCI_ROM_SLOT 6
595 #define PCI_NUM_REGIONS 7 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 struct PCIDevice { 610 struct PCIDevice {
597 /* PCI config space */ 611 /* PCI config space */
598 uint8_t config[256]; 612 uint8_t config[256];
@@ -606,6 +620,7 @@ struct PCIDevice { @@ -606,6 +620,7 @@ struct PCIDevice {
606 /* do not access the following fields */ 620 /* do not access the following fields */
607 PCIConfigReadFunc *config_read; 621 PCIConfigReadFunc *config_read;
608 PCIConfigWriteFunc *config_write; 622 PCIConfigWriteFunc *config_write;
  623 + /* ??? This is a PC-specific hack, and should be removed. */
609 int irq_index; 624 int irq_index;
610 }; 625 };
611 626
@@ -627,21 +642,37 @@ void pci_default_write_config(PCIDevice *d, @@ -627,21 +642,37 @@ void pci_default_write_config(PCIDevice *d,
627 void generic_pci_save(QEMUFile* f, void *opaque); 642 void generic_pci_save(QEMUFile* f, void *opaque);
628 int generic_pci_load(QEMUFile* f, void *opaque, int version_id); 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 void pci_info(void); 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 PCIBus *pci_prep_init(void); 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 /* openpic.c */ 677 /* openpic.c */
647 typedef struct openpic_t openpic_t; 678 typedef struct openpic_t openpic_t;
@@ -726,7 +757,7 @@ void isa_ide_init(int iobase, int iobase2, int irq, @@ -726,7 +757,7 @@ void isa_ide_init(int iobase, int iobase2, int irq,
726 BlockDriverState *hd0, BlockDriverState *hd1); 757 BlockDriverState *hd0, BlockDriverState *hd1);
727 void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table, 758 void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
728 int secondary_ide_enabled); 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 int pmac_ide_init (BlockDriverState **hd_table, 761 int pmac_ide_init (BlockDriverState **hd_table,
731 SetIRQFunc *set_irq, void *irq_opaque, int irq); 762 SetIRQFunc *set_irq, void *irq_opaque, int irq);
732 763
@@ -843,7 +874,7 @@ int pcspk_audio_init(AudioState *); @@ -843,7 +874,7 @@ int pcspk_audio_init(AudioState *);
843 874
844 /* acpi.c */ 875 /* acpi.c */
845 extern int acpi_enabled; 876 extern int acpi_enabled;
846 -void piix4_pm_init(PCIBus *bus); 877 +void piix4_pm_init(PCIBus *bus, int devfn);
847 void acpi_bios_init(void); 878 void acpi_bios_init(void);
848 879
849 /* pc.c */ 880 /* pc.c */