root / hw / ssi.c @ 9ba2f660
History | View | Annotate | Download (1.6 kB)
1 | 90d37239 | Paul Brook | /*
|
---|---|---|---|
2 | 90d37239 | Paul Brook | * QEMU Synchronous Serial Interface support
|
3 | 90d37239 | Paul Brook | *
|
4 | 90d37239 | Paul Brook | * Copyright (c) 2009 CodeSourcery.
|
5 | 90d37239 | Paul Brook | * Written by Paul Brook
|
6 | 90d37239 | Paul Brook | *
|
7 | 90d37239 | Paul Brook | * This code is licenced under the GNU GPL v2.
|
8 | 90d37239 | Paul Brook | */
|
9 | 90d37239 | Paul Brook | |
10 | 90d37239 | Paul Brook | #include "ssi.h" |
11 | 90d37239 | Paul Brook | |
12 | 90d37239 | Paul Brook | struct SSIBus {
|
13 | 02e2da45 | Paul Brook | BusState qbus; |
14 | 90d37239 | Paul Brook | }; |
15 | 90d37239 | Paul Brook | |
16 | 10c4c98a | Gerd Hoffmann | static struct BusInfo ssi_bus_info = { |
17 | 10c4c98a | Gerd Hoffmann | .name = "SSI",
|
18 | 10c4c98a | Gerd Hoffmann | .size = sizeof(SSIBus),
|
19 | 10c4c98a | Gerd Hoffmann | }; |
20 | 10c4c98a | Gerd Hoffmann | |
21 | 81a322d4 | Gerd Hoffmann | static int ssi_slave_init(DeviceState *dev, DeviceInfo *base_info) |
22 | 90d37239 | Paul Brook | { |
23 | 02e2da45 | Paul Brook | SSISlaveInfo *info = container_of(base_info, SSISlaveInfo, qdev); |
24 | 90d37239 | Paul Brook | SSISlave *s = SSI_SLAVE_FROM_QDEV(dev); |
25 | 02e2da45 | Paul Brook | SSIBus *bus; |
26 | 02e2da45 | Paul Brook | |
27 | 02e2da45 | Paul Brook | bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev)); |
28 | 72cf2d4f | Blue Swirl | if (QLIST_FIRST(&bus->qbus.children) != dev
|
29 | 72cf2d4f | Blue Swirl | || QLIST_NEXT(dev, sibling) != NULL) {
|
30 | 02e2da45 | Paul Brook | hw_error("Too many devices on SSI bus");
|
31 | 02e2da45 | Paul Brook | } |
32 | 90d37239 | Paul Brook | |
33 | 90d37239 | Paul Brook | s->info = info; |
34 | 81a322d4 | Gerd Hoffmann | return info->init(s);
|
35 | 90d37239 | Paul Brook | } |
36 | 90d37239 | Paul Brook | |
37 | 074f2fff | Gerd Hoffmann | void ssi_register_slave(SSISlaveInfo *info)
|
38 | 90d37239 | Paul Brook | { |
39 | 074f2fff | Gerd Hoffmann | assert(info->qdev.size >= sizeof(SSISlave));
|
40 | 02e2da45 | Paul Brook | info->qdev.init = ssi_slave_init; |
41 | 10c4c98a | Gerd Hoffmann | info->qdev.bus_info = &ssi_bus_info; |
42 | 074f2fff | Gerd Hoffmann | qdev_register(&info->qdev); |
43 | 90d37239 | Paul Brook | } |
44 | 90d37239 | Paul Brook | |
45 | 90d37239 | Paul Brook | DeviceState *ssi_create_slave(SSIBus *bus, const char *name) |
46 | 90d37239 | Paul Brook | { |
47 | 90d37239 | Paul Brook | DeviceState *dev; |
48 | 02e2da45 | Paul Brook | dev = qdev_create(&bus->qbus, name); |
49 | e23a1b33 | Markus Armbruster | qdev_init_nofail(dev); |
50 | 90d37239 | Paul Brook | return dev;
|
51 | 90d37239 | Paul Brook | } |
52 | 90d37239 | Paul Brook | |
53 | 02e2da45 | Paul Brook | SSIBus *ssi_create_bus(DeviceState *parent, const char *name) |
54 | 90d37239 | Paul Brook | { |
55 | 02e2da45 | Paul Brook | BusState *bus; |
56 | 10c4c98a | Gerd Hoffmann | bus = qbus_create(&ssi_bus_info, parent, name); |
57 | 02e2da45 | Paul Brook | return FROM_QBUS(SSIBus, bus);
|
58 | 90d37239 | Paul Brook | } |
59 | 90d37239 | Paul Brook | |
60 | 90d37239 | Paul Brook | uint32_t ssi_transfer(SSIBus *bus, uint32_t val) |
61 | 90d37239 | Paul Brook | { |
62 | 02e2da45 | Paul Brook | DeviceState *dev; |
63 | 02e2da45 | Paul Brook | SSISlave *slave; |
64 | 72cf2d4f | Blue Swirl | dev = QLIST_FIRST(&bus->qbus.children); |
65 | 02e2da45 | Paul Brook | if (!dev) {
|
66 | 90d37239 | Paul Brook | return 0; |
67 | 90d37239 | Paul Brook | } |
68 | 02e2da45 | Paul Brook | slave = SSI_SLAVE_FROM_QDEV(dev); |
69 | 02e2da45 | Paul Brook | return slave->info->transfer(slave, val);
|
70 | 90d37239 | Paul Brook | } |