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) |
... | ... |