aboutsummaryrefslogtreecommitdiff
path: root/hw/pci.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-07-23 14:27:54 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-07-23 14:27:54 +0000
commit8346901560d96edf94b803fd3f94db940ad370b3 (patch)
tree4f7736383fd41291f63d97c92767409330a7acb9 /hw/pci.c
parentb7c7b18129e137bd24240800d7fac02eee3b1edf (diff)
sparc64 fixes (Blue Swirl)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1514 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/pci.c')
-rw-r--r--hw/pci.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/hw/pci.c b/hw/pci.c
index a5ecbf1be8..efca2cd530 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1291,6 +1291,253 @@ PCIBus *pci_pmac_init(void)
return s;
}
+/* Ultrasparc APB PCI host */
+static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+ PCIBus *s = opaque;
+ int i;
+
+ for (i = 11; i < 32; i++) {
+ if ((val & (1 << i)) != 0)
+ break;
+ }
+ s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11);
+}
+
+static uint32_t pci_apb_config_readl (void *opaque,
+ target_phys_addr_t addr)
+{
+ PCIBus *s = opaque;
+ uint32_t val;
+ int devfn;
+
+ devfn = (s->config_reg >> 8) & 0xFF;
+ val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
+ return val;
+}
+
+static CPUWriteMemoryFunc *pci_apb_config_write[] = {
+ &pci_apb_config_writel,
+ &pci_apb_config_writel,
+ &pci_apb_config_writel,
+};
+
+static CPUReadMemoryFunc *pci_apb_config_read[] = {
+ &pci_apb_config_readl,
+ &pci_apb_config_readl,
+ &pci_apb_config_readl,
+};
+
+static void apb_config_writel (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+ //PCIBus *s = opaque;
+
+ switch (addr & 0x3f) {
+ case 0x00: // Control/Status
+ case 0x10: // AFSR
+ case 0x18: // AFAR
+ case 0x20: // Diagnostic
+ case 0x28: // Target address space
+ // XXX
+ default:
+ break;
+ }
+}
+
+static uint32_t apb_config_readl (void *opaque,
+ target_phys_addr_t addr)
+{
+ //PCIBus *s = opaque;
+ uint32_t val;
+
+ switch (addr & 0x3f) {
+ case 0x00: // Control/Status
+ case 0x10: // AFSR
+ case 0x18: // AFAR
+ case 0x20: // Diagnostic
+ case 0x28: // Target address space
+ // XXX
+ default:
+ val = 0;
+ break;
+ }
+ return val;
+}
+
+static CPUWriteMemoryFunc *apb_config_write[] = {
+ &apb_config_writel,
+ &apb_config_writel,
+ &apb_config_writel,
+};
+
+static CPUReadMemoryFunc *apb_config_read[] = {
+ &apb_config_readl,
+ &apb_config_readl,
+ &apb_config_readl,
+};
+
+static void pci_apb_writeb (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+ PCIBus *s = opaque;
+
+ pci_data_write(s, addr & 7, val, 1);
+}
+
+static void pci_apb_writew (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+ PCIBus *s = opaque;
+
+ pci_data_write(s, addr & 7, val, 2);
+}
+
+static void pci_apb_writel (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+ PCIBus *s = opaque;
+
+ pci_data_write(s, addr & 7, val, 4);
+}
+
+static uint32_t pci_apb_readb (void *opaque, target_phys_addr_t addr)
+{
+ PCIBus *s = opaque;
+ uint32_t val;
+
+ val = pci_data_read(s, addr & 7, 1);
+ return val;
+}
+
+static uint32_t pci_apb_readw (void *opaque, target_phys_addr_t addr)
+{
+ PCIBus *s = opaque;
+ uint32_t val;
+
+ val = pci_data_read(s, addr & 7, 2);
+ return val;
+}
+
+static uint32_t pci_apb_readl (void *opaque, target_phys_addr_t addr)
+{
+ PCIBus *s = opaque;
+ uint32_t val;
+
+ val = pci_data_read(s, addr, 4);
+ return val;
+}
+
+static CPUWriteMemoryFunc *pci_apb_write[] = {
+ &pci_apb_writeb,
+ &pci_apb_writew,
+ &pci_apb_writel,
+};
+
+static CPUReadMemoryFunc *pci_apb_read[] = {
+ &pci_apb_readb,
+ &pci_apb_readw,
+ &pci_apb_readl,
+};
+
+static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+ cpu_outb(NULL, addr & 0xffff, val);
+}
+
+static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+ cpu_outw(NULL, addr & 0xffff, val);
+}
+
+static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+ cpu_outl(NULL, addr & 0xffff, val);
+}
+
+static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr)
+{
+ uint32_t val;
+
+ val = cpu_inb(NULL, addr & 0xffff);
+ return val;
+}
+
+static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr)
+{
+ uint32_t val;
+
+ val = cpu_inw(NULL, addr & 0xffff);
+ return val;
+}
+
+static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)
+{
+ uint32_t val;
+
+ val = cpu_inl(NULL, addr & 0xffff);
+ return val;
+}
+
+static CPUWriteMemoryFunc *pci_apb_iowrite[] = {
+ &pci_apb_iowriteb,
+ &pci_apb_iowritew,
+ &pci_apb_iowritel,
+};
+
+static CPUReadMemoryFunc *pci_apb_ioread[] = {
+ &pci_apb_ioreadb,
+ &pci_apb_ioreadw,
+ &pci_apb_ioreadl,
+};
+
+PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base)
+{
+ PCIBus *s;
+ PCIDevice *d;
+ int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
+
+ /* Ultrasparc APB main bus */
+ s = pci_register_bus();
+ s->set_irq = pci_set_irq_simple;
+
+ pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read,
+ pci_apb_config_write, s);
+ apb_config = cpu_register_io_memory(0, apb_config_read,
+ apb_config_write, s);
+ pci_mem_data = cpu_register_io_memory(0, pci_apb_read,
+ pci_apb_write, s);
+ pci_ioport = cpu_register_io_memory(0, pci_apb_ioread,
+ pci_apb_iowrite, s);
+
+ cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config);
+ cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10, pci_mem_config);
+ cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, pci_ioport);
+ cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom
+
+ d = pci_register_device(s, "Advanced PCI Bus", sizeof(PCIDevice),
+ -1, NULL, NULL);
+ d->config[0x00] = 0x8e; // vendor_id : Sun
+ d->config[0x01] = 0x10;
+ d->config[0x02] = 0x00; // device_id
+ d->config[0x03] = 0xa0;
+ d->config[0x04] = 0x06; // command = bus master, pci mem
+ d->config[0x05] = 0x00;
+ d->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
+ d->config[0x07] = 0x03; // status = medium devsel
+ d->config[0x08] = 0x00; // revision
+ d->config[0x09] = 0x00; // programming i/f
+ d->config[0x0A] = 0x00; // class_sub = pci host
+ d->config[0x0B] = 0x06; // class_base = PCI_bridge
+ d->config[0x0D] = 0x10; // latency_timer
+ d->config[0x0E] = 0x00; // header_type
+ return s;
+}
+
/***********************************************************/
/* generic PCI irq support */