1 /* 2 * QEMU model of the Xilinx BBRAM Battery Backed RAM 3 * 4 * Copyright (c) 2014-2021 Xilinx Inc. 5 * Copyright (c) 2023 Advanced Micro Devices, Inc. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 * THE SOFTWARE. 24 */ 25 26 #include "qemu/osdep.h" 27 #include "hw/nvram/xlnx-bbram.h" 28 29 #include "qemu/error-report.h" 30 #include "qemu/log.h" 31 #include "qapi/error.h" 32 #include "sysemu/blockdev.h" 33 #include "migration/vmstate.h" 34 #include "hw/qdev-properties.h" 35 #include "hw/qdev-properties-system.h" 36 #include "hw/nvram/xlnx-efuse.h" 37 38 #ifndef XLNX_BBRAM_ERR_DEBUG 39 #define XLNX_BBRAM_ERR_DEBUG 0 40 #endif 41 42 REG32(BBRAM_STATUS, 0x0) 43 FIELD(BBRAM_STATUS, AES_CRC_PASS, 9, 1) 44 FIELD(BBRAM_STATUS, AES_CRC_DONE, 8, 1) 45 FIELD(BBRAM_STATUS, BBRAM_ZEROIZED, 4, 1) 46 FIELD(BBRAM_STATUS, PGM_MODE, 0, 1) 47 REG32(BBRAM_CTRL, 0x4) 48 FIELD(BBRAM_CTRL, ZEROIZE, 0, 1) 49 REG32(PGM_MODE, 0x8) 50 REG32(BBRAM_AES_CRC, 0xc) 51 REG32(BBRAM_0, 0x10) 52 REG32(BBRAM_1, 0x14) 53 REG32(BBRAM_2, 0x18) 54 REG32(BBRAM_3, 0x1c) 55 REG32(BBRAM_4, 0x20) 56 REG32(BBRAM_5, 0x24) 57 REG32(BBRAM_6, 0x28) 58 REG32(BBRAM_7, 0x2c) 59 REG32(BBRAM_8, 0x30) 60 REG32(BBRAM_SLVERR, 0x34) 61 FIELD(BBRAM_SLVERR, ENABLE, 0, 1) 62 REG32(BBRAM_ISR, 0x38) 63 FIELD(BBRAM_ISR, APB_SLVERR, 0, 1) 64 REG32(BBRAM_IMR, 0x3c) 65 FIELD(BBRAM_IMR, APB_SLVERR, 0, 1) 66 REG32(BBRAM_IER, 0x40) 67 FIELD(BBRAM_IER, APB_SLVERR, 0, 1) 68 REG32(BBRAM_IDR, 0x44) 69 FIELD(BBRAM_IDR, APB_SLVERR, 0, 1) 70 REG32(BBRAM_MSW_LOCK, 0x4c) 71 FIELD(BBRAM_MSW_LOCK, VAL, 0, 1) 72 73 #define R_MAX (R_BBRAM_MSW_LOCK + 1) 74 75 #define RAM_MAX (A_BBRAM_8 + 4 - A_BBRAM_0) 76 77 #define BBRAM_PGM_MAGIC 0x757bdf0d 78 79 QEMU_BUILD_BUG_ON(R_MAX != ARRAY_SIZE(((XlnxBBRam *)0)->regs)); 80 81 static bool bbram_msw_locked(XlnxBBRam *s) 82 { 83 return ARRAY_FIELD_EX32(s->regs, BBRAM_MSW_LOCK, VAL) != 0; 84 } 85 86 static bool bbram_pgm_enabled(XlnxBBRam *s) 87 { 88 return ARRAY_FIELD_EX32(s->regs, BBRAM_STATUS, PGM_MODE) != 0; 89 } 90 91 static void bbram_bdrv_error(XlnxBBRam *s, int rc, gchar *detail) 92 { 93 Error *errp = NULL; 94 95 error_setg_errno(&errp, -rc, "%s: BBRAM backstore %s failed.", 96 blk_name(s->blk), detail); 97 error_report("%s", error_get_pretty(errp)); 98 error_free(errp); 99 100 g_free(detail); 101 } 102 103 static void bbram_bdrv_read(XlnxBBRam *s, Error **errp) 104 { 105 uint32_t *ram = &s->regs[R_BBRAM_0]; 106 int nr = RAM_MAX; 107 108 if (!s->blk) { 109 return; 110 } 111 112 s->blk_ro = !blk_supports_write_perm(s->blk); 113 if (!s->blk_ro) { 114 int rc; 115 116 rc = blk_set_perm(s->blk, 117 (BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE), 118 BLK_PERM_ALL, NULL); 119 if (rc) { 120 s->blk_ro = true; 121 } 122 } 123 if (s->blk_ro) { 124 warn_report("%s: Skip saving updates to read-only BBRAM backstore.", 125 blk_name(s->blk)); 126 } 127 128 if (blk_pread(s->blk, 0, nr, ram, 0) < 0) { 129 error_setg(errp, 130 "%s: Failed to read %u bytes from BBRAM backstore.", 131 blk_name(s->blk), nr); 132 return; 133 } 134 135 /* Convert from little-endian backstore for each 32-bit word */ 136 nr /= 4; 137 while (nr--) { 138 ram[nr] = le32_to_cpu(ram[nr]); 139 } 140 } 141 142 static void bbram_bdrv_sync(XlnxBBRam *s, uint64_t hwaddr) 143 { 144 uint32_t le32; 145 unsigned offset; 146 int rc; 147 148 assert(A_BBRAM_0 <= hwaddr && hwaddr <= A_BBRAM_8); 149 150 /* Backstore is always in little-endian */ 151 le32 = cpu_to_le32(s->regs[hwaddr / 4]); 152 153 /* Update zeroized flag */ 154 if (le32 && (hwaddr != A_BBRAM_8 || s->bbram8_wo)) { 155 ARRAY_FIELD_DP32(s->regs, BBRAM_STATUS, BBRAM_ZEROIZED, 0); 156 } 157 158 if (!s->blk || s->blk_ro) { 159 return; 160 } 161 162 offset = hwaddr - A_BBRAM_0; 163 rc = blk_pwrite(s->blk, offset, 4, &le32, 0); 164 if (rc < 0) { 165 bbram_bdrv_error(s, rc, g_strdup_printf("write to offset %u", offset)); 166 } 167 } 168 169 static void bbram_bdrv_zero(XlnxBBRam *s) 170 { 171 int rc; 172 173 ARRAY_FIELD_DP32(s->regs, BBRAM_STATUS, BBRAM_ZEROIZED, 1); 174 175 if (!s->blk || s->blk_ro) { 176 return; 177 } 178 179 rc = blk_make_zero(s->blk, 0); 180 if (rc < 0) { 181 bbram_bdrv_error(s, rc, g_strdup("zeroizing")); 182 } 183 184 /* Restore bbram8 if it is non-zero */ 185 if (s->regs[R_BBRAM_8]) { 186 bbram_bdrv_sync(s, A_BBRAM_8); 187 } 188 } 189 190 static void bbram_zeroize(XlnxBBRam *s) 191 { 192 int nr = RAM_MAX - (s->bbram8_wo ? 0 : 4); /* only wo bbram8 is cleared */ 193 194 memset(&s->regs[R_BBRAM_0], 0, nr); 195 bbram_bdrv_zero(s); 196 } 197 198 static void bbram_update_irq(XlnxBBRam *s) 199 { 200 bool pending = s->regs[R_BBRAM_ISR] & ~s->regs[R_BBRAM_IMR]; 201 202 qemu_set_irq(s->irq_bbram, pending); 203 } 204 205 static void bbram_ctrl_postw(RegisterInfo *reg, uint64_t val64) 206 { 207 XlnxBBRam *s = XLNX_BBRAM(reg->opaque); 208 uint32_t val = val64; 209 210 if (val & R_BBRAM_CTRL_ZEROIZE_MASK) { 211 bbram_zeroize(s); 212 /* The bit is self clearing */ 213 s->regs[R_BBRAM_CTRL] &= ~R_BBRAM_CTRL_ZEROIZE_MASK; 214 } 215 } 216 217 static void bbram_pgm_mode_postw(RegisterInfo *reg, uint64_t val64) 218 { 219 XlnxBBRam *s = XLNX_BBRAM(reg->opaque); 220 uint32_t val = val64; 221 222 if (val == BBRAM_PGM_MAGIC) { 223 bbram_zeroize(s); 224 225 /* The status bit is cleared only by POR */ 226 ARRAY_FIELD_DP32(s->regs, BBRAM_STATUS, PGM_MODE, 1); 227 } 228 } 229 230 static void bbram_aes_crc_postw(RegisterInfo *reg, uint64_t val64) 231 { 232 XlnxBBRam *s = XLNX_BBRAM(reg->opaque); 233 uint32_t calc_crc; 234 235 if (!bbram_pgm_enabled(s)) { 236 /* We are not in programming mode, don't do anything */ 237 return; 238 } 239 240 /* Perform the AES integrity check */ 241 s->regs[R_BBRAM_STATUS] |= R_BBRAM_STATUS_AES_CRC_DONE_MASK; 242 243 /* 244 * Set check status. 245 * 246 * ZynqMP BBRAM check has a zero-u32 prepended; see: 247 * https://github.com/Xilinx/embeddedsw/blob/release-2019.2/lib/sw_services/xilskey/src/xilskey_bbramps_zynqmp.c#L311 248 */ 249 calc_crc = xlnx_efuse_calc_crc(&s->regs[R_BBRAM_0], 250 (R_BBRAM_8 - R_BBRAM_0), s->crc_zpads); 251 252 ARRAY_FIELD_DP32(s->regs, BBRAM_STATUS, AES_CRC_PASS, 253 (s->regs[R_BBRAM_AES_CRC] == calc_crc)); 254 } 255 256 static uint64_t bbram_key_prew(RegisterInfo *reg, uint64_t val64) 257 { 258 XlnxBBRam *s = XLNX_BBRAM(reg->opaque); 259 uint32_t original_data = *(uint32_t *) reg->data; 260 261 if (bbram_pgm_enabled(s)) { 262 return val64; 263 } else { 264 /* We are not in programming mode, don't do anything */ 265 qemu_log_mask(LOG_GUEST_ERROR, 266 "Not in programming mode, dropping the write\n"); 267 return original_data; 268 } 269 } 270 271 static void bbram_key_postw(RegisterInfo *reg, uint64_t val64) 272 { 273 XlnxBBRam *s = XLNX_BBRAM(reg->opaque); 274 275 bbram_bdrv_sync(s, reg->access->addr); 276 } 277 278 static uint64_t bbram_wo_postr(RegisterInfo *reg, uint64_t val) 279 { 280 return 0; 281 } 282 283 static uint64_t bbram_r8_postr(RegisterInfo *reg, uint64_t val) 284 { 285 XlnxBBRam *s = XLNX_BBRAM(reg->opaque); 286 287 return s->bbram8_wo ? bbram_wo_postr(reg, val) : val; 288 } 289 290 static bool bbram_r8_readonly(XlnxBBRam *s) 291 { 292 return !bbram_pgm_enabled(s) || bbram_msw_locked(s); 293 } 294 295 static uint64_t bbram_r8_prew(RegisterInfo *reg, uint64_t val64) 296 { 297 XlnxBBRam *s = XLNX_BBRAM(reg->opaque); 298 299 if (bbram_r8_readonly(s)) { 300 val64 = *(uint32_t *)reg->data; 301 } 302 303 return val64; 304 } 305 306 static void bbram_r8_postw(RegisterInfo *reg, uint64_t val64) 307 { 308 XlnxBBRam *s = XLNX_BBRAM(reg->opaque); 309 310 if (!bbram_r8_readonly(s)) { 311 bbram_bdrv_sync(s, A_BBRAM_8); 312 } 313 } 314 315 static uint64_t bbram_msw_lock_prew(RegisterInfo *reg, uint64_t val64) 316 { 317 XlnxBBRam *s = XLNX_BBRAM(reg->opaque); 318 319 /* Never lock if bbram8 is wo; and, only POR can clear the lock */ 320 if (s->bbram8_wo) { 321 val64 = 0; 322 } else { 323 val64 |= s->regs[R_BBRAM_MSW_LOCK]; 324 } 325 326 return val64; 327 } 328 329 static void bbram_isr_postw(RegisterInfo *reg, uint64_t val64) 330 { 331 XlnxBBRam *s = XLNX_BBRAM(reg->opaque); 332 333 bbram_update_irq(s); 334 } 335 336 static uint64_t bbram_ier_prew(RegisterInfo *reg, uint64_t val64) 337 { 338 XlnxBBRam *s = XLNX_BBRAM(reg->opaque); 339 uint32_t val = val64; 340 341 s->regs[R_BBRAM_IMR] &= ~val; 342 bbram_update_irq(s); 343 return 0; 344 } 345 346 static uint64_t bbram_idr_prew(RegisterInfo *reg, uint64_t val64) 347 { 348 XlnxBBRam *s = XLNX_BBRAM(reg->opaque); 349 uint32_t val = val64; 350 351 s->regs[R_BBRAM_IMR] |= val; 352 bbram_update_irq(s); 353 return 0; 354 } 355 356 static RegisterAccessInfo bbram_ctrl_regs_info[] = { 357 { .name = "BBRAM_STATUS", .addr = A_BBRAM_STATUS, 358 .rsvd = 0xee, 359 .ro = 0x3ff, 360 },{ .name = "BBRAM_CTRL", .addr = A_BBRAM_CTRL, 361 .post_write = bbram_ctrl_postw, 362 },{ .name = "PGM_MODE", .addr = A_PGM_MODE, 363 .post_write = bbram_pgm_mode_postw, 364 },{ .name = "BBRAM_AES_CRC", .addr = A_BBRAM_AES_CRC, 365 .post_write = bbram_aes_crc_postw, 366 .post_read = bbram_wo_postr, 367 },{ .name = "BBRAM_0", .addr = A_BBRAM_0, 368 .pre_write = bbram_key_prew, 369 .post_write = bbram_key_postw, 370 .post_read = bbram_wo_postr, 371 },{ .name = "BBRAM_1", .addr = A_BBRAM_1, 372 .pre_write = bbram_key_prew, 373 .post_write = bbram_key_postw, 374 .post_read = bbram_wo_postr, 375 },{ .name = "BBRAM_2", .addr = A_BBRAM_2, 376 .pre_write = bbram_key_prew, 377 .post_write = bbram_key_postw, 378 .post_read = bbram_wo_postr, 379 },{ .name = "BBRAM_3", .addr = A_BBRAM_3, 380 .pre_write = bbram_key_prew, 381 .post_write = bbram_key_postw, 382 .post_read = bbram_wo_postr, 383 },{ .name = "BBRAM_4", .addr = A_BBRAM_4, 384 .pre_write = bbram_key_prew, 385 .post_write = bbram_key_postw, 386 .post_read = bbram_wo_postr, 387 },{ .name = "BBRAM_5", .addr = A_BBRAM_5, 388 .pre_write = bbram_key_prew, 389 .post_write = bbram_key_postw, 390 .post_read = bbram_wo_postr, 391 },{ .name = "BBRAM_6", .addr = A_BBRAM_6, 392 .pre_write = bbram_key_prew, 393 .post_write = bbram_key_postw, 394 .post_read = bbram_wo_postr, 395 },{ .name = "BBRAM_7", .addr = A_BBRAM_7, 396 .pre_write = bbram_key_prew, 397 .post_write = bbram_key_postw, 398 .post_read = bbram_wo_postr, 399 },{ .name = "BBRAM_8", .addr = A_BBRAM_8, 400 .pre_write = bbram_r8_prew, 401 .post_write = bbram_r8_postw, 402 .post_read = bbram_r8_postr, 403 },{ .name = "BBRAM_SLVERR", .addr = A_BBRAM_SLVERR, 404 .rsvd = ~1, 405 },{ .name = "BBRAM_ISR", .addr = A_BBRAM_ISR, 406 .w1c = 0x1, 407 .post_write = bbram_isr_postw, 408 },{ .name = "BBRAM_IMR", .addr = A_BBRAM_IMR, 409 .ro = 0x1, 410 },{ .name = "BBRAM_IER", .addr = A_BBRAM_IER, 411 .pre_write = bbram_ier_prew, 412 },{ .name = "BBRAM_IDR", .addr = A_BBRAM_IDR, 413 .pre_write = bbram_idr_prew, 414 },{ .name = "BBRAM_MSW_LOCK", .addr = A_BBRAM_MSW_LOCK, 415 .pre_write = bbram_msw_lock_prew, 416 .ro = ~R_BBRAM_MSW_LOCK_VAL_MASK, 417 } 418 }; 419 420 static void bbram_ctrl_reset_hold(Object *obj) 421 { 422 XlnxBBRam *s = XLNX_BBRAM(obj); 423 unsigned int i; 424 425 for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) { 426 if (i < R_BBRAM_0 || i > R_BBRAM_8) { 427 register_reset(&s->regs_info[i]); 428 } 429 } 430 431 bbram_update_irq(s); 432 } 433 434 static const MemoryRegionOps bbram_ctrl_ops = { 435 .read = register_read_memory, 436 .write = register_write_memory, 437 .endianness = DEVICE_LITTLE_ENDIAN, 438 .valid = { 439 .min_access_size = 4, 440 .max_access_size = 4, 441 }, 442 }; 443 444 static void bbram_ctrl_realize(DeviceState *dev, Error **errp) 445 { 446 XlnxBBRam *s = XLNX_BBRAM(dev); 447 448 if (s->crc_zpads) { 449 s->bbram8_wo = true; 450 } 451 452 bbram_bdrv_read(s, errp); 453 } 454 455 static void bbram_ctrl_init(Object *obj) 456 { 457 XlnxBBRam *s = XLNX_BBRAM(obj); 458 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 459 RegisterInfoArray *reg_array; 460 461 reg_array = 462 register_init_block32(DEVICE(obj), bbram_ctrl_regs_info, 463 ARRAY_SIZE(bbram_ctrl_regs_info), 464 s->regs_info, s->regs, 465 &bbram_ctrl_ops, 466 XLNX_BBRAM_ERR_DEBUG, 467 R_MAX * 4); 468 469 sysbus_init_mmio(sbd, ®_array->mem); 470 sysbus_init_irq(sbd, &s->irq_bbram); 471 } 472 473 static void bbram_prop_set_drive(Object *obj, Visitor *v, const char *name, 474 void *opaque, Error **errp) 475 { 476 DeviceState *dev = DEVICE(obj); 477 478 qdev_prop_drive.set(obj, v, name, opaque, errp); 479 480 /* Fill initial data if backend is attached after realized */ 481 if (dev->realized) { 482 bbram_bdrv_read(XLNX_BBRAM(obj), errp); 483 } 484 } 485 486 static void bbram_prop_get_drive(Object *obj, Visitor *v, const char *name, 487 void *opaque, Error **errp) 488 { 489 qdev_prop_drive.get(obj, v, name, opaque, errp); 490 } 491 492 static void bbram_prop_release_drive(Object *obj, const char *name, 493 void *opaque) 494 { 495 qdev_prop_drive.release(obj, name, opaque); 496 } 497 498 static const PropertyInfo bbram_prop_drive = { 499 .name = "str", 500 .description = "Node name or ID of a block device to use as BBRAM backend", 501 .realized_set_allowed = true, 502 .get = bbram_prop_get_drive, 503 .set = bbram_prop_set_drive, 504 .release = bbram_prop_release_drive, 505 }; 506 507 static const VMStateDescription vmstate_bbram_ctrl = { 508 .name = TYPE_XLNX_BBRAM, 509 .version_id = 1, 510 .minimum_version_id = 1, 511 .fields = (VMStateField[]) { 512 VMSTATE_UINT32_ARRAY(regs, XlnxBBRam, R_MAX), 513 VMSTATE_END_OF_LIST(), 514 } 515 }; 516 517 static Property bbram_ctrl_props[] = { 518 DEFINE_PROP("drive", XlnxBBRam, blk, bbram_prop_drive, BlockBackend *), 519 DEFINE_PROP_UINT32("crc-zpads", XlnxBBRam, crc_zpads, 1), 520 DEFINE_PROP_END_OF_LIST(), 521 }; 522 523 static void bbram_ctrl_class_init(ObjectClass *klass, void *data) 524 { 525 DeviceClass *dc = DEVICE_CLASS(klass); 526 ResettableClass *rc = RESETTABLE_CLASS(klass); 527 528 rc->phases.hold = bbram_ctrl_reset_hold; 529 dc->realize = bbram_ctrl_realize; 530 dc->vmsd = &vmstate_bbram_ctrl; 531 device_class_set_props(dc, bbram_ctrl_props); 532 } 533 534 static const TypeInfo bbram_ctrl_info = { 535 .name = TYPE_XLNX_BBRAM, 536 .parent = TYPE_SYS_BUS_DEVICE, 537 .instance_size = sizeof(XlnxBBRam), 538 .class_init = bbram_ctrl_class_init, 539 .instance_init = bbram_ctrl_init, 540 }; 541 542 static void bbram_ctrl_register_types(void) 543 { 544 type_register_static(&bbram_ctrl_info); 545 } 546 547 type_init(bbram_ctrl_register_types) 548