1
2
3
4
5
6
7
8
9
10
11#include "qemu/osdep.h"
12#include "hw/hw.h"
13#include "qapi/error.h"
14#include "qemu/error-report.h"
15#include "hw/register-dep.h"
16#include "qemu/log.h"
17
18static inline void register_write_log(DepRegisterInfo *reg, int dir, uint64_t val,
19 int mask, const char *msg,
20 const char *reason)
21{
22 qemu_log_mask(mask, "%s:%s bits %#" PRIx64 " %s write of %d%s%s\n",
23 reg->prefix, reg->access->name, val, msg, dir,
24 reason ? ": " : "", reason ? reason : "");
25}
26
27static inline void register_write_val(DepRegisterInfo *reg, uint64_t val)
28{
29 if (!reg->data) {
30 return;
31 }
32 switch (reg->data_size) {
33 case 1:
34 *(uint8_t *)reg->data = val;
35 break;
36 case 2:
37 *(uint16_t *)reg->data = val;
38 break;
39 case 4:
40 *(uint32_t *)reg->data = val;
41 break;
42 case 8:
43 *(uint64_t *)reg->data = val;
44 break;
45 default:
46 abort();
47 }
48}
49
50static inline uint64_t register_read_val(DepRegisterInfo *reg)
51{
52 switch (reg->data_size) {
53 case 1:
54 return *(uint8_t *)reg->data;
55 case 2:
56 return *(uint16_t *)reg->data;
57 case 4:
58 return *(uint32_t *)reg->data;
59 case 8:
60 return *(uint64_t *)reg->data;
61 default:
62 abort();
63 }
64 return 0;
65}
66
67void dep_register_write(DepRegisterInfo *reg, uint64_t val, uint64_t we)
68{
69 uint64_t old_val, new_val, test, no_w_mask;
70 const DepRegisterAccessInfo *ac;
71 const DepRegisterAccessError *rae;
72
73 assert(reg);
74
75 ac = reg->access;
76 old_val = reg->data ? register_read_val(reg) : ac->reset;
77 if (reg->write_lite && !~we) {
78 new_val = val;
79 goto register_write_fast;
80 }
81
82 if (!ac || !ac->name) {
83 qemu_log_mask(LOG_GUEST_ERROR, "%s: write to undefined device state "
84 "(written value: %#" PRIx64 ")\n", reg->prefix, val);
85 return;
86 }
87
88 no_w_mask = ac->ro | ac->w1c | ~we;
89
90 if (reg->debug) {
91 qemu_log("%s:%s: write of value %#" PRIx64 "\n", reg->prefix, ac->name,
92 val);
93 }
94
95 if (qemu_loglevel_mask(LOG_GUEST_ERROR)) {
96 test = (old_val ^ val) & ac->rsvd;
97 if (test) {
98 qemu_log_mask(LOG_GUEST_ERROR, "%s: change of value in reserved bit"
99 "fields: %#" PRIx64 ")\n", reg->prefix, test);
100 }
101 for (rae = ac->ge1; rae && rae->mask; rae++) {
102 test = val & rae->mask;
103 if (test) {
104 register_write_log(reg, 1, test, LOG_GUEST_ERROR,
105 "invalid", rae->reason);
106 }
107 }
108 for (rae = ac->ge0; rae && rae->mask; rae++) {
109 test = ~val & rae->mask;
110 if (test) {
111 register_write_log(reg, 0, test, LOG_GUEST_ERROR,
112 "invalid", rae->reason);
113 }
114 }
115 }
116
117 if (qemu_loglevel_mask(LOG_UNIMP)) {
118 for (rae = ac->ui1; rae && rae->mask; rae++) {
119 test = val & rae->mask;
120 if (test) {
121 register_write_log(reg, 1, test, LOG_GUEST_ERROR,
122 "unimplmented", rae->reason);
123 }
124 }
125 for (rae = ac->ui0; rae && rae->mask; rae++) {
126 test = ~val & rae->mask;
127 if (test) {
128 register_write_log(reg, 0, test, LOG_GUEST_ERROR,
129 "unimplemented", rae->reason);
130 }
131 }
132 }
133
134 new_val = (val & ~no_w_mask) | (old_val & no_w_mask);
135 new_val &= ~(val & ac->w1c);
136
137 if (ac->pre_write) {
138 new_val = ac->pre_write(reg, new_val);
139 }
140register_write_fast:
141 register_write_val(reg, new_val);
142 dep_register_refresh_gpios(reg, old_val);
143
144 if (ac->post_write) {
145 ac->post_write(reg, new_val);
146 }
147}
148
149uint64_t dep_register_read(DepRegisterInfo *reg)
150{
151 uint64_t ret;
152 const DepRegisterAccessInfo *ac;
153
154 assert(reg);
155
156 ac = reg->access;
157 if (!ac || !ac->name) {
158 qemu_log_mask(LOG_GUEST_ERROR, "%s: read from undefined device state\n",
159 reg->prefix);
160 return 0;
161 }
162
163 ret = reg->data ? register_read_val(reg) : ac->reset;
164
165 if (!reg->read_lite) {
166 register_write_val(reg, ret & ~ac->cor);
167 }
168
169 if (ac->post_read) {
170 ret = ac->post_read(reg, ret);
171 }
172
173 if (!reg->read_lite) {
174 if (reg->debug) {
175 qemu_log("%s:%s: read of value %#" PRIx64 "\n", reg->prefix,
176 ac->name, ret);
177 }
178 }
179
180 return ret;
181}
182
183void dep_register_reset(DepRegisterInfo *reg)
184{
185 assert(reg);
186 const DepRegisterAccessInfo *ac;
187 uint64_t val;
188
189 if (!reg->data || !reg->access) {
190 return;
191 }
192
193 ac = reg->access;
194
195 val = register_read_val(reg);
196 if (!(val & ac->inhibit_reset)) {
197 val = reg->access->reset;
198 }
199
200
201 reg->write_lite = reg->debug || ac->ro || ac->w1c || ac->pre_write ||
202 ((ac->ge0 || ac->ge1) && qemu_loglevel_mask(LOG_GUEST_ERROR)) ||
203 ((ac->ui0 || ac->ui1) && qemu_loglevel_mask(LOG_UNIMP))
204 ? false : true;
205
206 reg->read_lite = reg->debug || ac->cor ? false : true;
207
208 register_write_val(reg, val);
209 dep_register_refresh_gpios(reg, ~val);
210}
211
212void dep_register_refresh_gpios(DepRegisterInfo *reg, uint64_t old_value)
213{
214 const DepRegisterAccessInfo *ac;
215 const DepRegisterGPIOMapping *gpio;
216
217 ac = reg->access;
218 for (gpio = ac->gpios; gpio && gpio->name; gpio++) {
219 int i;
220
221 if (gpio->input) {
222 continue;
223 }
224
225 for (i = 0; i < gpio->num; ++i) {
226 uint64_t gpio_value, gpio_value_old;
227
228 qemu_irq gpo = qdev_get_gpio_out_named(DEVICE(reg), gpio->name, i);
229
230 if (!gpio->width) {
231 ((DepRegisterGPIOMapping *)gpio)->width = 1;
232 }
233 gpio_value_old = extract64(old_value,
234 gpio->bit_pos + i * gpio->width,
235 gpio->width) ^ gpio->polarity;
236 gpio_value = extract64(register_read_val(reg),
237 gpio->bit_pos + i * gpio->width,
238 gpio->width) ^ gpio->polarity;
239 if (!(gpio_value_old ^ gpio_value)) {
240 continue;
241 }
242 if (reg->debug && gpo) {
243 qemu_log("refreshing gpio out %s to %" PRIx64 "\n",
244 gpio->name, gpio_value);
245 }
246 qemu_set_irq(gpo, gpio_value);
247 }
248 }
249}
250
251typedef struct DeviceNamedGPIOHandlerOpaque {
252 DeviceState *dev;
253 const char *name;
254} DeviceNamedGPIOHandlerOpaque;
255
256static void register_gpio_handler(void *opaque, int n, int level)
257{
258 DeviceNamedGPIOHandlerOpaque *gho = opaque;
259 DepRegisterInfo *reg = DEP_REGISTER(gho->dev);
260
261 const DepRegisterAccessInfo *ac;
262 const DepRegisterGPIOMapping *gpio;
263
264 ac = reg->access;
265 for (gpio = ac->gpios; gpio && gpio->name; gpio++) {
266 if (gpio->input && !strcmp(gho->name, gpio->name)) {
267
268 if (!gpio->width) {
269 ((DepRegisterGPIOMapping *)gpio)->width = 1;
270 }
271 register_write_val(reg, deposit64(register_read_val(reg),
272 gpio->bit_pos + n * gpio->width,
273 gpio->width,
274 level ^ gpio->polarity));
275 return;
276 }
277 }
278
279 abort();
280}
281
282
283
284void dep_register_init(DepRegisterInfo *reg)
285{
286 assert(reg);
287 const DepRegisterAccessInfo *ac;
288 const DepRegisterGPIOMapping *gpio;
289
290 if (!reg->data || !reg->access) {
291 return;
292 }
293
294 object_initialize((void *)reg, sizeof(*reg), TYPE_DEP_REGISTER);
295
296 ac = reg->access;
297 for (gpio = ac->gpios; gpio && gpio->name; gpio++) {
298 if (!gpio->num) {
299 ((DepRegisterGPIOMapping *)gpio)->num = 1;
300 }
301 if (gpio->input) {
302 DeviceNamedGPIOHandlerOpaque gho = {
303 .name = gpio->name,
304 .dev = DEVICE(reg),
305 };
306 qemu_irq irq;
307
308 qdev_init_gpio_in_named(DEVICE(reg), register_gpio_handler,
309 gpio->name, gpio->num);
310
311 irq = qdev_get_gpio_in_named(DEVICE(reg), gpio->name, gpio->num);
312 irq->opaque = g_memdup(&gho, sizeof(gho));
313 } else {
314
315 qemu_irq *gpos = g_new0(qemu_irq, gpio->num);
316
317 qdev_init_gpio_out_named(DEVICE(reg), gpos, gpio->name, gpio->num);
318 }
319 }
320}
321
322static inline void register_write_memory(void *opaque, hwaddr addr,
323 uint64_t value, unsigned size, bool be)
324{
325 DepRegisterInfo *reg = opaque;
326 uint64_t we = ~0;
327 int shift = 0;
328
329 if (reg->data_size != size) {
330 we = (size == 8) ? ~0ull : (1ull << size * 8) - 1;
331 shift = 8 * (be ? reg->data_size - size - addr : addr);
332 }
333
334 assert(size + addr <= reg->data_size);
335 dep_register_write(reg, value << shift, we << shift);
336}
337
338void dep_register_write_memory_be(void *opaque, hwaddr addr, uint64_t value,
339 unsigned size)
340{
341 register_write_memory(opaque, addr, value, size, true);
342}
343
344
345void dep_register_write_memory_le(void *opaque, hwaddr addr, uint64_t value,
346 unsigned size)
347{
348 register_write_memory(opaque, addr, value, size, false);
349}
350
351static inline uint64_t register_read_memory(void *opaque, hwaddr addr,
352 unsigned size, bool be)
353{
354 DepRegisterInfo *reg = opaque;
355 int shift = 8 * (be ? reg->data_size - size - addr : addr);
356
357 return dep_register_read(reg) >> shift;
358}
359
360uint64_t dep_register_read_memory_be(void *opaque, hwaddr addr, unsigned size)
361{
362 return register_read_memory(opaque, addr, size, true);
363}
364
365uint64_t dep_register_read_memory_le(void *opaque, hwaddr addr, unsigned size)
366{
367 return register_read_memory(opaque, addr, size, false);
368}
369
370static const TypeInfo register_info = {
371 .name = TYPE_DEP_REGISTER,
372 .parent = TYPE_DEVICE,
373};
374
375static void register_register_types(void)
376{
377 type_register_static(®ister_info);
378}
379
380type_init(register_register_types)
381