Paul Brook | 90d3723 | 2009-05-14 22:35:09 +0100 | [diff] [blame] | 1 | /* |
| 2 | * QEMU Synchronous Serial Interface support |
| 3 | * |
| 4 | * Copyright (c) 2009 CodeSourcery. |
| 5 | * Written by Paul Brook |
| 6 | * |
| 7 | * This code is licenced under the GNU GPL v2. |
| 8 | */ |
| 9 | |
| 10 | #include "ssi.h" |
| 11 | |
| 12 | struct SSIBus { |
Paul Brook | 02e2da4 | 2009-05-23 00:05:19 +0100 | [diff] [blame] | 13 | BusState qbus; |
Paul Brook | 90d3723 | 2009-05-14 22:35:09 +0100 | [diff] [blame] | 14 | }; |
| 15 | |
Gerd Hoffmann | 10c4c98 | 2009-06-30 14:12:08 +0200 | [diff] [blame] | 16 | static struct BusInfo ssi_bus_info = { |
| 17 | .name = "SSI", |
| 18 | .size = sizeof(SSIBus), |
| 19 | }; |
| 20 | |
Paul Brook | 02e2da4 | 2009-05-23 00:05:19 +0100 | [diff] [blame] | 21 | static void ssi_slave_init(DeviceState *dev, DeviceInfo *base_info) |
Paul Brook | 90d3723 | 2009-05-14 22:35:09 +0100 | [diff] [blame] | 22 | { |
Paul Brook | 02e2da4 | 2009-05-23 00:05:19 +0100 | [diff] [blame] | 23 | SSISlaveInfo *info = container_of(base_info, SSISlaveInfo, qdev); |
Paul Brook | 90d3723 | 2009-05-14 22:35:09 +0100 | [diff] [blame] | 24 | SSISlave *s = SSI_SLAVE_FROM_QDEV(dev); |
Paul Brook | 02e2da4 | 2009-05-23 00:05:19 +0100 | [diff] [blame] | 25 | SSIBus *bus; |
Paul Brook | 90d3723 | 2009-05-14 22:35:09 +0100 | [diff] [blame] | 26 | |
Paul Brook | 02e2da4 | 2009-05-23 00:05:19 +0100 | [diff] [blame] | 27 | bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev)); |
| 28 | if (LIST_FIRST(&bus->qbus.children) != dev |
| 29 | || LIST_NEXT(dev, sibling) != NULL) { |
| 30 | hw_error("Too many devices on SSI bus"); |
| 31 | } |
| 32 | |
Paul Brook | 90d3723 | 2009-05-14 22:35:09 +0100 | [diff] [blame] | 33 | s->info = info; |
| 34 | info->init(s); |
| 35 | } |
| 36 | |
Gerd Hoffmann | 074f2ff | 2009-06-10 09:41:42 +0200 | [diff] [blame] | 37 | void ssi_register_slave(SSISlaveInfo *info) |
Paul Brook | 90d3723 | 2009-05-14 22:35:09 +0100 | [diff] [blame] | 38 | { |
Gerd Hoffmann | 074f2ff | 2009-06-10 09:41:42 +0200 | [diff] [blame] | 39 | assert(info->qdev.size >= sizeof(SSISlave)); |
Paul Brook | 02e2da4 | 2009-05-23 00:05:19 +0100 | [diff] [blame] | 40 | info->qdev.init = ssi_slave_init; |
Gerd Hoffmann | 10c4c98 | 2009-06-30 14:12:08 +0200 | [diff] [blame] | 41 | info->qdev.bus_info = &ssi_bus_info; |
Gerd Hoffmann | 074f2ff | 2009-06-10 09:41:42 +0200 | [diff] [blame] | 42 | qdev_register(&info->qdev); |
Paul Brook | 90d3723 | 2009-05-14 22:35:09 +0100 | [diff] [blame] | 43 | } |
| 44 | |
| 45 | DeviceState *ssi_create_slave(SSIBus *bus, const char *name) |
| 46 | { |
| 47 | DeviceState *dev; |
Paul Brook | 02e2da4 | 2009-05-23 00:05:19 +0100 | [diff] [blame] | 48 | dev = qdev_create(&bus->qbus, name); |
Paul Brook | 90d3723 | 2009-05-14 22:35:09 +0100 | [diff] [blame] | 49 | qdev_init(dev); |
| 50 | return dev; |
| 51 | } |
| 52 | |
Paul Brook | 02e2da4 | 2009-05-23 00:05:19 +0100 | [diff] [blame] | 53 | SSIBus *ssi_create_bus(DeviceState *parent, const char *name) |
Paul Brook | 90d3723 | 2009-05-14 22:35:09 +0100 | [diff] [blame] | 54 | { |
Paul Brook | 02e2da4 | 2009-05-23 00:05:19 +0100 | [diff] [blame] | 55 | BusState *bus; |
Gerd Hoffmann | 10c4c98 | 2009-06-30 14:12:08 +0200 | [diff] [blame] | 56 | bus = qbus_create(&ssi_bus_info, parent, name); |
Paul Brook | 02e2da4 | 2009-05-23 00:05:19 +0100 | [diff] [blame] | 57 | return FROM_QBUS(SSIBus, bus); |
Paul Brook | 90d3723 | 2009-05-14 22:35:09 +0100 | [diff] [blame] | 58 | } |
| 59 | |
| 60 | uint32_t ssi_transfer(SSIBus *bus, uint32_t val) |
| 61 | { |
Paul Brook | 02e2da4 | 2009-05-23 00:05:19 +0100 | [diff] [blame] | 62 | DeviceState *dev; |
| 63 | SSISlave *slave; |
| 64 | dev = LIST_FIRST(&bus->qbus.children); |
| 65 | if (!dev) { |
Paul Brook | 90d3723 | 2009-05-14 22:35:09 +0100 | [diff] [blame] | 66 | return 0; |
| 67 | } |
Paul Brook | 02e2da4 | 2009-05-23 00:05:19 +0100 | [diff] [blame] | 68 | slave = SSI_SLAVE_FROM_QDEV(dev); |
| 69 | return slave->info->transfer(slave, val); |
Paul Brook | 90d3723 | 2009-05-14 22:35:09 +0100 | [diff] [blame] | 70 | } |