1 /* 2 * System (CPU) Bus device support code 3 * 4 * Copyright (c) 2009 CodeSourcery 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "hw/sysbus.h" 21 #include "monitor/monitor.h" 22 #include "exec/address-spaces.h" 23 24 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent); 25 static char *sysbus_get_fw_dev_path(DeviceState *dev); 26 27 static void system_bus_class_init(ObjectClass *klass, void *data) 28 { 29 BusClass *k = BUS_CLASS(klass); 30 31 k->print_dev = sysbus_dev_print; 32 k->get_fw_dev_path = sysbus_get_fw_dev_path; 33 } 34 35 static const TypeInfo system_bus_info = { 36 .name = TYPE_SYSTEM_BUS, 37 .parent = TYPE_BUS, 38 .instance_size = sizeof(BusState), 39 .class_init = system_bus_class_init, 40 }; 41 42 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq) 43 { 44 qdev_connect_gpio_out_named(DEVICE(dev), SYSBUS_DEVICE_GPIO_IRQ, n, irq); 45 } 46 47 static void sysbus_mmio_map_common(SysBusDevice *dev, int n, hwaddr addr, 48 bool may_overlap, int priority) 49 { 50 assert(n >= 0 && n < dev->num_mmio); 51 52 if (dev->mmio[n].addr == addr) { 53 /* ??? region already mapped here. */ 54 return; 55 } 56 if (dev->mmio[n].addr != (hwaddr)-1) { 57 /* Unregister previous mapping. */ 58 memory_region_del_subregion(get_system_memory(), dev->mmio[n].memory); 59 } 60 dev->mmio[n].addr = addr; 61 if (may_overlap) { 62 memory_region_add_subregion_overlap(get_system_memory(), 63 addr, 64 dev->mmio[n].memory, 65 priority); 66 } 67 else { 68 memory_region_add_subregion(get_system_memory(), 69 addr, 70 dev->mmio[n].memory); 71 } 72 } 73 74 void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr) 75 { 76 sysbus_mmio_map_common(dev, n, addr, false, 0); 77 } 78 79 void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr, 80 int priority) 81 { 82 sysbus_mmio_map_common(dev, n, addr, true, priority); 83 } 84 85 /* Request an IRQ source. The actual IRQ object may be populated later. */ 86 void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p) 87 { 88 qdev_init_gpio_out_named(DEVICE(dev), p, SYSBUS_DEVICE_GPIO_IRQ, 1); 89 } 90 91 /* Pass IRQs from a target device. */ 92 void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target) 93 { 94 qdev_pass_gpios(DEVICE(target), DEVICE(dev), SYSBUS_DEVICE_GPIO_IRQ); 95 } 96 97 void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory) 98 { 99 int n; 100 101 assert(dev->num_mmio < QDEV_MAX_MMIO); 102 n = dev->num_mmio++; 103 dev->mmio[n].addr = -1; 104 dev->mmio[n].memory = memory; 105 } 106 107 MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n) 108 { 109 return dev->mmio[n].memory; 110 } 111 112 void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size) 113 { 114 pio_addr_t i; 115 116 for (i = 0; i < size; i++) { 117 assert(dev->num_pio < QDEV_MAX_PIO); 118 dev->pio[dev->num_pio++] = ioport++; 119 } 120 } 121 122 static int sysbus_device_init(DeviceState *dev) 123 { 124 SysBusDevice *sd = SYS_BUS_DEVICE(dev); 125 SysBusDeviceClass *sbc = SYS_BUS_DEVICE_GET_CLASS(sd); 126 127 if (!sbc->init) { 128 return 0; 129 } 130 return sbc->init(sd); 131 } 132 133 DeviceState *sysbus_create_varargs(const char *name, 134 hwaddr addr, ...) 135 { 136 DeviceState *dev; 137 SysBusDevice *s; 138 va_list va; 139 qemu_irq irq; 140 int n; 141 142 dev = qdev_create(NULL, name); 143 s = SYS_BUS_DEVICE(dev); 144 qdev_init_nofail(dev); 145 if (addr != (hwaddr)-1) { 146 sysbus_mmio_map(s, 0, addr); 147 } 148 va_start(va, addr); 149 n = 0; 150 while (1) { 151 irq = va_arg(va, qemu_irq); 152 if (!irq) { 153 break; 154 } 155 sysbus_connect_irq(s, n, irq); 156 n++; 157 } 158 va_end(va); 159 return dev; 160 } 161 162 DeviceState *sysbus_try_create_varargs(const char *name, 163 hwaddr addr, ...) 164 { 165 DeviceState *dev; 166 SysBusDevice *s; 167 va_list va; 168 qemu_irq irq; 169 int n; 170 171 dev = qdev_try_create(NULL, name); 172 if (!dev) { 173 return NULL; 174 } 175 s = SYS_BUS_DEVICE(dev); 176 qdev_init_nofail(dev); 177 if (addr != (hwaddr)-1) { 178 sysbus_mmio_map(s, 0, addr); 179 } 180 va_start(va, addr); 181 n = 0; 182 while (1) { 183 irq = va_arg(va, qemu_irq); 184 if (!irq) { 185 break; 186 } 187 sysbus_connect_irq(s, n, irq); 188 n++; 189 } 190 va_end(va); 191 return dev; 192 } 193 194 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent) 195 { 196 SysBusDevice *s = SYS_BUS_DEVICE(dev); 197 hwaddr size; 198 int i; 199 200 for (i = 0; i < s->num_mmio; i++) { 201 size = memory_region_size(s->mmio[i].memory); 202 monitor_printf(mon, "%*smmio " TARGET_FMT_plx "/" TARGET_FMT_plx "\n", 203 indent, "", s->mmio[i].addr, size); 204 } 205 } 206 207 static char *sysbus_get_fw_dev_path(DeviceState *dev) 208 { 209 SysBusDevice *s = SYS_BUS_DEVICE(dev); 210 char path[40]; 211 int off; 212 213 off = snprintf(path, sizeof(path), "%s", qdev_fw_name(dev)); 214 215 if (s->num_mmio) { 216 snprintf(path + off, sizeof(path) - off, "@"TARGET_FMT_plx, 217 s->mmio[0].addr); 218 } else if (s->num_pio) { 219 snprintf(path + off, sizeof(path) - off, "@i%04x", s->pio[0]); 220 } 221 222 return g_strdup(path); 223 } 224 225 void sysbus_add_io(SysBusDevice *dev, hwaddr addr, 226 MemoryRegion *mem) 227 { 228 memory_region_add_subregion(get_system_io(), addr, mem); 229 } 230 231 MemoryRegion *sysbus_address_space(SysBusDevice *dev) 232 { 233 return get_system_memory(); 234 } 235 236 static void sysbus_device_class_init(ObjectClass *klass, void *data) 237 { 238 DeviceClass *k = DEVICE_CLASS(klass); 239 k->init = sysbus_device_init; 240 k->bus_type = TYPE_SYSTEM_BUS; 241 /* 242 * device_add plugs devices into suitable bus. For "real" buses, 243 * that actually connects the device. For sysbus, the connections 244 * need to be made separately, and device_add can't do that. The 245 * device would be left unconnected, and could not possibly work. 246 */ 247 k->cannot_instantiate_with_device_add_yet = true; 248 } 249 250 static const TypeInfo sysbus_device_type_info = { 251 .name = TYPE_SYS_BUS_DEVICE, 252 .parent = TYPE_DEVICE, 253 .instance_size = sizeof(SysBusDevice), 254 .abstract = true, 255 .class_size = sizeof(SysBusDeviceClass), 256 .class_init = sysbus_device_class_init, 257 }; 258 259 /* This is a nasty hack to allow passing a NULL bus to qdev_create. */ 260 static BusState *main_system_bus; 261 262 static void main_system_bus_create(void) 263 { 264 /* assign main_system_bus before qbus_create_inplace() 265 * in order to make "if (bus != sysbus_get_default())" work */ 266 main_system_bus = g_malloc0(system_bus_info.instance_size); 267 qbus_create_inplace(main_system_bus, system_bus_info.instance_size, 268 TYPE_SYSTEM_BUS, NULL, "main-system-bus"); 269 OBJECT(main_system_bus)->free = g_free; 270 object_property_add_child(container_get(qdev_get_machine(), 271 "/unattached"), 272 "sysbus", OBJECT(main_system_bus), NULL); 273 } 274 275 BusState *sysbus_get_default(void) 276 { 277 if (!main_system_bus) { 278 main_system_bus_create(); 279 } 280 return main_system_bus; 281 } 282 283 static void sysbus_register_types(void) 284 { 285 type_register_static(&system_bus_info); 286 type_register_static(&sysbus_device_type_info); 287 } 288 289 type_init(sysbus_register_types) 290