aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2009-01-10 11:33:32 +0000
committerblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2009-01-10 11:33:32 +0000
commitc190ea07290c3973f4549d6e2ed9e8b2cddaf497 (patch)
treee03f6ad115faac96b3f31dfee49108e3a85c971d
parenta94fd955eb70b629032afebcd323355323452f96 (diff)
Add EBUS bridge
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6266 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--hw/apb_pci.c11
-rw-r--r--hw/pci.h5
-rw-r--r--hw/sun4u.c50
3 files changed, 56 insertions, 10 deletions
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 086908a846..f222f3c0eb 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -223,12 +223,11 @@ static void pci_apb_set_irq(qemu_irq *pic, int irq_num, int level)
PCIBus *pci_apb_init(target_phys_addr_t special_base,
target_phys_addr_t mem_base,
- qemu_irq *pic)
+ qemu_irq *pic, PCIBus **bus2, PCIBus **bus3)
{
APBState *s;
PCIDevice *d;
int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
- PCIBus *secondary;
s = qemu_mallocz(sizeof(APBState));
/* Ultrasparc PBM main bus */
@@ -269,9 +268,9 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
d->config[0x0E] = 0x00; // header_type
/* APB secondary busses */
- secondary = pci_bridge_init(s->bus, 8, 0x108e5000, pci_apb_map_irq,
- "Advanced PCI Bus secondary bridge 1");
- pci_bridge_init(s->bus, 9, 0x108e5000, pci_apb_map_irq,
- "Advanced PCI Bus secondary bridge 2");
+ *bus2 = pci_bridge_init(s->bus, 8, 0x108e5000, pci_apb_map_irq,
+ "Advanced PCI Bus secondary bridge 1");
+ *bus3 = pci_bridge_init(s->bus, 9, 0x108e5000, pci_apb_map_irq,
+ "Advanced PCI Bus secondary bridge 2");
return s->bus;
}
diff --git a/hw/pci.h b/hw/pci.h
index 3b1caf5ca8..d34f618377 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -168,8 +168,9 @@ void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn);
PCIBus *pci_prep_init(qemu_irq *pic);
/* apb_pci.c */
-PCIBus *pci_apb_init(target_phys_addr_t special_base, target_phys_addr_t mem_base,
- qemu_irq *pic);
+PCIBus *pci_apb_init(target_phys_addr_t special_base,
+ target_phys_addr_t mem_base,
+ qemu_irq *pic, PCIBus **bus2, PCIBus **bus3);
/* sh_pci.c */
PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 101d82d621..35f299c89b 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -344,6 +344,48 @@ static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 };
static fdctrl_t *floppy_controller;
+static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num,
+ uint32_t addr, uint32_t size, int type)
+{
+ DPRINTF("Mapping region %d registers at %08x\n", region_num, addr);
+ switch (region_num) {
+ case 0:
+ isa_mmio_init(addr, 0x1000000);
+ break;
+ case 1:
+ isa_mmio_init(addr, 0x800000);
+ break;
+ }
+}
+
+/* EBUS (Eight bit bus) bridge */
+static void
+pci_ebus_init(PCIBus *bus, int devfn)
+{
+ PCIDevice *s;
+
+ s = pci_register_device(bus, "EBUS", sizeof(*s), devfn, NULL, NULL);
+ s->config[0x00] = 0x8e; // vendor_id : Sun
+ s->config[0x01] = 0x10;
+ s->config[0x02] = 0x00; // device_id
+ s->config[0x03] = 0x10;
+ s->config[0x04] = 0x06; // command = bus master, pci mem
+ s->config[0x05] = 0x00;
+ s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
+ s->config[0x07] = 0x03; // status = medium devsel
+ s->config[0x08] = 0x01; // revision
+ s->config[0x09] = 0x00; // programming i/f
+ s->config[0x0A] = 0x80; // class_sub = misc bridge
+ s->config[0x0B] = 0x06; // class_base = PCI_bridge
+ s->config[0x0D] = 0x0a; // latency_timer
+ s->config[0x0E] = 0x00; // header_type
+
+ pci_register_io_region(s, 0, 0x1000000, PCI_ADDRESS_SPACE_MEM,
+ ebus_mmio_mapfunc);
+ pci_register_io_region(s, 1, 0x800000, PCI_ADDRESS_SPACE_MEM,
+ ebus_mmio_mapfunc);
+}
+
static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
const char *boot_devices, DisplayState *ds,
const char *kernel_filename, const char *kernel_cmdline,
@@ -357,7 +399,7 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
unsigned int i;
ram_addr_t ram_offset, prom_offset, vga_ram_offset;
long initrd_size, kernel_size;
- PCIBus *pci_bus;
+ PCIBus *pci_bus, *pci_bus2, *pci_bus3;
QEMUBH *bh;
qemu_irq *irq;
int drive_index;
@@ -462,13 +504,17 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
}
}
}
- pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, NULL);
+ pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, NULL, &pci_bus2,
+ &pci_bus3);
isa_mem_base = VGA_BASE;
vga_ram_offset = qemu_ram_alloc(vga_ram_size);
pci_vga_init(pci_bus, ds, phys_ram_base + vga_ram_offset,
vga_ram_offset, vga_ram_size,
0, 0);
+ // XXX Should be pci_bus3
+ pci_ebus_init(pci_bus, -1);
+
i = 0;
if (hwdef->console_serial_base) {
serial_mm_init(hwdef->console_serial_base, 0, NULL, 115200,