1 /* 2 * Register Definition API 3 * 4 * Copyright (c) 2016 Xilinx Inc. 5 * Copyright (c) 2013 Peter Crosthwaite <peter.crosthwaite@xilinx.com> 6 * 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. 11 * 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 15 * for more details. 16 */ 17 18 #include "qemu/osdep.h" 19 #include "hw/register.h" 20 #include "hw/qdev.h" 21 #include "qemu/log.h" 22 23 static inline void register_write_val(RegisterInfo *reg, uint64_t val) 24 { 25 g_assert(reg->data); 26 27 switch (reg->data_size) { 28 case 1: 29 *(uint8_t *)reg->data = val; 30 break; 31 case 2: 32 *(uint16_t *)reg->data = val; 33 break; 34 case 4: 35 *(uint32_t *)reg->data = val; 36 break; 37 case 8: 38 *(uint64_t *)reg->data = val; 39 break; 40 default: 41 g_assert_not_reached(); 42 } 43 } 44 45 static inline uint64_t register_read_val(RegisterInfo *reg) 46 { 47 switch (reg->data_size) { 48 case 1: 49 return *(uint8_t *)reg->data; 50 case 2: 51 return *(uint16_t *)reg->data; 52 case 4: 53 return *(uint32_t *)reg->data; 54 case 8: 55 return *(uint64_t *)reg->data; 56 default: 57 g_assert_not_reached(); 58 } 59 return 0; /* unreachable */ 60 } 61 62 static inline uint64_t register_enabled_mask(int data_size, unsigned size) 63 { 64 if (data_size < size) { 65 size = data_size; 66 } 67 68 return MAKE_64BIT_MASK(0, size * 8); 69 } 70 71 void register_write(RegisterInfo *reg, uint64_t val, uint64_t we, 72 const char *prefix, bool debug) 73 { 74 uint64_t old_val, new_val, test, no_w_mask; 75 const RegisterAccessInfo *ac; 76 77 assert(reg); 78 79 ac = reg->access; 80 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); 84 return; 85 } 86 87 old_val = reg->data ? register_read_val(reg) : ac->reset; 88 89 test = (old_val ^ val) & ac->rsvd; 90 if (test) { 91 qemu_log_mask(LOG_GUEST_ERROR, "%s: change of value in reserved bit" 92 "fields: %#" PRIx64 ")\n", prefix, test); 93 } 94 95 test = val & ac->unimp; 96 if (test) { 97 qemu_log_mask(LOG_UNIMP, 98 "%s:%s writing %#" PRIx64 " to unimplemented bits:" \ 99 " %#" PRIx64 "\n", 100 prefix, reg->access->name, val, ac->unimp); 101 } 102 103 /* Create the no write mask based on the read only, write to clear and 104 * reserved bit masks. 105 */ 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); 109 110 if (ac->pre_write) { 111 new_val = ac->pre_write(reg, new_val); 112 } 113 114 if (debug) { 115 qemu_log("%s:%s: write of value %#" PRIx64 "\n", prefix, ac->name, 116 new_val); 117 } 118 119 register_write_val(reg, new_val); 120 121 if (ac->post_write) { 122 ac->post_write(reg, new_val); 123 } 124 } 125 126 uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix, 127 bool debug) 128 { 129 uint64_t ret; 130 const RegisterAccessInfo *ac; 131 132 assert(reg); 133 134 ac = reg->access; 135 if (!ac || !ac->name) { 136 qemu_log_mask(LOG_GUEST_ERROR, "%s: read from undefined device state\n", 137 prefix); 138 return 0; 139 } 140 141 ret = reg->data ? register_read_val(reg) : ac->reset; 142 143 register_write_val(reg, ret & ~(ac->cor & re)); 144 145 /* Mask based on the read enable size */ 146 ret &= re; 147 148 if (ac->post_read) { 149 ret = ac->post_read(reg, ret); 150 } 151 152 if (debug) { 153 qemu_log("%s:%s: read of value %#" PRIx64 "\n", prefix, 154 ac->name, ret); 155 } 156 157 return ret; 158 } 159 160 void register_reset(RegisterInfo *reg) 161 { 162 const RegisterAccessInfo *ac; 163 164 g_assert(reg); 165 166 if (!reg->data || !reg->access) { 167 return; 168 } 169 170 ac = reg->access; 171 172 register_write_val(reg, reg->access->reset); 173 174 if (ac->post_write) { 175 ac->post_write(reg, reg->access->reset); 176 } 177 } 178 179 void register_init(RegisterInfo *reg) 180 { 181 assert(reg); 182 183 if (!reg->data || !reg->access) { 184 return; 185 } 186 187 object_initialize((void *)reg, sizeof(*reg), TYPE_REGISTER); 188 } 189 190 void register_write_memory(void *opaque, hwaddr addr, 191 uint64_t value, unsigned size) 192 { 193 RegisterInfoArray *reg_array = opaque; 194 RegisterInfo *reg = NULL; 195 uint64_t we; 196 int i; 197 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]; 201 break; 202 } 203 } 204 205 if (!reg) { 206 qemu_log_mask(LOG_GUEST_ERROR, "%s: write to unimplemented register " \ 207 "at address: %#" PRIx64 "\n", reg_array->prefix, addr); 208 return; 209 } 210 211 /* Generate appropriate write enable mask */ 212 we = register_enabled_mask(reg->data_size, size); 213 214 register_write(reg, value, we, reg_array->prefix, 215 reg_array->debug); 216 } 217 218 uint64_t register_read_memory(void *opaque, hwaddr addr, 219 unsigned size) 220 { 221 RegisterInfoArray *reg_array = opaque; 222 RegisterInfo *reg = NULL; 223 uint64_t read_val; 224 uint64_t re; 225 int i; 226 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]; 230 break; 231 } 232 } 233 234 if (!reg) { 235 qemu_log_mask(LOG_GUEST_ERROR, "%s: read to unimplemented register " \ 236 "at address: %#" PRIx64 "\n", reg_array->prefix, addr); 237 return 0; 238 } 239 240 /* Generate appropriate read enable mask */ 241 re = register_enabled_mask(reg->data_size, size); 242 243 read_val = register_read(reg, re, reg_array->prefix, 244 reg_array->debug); 245 246 return extract64(read_val, 0, size * 8); 247 } 248 249 RegisterInfoArray *register_init_block32(DeviceState *owner, 250 const RegisterAccessInfo *rae, 251 int num, RegisterInfo *ri, 252 uint32_t *data, 253 const MemoryRegionOps *ops, 254 bool debug_enabled, 255 uint64_t memory_size) 256 { 257 const char *device_prefix = object_get_typename(OBJECT(owner)); 258 RegisterInfoArray *r_array = g_new0(RegisterInfoArray, 1); 259 int i; 260 261 r_array->r = g_new0(RegisterInfo *, num); 262 r_array->num_elements = num; 263 r_array->debug = debug_enabled; 264 r_array->prefix = device_prefix; 265 266 for (i = 0; i < num; i++) { 267 int index = rae[i].addr / 4; 268 RegisterInfo *r = &ri[index]; 269 270 *r = (RegisterInfo) { 271 .data = &data[index], 272 .data_size = sizeof(uint32_t), 273 .access = &rae[i], 274 .opaque = owner, 275 }; 276 register_init(r); 277 278 r_array->r[i] = r; 279 } 280 281 memory_region_init_io(&r_array->mem, OBJECT(owner), ops, r_array, 282 device_prefix, memory_size); 283 284 return r_array; 285 } 286 287 void register_finalize_block(RegisterInfoArray *r_array) 288 { 289 object_unparent(OBJECT(&r_array->mem)); 290 g_free(r_array->r); 291 g_free(r_array); 292 } 293 294 static void register_class_init(ObjectClass *oc, void *data) 295 { 296 DeviceClass *dc = DEVICE_CLASS(oc); 297 298 /* Reason: needs to be wired up to work */ 299 dc->user_creatable = false; 300 } 301 302 static const TypeInfo register_info = { 303 .name = TYPE_REGISTER, 304 .parent = TYPE_DEVICE, 305 .class_init = register_class_init, 306 }; 307 308 static void register_register_types(void) 309 { 310 type_register_static(®ister_info); 311 } 312 313 type_init(register_register_types) 314