root / hw / ssi.c @ cae4956e
History | View | Annotate | Download (1.5 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 | 02e2da45 | Paul Brook | static void ssi_slave_init(DeviceState *dev, DeviceInfo *base_info) |
17 | 90d37239 | Paul Brook | { |
18 | 02e2da45 | Paul Brook | SSISlaveInfo *info = container_of(base_info, SSISlaveInfo, qdev); |
19 | 90d37239 | Paul Brook | SSISlave *s = SSI_SLAVE_FROM_QDEV(dev); |
20 | 02e2da45 | Paul Brook | SSIBus *bus; |
21 | 02e2da45 | Paul Brook | |
22 | 02e2da45 | Paul Brook | bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev)); |
23 | 02e2da45 | Paul Brook | if (LIST_FIRST(&bus->qbus.children) != dev
|
24 | 02e2da45 | Paul Brook | || LIST_NEXT(dev, sibling) != NULL) {
|
25 | 02e2da45 | Paul Brook | hw_error("Too many devices on SSI bus");
|
26 | 02e2da45 | Paul Brook | } |
27 | 90d37239 | Paul Brook | |
28 | 90d37239 | Paul Brook | s->info = info; |
29 | 90d37239 | Paul Brook | info->init(s); |
30 | 90d37239 | Paul Brook | } |
31 | 90d37239 | Paul Brook | |
32 | 90d37239 | Paul Brook | void ssi_register_slave(const char *name, int size, SSISlaveInfo *info) |
33 | 90d37239 | Paul Brook | { |
34 | 90d37239 | Paul Brook | assert(size >= sizeof(SSISlave));
|
35 | 02e2da45 | Paul Brook | info->qdev.init = ssi_slave_init; |
36 | 02e2da45 | Paul Brook | info->qdev.bus_type = BUS_TYPE_SSI; |
37 | 02e2da45 | Paul Brook | qdev_register(name, size, &info->qdev); |
38 | 90d37239 | Paul Brook | } |
39 | 90d37239 | Paul Brook | |
40 | 90d37239 | Paul Brook | DeviceState *ssi_create_slave(SSIBus *bus, const char *name) |
41 | 90d37239 | Paul Brook | { |
42 | 90d37239 | Paul Brook | DeviceState *dev; |
43 | 02e2da45 | Paul Brook | dev = qdev_create(&bus->qbus, name); |
44 | 90d37239 | Paul Brook | qdev_init(dev); |
45 | 90d37239 | Paul Brook | return dev;
|
46 | 90d37239 | Paul Brook | } |
47 | 90d37239 | Paul Brook | |
48 | 02e2da45 | Paul Brook | SSIBus *ssi_create_bus(DeviceState *parent, const char *name) |
49 | 90d37239 | Paul Brook | { |
50 | 02e2da45 | Paul Brook | BusState *bus; |
51 | 02e2da45 | Paul Brook | bus = qbus_create(BUS_TYPE_SSI, sizeof(SSIBus), parent, name);
|
52 | 02e2da45 | Paul Brook | return FROM_QBUS(SSIBus, bus);
|
53 | 90d37239 | Paul Brook | } |
54 | 90d37239 | Paul Brook | |
55 | 90d37239 | Paul Brook | uint32_t ssi_transfer(SSIBus *bus, uint32_t val) |
56 | 90d37239 | Paul Brook | { |
57 | 02e2da45 | Paul Brook | DeviceState *dev; |
58 | 02e2da45 | Paul Brook | SSISlave *slave; |
59 | 02e2da45 | Paul Brook | dev = LIST_FIRST(&bus->qbus.children); |
60 | 02e2da45 | Paul Brook | if (!dev) {
|
61 | 90d37239 | Paul Brook | return 0; |
62 | 90d37239 | Paul Brook | } |
63 | 02e2da45 | Paul Brook | slave = SSI_SLAVE_FROM_QDEV(dev); |
64 | 02e2da45 | Paul Brook | return slave->info->transfer(slave, val);
|
65 | 90d37239 | Paul Brook | } |