Commit 40905a6a31f6dd1904f54ea48763c5fbe745bafa
1 parent
2c6554bc
Stellaris qdev conversion
Signed-off-by: Paul Brook <paul@codesourcery.com>
Showing
4 changed files
with
97 additions
and
51 deletions
hw/armv7m.c
| @@ -117,18 +117,35 @@ static CPUWriteMemoryFunc *bitband_writefn[] = { | @@ -117,18 +117,35 @@ static CPUWriteMemoryFunc *bitband_writefn[] = { | ||
| 117 | bitband_writel | 117 | bitband_writel |
| 118 | }; | 118 | }; |
| 119 | 119 | ||
| 120 | -static void armv7m_bitband_init(void) | 120 | +typedef struct { |
| 121 | + SysBusDevice busdev; | ||
| 122 | + uint32_t base; | ||
| 123 | +} BitBandState; | ||
| 124 | + | ||
| 125 | +static void bitband_init(SysBusDevice *dev) | ||
| 121 | { | 126 | { |
| 127 | + BitBandState *s = FROM_SYSBUS(BitBandState, dev); | ||
| 122 | int iomemtype; | 128 | int iomemtype; |
| 123 | - static uint32_t bitband1_offset = 0x20000000; | ||
| 124 | - static uint32_t bitband2_offset = 0x40000000; | ||
| 125 | 129 | ||
| 130 | + s->base = qdev_get_prop_int(&dev->qdev, "base", 0); | ||
| 126 | iomemtype = cpu_register_io_memory(0, bitband_readfn, bitband_writefn, | 131 | iomemtype = cpu_register_io_memory(0, bitband_readfn, bitband_writefn, |
| 127 | - &bitband1_offset); | ||
| 128 | - cpu_register_physical_memory(0x22000000, 0x02000000, iomemtype); | ||
| 129 | - iomemtype = cpu_register_io_memory(0, bitband_readfn, bitband_writefn, | ||
| 130 | - &bitband2_offset); | ||
| 131 | - cpu_register_physical_memory(0x42000000, 0x02000000, iomemtype); | 132 | + &s->base); |
| 133 | + sysbus_init_mmio(dev, 0x02000000, iomemtype); | ||
| 134 | +} | ||
| 135 | + | ||
| 136 | +static void armv7m_bitband_init(void) | ||
| 137 | +{ | ||
| 138 | + DeviceState *dev; | ||
| 139 | + | ||
| 140 | + dev = qdev_create(NULL, "ARM,bitband-memory"); | ||
| 141 | + qdev_set_prop_int(dev, "base", 0x20000000); | ||
| 142 | + qdev_init(dev); | ||
| 143 | + sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0x22000000); | ||
| 144 | + | ||
| 145 | + dev = qdev_create(NULL, "ARM,bitband-memory"); | ||
| 146 | + qdev_set_prop_int(dev, "base", 0x40000000); | ||
| 147 | + qdev_init(dev); | ||
| 148 | + sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0x42000000); | ||
| 132 | } | 149 | } |
| 133 | 150 | ||
| 134 | /* Board init. */ | 151 | /* Board init. */ |
| @@ -220,3 +237,11 @@ qemu_irq *armv7m_init(int flash_size, int sram_size, | @@ -220,3 +237,11 @@ qemu_irq *armv7m_init(int flash_size, int sram_size, | ||
| 220 | 237 | ||
| 221 | return pic; | 238 | return pic; |
| 222 | } | 239 | } |
| 240 | + | ||
| 241 | +static void armv7m_register_devices(void) | ||
| 242 | +{ | ||
| 243 | + sysbus_register_dev("ARM,bitband-memory", sizeof(BitBandState), | ||
| 244 | + bitband_init); | ||
| 245 | +} | ||
| 246 | + | ||
| 247 | +device_init(armv7m_register_devices) |
hw/pl061.c
| @@ -8,8 +8,7 @@ | @@ -8,8 +8,7 @@ | ||
| 8 | * This code is licenced under the GPL. | 8 | * This code is licenced under the GPL. |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | -#include "hw.h" | ||
| 12 | -#include "primecell.h" | 11 | +#include "sysbus.h" |
| 13 | 12 | ||
| 14 | //#define DEBUG_PL061 1 | 13 | //#define DEBUG_PL061 1 |
| 15 | 14 | ||
| @@ -28,6 +27,7 @@ static const uint8_t pl061_id[12] = | @@ -28,6 +27,7 @@ static const uint8_t pl061_id[12] = | ||
| 28 | { 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 }; | 27 | { 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 }; |
| 29 | 28 | ||
| 30 | typedef struct { | 29 | typedef struct { |
| 30 | + SysBusDevice busdev; | ||
| 31 | int locked; | 31 | int locked; |
| 32 | uint8_t data; | 32 | uint8_t data; |
| 33 | uint8_t old_data; | 33 | uint8_t old_data; |
| @@ -291,21 +291,25 @@ static int pl061_load(QEMUFile *f, void *opaque, int version_id) | @@ -291,21 +291,25 @@ static int pl061_load(QEMUFile *f, void *opaque, int version_id) | ||
| 291 | return 0; | 291 | return 0; |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | -/* Returns an array of inputs. */ | ||
| 295 | -qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out) | 294 | +static void pl061_init(SysBusDevice *dev) |
| 296 | { | 295 | { |
| 297 | int iomemtype; | 296 | int iomemtype; |
| 298 | - pl061_state *s; | 297 | + pl061_state *s = FROM_SYSBUS(pl061_state, dev); |
| 299 | 298 | ||
| 300 | - s = (pl061_state *)qemu_mallocz(sizeof(pl061_state)); | ||
| 301 | iomemtype = cpu_register_io_memory(0, pl061_readfn, | 299 | iomemtype = cpu_register_io_memory(0, pl061_readfn, |
| 302 | pl061_writefn, s); | 300 | pl061_writefn, s); |
| 303 | - cpu_register_physical_memory(base, 0x00001000, iomemtype); | ||
| 304 | - s->irq = irq; | 301 | + sysbus_init_mmio(dev, 0x1000, iomemtype); |
| 302 | + sysbus_init_irq(dev, &s->irq); | ||
| 303 | + qdev_init_gpio_in(&dev->qdev, pl061_set_irq, 8); | ||
| 304 | + qdev_init_gpio_out(&dev->qdev, s->out, 8); | ||
| 305 | pl061_reset(s); | 305 | pl061_reset(s); |
| 306 | - if (out) | ||
| 307 | - *out = s->out; | ||
| 308 | - | ||
| 309 | register_savevm("pl061_gpio", -1, 1, pl061_save, pl061_load, s); | 306 | register_savevm("pl061_gpio", -1, 1, pl061_save, pl061_load, s); |
| 310 | - return qemu_allocate_irqs(pl061_set_irq, s, 8); | ||
| 311 | } | 307 | } |
| 308 | + | ||
| 309 | +static void pl061_register_devices(void) | ||
| 310 | +{ | ||
| 311 | + sysbus_register_dev("pl061", sizeof(pl061_state), | ||
| 312 | + pl061_init); | ||
| 313 | +} | ||
| 314 | + | ||
| 315 | +device_init(pl061_register_devices) |
hw/primecell.h
| @@ -5,10 +5,6 @@ | @@ -5,10 +5,6 @@ | ||
| 5 | /* Also includes some devices that are currently only used by the | 5 | /* Also includes some devices that are currently only used by the |
| 6 | ARM boards. */ | 6 | ARM boards. */ |
| 7 | 7 | ||
| 8 | -/* pl061.c */ | ||
| 9 | -void pl061_float_high(void *opaque, uint8_t mask); | ||
| 10 | -qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out); | ||
| 11 | - | ||
| 12 | /* pl080.c */ | 8 | /* pl080.c */ |
| 13 | void *pl080_init(uint32_t base, qemu_irq irq, int nchannels); | 9 | void *pl080_init(uint32_t base, qemu_irq irq, int nchannels); |
| 14 | 10 |
hw/stellaris.c
| @@ -10,7 +10,6 @@ | @@ -10,7 +10,6 @@ | ||
| 10 | #include "sysbus.h" | 10 | #include "sysbus.h" |
| 11 | #include "ssi.h" | 11 | #include "ssi.h" |
| 12 | #include "arm-misc.h" | 12 | #include "arm-misc.h" |
| 13 | -#include "primecell.h" | ||
| 14 | #include "devices.h" | 13 | #include "devices.h" |
| 15 | #include "qemu-timer.h" | 14 | #include "qemu-timer.h" |
| 16 | #include "i2c.h" | 15 | #include "i2c.h" |
| @@ -45,6 +44,7 @@ typedef const struct { | @@ -45,6 +44,7 @@ typedef const struct { | ||
| 45 | /* General purpose timer module. */ | 44 | /* General purpose timer module. */ |
| 46 | 45 | ||
| 47 | typedef struct gptm_state { | 46 | typedef struct gptm_state { |
| 47 | + SysBusDevice busdev; | ||
| 48 | uint32_t config; | 48 | uint32_t config; |
| 49 | uint32_t mode[2]; | 49 | uint32_t mode[2]; |
| 50 | uint32_t control; | 50 | uint32_t control; |
| @@ -112,8 +112,7 @@ static void gptm_tick(void *opaque) | @@ -112,8 +112,7 @@ static void gptm_tick(void *opaque) | ||
| 112 | s->state |= 1; | 112 | s->state |= 1; |
| 113 | if ((s->control & 0x20)) { | 113 | if ((s->control & 0x20)) { |
| 114 | /* Output trigger. */ | 114 | /* Output trigger. */ |
| 115 | - qemu_irq_raise(s->trigger); | ||
| 116 | - qemu_irq_lower(s->trigger); | 115 | + qemu_irq_pulse(s->trigger); |
| 117 | } | 116 | } |
| 118 | if (s->mode[0] & 1) { | 117 | if (s->mode[0] & 1) { |
| 119 | /* One-shot. */ | 118 | /* One-shot. */ |
| @@ -340,19 +339,19 @@ static int gptm_load(QEMUFile *f, void *opaque, int version_id) | @@ -340,19 +339,19 @@ static int gptm_load(QEMUFile *f, void *opaque, int version_id) | ||
| 340 | return 0; | 339 | return 0; |
| 341 | } | 340 | } |
| 342 | 341 | ||
| 343 | -static void stellaris_gptm_init(uint32_t base, qemu_irq irq, qemu_irq trigger) | 342 | +static void stellaris_gptm_init(SysBusDevice *dev) |
| 344 | { | 343 | { |
| 345 | int iomemtype; | 344 | int iomemtype; |
| 346 | - gptm_state *s; | 345 | + gptm_state *s = FROM_SYSBUS(gptm_state, dev); |
| 347 | 346 | ||
| 348 | - s = (gptm_state *)qemu_mallocz(sizeof(gptm_state)); | ||
| 349 | - s->irq = irq; | ||
| 350 | - s->trigger = trigger; | ||
| 351 | - s->opaque[0] = s->opaque[1] = s; | 347 | + sysbus_init_irq(dev, &s->irq); |
| 348 | + qdev_init_gpio_out(&dev->qdev, &s->trigger, 1); | ||
| 352 | 349 | ||
| 353 | iomemtype = cpu_register_io_memory(0, gptm_readfn, | 350 | iomemtype = cpu_register_io_memory(0, gptm_readfn, |
| 354 | gptm_writefn, s); | 351 | gptm_writefn, s); |
| 355 | - cpu_register_physical_memory(base, 0x00001000, iomemtype); | 352 | + sysbus_init_mmio(dev, 0x1000, iomemtype); |
| 353 | + | ||
| 354 | + s->opaque[0] = s->opaque[1] = s; | ||
| 356 | s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]); | 355 | s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]); |
| 357 | s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]); | 356 | s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]); |
| 358 | register_savevm("stellaris_gptm", -1, 1, gptm_save, gptm_load, s); | 357 | register_savevm("stellaris_gptm", -1, 1, gptm_save, gptm_load, s); |
| @@ -906,6 +905,7 @@ static void stellaris_i2c_init(SysBusDevice * dev) | @@ -906,6 +905,7 @@ static void stellaris_i2c_init(SysBusDevice * dev) | ||
| 906 | 905 | ||
| 907 | typedef struct | 906 | typedef struct |
| 908 | { | 907 | { |
| 908 | + SysBusDevice busdev; | ||
| 909 | uint32_t actss; | 909 | uint32_t actss; |
| 910 | uint32_t ris; | 910 | uint32_t ris; |
| 911 | uint32_t im; | 911 | uint32_t im; |
| @@ -1178,26 +1178,23 @@ static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id) | @@ -1178,26 +1178,23 @@ static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id) | ||
| 1178 | return 0; | 1178 | return 0; |
| 1179 | } | 1179 | } |
| 1180 | 1180 | ||
| 1181 | -static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq *irq) | 1181 | +static void stellaris_adc_init(SysBusDevice *dev) |
| 1182 | { | 1182 | { |
| 1183 | - stellaris_adc_state *s; | 1183 | + stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev); |
| 1184 | int iomemtype; | 1184 | int iomemtype; |
| 1185 | - qemu_irq *qi; | ||
| 1186 | int n; | 1185 | int n; |
| 1187 | 1186 | ||
| 1188 | - s = (stellaris_adc_state *)qemu_mallocz(sizeof(stellaris_adc_state)); | ||
| 1189 | for (n = 0; n < 4; n++) { | 1187 | for (n = 0; n < 4; n++) { |
| 1190 | - s->irq[n] = irq[n]; | 1188 | + sysbus_init_irq(dev, &s->irq[n]); |
| 1191 | } | 1189 | } |
| 1192 | 1190 | ||
| 1193 | iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn, | 1191 | iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn, |
| 1194 | stellaris_adc_writefn, s); | 1192 | stellaris_adc_writefn, s); |
| 1195 | - cpu_register_physical_memory(base, 0x00001000, iomemtype); | 1193 | + sysbus_init_mmio(dev, 0x1000, iomemtype); |
| 1196 | stellaris_adc_reset(s); | 1194 | stellaris_adc_reset(s); |
| 1197 | - qi = qemu_allocate_irqs(stellaris_adc_trigger, s, 1); | 1195 | + qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1); |
| 1198 | register_savevm("stellaris_adc", -1, 1, | 1196 | register_savevm("stellaris_adc", -1, 1, |
| 1199 | stellaris_adc_save, stellaris_adc_load, s); | 1197 | stellaris_adc_save, stellaris_adc_load, s); |
| 1200 | - return qi[0]; | ||
| 1201 | } | 1198 | } |
| 1202 | 1199 | ||
| 1203 | /* Some boards have both an OLED controller and SD card connected to | 1200 | /* Some boards have both an OLED controller and SD card connected to |
| @@ -1294,27 +1291,36 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, | @@ -1294,27 +1291,36 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, | ||
| 1294 | static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31}; | 1291 | static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31}; |
| 1295 | 1292 | ||
| 1296 | qemu_irq *pic; | 1293 | qemu_irq *pic; |
| 1297 | - qemu_irq *gpio_in[7]; | ||
| 1298 | - qemu_irq *gpio_out[7]; | 1294 | + DeviceState *gpio_dev[7]; |
| 1295 | + qemu_irq gpio_in[7][8]; | ||
| 1296 | + qemu_irq gpio_out[7][8]; | ||
| 1299 | qemu_irq adc; | 1297 | qemu_irq adc; |
| 1300 | int sram_size; | 1298 | int sram_size; |
| 1301 | int flash_size; | 1299 | int flash_size; |
| 1302 | i2c_bus *i2c; | 1300 | i2c_bus *i2c; |
| 1301 | + DeviceState *dev; | ||
| 1303 | int i; | 1302 | int i; |
| 1303 | + int j; | ||
| 1304 | 1304 | ||
| 1305 | flash_size = ((board->dc0 & 0xffff) + 1) << 1; | 1305 | flash_size = ((board->dc0 & 0xffff) + 1) << 1; |
| 1306 | sram_size = (board->dc0 >> 18) + 1; | 1306 | sram_size = (board->dc0 >> 18) + 1; |
| 1307 | pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model); | 1307 | pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model); |
| 1308 | 1308 | ||
| 1309 | if (board->dc1 & (1 << 16)) { | 1309 | if (board->dc1 & (1 << 16)) { |
| 1310 | - adc = stellaris_adc_init(0x40038000, pic + 14); | 1310 | + dev = sysbus_create_varargs("stellaris-adc", 0x40038000, |
| 1311 | + pic[14], pic[15], pic[16], pic[17], NULL); | ||
| 1312 | + adc = qdev_get_gpio_in(dev, 0); | ||
| 1311 | } else { | 1313 | } else { |
| 1312 | adc = NULL; | 1314 | adc = NULL; |
| 1313 | } | 1315 | } |
| 1314 | for (i = 0; i < 4; i++) { | 1316 | for (i = 0; i < 4; i++) { |
| 1315 | if (board->dc2 & (0x10000 << i)) { | 1317 | if (board->dc2 & (0x10000 << i)) { |
| 1316 | - stellaris_gptm_init(0x40030000 + i * 0x1000, | ||
| 1317 | - pic[timer_irq[i]], adc); | 1318 | + dev = sysbus_create_simple("stellaris-gptm", |
| 1319 | + 0x40030000 + i * 0x1000, | ||
| 1320 | + pic[timer_irq[i]]); | ||
| 1321 | + /* TODO: This is incorrect, but we get away with it because | ||
| 1322 | + the ADC output is only ever pulsed. */ | ||
| 1323 | + qdev_connect_gpio_out(dev, 0, adc); | ||
| 1318 | } | 1324 | } |
| 1319 | } | 1325 | } |
| 1320 | 1326 | ||
| @@ -1322,13 +1328,16 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, | @@ -1322,13 +1328,16 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, | ||
| 1322 | 1328 | ||
| 1323 | for (i = 0; i < 7; i++) { | 1329 | for (i = 0; i < 7; i++) { |
| 1324 | if (board->dc4 & (1 << i)) { | 1330 | if (board->dc4 & (1 << i)) { |
| 1325 | - gpio_in[i] = pl061_init(gpio_addr[i], pic[gpio_irq[i]], | ||
| 1326 | - &gpio_out[i]); | 1331 | + gpio_dev[i] = sysbus_create_simple("pl061", gpio_addr[i], |
| 1332 | + pic[gpio_irq[i]]); | ||
| 1333 | + for (j = 0; j < 8; j++) { | ||
| 1334 | + gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j); | ||
| 1335 | + gpio_out[i][j] = NULL; | ||
| 1336 | + } | ||
| 1327 | } | 1337 | } |
| 1328 | } | 1338 | } |
| 1329 | 1339 | ||
| 1330 | if (board->dc2 & (1 << 12)) { | 1340 | if (board->dc2 & (1 << 12)) { |
| 1331 | - DeviceState *dev; | ||
| 1332 | dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]); | 1341 | dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]); |
| 1333 | i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); | 1342 | i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); |
| 1334 | if (board->peripherals & BP_OLED_I2C) { | 1343 | if (board->peripherals & BP_OLED_I2C) { |
| @@ -1343,7 +1352,6 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, | @@ -1343,7 +1352,6 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, | ||
| 1343 | } | 1352 | } |
| 1344 | } | 1353 | } |
| 1345 | if (board->dc2 & (1 << 4)) { | 1354 | if (board->dc2 & (1 << 4)) { |
| 1346 | - DeviceState *dev; | ||
| 1347 | dev = sysbus_create_simple("pl022", 0x40008000, pic[7]); | 1355 | dev = sysbus_create_simple("pl022", 0x40008000, pic[7]); |
| 1348 | if (board->peripherals & BP_OLED_SSI) { | 1356 | if (board->peripherals & BP_OLED_SSI) { |
| 1349 | DeviceState *mux; | 1357 | DeviceState *mux; |
| @@ -1387,6 +1395,15 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, | @@ -1387,6 +1395,15 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, | ||
| 1387 | 1395 | ||
| 1388 | stellaris_gamepad_init(5, gpad_irq, gpad_keycode); | 1396 | stellaris_gamepad_init(5, gpad_irq, gpad_keycode); |
| 1389 | } | 1397 | } |
| 1398 | + for (i = 0; i < 7; i++) { | ||
| 1399 | + if (board->dc4 & (1 << i)) { | ||
| 1400 | + for (j = 0; j < 8; j++) { | ||
| 1401 | + if (gpio_out[i][j]) { | ||
| 1402 | + qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]); | ||
| 1403 | + } | ||
| 1404 | + } | ||
| 1405 | + } | ||
| 1406 | + } | ||
| 1390 | } | 1407 | } |
| 1391 | 1408 | ||
| 1392 | /* FIXME: Figure out how to generate these from stellaris_boards. */ | 1409 | /* FIXME: Figure out how to generate these from stellaris_boards. */ |
| @@ -1435,6 +1452,10 @@ static void stellaris_register_devices(void) | @@ -1435,6 +1452,10 @@ static void stellaris_register_devices(void) | ||
| 1435 | { | 1452 | { |
| 1436 | sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state), | 1453 | sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state), |
| 1437 | stellaris_i2c_init); | 1454 | stellaris_i2c_init); |
| 1455 | + sysbus_register_dev("stellaris-gptm", sizeof(gptm_state), | ||
| 1456 | + stellaris_gptm_init); | ||
| 1457 | + sysbus_register_dev("stellaris-adc", sizeof(stellaris_adc_state), | ||
| 1458 | + stellaris_adc_init); | ||
| 1438 | ssi_register_slave("evb6965-ssi", sizeof(stellaris_ssi_bus_state), | 1459 | ssi_register_slave("evb6965-ssi", sizeof(stellaris_ssi_bus_state), |
| 1439 | &stellaris_ssi_bus_info); | 1460 | &stellaris_ssi_bus_info); |
| 1440 | } | 1461 | } |