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 #include "hw/sysbus.h" 25 #include "hw/sh4/sh.h" 26 #include "hw/pci/pci.h" 27 #include "hw/pci/pci_host.h" 28 #include "qemu/bswap.h" 29 #include "exec/address-spaces.h" 30 31 #define TYPE_SH_PCI_HOST_BRIDGE "sh_pci" 32 33 #define SH_PCI_HOST_BRIDGE(obj) \ 34 OBJECT_CHECK(SHPCIState, (obj), TYPE_SH_PCI_HOST_BRIDGE) 35 36 typedef struct SHPCIState { 37 PCIHostState parent_obj; 38 39 PCIDevice *dev; 40 qemu_irq irq[4]; 41 MemoryRegion memconfig_p4; 42 MemoryRegion memconfig_a7; 43 MemoryRegion isa; 44 uint32_t par; 45 uint32_t mbr; 46 uint32_t iobr; 47 } SHPCIState; 48 49 static void sh_pci_reg_write (void *p, hwaddr addr, uint64_t val, 50 unsigned size) 51 { 52 SHPCIState *pcic = p; 53 PCIHostState *phb = PCI_HOST_BRIDGE(pcic); 54 55 switch(addr) { 56 case 0 ... 0xfc: 57 cpu_to_le32w((uint32_t*)(pcic->dev->config + addr), val); 58 break; 59 case 0x1c0: 60 pcic->par = val; 61 break; 62 case 0x1c4: 63 pcic->mbr = val & 0xff000001; 64 break; 65 case 0x1c8: 66 if ((val & 0xfffc0000) != (pcic->iobr & 0xfffc0000)) { 67 memory_region_del_subregion(get_system_memory(), &pcic->isa); 68 pcic->iobr = val & 0xfffc0001; 69 memory_region_add_subregion(get_system_memory(), 70 pcic->iobr & 0xfffc0000, &pcic->isa); 71 } 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 le32_to_cpup((uint32_t*)(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 (d->devfn >> 3); 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 int sh_pci_device_init(SysBusDevice *dev) 123 { 124 PCIHostState *phb; 125 SHPCIState *s; 126 int i; 127 128 s = SH_PCI_HOST_BRIDGE(dev); 129 phb = PCI_HOST_BRIDGE(s); 130 for (i = 0; i < 4; i++) { 131 sysbus_init_irq(dev, &s->irq[i]); 132 } 133 phb->bus = pci_register_bus(DEVICE(dev), "pci", 134 sh_pci_set_irq, sh_pci_map_irq, 135 s->irq, 136 get_system_memory(), 137 get_system_io(), 138 PCI_DEVFN(0, 0), 4, TYPE_PCI_BUS); 139 memory_region_init_io(&s->memconfig_p4, OBJECT(s), &sh_pci_reg_ops, s, 140 "sh_pci", 0x224); 141 memory_region_init_alias(&s->memconfig_a7, OBJECT(s), "sh_pci.2", 142 &s->memconfig_p4, 0, 0x224); 143 memory_region_init_alias(&s->isa, OBJECT(s), "sh_pci.isa", 144 get_system_io(), 0, 0x40000); 145 sysbus_init_mmio(dev, &s->memconfig_p4); 146 sysbus_init_mmio(dev, &s->memconfig_a7); 147 s->iobr = 0xfe240000; 148 memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa); 149 150 s->dev = pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "sh_pci_host"); 151 return 0; 152 } 153 154 static int sh_pci_host_init(PCIDevice *d) 155 { 156 pci_set_word(d->config + PCI_COMMAND, PCI_COMMAND_WAIT); 157 pci_set_word(d->config + PCI_STATUS, PCI_STATUS_CAP_LIST | 158 PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); 159 return 0; 160 } 161 162 static void sh_pci_host_class_init(ObjectClass *klass, void *data) 163 { 164 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 165 DeviceClass *dc = DEVICE_CLASS(klass); 166 167 k->init = sh_pci_host_init; 168 k->vendor_id = PCI_VENDOR_ID_HITACHI; 169 k->device_id = PCI_DEVICE_ID_HITACHI_SH7751R; 170 /* 171 * PCI-facing part of the host bridge, not usable without the 172 * host-facing part, which can't be device_add'ed, yet. 173 */ 174 dc->cannot_instantiate_with_device_add_yet = true; 175 } 176 177 static const TypeInfo sh_pci_host_info = { 178 .name = "sh_pci_host", 179 .parent = TYPE_PCI_DEVICE, 180 .instance_size = sizeof(PCIDevice), 181 .class_init = sh_pci_host_class_init, 182 }; 183 184 static void sh_pci_device_class_init(ObjectClass *klass, void *data) 185 { 186 SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); 187 188 sdc->init = sh_pci_device_init; 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