Commit 5493e33f12b75207f8b1bb993ba97e47b3d8de85
1 parent
90d37239
Stellaris SSI qdev conversion
Signed-off-by: Paul Brook <paul@codesourcery.com>
Showing
7 changed files
with
95 additions
and
80 deletions
hw/devices.h
| ... | ... | @@ -6,10 +6,6 @@ |
| 6 | 6 | /* smc91c111.c */ |
| 7 | 7 | void smc91c111_init(NICInfo *, uint32_t, qemu_irq); |
| 8 | 8 | |
| 9 | -/* ssd0323.c */ | |
| 10 | -int ssd0323_xfer_ssi(void *opaque, int data); | |
| 11 | -void *ssd0323_init(qemu_irq *cmd_p); | |
| 12 | - | |
| 13 | 9 | /* ads7846.c */ |
| 14 | 10 | typedef struct ADS7846State ADS7846State; |
| 15 | 11 | uint32_t ads7846_read(void *opaque); | ... | ... |
hw/pl022.c
| ... | ... | @@ -7,7 +7,8 @@ |
| 7 | 7 | * This code is licenced under the GPL. |
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | -#include "hw.h" | |
| 10 | +#include "sysbus.h" | |
| 11 | +#include "ssi.h" | |
| 11 | 12 | #include "primecell.h" |
| 12 | 13 | |
| 13 | 14 | //#define DEBUG_PL022 1 |
| ... | ... | @@ -40,6 +41,7 @@ do { fprintf(stderr, "pl022: error: " fmt , ## __VA_ARGS__);} while (0) |
| 40 | 41 | #define PL022_INT_TX 0x08 |
| 41 | 42 | |
| 42 | 43 | typedef struct { |
| 44 | + SysBusDevice busdev; | |
| 43 | 45 | uint32_t cr0; |
| 44 | 46 | uint32_t cr1; |
| 45 | 47 | uint32_t bitmask; |
| ... | ... | @@ -55,8 +57,7 @@ typedef struct { |
| 55 | 57 | uint16_t tx_fifo[8]; |
| 56 | 58 | uint16_t rx_fifo[8]; |
| 57 | 59 | qemu_irq irq; |
| 58 | - int (*xfer_cb)(void *, int); | |
| 59 | - void *opaque; | |
| 60 | + SSIBus *ssi; | |
| 60 | 61 | } pl022_state; |
| 61 | 62 | |
| 62 | 63 | static const unsigned char pl022_id[8] = |
| ... | ... | @@ -116,10 +117,8 @@ static void pl022_xfer(pl022_state *s) |
| 116 | 117 | val = s->tx_fifo[i]; |
| 117 | 118 | if (s->cr1 & PL022_CR1_LBM) { |
| 118 | 119 | /* Loopback mode. */ |
| 119 | - } else if (s->xfer_cb) { | |
| 120 | - val = s->xfer_cb(s->opaque, val); | |
| 121 | 120 | } else { |
| 122 | - val = 0; | |
| 121 | + val = ssi_transfer(s->ssi, val); | |
| 123 | 122 | } |
| 124 | 123 | s->rx_fifo[o] = val & s->bitmask; |
| 125 | 124 | i = (i + 1) & 7; |
| ... | ... | @@ -289,19 +288,24 @@ static int pl022_load(QEMUFile *f, void *opaque, int version_id) |
| 289 | 288 | return 0; |
| 290 | 289 | } |
| 291 | 290 | |
| 292 | -void pl022_init(uint32_t base, qemu_irq irq, int (*xfer_cb)(void *, int), | |
| 293 | - void * opaque) | |
| 291 | +static void pl022_init(SysBusDevice *dev) | |
| 294 | 292 | { |
| 293 | + pl022_state *s = FROM_SYSBUS(pl022_state, dev); | |
| 295 | 294 | int iomemtype; |
| 296 | - pl022_state *s; | |
| 297 | 295 | |
| 298 | - s = (pl022_state *)qemu_mallocz(sizeof(pl022_state)); | |
| 299 | 296 | iomemtype = cpu_register_io_memory(0, pl022_readfn, |
| 300 | 297 | pl022_writefn, s); |
| 301 | - cpu_register_physical_memory(base, 0x00001000, iomemtype); | |
| 302 | - s->irq = irq; | |
| 303 | - s->xfer_cb = xfer_cb; | |
| 304 | - s->opaque = opaque; | |
| 298 | + sysbus_init_mmio(dev, 0x1000, iomemtype); | |
| 299 | + sysbus_init_irq(dev, &s->irq); | |
| 300 | + s->ssi = ssi_create_bus(); | |
| 301 | + qdev_attach_child_bus(&dev->qdev, "ssi", s->ssi); | |
| 305 | 302 | pl022_reset(s); |
| 306 | 303 | register_savevm("pl022_ssp", -1, 1, pl022_save, pl022_load, s); |
| 307 | 304 | } |
| 305 | + | |
| 306 | +static void pl022_register_devices(void) | |
| 307 | +{ | |
| 308 | + sysbus_register_dev("pl022", sizeof(pl022_state), pl022_init); | |
| 309 | +} | |
| 310 | + | |
| 311 | +device_init(pl022_register_devices) | ... | ... |
hw/primecell.h
| ... | ... | @@ -5,11 +5,6 @@ |
| 5 | 5 | /* Also includes some devices that are currently only used by the |
| 6 | 6 | ARM boards. */ |
| 7 | 7 | |
| 8 | -/* pl022.c */ | |
| 9 | -typedef int (*ssi_xfer_cb)(void *, int); | |
| 10 | -void pl022_init(uint32_t base, qemu_irq irq, ssi_xfer_cb xfer_cb, | |
| 11 | - void *opaque); | |
| 12 | - | |
| 13 | 8 | /* pl061.c */ |
| 14 | 9 | void pl061_float_high(void *opaque, uint8_t mask); |
| 15 | 10 | qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out); | ... | ... |
hw/sd.h
| ... | ... | @@ -76,8 +76,4 @@ void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert); |
| 76 | 76 | int sd_data_ready(SDState *sd); |
| 77 | 77 | void sd_enable(SDState *sd, int enable); |
| 78 | 78 | |
| 79 | -/* ssi-sd.c */ | |
| 80 | -int ssi_sd_xfer(void *opaque, int val); | |
| 81 | -void *ssi_sd_init(BlockDriverState *bs); | |
| 82 | - | |
| 83 | 79 | #endif /* __hw_sd_h */ | ... | ... |
hw/ssd0323.c
| ... | ... | @@ -10,8 +10,7 @@ |
| 10 | 10 | /* The controller can support a variety of different displays, but we only |
| 11 | 11 | implement one. Most of the commends relating to brightness and geometry |
| 12 | 12 | setup are ignored. */ |
| 13 | -#include "hw.h" | |
| 14 | -#include "devices.h" | |
| 13 | +#include "ssi.h" | |
| 15 | 14 | #include "console.h" |
| 16 | 15 | |
| 17 | 16 | //#define DEBUG_SSD0323 1 |
| ... | ... | @@ -43,6 +42,7 @@ enum ssd0323_mode |
| 43 | 42 | }; |
| 44 | 43 | |
| 45 | 44 | typedef struct { |
| 45 | + SSISlave ssidev; | |
| 46 | 46 | DisplayState *ds; |
| 47 | 47 | |
| 48 | 48 | int cmd_len; |
| ... | ... | @@ -60,9 +60,10 @@ typedef struct { |
| 60 | 60 | uint8_t framebuffer[128 * 80 / 2]; |
| 61 | 61 | } ssd0323_state; |
| 62 | 62 | |
| 63 | -int ssd0323_xfer_ssi(void *opaque, int data) | |
| 63 | +static uint32_t ssd0323_transfer(SSISlave *dev, uint32_t data) | |
| 64 | 64 | { |
| 65 | - ssd0323_state *s = (ssd0323_state *)opaque; | |
| 65 | + ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev); | |
| 66 | + | |
| 66 | 67 | switch (s->mode) { |
| 67 | 68 | case SSD0323_DATA: |
| 68 | 69 | DPRINTF("data 0x%02x\n", data); |
| ... | ... | @@ -321,12 +322,10 @@ static int ssd0323_load(QEMUFile *f, void *opaque, int version_id) |
| 321 | 322 | return 0; |
| 322 | 323 | } |
| 323 | 324 | |
| 324 | -void *ssd0323_init(qemu_irq *cmd_p) | |
| 325 | +static void ssd0323_init(SSISlave *dev) | |
| 325 | 326 | { |
| 326 | - ssd0323_state *s; | |
| 327 | - qemu_irq *cmd; | |
| 327 | + ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev); | |
| 328 | 328 | |
| 329 | - s = (ssd0323_state *)qemu_mallocz(sizeof(ssd0323_state)); | |
| 330 | 329 | s->col_end = 63; |
| 331 | 330 | s->row_end = 79; |
| 332 | 331 | s->ds = graphic_console_init(ssd0323_update_display, |
| ... | ... | @@ -334,10 +333,19 @@ void *ssd0323_init(qemu_irq *cmd_p) |
| 334 | 333 | NULL, NULL, s); |
| 335 | 334 | qemu_console_resize(s->ds, 128 * MAGNIFY, 64 * MAGNIFY); |
| 336 | 335 | |
| 337 | - cmd = qemu_allocate_irqs(ssd0323_cd, s, 1); | |
| 338 | - *cmd_p = *cmd; | |
| 336 | + qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1); | |
| 339 | 337 | |
| 340 | 338 | register_savevm("ssd0323_oled", -1, 1, ssd0323_save, ssd0323_load, s); |
| 339 | +} | |
| 341 | 340 | |
| 342 | - return s; | |
| 341 | +static SSISlaveInfo ssd0323_info = { | |
| 342 | + .init = ssd0323_init, | |
| 343 | + .transfer = ssd0323_transfer | |
| 344 | +}; | |
| 345 | + | |
| 346 | +static void ssd03232_register_devices(void) | |
| 347 | +{ | |
| 348 | + ssi_register_slave("ssd0323", sizeof(ssd0323_state), &ssd0323_info); | |
| 343 | 349 | } |
| 350 | + | |
| 351 | +device_init(ssd03232_register_devices) | ... | ... |
hw/ssi-sd.c
| 1 | 1 | /* |
| 2 | 2 | * SSI to SD card adapter. |
| 3 | 3 | * |
| 4 | - * Copyright (c) 2007 CodeSourcery. | |
| 4 | + * Copyright (c) 2007-2009 CodeSourcery. | |
| 5 | 5 | * Written by Paul Brook |
| 6 | 6 | * |
| 7 | - * This code is licenced under the GPL. | |
| 7 | + * This code is licenced under the GNU GPL v2. | |
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | -#include "hw.h" | |
| 10 | +#include "ssi.h" | |
| 11 | 11 | #include "sd.h" |
| 12 | +#include "sysemu.h" | |
| 12 | 13 | |
| 13 | 14 | //#define DEBUG_SSI_SD 1 |
| 14 | 15 | |
| ... | ... | @@ -32,6 +33,7 @@ typedef enum { |
| 32 | 33 | } ssi_sd_mode; |
| 33 | 34 | |
| 34 | 35 | typedef struct { |
| 36 | + SSISlave ssidev; | |
| 35 | 37 | ssi_sd_mode mode; |
| 36 | 38 | int cmd; |
| 37 | 39 | uint8_t cmdarg[4]; |
| ... | ... | @@ -59,9 +61,9 @@ typedef struct { |
| 59 | 61 | #define SSI_SDR_ADDRESS_ERROR 0x2000 |
| 60 | 62 | #define SSI_SDR_PARAMETER_ERROR 0x4000 |
| 61 | 63 | |
| 62 | -int ssi_sd_xfer(void *opaque, int val) | |
| 64 | +static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val) | |
| 63 | 65 | { |
| 64 | - ssi_sd_state *s = (ssi_sd_state *)opaque; | |
| 66 | + ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, dev); | |
| 65 | 67 | |
| 66 | 68 | /* Special case: allow CMD12 (STOP TRANSMISSION) while reading data. */ |
| 67 | 69 | if (s->mode == SSI_SD_DATA_READ && val == 0x4d) { |
| ... | ... | @@ -227,13 +229,25 @@ static int ssi_sd_load(QEMUFile *f, void *opaque, int version_id) |
| 227 | 229 | return 0; |
| 228 | 230 | } |
| 229 | 231 | |
| 230 | -void *ssi_sd_init(BlockDriverState *bs) | |
| 232 | +static void ssi_sd_init(SSISlave *dev) | |
| 231 | 233 | { |
| 232 | - ssi_sd_state *s; | |
| 234 | + ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, dev); | |
| 235 | + BlockDriverState *bs; | |
| 233 | 236 | |
| 234 | - s = (ssi_sd_state *)qemu_mallocz(sizeof(ssi_sd_state)); | |
| 235 | 237 | s->mode = SSI_SD_CMD; |
| 238 | + bs = qdev_init_bdrv(&dev->qdev, IF_SD); | |
| 236 | 239 | s->sd = sd_init(bs, 1); |
| 237 | 240 | register_savevm("ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s); |
| 238 | - return s; | |
| 239 | 241 | } |
| 242 | + | |
| 243 | +static SSISlaveInfo ssi_sd_info = { | |
| 244 | + .init = ssi_sd_init, | |
| 245 | + .transfer = ssi_sd_transfer | |
| 246 | +}; | |
| 247 | + | |
| 248 | +static void ssi_sd_register_devices(void) | |
| 249 | +{ | |
| 250 | + ssi_register_slave("ssi-sd", sizeof(ssi_sd_state), &ssi_sd_info); | |
| 251 | +} | |
| 252 | + | |
| 253 | +device_init(ssi_sd_register_devices) | ... | ... |
hw/stellaris.c
| ... | ... | @@ -8,13 +8,13 @@ |
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | 10 | #include "sysbus.h" |
| 11 | +#include "ssi.h" | |
| 11 | 12 | #include "arm-misc.h" |
| 12 | 13 | #include "primecell.h" |
| 13 | 14 | #include "devices.h" |
| 14 | 15 | #include "qemu-timer.h" |
| 15 | 16 | #include "i2c.h" |
| 16 | 17 | #include "net.h" |
| 17 | -#include "sd.h" | |
| 18 | 18 | #include "sysemu.h" |
| 19 | 19 | #include "boards.h" |
| 20 | 20 | |
| ... | ... | @@ -1196,10 +1196,10 @@ static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq) |
| 1196 | 1196 | 0xff commands that occur when deselecting the SD card. */ |
| 1197 | 1197 | |
| 1198 | 1198 | typedef struct { |
| 1199 | - ssi_xfer_cb xfer_cb[2]; | |
| 1200 | - void *opaque[2]; | |
| 1199 | + SSISlave ssidev; | |
| 1201 | 1200 | qemu_irq irq; |
| 1202 | 1201 | int current_dev; |
| 1202 | + SSIBus *bus[2]; | |
| 1203 | 1203 | } stellaris_ssi_bus_state; |
| 1204 | 1204 | |
| 1205 | 1205 | static void stellaris_ssi_bus_select(void *opaque, int irq, int level) |
| ... | ... | @@ -1209,11 +1209,11 @@ static void stellaris_ssi_bus_select(void *opaque, int irq, int level) |
| 1209 | 1209 | s->current_dev = level; |
| 1210 | 1210 | } |
| 1211 | 1211 | |
| 1212 | -static int stellaris_ssi_bus_xfer(void *opaque, int val) | |
| 1212 | +static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val) | |
| 1213 | 1213 | { |
| 1214 | - stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque; | |
| 1214 | + stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev); | |
| 1215 | 1215 | |
| 1216 | - return s->xfer_cb[s->current_dev](s->opaque[s->current_dev], val); | |
| 1216 | + return ssi_transfer(s->bus[s->current_dev], val); | |
| 1217 | 1217 | } |
| 1218 | 1218 | |
| 1219 | 1219 | static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque) |
| ... | ... | @@ -1235,23 +1235,18 @@ static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id) |
| 1235 | 1235 | return 0; |
| 1236 | 1236 | } |
| 1237 | 1237 | |
| 1238 | -static void *stellaris_ssi_bus_init(qemu_irq *irqp, | |
| 1239 | - ssi_xfer_cb cb0, void *opaque0, | |
| 1240 | - ssi_xfer_cb cb1, void *opaque1) | |
| 1238 | +static void stellaris_ssi_bus_init(SSISlave *dev) | |
| 1241 | 1239 | { |
| 1242 | - qemu_irq *qi; | |
| 1243 | - stellaris_ssi_bus_state *s; | |
| 1244 | - | |
| 1245 | - s = (stellaris_ssi_bus_state *)qemu_mallocz(sizeof(stellaris_ssi_bus_state)); | |
| 1246 | - s->xfer_cb[0] = cb0; | |
| 1247 | - s->opaque[0] = opaque0; | |
| 1248 | - s->xfer_cb[1] = cb1; | |
| 1249 | - s->opaque[1] = opaque1; | |
| 1250 | - qi = qemu_allocate_irqs(stellaris_ssi_bus_select, s, 1); | |
| 1251 | - *irqp = *qi; | |
| 1240 | + stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev); | |
| 1241 | + | |
| 1242 | + s->bus[0] = ssi_create_bus(); | |
| 1243 | + qdev_attach_child_bus(&dev->qdev, "ssi0", s->bus[0]); | |
| 1244 | + s->bus[1] = ssi_create_bus(); | |
| 1245 | + qdev_attach_child_bus(&dev->qdev, "ssi1", s->bus[1]); | |
| 1246 | + qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1); | |
| 1247 | + | |
| 1252 | 1248 | register_savevm("stellaris_ssi_bus", -1, 1, |
| 1253 | 1249 | stellaris_ssi_bus_save, stellaris_ssi_bus_load, s); |
| 1254 | - return s; | |
| 1255 | 1250 | } |
| 1256 | 1251 | |
| 1257 | 1252 | /* Board init. */ |
| ... | ... | @@ -1338,25 +1333,25 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, |
| 1338 | 1333 | } |
| 1339 | 1334 | } |
| 1340 | 1335 | if (board->dc2 & (1 << 4)) { |
| 1336 | + DeviceState *dev; | |
| 1337 | + dev = sysbus_create_simple("pl022", 0x40008000, pic[7]); | |
| 1341 | 1338 | if (board->peripherals & BP_OLED_SSI) { |
| 1342 | - void * oled; | |
| 1343 | - void * sd; | |
| 1344 | - void *ssi_bus; | |
| 1345 | - int index; | |
| 1339 | + DeviceState *mux; | |
| 1340 | + void *bus; | |
| 1346 | 1341 | |
| 1347 | - oled = ssd0323_init(&gpio_out[GPIO_C][7]); | |
| 1348 | - index = drive_get_index(IF_SD, 0, 0); | |
| 1349 | - sd = ssi_sd_init(drives_table[index].bdrv); | |
| 1342 | + bus = qdev_get_child_bus(dev, "ssi"); | |
| 1343 | + mux = ssi_create_slave(bus, "evb6965-ssi"); | |
| 1344 | + gpio_out[GPIO_D][0] = qdev_get_gpio_in(mux, 0); | |
| 1350 | 1345 | |
| 1351 | - ssi_bus = stellaris_ssi_bus_init(&gpio_out[GPIO_D][0], | |
| 1352 | - ssi_sd_xfer, sd, | |
| 1353 | - ssd0323_xfer_ssi, oled); | |
| 1346 | + bus = qdev_get_child_bus(mux, "ssi0"); | |
| 1347 | + dev = ssi_create_slave(bus, "ssi-sd"); | |
| 1348 | + | |
| 1349 | + bus = qdev_get_child_bus(mux, "ssi1"); | |
| 1350 | + dev = ssi_create_slave(bus, "ssd0323"); | |
| 1351 | + gpio_out[GPIO_C][7] = qdev_get_gpio_in(dev, 0); | |
| 1354 | 1352 | |
| 1355 | - pl022_init(0x40008000, pic[7], stellaris_ssi_bus_xfer, ssi_bus); | |
| 1356 | 1353 | /* Make sure the select pin is high. */ |
| 1357 | 1354 | qemu_irq_raise(gpio_out[GPIO_D][0]); |
| 1358 | - } else { | |
| 1359 | - pl022_init(0x40008000, pic[7], NULL, NULL); | |
| 1360 | 1355 | } |
| 1361 | 1356 | } |
| 1362 | 1357 | if (board->dc4 & (1 << 28)) { |
| ... | ... | @@ -1413,10 +1408,17 @@ QEMUMachine lm3s6965evb_machine = { |
| 1413 | 1408 | .init = lm3s6965evb_init, |
| 1414 | 1409 | }; |
| 1415 | 1410 | |
| 1411 | +static SSISlaveInfo stellaris_ssi_bus_info = { | |
| 1412 | + .init = stellaris_ssi_bus_init, | |
| 1413 | + .transfer = stellaris_ssi_bus_transfer | |
| 1414 | +}; | |
| 1415 | + | |
| 1416 | 1416 | static void stellaris_register_devices(void) |
| 1417 | 1417 | { |
| 1418 | 1418 | sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state), |
| 1419 | 1419 | stellaris_i2c_init); |
| 1420 | + ssi_register_slave("evb6965-ssi", sizeof(stellaris_ssi_bus_state), | |
| 1421 | + &stellaris_ssi_bus_info); | |
| 1420 | 1422 | } |
| 1421 | 1423 | |
| 1422 | 1424 | device_init(stellaris_register_devices) | ... | ... |