1 /* 2 * ACPI Error Record Serialization Table, ERST, Implementation 3 * 4 * ACPI ERST introduced in ACPI 4.0, June 16, 2009. 5 * ACPI Platform Error Interfaces : Error Serialization 6 * 7 * Copyright (c) 2021 Oracle and/or its affiliates. 8 * 9 * SPDX-License-Identifier: GPL-2.0-or-later 10 */ 11 12 #include "qemu/osdep.h" 13 #include "qapi/error.h" 14 #include "hw/qdev-core.h" 15 #include "exec/memory.h" 16 #include "qom/object.h" 17 #include "hw/pci/pci.h" 18 #include "qom/object_interfaces.h" 19 #include "qemu/error-report.h" 20 #include "migration/vmstate.h" 21 #include "hw/qdev-properties.h" 22 #include "hw/acpi/acpi.h" 23 #include "hw/acpi/acpi-defs.h" 24 #include "hw/acpi/aml-build.h" 25 #include "hw/acpi/bios-linker-loader.h" 26 #include "exec/address-spaces.h" 27 #include "sysemu/hostmem.h" 28 #include "hw/acpi/erst.h" 29 #include "trace.h" 30 31 /* ACPI 4.0: Table 17-16 Serialization Actions */ 32 #define ACTION_BEGIN_WRITE_OPERATION 0x0 33 #define ACTION_BEGIN_READ_OPERATION 0x1 34 #define ACTION_BEGIN_CLEAR_OPERATION 0x2 35 #define ACTION_END_OPERATION 0x3 36 #define ACTION_SET_RECORD_OFFSET 0x4 37 #define ACTION_EXECUTE_OPERATION 0x5 38 #define ACTION_CHECK_BUSY_STATUS 0x6 39 #define ACTION_GET_COMMAND_STATUS 0x7 40 #define ACTION_GET_RECORD_IDENTIFIER 0x8 41 #define ACTION_SET_RECORD_IDENTIFIER 0x9 42 #define ACTION_GET_RECORD_COUNT 0xA 43 #define ACTION_BEGIN_DUMMY_WRITE_OPERATION 0xB 44 #define ACTION_RESERVED 0xC 45 #define ACTION_GET_ERROR_LOG_ADDRESS_RANGE 0xD 46 #define ACTION_GET_ERROR_LOG_ADDRESS_LENGTH 0xE 47 #define ACTION_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES 0xF 48 #define ACTION_GET_EXECUTE_OPERATION_TIMINGS 0x10 /* ACPI 6.3 */ 49 50 /* ACPI 4.0: Table 17-17 Command Status Definitions */ 51 #define STATUS_SUCCESS 0x00 52 #define STATUS_NOT_ENOUGH_SPACE 0x01 53 #define STATUS_HARDWARE_NOT_AVAILABLE 0x02 54 #define STATUS_FAILED 0x03 55 #define STATUS_RECORD_STORE_EMPTY 0x04 56 #define STATUS_RECORD_NOT_FOUND 0x05 57 58 /* ACPI 4.0: Table 17-19 Serialization Instructions */ 59 #define INST_READ_REGISTER 0x00 60 #define INST_READ_REGISTER_VALUE 0x01 61 #define INST_WRITE_REGISTER 0x02 62 #define INST_WRITE_REGISTER_VALUE 0x03 63 #define INST_NOOP 0x04 64 #define INST_LOAD_VAR1 0x05 65 #define INST_LOAD_VAR2 0x06 66 #define INST_STORE_VAR1 0x07 67 #define INST_ADD 0x08 68 #define INST_SUBTRACT 0x09 69 #define INST_ADD_VALUE 0x0A 70 #define INST_SUBTRACT_VALUE 0x0B 71 #define INST_STALL 0x0C 72 #define INST_STALL_WHILE_TRUE 0x0D 73 #define INST_SKIP_NEXT_INSTRUCTION_IF_TRUE 0x0E 74 #define INST_GOTO 0x0F 75 #define INST_SET_SRC_ADDRESS_BASE 0x10 76 #define INST_SET_DST_ADDRESS_BASE 0x11 77 #define INST_MOVE_DATA 0x12 78 79 /* UEFI 2.1: Appendix N Common Platform Error Record */ 80 #define UEFI_CPER_RECORD_MIN_SIZE 128U 81 #define UEFI_CPER_RECORD_LENGTH_OFFSET 20U 82 #define UEFI_CPER_RECORD_ID_OFFSET 96U 83 #define IS_UEFI_CPER_RECORD(ptr) \ 84 (((ptr)[0] == 'C') && \ 85 ((ptr)[1] == 'P') && \ 86 ((ptr)[2] == 'E') && \ 87 ((ptr)[3] == 'R')) 88 89 /* 90 * NOTE that when accessing CPER fields within a record, memcpy() 91 * is utilized to avoid a possible misaligned access on the host. 92 */ 93 94 /* 95 * This implementation is an ACTION (cmd) and VALUE (data) 96 * interface consisting of just two 64-bit registers. 97 */ 98 #define ERST_REG_SIZE (16UL) 99 #define ERST_ACTION_OFFSET (0UL) /* action (cmd) */ 100 #define ERST_VALUE_OFFSET (8UL) /* argument/value (data) */ 101 102 /* 103 * ERST_RECORD_SIZE is the buffer size for exchanging ERST 104 * record contents. Thus, it defines the maximum record size. 105 * As this is mapped through a PCI BAR, it must be a power of 106 * two and larger than UEFI_CPER_RECORD_MIN_SIZE. 107 * The backing storage is divided into fixed size "slots", 108 * each ERST_RECORD_SIZE in length, and each "slot" 109 * storing a single record. No attempt at optimizing storage 110 * through compression, compaction, etc is attempted. 111 * NOTE that slot 0 is reserved for the backing storage header. 112 * Depending upon the size of the backing storage, additional 113 * slots will be part of the slot 0 header in order to account 114 * for a record_id for each available remaining slot. 115 */ 116 /* 8KiB records, not too small, not too big */ 117 #define ERST_RECORD_SIZE (8192UL) 118 119 #define ACPI_ERST_MEMDEV_PROP "memdev" 120 #define ACPI_ERST_RECORD_SIZE_PROP "record_size" 121 122 /* 123 * From the ACPI ERST spec sections: 124 * A record id of all 0s is used to indicate 'unspecified' record id. 125 * A record id of all 1s is used to indicate empty or end. 126 */ 127 #define ERST_UNSPECIFIED_RECORD_ID (0UL) 128 #define ERST_EMPTY_END_RECORD_ID (~0UL) 129 130 #define ERST_IS_VALID_RECORD_ID(rid) \ 131 ((rid != ERST_UNSPECIFIED_RECORD_ID) && \ 132 (rid != ERST_EMPTY_END_RECORD_ID)) 133 134 /* 135 * Implementation-specific definitions and types. 136 * Values are arbitrary and chosen for this implementation. 137 * See erst.rst documentation for details. 138 */ 139 #define ERST_EXECUTE_OPERATION_MAGIC 0x9CUL 140 #define ERST_STORE_MAGIC 0x524F545354535245UL /* ERSTSTOR */ 141 typedef struct { 142 uint64_t magic; 143 uint32_t record_size; 144 uint32_t storage_offset; /* offset to record storage beyond header */ 145 uint16_t version; 146 uint16_t reserved; 147 uint32_t record_count; 148 uint64_t map[]; /* contains record_ids, and position indicates index */ 149 } __attribute__((packed)) ERSTStorageHeader; 150 151 /* 152 * Object cast macro 153 */ 154 #define ACPIERST(obj) \ 155 OBJECT_CHECK(ERSTDeviceState, (obj), TYPE_ACPI_ERST) 156 157 /* 158 * Main ERST device state structure 159 */ 160 typedef struct { 161 PCIDevice parent_obj; 162 163 /* Backend storage */ 164 HostMemoryBackend *hostmem; 165 MemoryRegion *hostmem_mr; 166 uint32_t storage_size; 167 uint32_t default_record_size; 168 169 /* Programming registers */ 170 MemoryRegion iomem_mr; 171 172 /* Exchange buffer */ 173 MemoryRegion exchange_mr; 174 175 /* Interface state */ 176 uint8_t operation; 177 uint8_t busy_status; 178 uint8_t command_status; 179 uint32_t record_offset; 180 uint64_t reg_action; 181 uint64_t reg_value; 182 uint64_t record_identifier; 183 ERSTStorageHeader *header; 184 unsigned first_record_index; 185 unsigned last_record_index; 186 unsigned next_record_index; 187 188 } ERSTDeviceState; 189 190 /*******************************************************************/ 191 /*******************************************************************/ 192 typedef struct { 193 GArray *table_data; 194 pcibus_t bar; 195 uint8_t instruction; 196 uint8_t flags; 197 uint8_t register_bit_width; 198 pcibus_t register_offset; 199 } BuildSerializationInstructionEntry; 200 201 /* ACPI 4.0: 17.4.1.2 Serialization Instruction Entries */ 202 static void build_serialization_instruction( 203 BuildSerializationInstructionEntry *e, 204 uint8_t serialization_action, 205 uint64_t value) 206 { 207 /* ACPI 4.0: Table 17-18 Serialization Instruction Entry */ 208 struct AcpiGenericAddress gas; 209 uint64_t mask; 210 211 /* Serialization Action */ 212 build_append_int_noprefix(e->table_data, serialization_action, 1); 213 /* Instruction */ 214 build_append_int_noprefix(e->table_data, e->instruction, 1); 215 /* Flags */ 216 build_append_int_noprefix(e->table_data, e->flags, 1); 217 /* Reserved */ 218 build_append_int_noprefix(e->table_data, 0, 1); 219 /* Register Region */ 220 gas.space_id = AML_SYSTEM_MEMORY; 221 gas.bit_width = e->register_bit_width; 222 gas.bit_offset = 0; 223 gas.access_width = (uint8_t)ctz32(e->register_bit_width) - 2; 224 gas.address = (uint64_t)(e->bar + e->register_offset); 225 build_append_gas_from_struct(e->table_data, &gas); 226 /* Value */ 227 build_append_int_noprefix(e->table_data, value, 8); 228 /* Mask */ 229 mask = (1ULL << (e->register_bit_width - 1) << 1) - 1; 230 build_append_int_noprefix(e->table_data, mask, 8); 231 } 232 233 /* ACPI 4.0: 17.4.1 Serialization Action Table */ 234 void build_erst(GArray *table_data, BIOSLinker *linker, Object *erst_dev, 235 const char *oem_id, const char *oem_table_id) 236 { 237 /* 238 * Serialization Action Table 239 * The serialization action table must be generated first 240 * so that its size can be known in order to populate the 241 * Instruction Entry Count field. 242 */ 243 unsigned action; 244 GArray *table_instruction_data = g_array_new(FALSE, FALSE, sizeof(char)); 245 pcibus_t bar0 = pci_get_bar_addr(PCI_DEVICE(erst_dev), 0); 246 AcpiTable table = { .sig = "ERST", .rev = 1, .oem_id = oem_id, 247 .oem_table_id = oem_table_id }; 248 /* Contexts for the different ways ACTION and VALUE are accessed */ 249 BuildSerializationInstructionEntry rd_value_32_val = { 250 .table_data = table_instruction_data, .bar = bar0, .flags = 0, 251 .instruction = INST_READ_REGISTER_VALUE, 252 .register_bit_width = 32, 253 .register_offset = ERST_VALUE_OFFSET, 254 }; 255 BuildSerializationInstructionEntry rd_value_32 = { 256 .table_data = table_instruction_data, .bar = bar0, .flags = 0, 257 .instruction = INST_READ_REGISTER, 258 .register_bit_width = 32, 259 .register_offset = ERST_VALUE_OFFSET, 260 }; 261 BuildSerializationInstructionEntry rd_value_64 = { 262 .table_data = table_instruction_data, .bar = bar0, .flags = 0, 263 .instruction = INST_READ_REGISTER, 264 .register_bit_width = 64, 265 .register_offset = ERST_VALUE_OFFSET, 266 }; 267 BuildSerializationInstructionEntry wr_value_32_val = { 268 .table_data = table_instruction_data, .bar = bar0, .flags = 0, 269 .instruction = INST_WRITE_REGISTER_VALUE, 270 .register_bit_width = 32, 271 .register_offset = ERST_VALUE_OFFSET, 272 }; 273 BuildSerializationInstructionEntry wr_value_32 = { 274 .table_data = table_instruction_data, .bar = bar0, .flags = 0, 275 .instruction = INST_WRITE_REGISTER, 276 .register_bit_width = 32, 277 .register_offset = ERST_VALUE_OFFSET, 278 }; 279 BuildSerializationInstructionEntry wr_value_64 = { 280 .table_data = table_instruction_data, .bar = bar0, .flags = 0, 281 .instruction = INST_WRITE_REGISTER, 282 .register_bit_width = 64, 283 .register_offset = ERST_VALUE_OFFSET, 284 }; 285 BuildSerializationInstructionEntry wr_action = { 286 .table_data = table_instruction_data, .bar = bar0, .flags = 0, 287 .instruction = INST_WRITE_REGISTER_VALUE, 288 .register_bit_width = 32, 289 .register_offset = ERST_ACTION_OFFSET, 290 }; 291 292 trace_acpi_erst_pci_bar_0(bar0); 293 294 /* Serialization Instruction Entries */ 295 action = ACTION_BEGIN_WRITE_OPERATION; 296 build_serialization_instruction(&wr_action, action, action); 297 298 action = ACTION_BEGIN_READ_OPERATION; 299 build_serialization_instruction(&wr_action, action, action); 300 301 action = ACTION_BEGIN_CLEAR_OPERATION; 302 build_serialization_instruction(&wr_action, action, action); 303 304 action = ACTION_END_OPERATION; 305 build_serialization_instruction(&wr_action, action, action); 306 307 action = ACTION_SET_RECORD_OFFSET; 308 build_serialization_instruction(&wr_value_32, action, 0); 309 build_serialization_instruction(&wr_action, action, action); 310 311 action = ACTION_EXECUTE_OPERATION; 312 build_serialization_instruction(&wr_value_32_val, action, 313 ERST_EXECUTE_OPERATION_MAGIC); 314 build_serialization_instruction(&wr_action, action, action); 315 316 action = ACTION_CHECK_BUSY_STATUS; 317 build_serialization_instruction(&wr_action, action, action); 318 build_serialization_instruction(&rd_value_32_val, action, 0x01); 319 320 action = ACTION_GET_COMMAND_STATUS; 321 build_serialization_instruction(&wr_action, action, action); 322 build_serialization_instruction(&rd_value_32, action, 0); 323 324 action = ACTION_GET_RECORD_IDENTIFIER; 325 build_serialization_instruction(&wr_action, action, action); 326 build_serialization_instruction(&rd_value_64, action, 0); 327 328 action = ACTION_SET_RECORD_IDENTIFIER; 329 build_serialization_instruction(&wr_value_64, action, 0); 330 build_serialization_instruction(&wr_action, action, action); 331 332 action = ACTION_GET_RECORD_COUNT; 333 build_serialization_instruction(&wr_action, action, action); 334 build_serialization_instruction(&rd_value_32, action, 0); 335 336 action = ACTION_BEGIN_DUMMY_WRITE_OPERATION; 337 build_serialization_instruction(&wr_action, action, action); 338 339 action = ACTION_GET_ERROR_LOG_ADDRESS_RANGE; 340 build_serialization_instruction(&wr_action, action, action); 341 build_serialization_instruction(&rd_value_64, action, 0); 342 343 action = ACTION_GET_ERROR_LOG_ADDRESS_LENGTH; 344 build_serialization_instruction(&wr_action, action, action); 345 build_serialization_instruction(&rd_value_64, action, 0); 346 347 action = ACTION_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES; 348 build_serialization_instruction(&wr_action, action, action); 349 build_serialization_instruction(&rd_value_32, action, 0); 350 351 action = ACTION_GET_EXECUTE_OPERATION_TIMINGS; 352 build_serialization_instruction(&wr_action, action, action); 353 build_serialization_instruction(&rd_value_64, action, 0); 354 355 /* Serialization Header */ 356 acpi_table_begin(&table, table_data); 357 358 /* Serialization Header Size */ 359 build_append_int_noprefix(table_data, 48, 4); 360 361 /* Reserved */ 362 build_append_int_noprefix(table_data, 0, 4); 363 364 /* 365 * Instruction Entry Count 366 * Each instruction entry is 32 bytes 367 */ 368 g_assert((table_instruction_data->len) % 32 == 0); 369 build_append_int_noprefix(table_data, 370 (table_instruction_data->len / 32), 4); 371 372 /* Serialization Instruction Entries */ 373 g_array_append_vals(table_data, table_instruction_data->data, 374 table_instruction_data->len); 375 g_array_free(table_instruction_data, TRUE); 376 377 acpi_table_end(linker, &table); 378 } 379 380 /*******************************************************************/ 381 /*******************************************************************/ 382 static uint8_t *get_nvram_ptr_by_index(ERSTDeviceState *s, unsigned index) 383 { 384 uint8_t *rc = NULL; 385 off_t offset = (index * le32_to_cpu(s->header->record_size)); 386 387 g_assert(offset < s->storage_size); 388 389 rc = memory_region_get_ram_ptr(s->hostmem_mr); 390 rc += offset; 391 392 return rc; 393 } 394 395 static void make_erst_storage_header(ERSTDeviceState *s) 396 { 397 ERSTStorageHeader *header = s->header; 398 unsigned mapsz, headersz; 399 400 header->magic = cpu_to_le64(ERST_STORE_MAGIC); 401 header->record_size = cpu_to_le32(s->default_record_size); 402 header->version = cpu_to_le16(0x0100); 403 header->reserved = cpu_to_le16(0x0000); 404 405 /* Compute mapsize */ 406 mapsz = s->storage_size / s->default_record_size; 407 mapsz *= sizeof(uint64_t); 408 /* Compute header+map size */ 409 headersz = sizeof(ERSTStorageHeader) + mapsz; 410 /* Round up to nearest integer multiple of ERST_RECORD_SIZE */ 411 headersz = QEMU_ALIGN_UP(headersz, s->default_record_size); 412 header->storage_offset = cpu_to_le32(headersz); 413 414 /* 415 * The HostMemoryBackend initializes contents to zero, 416 * so all record_ids stashed in the map are zero'd. 417 * As well the record_count is zero. Properly initialized. 418 */ 419 } 420 421 static void check_erst_backend_storage(ERSTDeviceState *s, Error **errp) 422 { 423 ERSTStorageHeader *header; 424 uint32_t record_size; 425 426 header = memory_region_get_ram_ptr(s->hostmem_mr); 427 s->header = header; 428 429 /* Ensure pointer to header is 64-bit aligned */ 430 g_assert(QEMU_PTR_IS_ALIGNED(header, sizeof(uint64_t))); 431 432 /* 433 * Check if header is uninitialized; HostMemoryBackend inits to 0 434 */ 435 if (le64_to_cpu(header->magic) == 0UL) { 436 make_erst_storage_header(s); 437 } 438 439 /* Validity check record_size */ 440 record_size = le32_to_cpu(header->record_size); 441 if (!( 442 (record_size) && /* non zero */ 443 (record_size >= UEFI_CPER_RECORD_MIN_SIZE) && 444 (((record_size - 1) & record_size) == 0) && /* is power of 2 */ 445 (record_size >= 4096) /* PAGE_SIZE */ 446 )) { 447 error_setg(errp, "ERST record_size %u is invalid", record_size); 448 } 449 450 /* Validity check header */ 451 if (!( 452 (le64_to_cpu(header->magic) == ERST_STORE_MAGIC) && 453 ((le32_to_cpu(header->storage_offset) % record_size) == 0) && 454 (le16_to_cpu(header->version) == 0x0100) && 455 (le16_to_cpu(header->reserved) == 0) 456 )) { 457 error_setg(errp, "ERST backend storage header is invalid"); 458 } 459 460 /* Check storage_size against record_size */ 461 if (((s->storage_size % record_size) != 0) || 462 (record_size > s->storage_size)) { 463 error_setg(errp, "ACPI ERST requires storage size be multiple of " 464 "record size (%uKiB)", record_size); 465 } 466 467 /* Compute offset of first and last record storage slot */ 468 s->first_record_index = le32_to_cpu(header->storage_offset) 469 / record_size; 470 s->last_record_index = (s->storage_size / record_size); 471 } 472 473 static void update_map_entry(ERSTDeviceState *s, unsigned index, 474 uint64_t record_id) 475 { 476 if (index < s->last_record_index) { 477 s->header->map[index] = cpu_to_le64(record_id); 478 } 479 } 480 481 static unsigned find_next_empty_record_index(ERSTDeviceState *s) 482 { 483 unsigned rc = 0; /* 0 not a valid index */ 484 unsigned index = s->first_record_index; 485 486 for (; index < s->last_record_index; ++index) { 487 if (le64_to_cpu(s->header->map[index]) == ERST_UNSPECIFIED_RECORD_ID) { 488 rc = index; 489 break; 490 } 491 } 492 493 return rc; 494 } 495 496 static unsigned lookup_erst_record(ERSTDeviceState *s, 497 uint64_t record_identifier) 498 { 499 unsigned rc = 0; /* 0 not a valid index */ 500 501 /* Find the record_identifier in the map */ 502 if (record_identifier != ERST_UNSPECIFIED_RECORD_ID) { 503 /* 504 * Count number of valid records encountered, and 505 * short-circuit the loop if identifier not found 506 */ 507 uint32_t record_count = le32_to_cpu(s->header->record_count); 508 unsigned count = 0; 509 unsigned index; 510 for (index = s->first_record_index; index < s->last_record_index && 511 count < record_count; ++index) { 512 if (le64_to_cpu(s->header->map[index]) == record_identifier) { 513 rc = index; 514 break; 515 } 516 if (le64_to_cpu(s->header->map[index]) != 517 ERST_UNSPECIFIED_RECORD_ID) { 518 ++count; 519 } 520 } 521 } 522 523 return rc; 524 } 525 526 /* 527 * ACPI 4.0: 17.4.1.1 Serialization Actions, also see 528 * ACPI 4.0: 17.4.2.2 Operations - Reading 6.c and 2.c 529 */ 530 static unsigned get_next_record_identifier(ERSTDeviceState *s, 531 uint64_t *record_identifier, bool first) 532 { 533 unsigned found = 0; 534 unsigned index; 535 536 /* For operations needing to return 'first' record identifier */ 537 if (first) { 538 /* Reset initial index to beginning */ 539 s->next_record_index = s->first_record_index; 540 } 541 index = s->next_record_index; 542 543 *record_identifier = ERST_EMPTY_END_RECORD_ID; 544 545 if (le32_to_cpu(s->header->record_count)) { 546 for (; index < s->last_record_index; ++index) { 547 if (le64_to_cpu(s->header->map[index]) != 548 ERST_UNSPECIFIED_RECORD_ID) { 549 /* where to start next time */ 550 s->next_record_index = index + 1; 551 *record_identifier = le64_to_cpu(s->header->map[index]); 552 found = 1; 553 break; 554 } 555 } 556 } 557 if (!found) { 558 /* at end (ie scan complete), reset */ 559 s->next_record_index = s->first_record_index; 560 } 561 562 return STATUS_SUCCESS; 563 } 564 565 /* ACPI 4.0: 17.4.2.3 Operations - Clearing */ 566 static unsigned clear_erst_record(ERSTDeviceState *s) 567 { 568 unsigned rc = STATUS_RECORD_NOT_FOUND; 569 unsigned index; 570 571 /* Check for valid record identifier */ 572 if (!ERST_IS_VALID_RECORD_ID(s->record_identifier)) { 573 return STATUS_FAILED; 574 } 575 576 index = lookup_erst_record(s, s->record_identifier); 577 if (index) { 578 /* No need to wipe record, just invalidate its map entry */ 579 uint32_t record_count; 580 update_map_entry(s, index, ERST_UNSPECIFIED_RECORD_ID); 581 record_count = le32_to_cpu(s->header->record_count); 582 record_count -= 1; 583 s->header->record_count = cpu_to_le32(record_count); 584 rc = STATUS_SUCCESS; 585 } 586 587 return rc; 588 } 589 590 /* ACPI 4.0: 17.4.2.2 Operations - Reading */ 591 static unsigned read_erst_record(ERSTDeviceState *s) 592 { 593 unsigned rc = STATUS_RECORD_NOT_FOUND; 594 unsigned exchange_length; 595 unsigned index; 596 597 /* Check if backend storage is empty */ 598 if (le32_to_cpu(s->header->record_count) == 0) { 599 return STATUS_RECORD_STORE_EMPTY; 600 } 601 602 exchange_length = memory_region_size(&s->exchange_mr); 603 604 /* Check for record identifier of all 0s */ 605 if (s->record_identifier == ERST_UNSPECIFIED_RECORD_ID) { 606 /* Set to 'first' record in storage */ 607 get_next_record_identifier(s, &s->record_identifier, true); 608 /* record_identifier is now a valid id, or all 1s */ 609 } 610 611 /* Check for record identifier of all 1s */ 612 if (s->record_identifier == ERST_EMPTY_END_RECORD_ID) { 613 return STATUS_FAILED; 614 } 615 616 /* Validate record_offset */ 617 if (s->record_offset > (exchange_length - UEFI_CPER_RECORD_MIN_SIZE)) { 618 return STATUS_FAILED; 619 } 620 621 index = lookup_erst_record(s, s->record_identifier); 622 if (index) { 623 uint8_t *nvram; 624 uint8_t *exchange; 625 uint32_t record_length; 626 627 /* Obtain pointer to the exchange buffer */ 628 exchange = memory_region_get_ram_ptr(&s->exchange_mr); 629 exchange += s->record_offset; 630 /* Obtain pointer to slot in storage */ 631 nvram = get_nvram_ptr_by_index(s, index); 632 /* Validate CPER record_length */ 633 memcpy((uint8_t *)&record_length, 634 &nvram[UEFI_CPER_RECORD_LENGTH_OFFSET], 635 sizeof(uint32_t)); 636 record_length = le32_to_cpu(record_length); 637 if (record_length < UEFI_CPER_RECORD_MIN_SIZE) { 638 rc = STATUS_FAILED; 639 } 640 if ((s->record_offset + record_length) > exchange_length) { 641 rc = STATUS_FAILED; 642 } 643 /* If all is ok, copy the record to the exchange buffer */ 644 if (rc != STATUS_FAILED) { 645 memcpy(exchange, nvram, record_length); 646 rc = STATUS_SUCCESS; 647 } 648 } else { 649 /* 650 * See "Reading : 'The steps performed by the platform ...' 2.c" 651 * Set to 'first' record in storage 652 */ 653 get_next_record_identifier(s, &s->record_identifier, true); 654 } 655 656 return rc; 657 } 658 659 /* ACPI 4.0: 17.4.2.1 Operations - Writing */ 660 static unsigned write_erst_record(ERSTDeviceState *s) 661 { 662 unsigned rc = STATUS_FAILED; 663 unsigned exchange_length; 664 unsigned index; 665 uint64_t record_identifier; 666 uint32_t record_length; 667 uint8_t *exchange; 668 uint8_t *nvram = NULL; 669 bool record_found = false; 670 671 exchange_length = memory_region_size(&s->exchange_mr); 672 673 /* Validate record_offset */ 674 if (s->record_offset > (exchange_length - UEFI_CPER_RECORD_MIN_SIZE)) { 675 return STATUS_FAILED; 676 } 677 678 /* Obtain pointer to record in the exchange buffer */ 679 exchange = memory_region_get_ram_ptr(&s->exchange_mr); 680 exchange += s->record_offset; 681 682 /* Validate CPER record_length */ 683 memcpy((uint8_t *)&record_length, &exchange[UEFI_CPER_RECORD_LENGTH_OFFSET], 684 sizeof(uint32_t)); 685 record_length = le32_to_cpu(record_length); 686 if (record_length < UEFI_CPER_RECORD_MIN_SIZE) { 687 return STATUS_FAILED; 688 } 689 if ((s->record_offset + record_length) > exchange_length) { 690 return STATUS_FAILED; 691 } 692 693 /* Extract record identifier */ 694 memcpy((uint8_t *)&record_identifier, &exchange[UEFI_CPER_RECORD_ID_OFFSET], 695 sizeof(uint64_t)); 696 record_identifier = le64_to_cpu(record_identifier); 697 698 /* Check for valid record identifier */ 699 if (!ERST_IS_VALID_RECORD_ID(record_identifier)) { 700 return STATUS_FAILED; 701 } 702 703 index = lookup_erst_record(s, record_identifier); 704 if (index) { 705 /* Record found, overwrite existing record */ 706 nvram = get_nvram_ptr_by_index(s, index); 707 record_found = true; 708 } else { 709 /* Record not found, not an overwrite, allocate for write */ 710 index = find_next_empty_record_index(s); 711 if (index) { 712 nvram = get_nvram_ptr_by_index(s, index); 713 } else { 714 /* All slots are occupied */ 715 rc = STATUS_NOT_ENOUGH_SPACE; 716 } 717 } 718 if (nvram) { 719 /* Write the record into the slot */ 720 memcpy(nvram, exchange, record_length); 721 memset(nvram + record_length, exchange_length - record_length, 0xFF); 722 /* If a new record, increment the record_count */ 723 if (!record_found) { 724 uint32_t record_count; 725 record_count = le32_to_cpu(s->header->record_count); 726 record_count += 1; /* writing new record */ 727 s->header->record_count = cpu_to_le32(record_count); 728 } 729 update_map_entry(s, index, record_identifier); 730 rc = STATUS_SUCCESS; 731 } 732 733 return rc; 734 } 735 736 /*******************************************************************/ 737 738 static uint64_t erst_rd_reg64(hwaddr addr, 739 uint64_t reg, unsigned size) 740 { 741 uint64_t rdval; 742 uint64_t mask; 743 unsigned shift; 744 745 if (size == sizeof(uint64_t)) { 746 /* 64b access */ 747 mask = 0xFFFFFFFFFFFFFFFFUL; 748 shift = 0; 749 } else { 750 /* 32b access */ 751 mask = 0x00000000FFFFFFFFUL; 752 shift = ((addr & 0x4) == 0x4) ? 32 : 0; 753 } 754 755 rdval = reg; 756 rdval >>= shift; 757 rdval &= mask; 758 759 return rdval; 760 } 761 762 static uint64_t erst_wr_reg64(hwaddr addr, 763 uint64_t reg, uint64_t val, unsigned size) 764 { 765 uint64_t wrval; 766 uint64_t mask; 767 unsigned shift; 768 769 if (size == sizeof(uint64_t)) { 770 /* 64b access */ 771 mask = 0xFFFFFFFFFFFFFFFFUL; 772 shift = 0; 773 } else { 774 /* 32b access */ 775 mask = 0x00000000FFFFFFFFUL; 776 shift = ((addr & 0x4) == 0x4) ? 32 : 0; 777 } 778 779 val &= mask; 780 val <<= shift; 781 mask <<= shift; 782 wrval = reg; 783 wrval &= ~mask; 784 wrval |= val; 785 786 return wrval; 787 } 788 789 static void erst_reg_write(void *opaque, hwaddr addr, 790 uint64_t val, unsigned size) 791 { 792 ERSTDeviceState *s = (ERSTDeviceState *)opaque; 793 794 /* 795 * NOTE: All actions/operations/side effects happen on the WRITE, 796 * by this implementation's design. The READs simply return the 797 * reg_value contents. 798 */ 799 trace_acpi_erst_reg_write(addr, val, size); 800 801 switch (addr) { 802 case ERST_VALUE_OFFSET + 0: 803 case ERST_VALUE_OFFSET + 4: 804 s->reg_value = erst_wr_reg64(addr, s->reg_value, val, size); 805 break; 806 case ERST_ACTION_OFFSET + 0: 807 /* 808 * NOTE: all valid values written to this register are of the 809 * ACTION_* variety. Thus there is no need to make this a 64-bit 810 * register, 32-bits is appropriate. As such ERST_ACTION_OFFSET+4 811 * is not needed. 812 */ 813 switch (val) { 814 case ACTION_BEGIN_WRITE_OPERATION: 815 case ACTION_BEGIN_READ_OPERATION: 816 case ACTION_BEGIN_CLEAR_OPERATION: 817 case ACTION_BEGIN_DUMMY_WRITE_OPERATION: 818 case ACTION_END_OPERATION: 819 s->operation = val; 820 break; 821 case ACTION_SET_RECORD_OFFSET: 822 s->record_offset = s->reg_value; 823 break; 824 case ACTION_EXECUTE_OPERATION: 825 if ((uint8_t)s->reg_value == ERST_EXECUTE_OPERATION_MAGIC) { 826 s->busy_status = 1; 827 switch (s->operation) { 828 case ACTION_BEGIN_WRITE_OPERATION: 829 s->command_status = write_erst_record(s); 830 break; 831 case ACTION_BEGIN_READ_OPERATION: 832 s->command_status = read_erst_record(s); 833 break; 834 case ACTION_BEGIN_CLEAR_OPERATION: 835 s->command_status = clear_erst_record(s); 836 break; 837 case ACTION_BEGIN_DUMMY_WRITE_OPERATION: 838 s->command_status = STATUS_SUCCESS; 839 break; 840 case ACTION_END_OPERATION: 841 s->command_status = STATUS_SUCCESS; 842 break; 843 default: 844 s->command_status = STATUS_FAILED; 845 break; 846 } 847 s->busy_status = 0; 848 } 849 break; 850 case ACTION_CHECK_BUSY_STATUS: 851 s->reg_value = s->busy_status; 852 break; 853 case ACTION_GET_COMMAND_STATUS: 854 s->reg_value = s->command_status; 855 break; 856 case ACTION_GET_RECORD_IDENTIFIER: 857 s->command_status = get_next_record_identifier(s, 858 &s->reg_value, false); 859 break; 860 case ACTION_SET_RECORD_IDENTIFIER: 861 s->record_identifier = s->reg_value; 862 break; 863 case ACTION_GET_RECORD_COUNT: 864 s->reg_value = le32_to_cpu(s->header->record_count); 865 break; 866 case ACTION_GET_ERROR_LOG_ADDRESS_RANGE: 867 s->reg_value = (hwaddr)pci_get_bar_addr(PCI_DEVICE(s), 1); 868 break; 869 case ACTION_GET_ERROR_LOG_ADDRESS_LENGTH: 870 s->reg_value = le32_to_cpu(s->header->record_size); 871 break; 872 case ACTION_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES: 873 s->reg_value = 0x0; /* intentional, not NVRAM mode */ 874 break; 875 case ACTION_GET_EXECUTE_OPERATION_TIMINGS: 876 s->reg_value = 877 (100ULL << 32) | /* 100us max time */ 878 (10ULL << 0) ; /* 10us min time */ 879 break; 880 default: 881 /* Unknown action/command, NOP */ 882 break; 883 } 884 break; 885 default: 886 /* This should not happen, but if it does, NOP */ 887 break; 888 } 889 } 890 891 static uint64_t erst_reg_read(void *opaque, hwaddr addr, 892 unsigned size) 893 { 894 ERSTDeviceState *s = (ERSTDeviceState *)opaque; 895 uint64_t val = 0; 896 897 switch (addr) { 898 case ERST_ACTION_OFFSET + 0: 899 case ERST_ACTION_OFFSET + 4: 900 val = erst_rd_reg64(addr, s->reg_action, size); 901 break; 902 case ERST_VALUE_OFFSET + 0: 903 case ERST_VALUE_OFFSET + 4: 904 val = erst_rd_reg64(addr, s->reg_value, size); 905 break; 906 default: 907 break; 908 } 909 trace_acpi_erst_reg_read(addr, val, size); 910 return val; 911 } 912 913 static const MemoryRegionOps erst_reg_ops = { 914 .read = erst_reg_read, 915 .write = erst_reg_write, 916 .endianness = DEVICE_NATIVE_ENDIAN, 917 }; 918 919 /*******************************************************************/ 920 /*******************************************************************/ 921 static int erst_post_load(void *opaque, int version_id) 922 { 923 ERSTDeviceState *s = opaque; 924 925 /* Recompute pointer to header */ 926 s->header = (ERSTStorageHeader *)get_nvram_ptr_by_index(s, 0); 927 trace_acpi_erst_post_load(s->header, le32_to_cpu(s->header->record_size)); 928 929 return 0; 930 } 931 932 static const VMStateDescription erst_vmstate = { 933 .name = "acpi-erst", 934 .version_id = 1, 935 .minimum_version_id = 1, 936 .post_load = erst_post_load, 937 .fields = (VMStateField[]) { 938 VMSTATE_UINT8(operation, ERSTDeviceState), 939 VMSTATE_UINT8(busy_status, ERSTDeviceState), 940 VMSTATE_UINT8(command_status, ERSTDeviceState), 941 VMSTATE_UINT32(record_offset, ERSTDeviceState), 942 VMSTATE_UINT64(reg_action, ERSTDeviceState), 943 VMSTATE_UINT64(reg_value, ERSTDeviceState), 944 VMSTATE_UINT64(record_identifier, ERSTDeviceState), 945 VMSTATE_UINT32(next_record_index, ERSTDeviceState), 946 VMSTATE_END_OF_LIST() 947 } 948 }; 949 950 static void erst_realizefn(PCIDevice *pci_dev, Error **errp) 951 { 952 ERSTDeviceState *s = ACPIERST(pci_dev); 953 954 trace_acpi_erst_realizefn_in(); 955 956 if (!s->hostmem) { 957 error_setg(errp, "'" ACPI_ERST_MEMDEV_PROP "' property is not set"); 958 return; 959 } else if (host_memory_backend_is_mapped(s->hostmem)) { 960 error_setg(errp, "can't use already busy memdev: %s", 961 object_get_canonical_path_component(OBJECT(s->hostmem))); 962 return; 963 } 964 965 s->hostmem_mr = host_memory_backend_get_memory(s->hostmem); 966 967 /* HostMemoryBackend size will be multiple of PAGE_SIZE */ 968 s->storage_size = object_property_get_int(OBJECT(s->hostmem), "size", errp); 969 970 /* Initialize backend storage and record_count */ 971 check_erst_backend_storage(s, errp); 972 973 /* BAR 0: Programming registers */ 974 memory_region_init_io(&s->iomem_mr, OBJECT(pci_dev), &erst_reg_ops, s, 975 TYPE_ACPI_ERST, ERST_REG_SIZE); 976 pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->iomem_mr); 977 978 /* BAR 1: Exchange buffer memory */ 979 memory_region_init_ram(&s->exchange_mr, OBJECT(pci_dev), 980 "erst.exchange", 981 le32_to_cpu(s->header->record_size), errp); 982 pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, 983 &s->exchange_mr); 984 985 /* Include the backend storage in the migration stream */ 986 vmstate_register_ram_global(s->hostmem_mr); 987 988 trace_acpi_erst_realizefn_out(s->storage_size); 989 } 990 991 static void erst_reset(DeviceState *dev) 992 { 993 ERSTDeviceState *s = ACPIERST(dev); 994 995 trace_acpi_erst_reset_in(le32_to_cpu(s->header->record_count)); 996 s->operation = 0; 997 s->busy_status = 0; 998 s->command_status = STATUS_SUCCESS; 999 s->record_identifier = ERST_UNSPECIFIED_RECORD_ID; 1000 s->record_offset = 0; 1001 s->next_record_index = s->first_record_index; 1002 /* NOTE: first/last_record_index are computed only once */ 1003 trace_acpi_erst_reset_out(le32_to_cpu(s->header->record_count)); 1004 } 1005 1006 static Property erst_properties[] = { 1007 DEFINE_PROP_LINK(ACPI_ERST_MEMDEV_PROP, ERSTDeviceState, hostmem, 1008 TYPE_MEMORY_BACKEND, HostMemoryBackend *), 1009 DEFINE_PROP_UINT32(ACPI_ERST_RECORD_SIZE_PROP, ERSTDeviceState, 1010 default_record_size, ERST_RECORD_SIZE), 1011 DEFINE_PROP_END_OF_LIST(), 1012 }; 1013 1014 static void erst_class_init(ObjectClass *klass, void *data) 1015 { 1016 DeviceClass *dc = DEVICE_CLASS(klass); 1017 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 1018 1019 trace_acpi_erst_class_init_in(); 1020 k->realize = erst_realizefn; 1021 k->vendor_id = PCI_VENDOR_ID_REDHAT; 1022 k->device_id = PCI_DEVICE_ID_REDHAT_ACPI_ERST; 1023 k->revision = 0x00; 1024 k->class_id = PCI_CLASS_OTHERS; 1025 dc->reset = erst_reset; 1026 dc->vmsd = &erst_vmstate; 1027 dc->user_creatable = true; 1028 dc->hotpluggable = false; 1029 device_class_set_props(dc, erst_properties); 1030 dc->desc = "ACPI Error Record Serialization Table (ERST) device"; 1031 set_bit(DEVICE_CATEGORY_MISC, dc->categories); 1032 trace_acpi_erst_class_init_out(); 1033 } 1034 1035 static const TypeInfo erst_type_info = { 1036 .name = TYPE_ACPI_ERST, 1037 .parent = TYPE_PCI_DEVICE, 1038 .class_init = erst_class_init, 1039 .instance_size = sizeof(ERSTDeviceState), 1040 .interfaces = (InterfaceInfo[]) { 1041 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 1042 { } 1043 } 1044 }; 1045 1046 static void erst_register_types(void) 1047 { 1048 type_register_static(&erst_type_info); 1049 } 1050 1051 type_init(erst_register_types) 1052