root / hw / ssi.c @ a75b3e0f
History | View | Annotate | Download (2.1 kB)
1 |
/*
|
---|---|
2 |
* QEMU Synchronous Serial Interface support
|
3 |
*
|
4 |
* Copyright (c) 2009 CodeSourcery.
|
5 |
* Written by Paul Brook
|
6 |
*
|
7 |
* This code is licensed under the GNU GPL v2.
|
8 |
*
|
9 |
* Contributions after 2012-01-13 are licensed under the terms of the
|
10 |
* GNU GPL, version 2 or (at your option) any later version.
|
11 |
*/
|
12 |
|
13 |
#include "ssi.h" |
14 |
|
15 |
struct SSIBus {
|
16 |
BusState qbus; |
17 |
}; |
18 |
|
19 |
#define TYPE_SSI_BUS "SSI" |
20 |
#define SSI_BUS(obj) OBJECT_CHECK(SSIBus, (obj), TYPE_SSI_BUS)
|
21 |
|
22 |
static const TypeInfo ssi_bus_info = { |
23 |
.name = TYPE_SSI_BUS, |
24 |
.parent = TYPE_BUS, |
25 |
.instance_size = sizeof(SSIBus),
|
26 |
}; |
27 |
|
28 |
static int ssi_slave_init(DeviceState *dev) |
29 |
{ |
30 |
SSISlave *s = SSI_SLAVE(dev); |
31 |
SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s); |
32 |
SSIBus *bus; |
33 |
BusChild *kid; |
34 |
|
35 |
bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev)); |
36 |
kid = QTAILQ_FIRST(&bus->qbus.children); |
37 |
if (kid->child != dev || QTAILQ_NEXT(kid, sibling) != NULL) { |
38 |
hw_error("Too many devices on SSI bus");
|
39 |
} |
40 |
|
41 |
return ssc->init(s);
|
42 |
} |
43 |
|
44 |
static void ssi_slave_class_init(ObjectClass *klass, void *data) |
45 |
{ |
46 |
DeviceClass *dc = DEVICE_CLASS(klass); |
47 |
dc->init = ssi_slave_init; |
48 |
dc->bus_type = TYPE_SSI_BUS; |
49 |
} |
50 |
|
51 |
static TypeInfo ssi_slave_info = {
|
52 |
.name = TYPE_SSI_SLAVE, |
53 |
.parent = TYPE_DEVICE, |
54 |
.class_init = ssi_slave_class_init, |
55 |
.class_size = sizeof(SSISlaveClass),
|
56 |
.abstract = true,
|
57 |
}; |
58 |
|
59 |
DeviceState *ssi_create_slave(SSIBus *bus, const char *name) |
60 |
{ |
61 |
DeviceState *dev; |
62 |
dev = qdev_create(&bus->qbus, name); |
63 |
qdev_init_nofail(dev); |
64 |
return dev;
|
65 |
} |
66 |
|
67 |
SSIBus *ssi_create_bus(DeviceState *parent, const char *name) |
68 |
{ |
69 |
BusState *bus; |
70 |
bus = qbus_create(TYPE_SSI_BUS, parent, name); |
71 |
return FROM_QBUS(SSIBus, bus);
|
72 |
} |
73 |
|
74 |
uint32_t ssi_transfer(SSIBus *bus, uint32_t val) |
75 |
{ |
76 |
BusChild *kid; |
77 |
SSISlave *slave; |
78 |
SSISlaveClass *ssc; |
79 |
|
80 |
kid = QTAILQ_FIRST(&bus->qbus.children); |
81 |
if (!kid) {
|
82 |
return 0; |
83 |
} |
84 |
slave = SSI_SLAVE(kid->child); |
85 |
ssc = SSI_SLAVE_GET_CLASS(slave); |
86 |
return ssc->transfer(slave, val);
|
87 |
} |
88 |
|
89 |
static void ssi_slave_register_types(void) |
90 |
{ |
91 |
type_register_static(&ssi_bus_info); |
92 |
type_register_static(&ssi_slave_info); |
93 |
} |
94 |
|
95 |
type_init(ssi_slave_register_types) |