1 /* 2 * SuperH on-chip PCIC emulation. 3 * 4 * Copyright (c) 2008 Takashi YOSHII 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 "qemu/osdep.h" 26 #include "hw/sysbus.h" 27 #include "hw/sh4/sh.h" 28 #include "hw/irq.h" 29 #include "hw/pci/pci.h" 30 #include "hw/pci/pci_host.h" 31 #include "qemu/bswap.h" 32 #include "qemu/module.h" 33 #include "exec/address-spaces.h" 34 #include "qom/object.h" 35 36 #define TYPE_SH_PCI_HOST_BRIDGE "sh_pci" 37 38 OBJECT_DECLARE_SIMPLE_TYPE(SHPCIState, SH_PCI_HOST_BRIDGE) 39 40 struct SHPCIState { 41 PCIHostState parent_obj; 42 43 PCIDevice *dev; 44 qemu_irq irq[4]; 45 MemoryRegion memconfig_p4; 46 MemoryRegion memconfig_a7; 47 MemoryRegion isa; 48 uint32_t par; 49 uint32_t mbr; 50 uint32_t iobr; 51 }; 52 53 static void sh_pci_reg_write (void *p, hwaddr addr, uint64_t val, 54 unsigned size) 55 { 56 SHPCIState *pcic = p; 57 PCIHostState *phb = PCI_HOST_BRIDGE(pcic); 58 59 switch(addr) { 60 case 0 ... 0xfc: 61 stl_le_p(pcic->dev->config + addr, val); 62 break; 63 case 0x1c0: 64 pcic->par = val; 65 break; 66 case 0x1c4: 67 pcic->mbr = val & 0xff000001; 68 break; 69 case 0x1c8: 70 pcic->iobr = val & 0xfffc0001; 71 memory_region_set_alias_offset(&pcic->isa, val & 0xfffc0000); 72 break; 73 case 0x220: 74 pci_data_write(phb->bus, pcic->par, val, 4); 75 break; 76 } 77 } 78 79 static uint64_t sh_pci_reg_read (void *p, hwaddr addr, 80 unsigned size) 81 { 82 SHPCIState *pcic = p; 83 PCIHostState *phb = PCI_HOST_BRIDGE(pcic); 84 85 switch(addr) { 86 case 0 ... 0xfc: 87 return ldl_le_p(pcic->dev->config + addr); 88 case 0x1c0: 89 return pcic->par; 90 case 0x1c4: 91 return pcic->mbr; 92 case 0x1c8: 93 return pcic->iobr; 94 case 0x220: 95 return pci_data_read(phb->bus, pcic->par, 4); 96 } 97 return 0; 98 } 99 100 static const MemoryRegionOps sh_pci_reg_ops = { 101 .read = sh_pci_reg_read, 102 .write = sh_pci_reg_write, 103 .endianness = DEVICE_NATIVE_ENDIAN, 104 .valid = { 105 .min_access_size = 4, 106 .max_access_size = 4, 107 }, 108 }; 109 110 static int sh_pci_map_irq(PCIDevice *d, int irq_num) 111 { 112 return PCI_SLOT(d->devfn); 113 } 114 115 static void sh_pci_set_irq(void *opaque, int irq_num, int level) 116 { 117 qemu_irq *pic = opaque; 118 119 qemu_set_irq(pic[irq_num], level); 120 } 121 122 static void sh_pci_device_realize(DeviceState *dev, Error **errp) 123 { 124 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 125 SHPCIState *s = SH_PCI_HOST_BRIDGE(dev); 126 PCIHostState *phb = PCI_HOST_BRIDGE(s); 127 int i; 128 129 for (i = 0; i < 4; i++) { 130 sysbus_init_irq(sbd, &s->irq[i]); 131 } 132 phb->bus = pci_register_root_bus(dev, "pci", 133 sh_pci_set_irq, sh_pci_map_irq, 134 s->irq, 135 get_system_memory(), 136 get_system_io(), 137 PCI_DEVFN(0, 0), 4, TYPE_PCI_BUS); 138 memory_region_init_io(&s->memconfig_p4, OBJECT(s), &sh_pci_reg_ops, s, 139 "sh_pci", 0x224); 140 memory_region_init_alias(&s->memconfig_a7, OBJECT(s), "sh_pci.2", 141 &s->memconfig_p4, 0, 0x224); 142 memory_region_init_alias(&s->isa, OBJECT(s), "sh_pci.isa", 143 get_system_io(), 0, 0x40000); 144 sysbus_init_mmio(sbd, &s->memconfig_p4); 145 sysbus_init_mmio(sbd, &s->memconfig_a7); 146 memory_region_add_subregion(get_system_memory(), 0xfe240000, &s->isa); 147 148 s->dev = pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "sh_pci_host"); 149 } 150 151 static void sh_pci_host_realize(PCIDevice *d, Error **errp) 152 { 153 pci_set_word(d->config + PCI_COMMAND, PCI_COMMAND_WAIT); 154 pci_set_word(d->config + PCI_STATUS, PCI_STATUS_CAP_LIST | 155 PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); 156 } 157 158 static void sh_pci_host_class_init(ObjectClass *klass, void *data) 159 { 160 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 161 DeviceClass *dc = DEVICE_CLASS(klass); 162 163 k->realize = sh_pci_host_realize; 164 k->vendor_id = PCI_VENDOR_ID_HITACHI; 165 k->device_id = PCI_DEVICE_ID_HITACHI_SH7751R; 166 /* 167 * PCI-facing part of the host bridge, not usable without the 168 * host-facing part, which can't be device_add'ed, yet. 169 */ 170 dc->user_creatable = false; 171 } 172 173 static const TypeInfo sh_pci_host_info = { 174 .name = "sh_pci_host", 175 .parent = TYPE_PCI_DEVICE, 176 .instance_size = sizeof(PCIDevice), 177 .class_init = sh_pci_host_class_init, 178 .interfaces = (InterfaceInfo[]) { 179 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 180 { }, 181 }, 182 }; 183 184 static void sh_pci_device_class_init(ObjectClass *klass, void *data) 185 { 186 DeviceClass *dc = DEVICE_CLASS(klass); 187 188 dc->realize = sh_pci_device_realize; 189 } 190 191 static const TypeInfo sh_pci_device_info = { 192 .name = TYPE_SH_PCI_HOST_BRIDGE, 193 .parent = TYPE_PCI_HOST_BRIDGE, 194 .instance_size = sizeof(SHPCIState), 195 .class_init = sh_pci_device_class_init, 196 }; 197 198 static void sh_pci_register_types(void) 199 { 200 type_register_static(&sh_pci_device_info); 201 type_register_static(&sh_pci_host_info); 202 } 203 204 type_init(sh_pci_register_types) 205