1
2
3
4
5
6
7
8
9
10
11#include "qemu/osdep.h"
12#include "sysemu/sysemu.h"
13#include "qemu/log.h"
14#include "qapi/qmp/qerror.h"
15#include "hw/qdev.h"
16#include "qapi/error.h"
17#include "hw/ssi/ssi.h"
18
19#include "hw/remote-port-proto.h"
20#include "hw/remote-port-device.h"
21
22#define TYPE_REMOTE_PORT_SSI_SLAVE "remote-port-ssi-slave"
23#define REMOTE_PORT_SSI_SLAVE(obj) \
24 OBJECT_CHECK(RemotePortSSISlave, (obj), \
25 TYPE_REMOTE_PORT_SSI_SLAVE)
26
27typedef struct RemotePortSSISlave {
28
29 DeviceState parent;
30
31 struct RemotePort *rp;
32 SSIBus *ssib;
33
34 uint16_t num_ssi_devs;
35} RemotePortSSISlave;
36
37static void rp_ssi_slave_write(RemotePortDevice *rpd, struct rp_pkt *pkt)
38{
39 RemotePortSSISlave *s = REMOTE_PORT_SSI_SLAVE(rpd);
40
41 size_t pktlen = sizeof(struct rp_pkt_busaccess) + 4;
42 size_t enclen;
43 int64_t delay;
44 uint32_t data, *data_p;
45 RemotePortDynPkt rsp;
46
47 data_p = (uint32_t *)(pkt + 1);
48 data = be32_to_cpu(*data_p);
49
50 assert(!(pkt->hdr.flags & RP_PKT_FLAGS_response));
51
52 memset(&rsp, 0, sizeof(rsp));
53 rp_dpkt_alloc(&rsp, pktlen);
54
55 data = ssi_transfer(s->ssib, data);
56 data_p = (uint32_t *)(rsp.pkt + 1);
57 *data_p = cpu_to_be32(data);
58
59
60
61 delay = 0;
62
63 enclen = rp_encode_read_resp(
64 pkt->hdr.id, pkt->hdr.dev, &rsp.pkt->busaccess,
65 pkt->busaccess.timestamp + delay,
66 0,
67 pkt->busaccess.addr,
68 pkt->busaccess.attributes,
69 pkt->busaccess.len,
70 pkt->busaccess.width,
71 pkt->busaccess.stream_width);
72
73 assert(enclen == pktlen);
74
75 rp_write(s->rp, (void *)rsp.pkt, pktlen);
76}
77
78static void rp_ssi_slave_realize(DeviceState *dev, Error **errp)
79{
80 RemotePortSSISlave *s = REMOTE_PORT_SSI_SLAVE(dev);
81
82 s->ssib = ssi_create_bus(dev, "ssib");
83}
84
85static void rp_ssi_slave_init(Object *obj)
86{
87 RemotePortSSISlave *rpms = REMOTE_PORT_SSI_SLAVE(obj);
88
89 object_property_add_link(obj, "rp-adaptor0", "remote-port",
90 (Object **)&rpms->rp,
91 qdev_prop_allow_set_link_before_realize,
92 OBJ_PROP_LINK_UNREF_ON_RELEASE,
93 &error_abort);
94}
95
96static Property rp_properties[] = {
97 DEFINE_PROP_UINT16("num-ssi-devs", RemotePortSSISlave, num_ssi_devs, 1),
98 DEFINE_PROP_END_OF_LIST(),
99};
100
101static void rp_ssi_slave_class_init(ObjectClass *oc, void *data)
102{
103 RemotePortDeviceClass *rpdc = REMOTE_PORT_DEVICE_CLASS(oc);
104 DeviceClass *dc = DEVICE_CLASS(oc);
105
106 rpdc->ops[RP_CMD_write] = rp_ssi_slave_write;
107 dc->realize = rp_ssi_slave_realize;
108 dc->props = rp_properties;
109}
110
111static const TypeInfo rp_info = {
112 .name = TYPE_REMOTE_PORT_SSI_SLAVE,
113 .parent = TYPE_DEVICE,
114 .instance_size = sizeof(RemotePortSSISlave),
115 .instance_init = rp_ssi_slave_init,
116 .class_init = rp_ssi_slave_class_init,
117 .interfaces = (InterfaceInfo[]) {
118 { TYPE_REMOTE_PORT_DEVICE },
119 { },
120 },
121};
122
123static void rp_register_types(void)
124{
125 type_register_static(&rp_info);
126}
127
128type_init(rp_register_types)
129