Statistics
| Branch: | Revision:

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
}