2 * Register Definition API
4 * Copyright (c) 2016 Xilinx Inc.
5 * Copyright (c) 2013 Peter Crosthwaite <peter.crosthwaite@xilinx.com>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 #include "qemu/osdep.h"
19 #include "hw/register.h"
21 #include "qemu/module.h"
23 static inline void register_write_val(RegisterInfo
*reg
, uint64_t val
)
27 switch (reg
->data_size
) {
29 *(uint8_t *)reg
->data
= val
;
32 *(uint16_t *)reg
->data
= val
;
35 *(uint32_t *)reg
->data
= val
;
38 *(uint64_t *)reg
->data
= val
;
41 g_assert_not_reached();
45 static inline uint64_t register_read_val(RegisterInfo
*reg
)
47 switch (reg
->data_size
) {
49 return *(uint8_t *)reg
->data
;
51 return *(uint16_t *)reg
->data
;
53 return *(uint32_t *)reg
->data
;
55 return *(uint64_t *)reg
->data
;
57 g_assert_not_reached();
59 return 0; /* unreachable */
62 static inline uint64_t register_enabled_mask(int data_size
, unsigned size
)
64 if (data_size
< size
) {
68 return MAKE_64BIT_MASK(0, size
* 8);
71 void register_write(RegisterInfo
*reg
, uint64_t val
, uint64_t we
,
72 const char *prefix
, bool debug
)
74 uint64_t old_val
, new_val
, test
, no_w_mask
;
75 const RegisterAccessInfo
*ac
;
81 if (!ac
|| !ac
->name
) {
82 qemu_log_mask(LOG_GUEST_ERROR
, "%s: write to undefined device state "
83 "(written value: %#" PRIx64
")\n", prefix
, val
);
87 old_val
= reg
->data
? register_read_val(reg
) : ac
->reset
;
89 test
= (old_val
^ val
) & ac
->rsvd
;
91 qemu_log_mask(LOG_GUEST_ERROR
, "%s: change of value in reserved bit"
92 "fields: %#" PRIx64
")\n", prefix
, test
);
95 test
= val
& ac
->unimp
;
97 qemu_log_mask(LOG_UNIMP
,
98 "%s:%s writing %#" PRIx64
" to unimplemented bits:" \
100 prefix
, reg
->access
->name
, val
, ac
->unimp
);
103 /* Create the no write mask based on the read only, write to clear and
104 * reserved bit masks.
106 no_w_mask
= ac
->ro
| ac
->w1c
| ac
->rsvd
| ~we
;
107 new_val
= (val
& ~no_w_mask
) | (old_val
& no_w_mask
);
108 new_val
&= ~(val
& ac
->w1c
);
111 new_val
= ac
->pre_write(reg
, new_val
);
115 qemu_log("%s:%s: write of value %#" PRIx64
"\n", prefix
, ac
->name
,
119 register_write_val(reg
, new_val
);
121 if (ac
->post_write
) {
122 ac
->post_write(reg
, new_val
);
126 uint64_t register_read(RegisterInfo
*reg
, uint64_t re
, const char* prefix
,
130 const RegisterAccessInfo
*ac
;
135 if (!ac
|| !ac
->name
) {
136 qemu_log_mask(LOG_GUEST_ERROR
, "%s: read from undefined device state\n",
141 ret
= reg
->data
? register_read_val(reg
) : ac
->reset
;
143 register_write_val(reg
, ret
& ~(ac
->cor
& re
));
145 /* Mask based on the read enable size */
149 ret
= ac
->post_read(reg
, ret
);
153 qemu_log("%s:%s: read of value %#" PRIx64
"\n", prefix
,
160 void register_reset(RegisterInfo
*reg
)
162 const RegisterAccessInfo
*ac
;
166 if (!reg
->data
|| !reg
->access
) {
172 register_write_val(reg
, reg
->access
->reset
);
174 if (ac
->post_write
) {
175 ac
->post_write(reg
, reg
->access
->reset
);
179 void register_init(RegisterInfo
*reg
)
183 if (!reg
->data
|| !reg
->access
) {
187 object_initialize((void *)reg
, sizeof(*reg
), TYPE_REGISTER
);
190 void register_write_memory(void *opaque
, hwaddr addr
,
191 uint64_t value
, unsigned size
)
193 RegisterInfoArray
*reg_array
= opaque
;
194 RegisterInfo
*reg
= NULL
;
198 for (i
= 0; i
< reg_array
->num_elements
; i
++) {
199 if (reg_array
->r
[i
]->access
->addr
== addr
) {
200 reg
= reg_array
->r
[i
];
206 qemu_log_mask(LOG_GUEST_ERROR
, "%s: write to unimplemented register " \
207 "at address: %#" PRIx64
"\n", reg_array
->prefix
, addr
);
211 /* Generate appropriate write enable mask */
212 we
= register_enabled_mask(reg
->data_size
, size
);
214 register_write(reg
, value
, we
, reg_array
->prefix
,
218 uint64_t register_read_memory(void *opaque
, hwaddr addr
,
221 RegisterInfoArray
*reg_array
= opaque
;
222 RegisterInfo
*reg
= NULL
;
227 for (i
= 0; i
< reg_array
->num_elements
; i
++) {
228 if (reg_array
->r
[i
]->access
->addr
== addr
) {
229 reg
= reg_array
->r
[i
];
235 qemu_log_mask(LOG_GUEST_ERROR
, "%s: read to unimplemented register " \
236 "at address: %#" PRIx64
"\n", reg_array
->prefix
, addr
);
240 /* Generate appropriate read enable mask */
241 re
= register_enabled_mask(reg
->data_size
, size
);
243 read_val
= register_read(reg
, re
, reg_array
->prefix
,
246 return extract64(read_val
, 0, size
* 8);
249 static RegisterInfoArray
*register_init_block(DeviceState
*owner
,
250 const RegisterAccessInfo
*rae
,
251 int num
, RegisterInfo
*ri
,
253 const MemoryRegionOps
*ops
,
255 uint64_t memory_size
,
256 size_t data_size_bits
)
258 const char *device_prefix
= object_get_typename(OBJECT(owner
));
259 RegisterInfoArray
*r_array
= g_new0(RegisterInfoArray
, 1);
260 int data_size
= data_size_bits
>> 3;
263 r_array
->r
= g_new0(RegisterInfo
*, num
);
264 r_array
->num_elements
= num
;
265 r_array
->debug
= debug_enabled
;
266 r_array
->prefix
= device_prefix
;
268 for (i
= 0; i
< num
; i
++) {
269 int index
= rae
[i
].addr
/ data_size
;
270 RegisterInfo
*r
= &ri
[index
];
272 *r
= (RegisterInfo
) {
273 .data
= data
+ data_size
* index
,
274 .data_size
= data_size
,
283 memory_region_init_io(&r_array
->mem
, OBJECT(owner
), ops
, r_array
,
284 device_prefix
, memory_size
);
289 RegisterInfoArray
*register_init_block8(DeviceState
*owner
,
290 const RegisterAccessInfo
*rae
,
291 int num
, RegisterInfo
*ri
,
293 const MemoryRegionOps
*ops
,
295 uint64_t memory_size
)
297 return register_init_block(owner
, rae
, num
, ri
, (void *)
298 data
, ops
, debug_enabled
, memory_size
, 8);
301 RegisterInfoArray
*register_init_block32(DeviceState
*owner
,
302 const RegisterAccessInfo
*rae
,
303 int num
, RegisterInfo
*ri
,
305 const MemoryRegionOps
*ops
,
307 uint64_t memory_size
)
309 return register_init_block(owner
, rae
, num
, ri
, (void *)
310 data
, ops
, debug_enabled
, memory_size
, 32);
313 void register_finalize_block(RegisterInfoArray
*r_array
)
315 object_unparent(OBJECT(&r_array
->mem
));
320 static void register_class_init(ObjectClass
*oc
, void *data
)
322 DeviceClass
*dc
= DEVICE_CLASS(oc
);
324 /* Reason: needs to be wired up to work */
325 dc
->user_creatable
= false;
328 static const TypeInfo register_info
= {
329 .name
= TYPE_REGISTER
,
330 .parent
= TYPE_DEVICE
,
331 .class_init
= register_class_init
,
334 static void register_register_types(void)
336 type_register_static(®ister_info
);
339 type_init(register_register_types
)