Commit 5493e33f12b75207f8b1bb993ba97e47b3d8de85

Authored by Paul Brook
1 parent 90d37239

Stellaris SSI qdev conversion

Signed-off-by: Paul Brook <paul@codesourcery.com>
hw/devices.h
@@ -6,10 +6,6 @@ @@ -6,10 +6,6 @@
6 /* smc91c111.c */ 6 /* smc91c111.c */
7 void smc91c111_init(NICInfo *, uint32_t, qemu_irq); 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 /* ads7846.c */ 9 /* ads7846.c */
14 typedef struct ADS7846State ADS7846State; 10 typedef struct ADS7846State ADS7846State;
15 uint32_t ads7846_read(void *opaque); 11 uint32_t ads7846_read(void *opaque);
hw/pl022.c
@@ -7,7 +7,8 @@ @@ -7,7 +7,8 @@
7 * This code is licenced under the GPL. 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 #include "primecell.h" 12 #include "primecell.h"
12 13
13 //#define DEBUG_PL022 1 14 //#define DEBUG_PL022 1
@@ -40,6 +41,7 @@ do { fprintf(stderr, &quot;pl022: error: &quot; fmt , ## __VA_ARGS__);} while (0) @@ -40,6 +41,7 @@ do { fprintf(stderr, &quot;pl022: error: &quot; fmt , ## __VA_ARGS__);} while (0)
40 #define PL022_INT_TX 0x08 41 #define PL022_INT_TX 0x08
41 42
42 typedef struct { 43 typedef struct {
  44 + SysBusDevice busdev;
43 uint32_t cr0; 45 uint32_t cr0;
44 uint32_t cr1; 46 uint32_t cr1;
45 uint32_t bitmask; 47 uint32_t bitmask;
@@ -55,8 +57,7 @@ typedef struct { @@ -55,8 +57,7 @@ typedef struct {
55 uint16_t tx_fifo[8]; 57 uint16_t tx_fifo[8];
56 uint16_t rx_fifo[8]; 58 uint16_t rx_fifo[8];
57 qemu_irq irq; 59 qemu_irq irq;
58 - int (*xfer_cb)(void *, int);  
59 - void *opaque; 60 + SSIBus *ssi;
60 } pl022_state; 61 } pl022_state;
61 62
62 static const unsigned char pl022_id[8] = 63 static const unsigned char pl022_id[8] =
@@ -116,10 +117,8 @@ static void pl022_xfer(pl022_state *s) @@ -116,10 +117,8 @@ static void pl022_xfer(pl022_state *s)
116 val = s->tx_fifo[i]; 117 val = s->tx_fifo[i];
117 if (s->cr1 & PL022_CR1_LBM) { 118 if (s->cr1 & PL022_CR1_LBM) {
118 /* Loopback mode. */ 119 /* Loopback mode. */
119 - } else if (s->xfer_cb) {  
120 - val = s->xfer_cb(s->opaque, val);  
121 } else { 120 } else {
122 - val = 0; 121 + val = ssi_transfer(s->ssi, val);
123 } 122 }
124 s->rx_fifo[o] = val & s->bitmask; 123 s->rx_fifo[o] = val & s->bitmask;
125 i = (i + 1) & 7; 124 i = (i + 1) & 7;
@@ -289,19 +288,24 @@ static int pl022_load(QEMUFile *f, void *opaque, int version_id) @@ -289,19 +288,24 @@ static int pl022_load(QEMUFile *f, void *opaque, int version_id)
289 return 0; 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 int iomemtype; 294 int iomemtype;
296 - pl022_state *s;  
297 295
298 - s = (pl022_state *)qemu_mallocz(sizeof(pl022_state));  
299 iomemtype = cpu_register_io_memory(0, pl022_readfn, 296 iomemtype = cpu_register_io_memory(0, pl022_readfn,
300 pl022_writefn, s); 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 pl022_reset(s); 302 pl022_reset(s);
306 register_savevm("pl022_ssp", -1, 1, pl022_save, pl022_load, s); 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,11 +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 -/* 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 /* pl061.c */ 8 /* pl061.c */
14 void pl061_float_high(void *opaque, uint8_t mask); 9 void pl061_float_high(void *opaque, uint8_t mask);
15 qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out); 10 qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out);
@@ -76,8 +76,4 @@ void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert); @@ -76,8 +76,4 @@ void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert);
76 int sd_data_ready(SDState *sd); 76 int sd_data_ready(SDState *sd);
77 void sd_enable(SDState *sd, int enable); 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 #endif /* __hw_sd_h */ 79 #endif /* __hw_sd_h */
hw/ssd0323.c
@@ -10,8 +10,7 @@ @@ -10,8 +10,7 @@
10 /* The controller can support a variety of different displays, but we only 10 /* The controller can support a variety of different displays, but we only
11 implement one. Most of the commends relating to brightness and geometry 11 implement one. Most of the commends relating to brightness and geometry
12 setup are ignored. */ 12 setup are ignored. */
13 -#include "hw.h"  
14 -#include "devices.h" 13 +#include "ssi.h"
15 #include "console.h" 14 #include "console.h"
16 15
17 //#define DEBUG_SSD0323 1 16 //#define DEBUG_SSD0323 1
@@ -43,6 +42,7 @@ enum ssd0323_mode @@ -43,6 +42,7 @@ enum ssd0323_mode
43 }; 42 };
44 43
45 typedef struct { 44 typedef struct {
  45 + SSISlave ssidev;
46 DisplayState *ds; 46 DisplayState *ds;
47 47
48 int cmd_len; 48 int cmd_len;
@@ -60,9 +60,10 @@ typedef struct { @@ -60,9 +60,10 @@ typedef struct {
60 uint8_t framebuffer[128 * 80 / 2]; 60 uint8_t framebuffer[128 * 80 / 2];
61 } ssd0323_state; 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 switch (s->mode) { 67 switch (s->mode) {
67 case SSD0323_DATA: 68 case SSD0323_DATA:
68 DPRINTF("data 0x%02x\n", data); 69 DPRINTF("data 0x%02x\n", data);
@@ -321,12 +322,10 @@ static int ssd0323_load(QEMUFile *f, void *opaque, int version_id) @@ -321,12 +322,10 @@ static int ssd0323_load(QEMUFile *f, void *opaque, int version_id)
321 return 0; 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 s->col_end = 63; 329 s->col_end = 63;
331 s->row_end = 79; 330 s->row_end = 79;
332 s->ds = graphic_console_init(ssd0323_update_display, 331 s->ds = graphic_console_init(ssd0323_update_display,
@@ -334,10 +333,19 @@ void *ssd0323_init(qemu_irq *cmd_p) @@ -334,10 +333,19 @@ void *ssd0323_init(qemu_irq *cmd_p)
334 NULL, NULL, s); 333 NULL, NULL, s);
335 qemu_console_resize(s->ds, 128 * MAGNIFY, 64 * MAGNIFY); 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 register_savevm("ssd0323_oled", -1, 1, ssd0323_save, ssd0323_load, s); 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 * SSI to SD card adapter. 2 * SSI to SD card adapter.
3 * 3 *
4 - * Copyright (c) 2007 CodeSourcery. 4 + * Copyright (c) 2007-2009 CodeSourcery.
5 * Written by Paul Brook 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 #include "sd.h" 11 #include "sd.h"
  12 +#include "sysemu.h"
12 13
13 //#define DEBUG_SSI_SD 1 14 //#define DEBUG_SSI_SD 1
14 15
@@ -32,6 +33,7 @@ typedef enum { @@ -32,6 +33,7 @@ typedef enum {
32 } ssi_sd_mode; 33 } ssi_sd_mode;
33 34
34 typedef struct { 35 typedef struct {
  36 + SSISlave ssidev;
35 ssi_sd_mode mode; 37 ssi_sd_mode mode;
36 int cmd; 38 int cmd;
37 uint8_t cmdarg[4]; 39 uint8_t cmdarg[4];
@@ -59,9 +61,9 @@ typedef struct { @@ -59,9 +61,9 @@ typedef struct {
59 #define SSI_SDR_ADDRESS_ERROR 0x2000 61 #define SSI_SDR_ADDRESS_ERROR 0x2000
60 #define SSI_SDR_PARAMETER_ERROR 0x4000 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 /* Special case: allow CMD12 (STOP TRANSMISSION) while reading data. */ 68 /* Special case: allow CMD12 (STOP TRANSMISSION) while reading data. */
67 if (s->mode == SSI_SD_DATA_READ && val == 0x4d) { 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,13 +229,25 @@ static int ssi_sd_load(QEMUFile *f, void *opaque, int version_id)
227 return 0; 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 s->mode = SSI_SD_CMD; 237 s->mode = SSI_SD_CMD;
  238 + bs = qdev_init_bdrv(&dev->qdev, IF_SD);
236 s->sd = sd_init(bs, 1); 239 s->sd = sd_init(bs, 1);
237 register_savevm("ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s); 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,13 +8,13 @@
8 */ 8 */
9 9
10 #include "sysbus.h" 10 #include "sysbus.h"
  11 +#include "ssi.h"
11 #include "arm-misc.h" 12 #include "arm-misc.h"
12 #include "primecell.h" 13 #include "primecell.h"
13 #include "devices.h" 14 #include "devices.h"
14 #include "qemu-timer.h" 15 #include "qemu-timer.h"
15 #include "i2c.h" 16 #include "i2c.h"
16 #include "net.h" 17 #include "net.h"
17 -#include "sd.h"  
18 #include "sysemu.h" 18 #include "sysemu.h"
19 #include "boards.h" 19 #include "boards.h"
20 20
@@ -1196,10 +1196,10 @@ static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq) @@ -1196,10 +1196,10 @@ static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq)
1196 0xff commands that occur when deselecting the SD card. */ 1196 0xff commands that occur when deselecting the SD card. */
1197 1197
1198 typedef struct { 1198 typedef struct {
1199 - ssi_xfer_cb xfer_cb[2];  
1200 - void *opaque[2]; 1199 + SSISlave ssidev;
1201 qemu_irq irq; 1200 qemu_irq irq;
1202 int current_dev; 1201 int current_dev;
  1202 + SSIBus *bus[2];
1203 } stellaris_ssi_bus_state; 1203 } stellaris_ssi_bus_state;
1204 1204
1205 static void stellaris_ssi_bus_select(void *opaque, int irq, int level) 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,11 +1209,11 @@ static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
1209 s->current_dev = level; 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 static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque) 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,23 +1235,18 @@ static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id)
1235 return 0; 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 register_savevm("stellaris_ssi_bus", -1, 1, 1248 register_savevm("stellaris_ssi_bus", -1, 1,
1253 stellaris_ssi_bus_save, stellaris_ssi_bus_load, s); 1249 stellaris_ssi_bus_save, stellaris_ssi_bus_load, s);
1254 - return s;  
1255 } 1250 }
1256 1251
1257 /* Board init. */ 1252 /* Board init. */
@@ -1338,25 +1333,25 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, @@ -1338,25 +1333,25 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1338 } 1333 }
1339 } 1334 }
1340 if (board->dc2 & (1 << 4)) { 1335 if (board->dc2 & (1 << 4)) {
  1336 + DeviceState *dev;
  1337 + dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
1341 if (board->peripherals & BP_OLED_SSI) { 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 /* Make sure the select pin is high. */ 1353 /* Make sure the select pin is high. */
1357 qemu_irq_raise(gpio_out[GPIO_D][0]); 1354 qemu_irq_raise(gpio_out[GPIO_D][0]);
1358 - } else {  
1359 - pl022_init(0x40008000, pic[7], NULL, NULL);  
1360 } 1355 }
1361 } 1356 }
1362 if (board->dc4 & (1 << 28)) { 1357 if (board->dc4 & (1 << 28)) {
@@ -1413,10 +1408,17 @@ QEMUMachine lm3s6965evb_machine = { @@ -1413,10 +1408,17 @@ QEMUMachine lm3s6965evb_machine = {
1413 .init = lm3s6965evb_init, 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 static void stellaris_register_devices(void) 1416 static void stellaris_register_devices(void)
1417 { 1417 {
1418 sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state), 1418 sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state),
1419 stellaris_i2c_init); 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 device_init(stellaris_register_devices) 1424 device_init(stellaris_register_devices)