Statistics
| Branch: | Revision:

root / hw / ssi.c @ 0dad6c35

History | View | Annotate | Download (1.9 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 8e31bf38 Matthew Fernandez
 * This code is licensed under the GNU GPL v2.
8 6b620ca3 Paolo Bonzini
 *
9 6b620ca3 Paolo Bonzini
 * Contributions after 2012-01-13 are licensed under the terms of the
10 6b620ca3 Paolo Bonzini
 * GNU GPL, version 2 or (at your option) any later version.
11 90d37239 Paul Brook
 */
12 90d37239 Paul Brook
13 90d37239 Paul Brook
#include "ssi.h"
14 90d37239 Paul Brook
15 90d37239 Paul Brook
struct SSIBus {
16 02e2da45 Paul Brook
    BusState qbus;
17 90d37239 Paul Brook
};
18 90d37239 Paul Brook
19 10c4c98a Gerd Hoffmann
static struct BusInfo ssi_bus_info = {
20 10c4c98a Gerd Hoffmann
    .name = "SSI",
21 10c4c98a Gerd Hoffmann
    .size = sizeof(SSIBus),
22 10c4c98a Gerd Hoffmann
};
23 10c4c98a Gerd Hoffmann
24 d307af79 Anthony Liguori
static int ssi_slave_init(DeviceState *dev)
25 90d37239 Paul Brook
{
26 cd6c4cf2 Anthony Liguori
    SSISlave *s = SSI_SLAVE(dev);
27 cd6c4cf2 Anthony Liguori
    SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s);
28 02e2da45 Paul Brook
    SSIBus *bus;
29 02e2da45 Paul Brook
30 02e2da45 Paul Brook
    bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev));
31 d8bb00d6 Paolo Bonzini
    if (QTAILQ_FIRST(&bus->qbus.children) != dev
32 d8bb00d6 Paolo Bonzini
        || QTAILQ_NEXT(dev, sibling) != NULL) {
33 02e2da45 Paul Brook
        hw_error("Too many devices on SSI bus");
34 02e2da45 Paul Brook
    }
35 90d37239 Paul Brook
36 cd6c4cf2 Anthony Liguori
    return ssc->init(s);
37 90d37239 Paul Brook
}
38 90d37239 Paul Brook
39 39bffca2 Anthony Liguori
static void ssi_slave_class_init(ObjectClass *klass, void *data)
40 90d37239 Paul Brook
{
41 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
42 39bffca2 Anthony Liguori
    dc->init = ssi_slave_init;
43 39bffca2 Anthony Liguori
    dc->bus_info = &ssi_bus_info;
44 90d37239 Paul Brook
}
45 90d37239 Paul Brook
46 39bffca2 Anthony Liguori
static TypeInfo ssi_slave_info = {
47 39bffca2 Anthony Liguori
    .name = TYPE_SSI_SLAVE,
48 39bffca2 Anthony Liguori
    .parent = TYPE_DEVICE,
49 39bffca2 Anthony Liguori
    .class_init = ssi_slave_class_init,
50 39bffca2 Anthony Liguori
    .class_size = sizeof(SSISlaveClass),
51 39bffca2 Anthony Liguori
    .abstract = true,
52 39bffca2 Anthony Liguori
};
53 39bffca2 Anthony Liguori
54 90d37239 Paul Brook
DeviceState *ssi_create_slave(SSIBus *bus, const char *name)
55 90d37239 Paul Brook
{
56 90d37239 Paul Brook
    DeviceState *dev;
57 02e2da45 Paul Brook
    dev = qdev_create(&bus->qbus, name);
58 e23a1b33 Markus Armbruster
    qdev_init_nofail(dev);
59 90d37239 Paul Brook
    return dev;
60 90d37239 Paul Brook
}
61 90d37239 Paul Brook
62 02e2da45 Paul Brook
SSIBus *ssi_create_bus(DeviceState *parent, const char *name)
63 90d37239 Paul Brook
{
64 02e2da45 Paul Brook
    BusState *bus;
65 10c4c98a Gerd Hoffmann
    bus = qbus_create(&ssi_bus_info, parent, name);
66 02e2da45 Paul Brook
    return FROM_QBUS(SSIBus, bus);
67 90d37239 Paul Brook
}
68 90d37239 Paul Brook
69 90d37239 Paul Brook
uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
70 90d37239 Paul Brook
{
71 02e2da45 Paul Brook
    DeviceState *dev;
72 02e2da45 Paul Brook
    SSISlave *slave;
73 cd6c4cf2 Anthony Liguori
    SSISlaveClass *ssc;
74 d8bb00d6 Paolo Bonzini
    dev = QTAILQ_FIRST(&bus->qbus.children);
75 02e2da45 Paul Brook
    if (!dev) {
76 90d37239 Paul Brook
        return 0;
77 90d37239 Paul Brook
    }
78 cd6c4cf2 Anthony Liguori
    slave = SSI_SLAVE(dev);
79 cd6c4cf2 Anthony Liguori
    ssc = SSI_SLAVE_GET_CLASS(slave);
80 cd6c4cf2 Anthony Liguori
    return ssc->transfer(slave, val);
81 90d37239 Paul Brook
}
82 39bffca2 Anthony Liguori
83 39bffca2 Anthony Liguori
static void register_ssi_slave(void)
84 39bffca2 Anthony Liguori
{
85 39bffca2 Anthony Liguori
    type_register_static(&ssi_slave_info);
86 39bffca2 Anthony Liguori
}
87 39bffca2 Anthony Liguori
88 39bffca2 Anthony Liguori
device_init(register_ssi_slave);