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.h"
16#include "qemu/log.h"
17
18static inline void register_write_log(RegisterInfo *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(RegisterInfo *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(RegisterInfo *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 register_write(RegisterInfo *reg, uint64_t val, uint64_t we)
68{
69 uint64_t old_val, new_val, test, no_w_mask;
70 const RegisterAccessInfo *ac;
71 const RegisterAccessError *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 register_refresh_gpios(reg, old_val);
143
144 if (ac->post_write) {
145 ac->post_write(reg, new_val);
146 }
147}
148
149uint64_t register_read(RegisterInfo *reg)
150{
151 uint64_t ret;
152 const RegisterAccessInfo *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 register_reset(RegisterInfo *reg)
184{
185 assert(reg);
186 const RegisterAccessInfo *ac;
187 uint64_t val, old_val;
188
189 if (!reg->data || !reg->access) {
190 return;
191 }
192
193 ac = reg->access;
194
195
196 val = old_val = register_read_val(reg);
197 if (!(val & ac->inhibit_reset)) {
198 val = reg->access->reset;
199 }
200
201
202 reg->write_lite = reg->debug || ac->ro || ac->w1c || ac->pre_write ||
203 ((ac->ge0 || ac->ge1) && qemu_loglevel_mask(LOG_GUEST_ERROR)) ||
204 ((ac->ui0 || ac->ui1) && qemu_loglevel_mask(LOG_UNIMP))
205 ? false : true;
206
207 reg->read_lite = reg->debug || ac->cor ? false : true;
208
209 register_write_val(reg, val);
210 register_refresh_gpios(reg, old_val);
211}
212
213void register_refresh_gpios(RegisterInfo *reg, uint64_t old_value)
214{
215 const RegisterAccessInfo *ac;
216 const RegisterGPIOMapping *gpio;
217
218 ac = reg->access;
219 for (gpio = ac->gpios; gpio && gpio->name; gpio++) {
220 int i;
221
222 if (gpio->input) {
223 continue;
224 }
225
226 for (i = 0; i < gpio->num; ++i) {
227 uint64_t gpio_value, gpio_value_old;
228
229 qemu_irq gpo = qdev_get_gpio_out_named(DEVICE(reg), gpio->name, i);
230
231 if (!gpio->width) {
232 ((RegisterGPIOMapping *)gpio)->width = 1;
233 }
234 gpio_value_old = extract64(old_value,
235 gpio->bit_pos + i * gpio->width,
236 gpio->width) ^ gpio->polarity;
237 gpio_value = extract64(register_read_val(reg),
238 gpio->bit_pos + i * gpio->width,
239 gpio->width) ^ gpio->polarity;
240 if (!(gpio_value_old ^ gpio_value)) {
241 continue;
242 }
243 if (reg->debug && gpo) {
244 qemu_log("refreshing gpio out %s to %" PRIx64 "\n",
245 gpio->name, gpio_value);
246 }
247 qemu_set_irq(gpo, gpio_value);
248 }
249 }
250}
251
252typedef struct DeviceNamedGPIOHandlerOpaque {
253 DeviceState *dev;
254 const char *name;
255} DeviceNamedGPIOHandlerOpaque;
256
257static void register_gpio_handler(void *opaque, int n, int level)
258{
259 DeviceNamedGPIOHandlerOpaque *gho = opaque;
260 RegisterInfo *reg = REGISTER(gho->dev);
261
262 const RegisterAccessInfo *ac;
263 const RegisterGPIOMapping *gpio;
264
265 ac = reg->access;
266 for (gpio = ac->gpios; gpio && gpio->name; gpio++) {
267 if (gpio->input && !strcmp(gho->name, gpio->name)) {
268
269 if (!gpio->width) {
270 ((RegisterGPIOMapping *)gpio)->width = 1;
271 }
272 register_write_val(reg, deposit64(register_read_val(reg),
273 gpio->bit_pos + n * gpio->width,
274 gpio->width,
275 level ^ gpio->polarity));
276 return;
277 }
278 }
279
280 abort();
281}
282
283
284
285void register_init(RegisterInfo *reg)
286{
287 assert(reg);
288 const RegisterAccessInfo *ac;
289 const RegisterGPIOMapping *gpio;
290
291 if (!reg->data || !reg->access) {
292 return;
293 }
294
295 object_initialize((void *)reg, sizeof(*reg), TYPE_REGISTER);
296
297 ac = reg->access;
298 for (gpio = ac->gpios; gpio && gpio->name; gpio++) {
299 if (!gpio->num) {
300 ((RegisterGPIOMapping *)gpio)->num = 1;
301 }
302 if (gpio->input) {
303 DeviceNamedGPIOHandlerOpaque gho = {
304 .name = gpio->name,
305 .dev = DEVICE(reg),
306 };
307 qemu_irq irq;
308
309 qdev_init_gpio_in_named(DEVICE(reg), register_gpio_handler,
310 gpio->name, gpio->num);
311
312 irq = qdev_get_gpio_in_named(DEVICE(reg), gpio->name, gpio->num);
313 irq->opaque = g_memdup(&gho, sizeof(gho));
314 } else {
315
316 qemu_irq *gpos = g_new0(qemu_irq, gpio->num);
317
318 qdev_init_gpio_out_named(DEVICE(reg), gpos, gpio->name, gpio->num);
319 }
320 }
321}
322
323static inline void register_write_memory(void *opaque, hwaddr addr,
324 uint64_t value, unsigned size, bool be)
325{
326 RegisterInfo *reg = opaque;
327 uint64_t we = ~0;
328 int shift = 0;
329
330 if (reg->data_size != size) {
331 we = (size == 8) ? ~0ull : (1ull << size * 8) - 1;
332 shift = 8 * (be ? reg->data_size - size - addr : addr);
333 }
334
335 assert(size + addr <= reg->data_size);
336 register_write(reg, value << shift, we << shift);
337}
338
339void register_write_memory_be(void *opaque, hwaddr addr, uint64_t value,
340 unsigned size)
341{
342 register_write_memory(opaque, addr, value, size, true);
343}
344
345
346void register_write_memory_le(void *opaque, hwaddr addr, uint64_t value,
347 unsigned size)
348{
349 register_write_memory(opaque, addr, value, size, false);
350}
351
352static inline uint64_t register_read_memory(void *opaque, hwaddr addr,
353 unsigned size, bool be)
354{
355 RegisterInfo *reg = opaque;
356 int shift = 8 * (be ? reg->data_size - size - addr : addr);
357
358 return register_read(reg) >> shift;
359}
360
361uint64_t register_read_memory_be(void *opaque, hwaddr addr, unsigned size)
362{
363 return register_read_memory(opaque, addr, size, true);
364}
365
366uint64_t register_read_memory_le(void *opaque, hwaddr addr, unsigned size)
367{
368 return register_read_memory(opaque, addr, size, false);
369}
370
371static const TypeInfo register_info = {
372 .name = TYPE_REGISTER,
373 .parent = TYPE_DEVICE,
374};
375
376static void register_register_types(void)
377{
378 type_register_static(®ister_info);
379}
380
381type_init(register_register_types)
382