1 /* 2 * NVDIMM ACPI Implementation 3 * 4 * Copyright(C) 2015 Intel Corporation. 5 * 6 * Author: 7 * Xiao Guangrong <guangrong.xiao@linux.intel.com> 8 * 9 * NFIT is defined in ACPI 6.0: 5.2.25 NVDIMM Firmware Interface Table (NFIT) 10 * and the DSM specification can be found at: 11 * http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf 12 * 13 * Currently, it only supports PMEM Virtualization. 14 * 15 * This library is free software; you can redistribute it and/or 16 * modify it under the terms of the GNU Lesser General Public 17 * License as published by the Free Software Foundation; either 18 * version 2 of the License, or (at your option) any later version. 19 * 20 * This library is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 * Lesser General Public License for more details. 24 * 25 * You should have received a copy of the GNU Lesser General Public 26 * License along with this library; if not, see <http://www.gnu.org/licenses/> 27 */ 28 29 #include "qemu/osdep.h" 30 #include "qemu/uuid.h" 31 #include "hw/acpi/acpi.h" 32 #include "hw/acpi/aml-build.h" 33 #include "hw/acpi/bios-linker-loader.h" 34 #include "hw/nvram/fw_cfg.h" 35 #include "hw/mem/nvdimm.h" 36 #include "qemu/nvdimm-utils.h" 37 38 /* 39 * define Byte Addressable Persistent Memory (PM) Region according to 40 * ACPI 6.0: 5.2.25.1 System Physical Address Range Structure. 41 */ 42 static const uint8_t nvdimm_nfit_spa_uuid[] = 43 UUID_LE(0x66f0d379, 0xb4f3, 0x4074, 0xac, 0x43, 0x0d, 0x33, 44 0x18, 0xb7, 0x8c, 0xdb); 45 46 /* 47 * NVDIMM Firmware Interface Table 48 * @signature: "NFIT" 49 * 50 * It provides information that allows OSPM to enumerate NVDIMM present in 51 * the platform and associate system physical address ranges created by the 52 * NVDIMMs. 53 * 54 * It is defined in ACPI 6.0: 5.2.25 NVDIMM Firmware Interface Table (NFIT) 55 */ 56 struct NvdimmNfitHeader { 57 ACPI_TABLE_HEADER_DEF 58 uint32_t reserved; 59 } QEMU_PACKED; 60 typedef struct NvdimmNfitHeader NvdimmNfitHeader; 61 62 /* 63 * define NFIT structures according to ACPI 6.0: 5.2.25 NVDIMM Firmware 64 * Interface Table (NFIT). 65 */ 66 67 /* 68 * System Physical Address Range Structure 69 * 70 * It describes the system physical address ranges occupied by NVDIMMs and 71 * the types of the regions. 72 */ 73 struct NvdimmNfitSpa { 74 uint16_t type; 75 uint16_t length; 76 uint16_t spa_index; 77 uint16_t flags; 78 uint32_t reserved; 79 uint32_t proximity_domain; 80 uint8_t type_guid[16]; 81 uint64_t spa_base; 82 uint64_t spa_length; 83 uint64_t mem_attr; 84 } QEMU_PACKED; 85 typedef struct NvdimmNfitSpa NvdimmNfitSpa; 86 87 /* 88 * Memory Device to System Physical Address Range Mapping Structure 89 * 90 * It enables identifying each NVDIMM region and the corresponding SPA 91 * describing the memory interleave 92 */ 93 struct NvdimmNfitMemDev { 94 uint16_t type; 95 uint16_t length; 96 uint32_t nfit_handle; 97 uint16_t phys_id; 98 uint16_t region_id; 99 uint16_t spa_index; 100 uint16_t dcr_index; 101 uint64_t region_len; 102 uint64_t region_offset; 103 uint64_t region_dpa; 104 uint16_t interleave_index; 105 uint16_t interleave_ways; 106 uint16_t flags; 107 uint16_t reserved; 108 } QEMU_PACKED; 109 typedef struct NvdimmNfitMemDev NvdimmNfitMemDev; 110 111 #define ACPI_NFIT_MEM_NOT_ARMED (1 << 3) 112 113 /* 114 * NVDIMM Control Region Structure 115 * 116 * It describes the NVDIMM and if applicable, Block Control Window. 117 */ 118 struct NvdimmNfitControlRegion { 119 uint16_t type; 120 uint16_t length; 121 uint16_t dcr_index; 122 uint16_t vendor_id; 123 uint16_t device_id; 124 uint16_t revision_id; 125 uint16_t sub_vendor_id; 126 uint16_t sub_device_id; 127 uint16_t sub_revision_id; 128 uint8_t reserved[6]; 129 uint32_t serial_number; 130 uint16_t fic; 131 uint16_t num_bcw; 132 uint64_t bcw_size; 133 uint64_t cmd_offset; 134 uint64_t cmd_size; 135 uint64_t status_offset; 136 uint64_t status_size; 137 uint16_t flags; 138 uint8_t reserved2[6]; 139 } QEMU_PACKED; 140 typedef struct NvdimmNfitControlRegion NvdimmNfitControlRegion; 141 142 /* 143 * NVDIMM Platform Capabilities Structure 144 * 145 * Defined in section 5.2.25.9 of ACPI 6.2 Errata A, September 2017 146 */ 147 struct NvdimmNfitPlatformCaps { 148 uint16_t type; 149 uint16_t length; 150 uint8_t highest_cap; 151 uint8_t reserved[3]; 152 uint32_t capabilities; 153 uint8_t reserved2[4]; 154 } QEMU_PACKED; 155 typedef struct NvdimmNfitPlatformCaps NvdimmNfitPlatformCaps; 156 157 /* 158 * Module serial number is a unique number for each device. We use the 159 * slot id of NVDIMM device to generate this number so that each device 160 * associates with a different number. 161 * 162 * 0x123456 is a magic number we arbitrarily chose. 163 */ 164 static uint32_t nvdimm_slot_to_sn(int slot) 165 { 166 return 0x123456 + slot; 167 } 168 169 /* 170 * handle is used to uniquely associate nfit_memdev structure with NVDIMM 171 * ACPI device - nfit_memdev.nfit_handle matches with the value returned 172 * by ACPI device _ADR method. 173 * 174 * We generate the handle with the slot id of NVDIMM device and reserve 175 * 0 for NVDIMM root device. 176 */ 177 static uint32_t nvdimm_slot_to_handle(int slot) 178 { 179 return slot + 1; 180 } 181 182 /* 183 * index uniquely identifies the structure, 0 is reserved which indicates 184 * that the structure is not valid or the associated structure is not 185 * present. 186 * 187 * Each NVDIMM device needs two indexes, one for nfit_spa and another for 188 * nfit_dc which are generated by the slot id of NVDIMM device. 189 */ 190 static uint16_t nvdimm_slot_to_spa_index(int slot) 191 { 192 return (slot + 1) << 1; 193 } 194 195 /* See the comments of nvdimm_slot_to_spa_index(). */ 196 static uint32_t nvdimm_slot_to_dcr_index(int slot) 197 { 198 return nvdimm_slot_to_spa_index(slot) + 1; 199 } 200 201 static NVDIMMDevice *nvdimm_get_device_by_handle(uint32_t handle) 202 { 203 NVDIMMDevice *nvdimm = NULL; 204 GSList *list, *device_list = nvdimm_get_device_list(); 205 206 for (list = device_list; list; list = list->next) { 207 NVDIMMDevice *nvd = list->data; 208 int slot = object_property_get_int(OBJECT(nvd), PC_DIMM_SLOT_PROP, 209 NULL); 210 211 if (nvdimm_slot_to_handle(slot) == handle) { 212 nvdimm = nvd; 213 break; 214 } 215 } 216 217 g_slist_free(device_list); 218 return nvdimm; 219 } 220 221 /* ACPI 6.0: 5.2.25.1 System Physical Address Range Structure */ 222 static void 223 nvdimm_build_structure_spa(GArray *structures, DeviceState *dev) 224 { 225 NvdimmNfitSpa *nfit_spa; 226 uint64_t addr = object_property_get_uint(OBJECT(dev), PC_DIMM_ADDR_PROP, 227 NULL); 228 uint64_t size = object_property_get_uint(OBJECT(dev), PC_DIMM_SIZE_PROP, 229 NULL); 230 uint32_t node = object_property_get_uint(OBJECT(dev), PC_DIMM_NODE_PROP, 231 NULL); 232 int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP, 233 NULL); 234 235 nfit_spa = acpi_data_push(structures, sizeof(*nfit_spa)); 236 237 nfit_spa->type = cpu_to_le16(0 /* System Physical Address Range 238 Structure */); 239 nfit_spa->length = cpu_to_le16(sizeof(*nfit_spa)); 240 nfit_spa->spa_index = cpu_to_le16(nvdimm_slot_to_spa_index(slot)); 241 242 /* 243 * Control region is strict as all the device info, such as SN, index, 244 * is associated with slot id. 245 */ 246 nfit_spa->flags = cpu_to_le16(1 /* Control region is strictly for 247 management during hot add/online 248 operation */ | 249 2 /* Data in Proximity Domain field is 250 valid*/); 251 252 /* NUMA node. */ 253 nfit_spa->proximity_domain = cpu_to_le32(node); 254 /* the region reported as PMEM. */ 255 memcpy(nfit_spa->type_guid, nvdimm_nfit_spa_uuid, 256 sizeof(nvdimm_nfit_spa_uuid)); 257 258 nfit_spa->spa_base = cpu_to_le64(addr); 259 nfit_spa->spa_length = cpu_to_le64(size); 260 261 /* It is the PMEM and can be cached as writeback. */ 262 nfit_spa->mem_attr = cpu_to_le64(0x8ULL /* EFI_MEMORY_WB */ | 263 0x8000ULL /* EFI_MEMORY_NV */); 264 } 265 266 /* 267 * ACPI 6.0: 5.2.25.2 Memory Device to System Physical Address Range Mapping 268 * Structure 269 */ 270 static void 271 nvdimm_build_structure_memdev(GArray *structures, DeviceState *dev) 272 { 273 NvdimmNfitMemDev *nfit_memdev; 274 NVDIMMDevice *nvdimm = NVDIMM(OBJECT(dev)); 275 uint64_t size = object_property_get_uint(OBJECT(dev), PC_DIMM_SIZE_PROP, 276 NULL); 277 int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP, 278 NULL); 279 uint32_t handle = nvdimm_slot_to_handle(slot); 280 281 nfit_memdev = acpi_data_push(structures, sizeof(*nfit_memdev)); 282 283 nfit_memdev->type = cpu_to_le16(1 /* Memory Device to System Address 284 Range Map Structure*/); 285 nfit_memdev->length = cpu_to_le16(sizeof(*nfit_memdev)); 286 nfit_memdev->nfit_handle = cpu_to_le32(handle); 287 288 /* 289 * associate memory device with System Physical Address Range 290 * Structure. 291 */ 292 nfit_memdev->spa_index = cpu_to_le16(nvdimm_slot_to_spa_index(slot)); 293 /* associate memory device with Control Region Structure. */ 294 nfit_memdev->dcr_index = cpu_to_le16(nvdimm_slot_to_dcr_index(slot)); 295 296 /* The memory region on the device. */ 297 nfit_memdev->region_len = cpu_to_le64(size); 298 /* The device address starts from 0. */ 299 nfit_memdev->region_dpa = cpu_to_le64(0); 300 301 /* Only one interleave for PMEM. */ 302 nfit_memdev->interleave_ways = cpu_to_le16(1); 303 304 if (nvdimm->unarmed) { 305 nfit_memdev->flags |= cpu_to_le16(ACPI_NFIT_MEM_NOT_ARMED); 306 } 307 } 308 309 /* 310 * ACPI 6.0: 5.2.25.5 NVDIMM Control Region Structure. 311 */ 312 static void nvdimm_build_structure_dcr(GArray *structures, DeviceState *dev) 313 { 314 NvdimmNfitControlRegion *nfit_dcr; 315 int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP, 316 NULL); 317 uint32_t sn = nvdimm_slot_to_sn(slot); 318 319 nfit_dcr = acpi_data_push(structures, sizeof(*nfit_dcr)); 320 321 nfit_dcr->type = cpu_to_le16(4 /* NVDIMM Control Region Structure */); 322 nfit_dcr->length = cpu_to_le16(sizeof(*nfit_dcr)); 323 nfit_dcr->dcr_index = cpu_to_le16(nvdimm_slot_to_dcr_index(slot)); 324 325 /* vendor: Intel. */ 326 nfit_dcr->vendor_id = cpu_to_le16(0x8086); 327 nfit_dcr->device_id = cpu_to_le16(1); 328 329 /* The _DSM method is following Intel's DSM specification. */ 330 nfit_dcr->revision_id = cpu_to_le16(1 /* Current Revision supported 331 in ACPI 6.0 is 1. */); 332 nfit_dcr->serial_number = cpu_to_le32(sn); 333 nfit_dcr->fic = cpu_to_le16(0x301 /* Format Interface Code: 334 Byte addressable, no energy backed. 335 See ACPI 6.2, sect 5.2.25.6 and 336 JEDEC Annex L Release 3. */); 337 } 338 339 /* 340 * ACPI 6.2 Errata A: 5.2.25.9 NVDIMM Platform Capabilities Structure 341 */ 342 static void 343 nvdimm_build_structure_caps(GArray *structures, uint32_t capabilities) 344 { 345 NvdimmNfitPlatformCaps *nfit_caps; 346 347 nfit_caps = acpi_data_push(structures, sizeof(*nfit_caps)); 348 349 nfit_caps->type = cpu_to_le16(7 /* NVDIMM Platform Capabilities */); 350 nfit_caps->length = cpu_to_le16(sizeof(*nfit_caps)); 351 nfit_caps->highest_cap = 31 - clz32(capabilities); 352 nfit_caps->capabilities = cpu_to_le32(capabilities); 353 } 354 355 static GArray *nvdimm_build_device_structure(NVDIMMState *state) 356 { 357 GSList *device_list = nvdimm_get_device_list(); 358 GArray *structures = g_array_new(false, true /* clear */, 1); 359 360 for (; device_list; device_list = device_list->next) { 361 DeviceState *dev = device_list->data; 362 363 /* build System Physical Address Range Structure. */ 364 nvdimm_build_structure_spa(structures, dev); 365 366 /* 367 * build Memory Device to System Physical Address Range Mapping 368 * Structure. 369 */ 370 nvdimm_build_structure_memdev(structures, dev); 371 372 /* build NVDIMM Control Region Structure. */ 373 nvdimm_build_structure_dcr(structures, dev); 374 } 375 g_slist_free(device_list); 376 377 if (state->persistence) { 378 nvdimm_build_structure_caps(structures, state->persistence); 379 } 380 381 return structures; 382 } 383 384 static void nvdimm_init_fit_buffer(NvdimmFitBuffer *fit_buf) 385 { 386 fit_buf->fit = g_array_new(false, true /* clear */, 1); 387 } 388 389 static void nvdimm_build_fit_buffer(NVDIMMState *state) 390 { 391 NvdimmFitBuffer *fit_buf = &state->fit_buf; 392 393 g_array_free(fit_buf->fit, true); 394 fit_buf->fit = nvdimm_build_device_structure(state); 395 fit_buf->dirty = true; 396 } 397 398 void nvdimm_plug(NVDIMMState *state) 399 { 400 nvdimm_build_fit_buffer(state); 401 } 402 403 static void nvdimm_build_nfit(NVDIMMState *state, GArray *table_offsets, 404 GArray *table_data, BIOSLinker *linker) 405 { 406 NvdimmFitBuffer *fit_buf = &state->fit_buf; 407 unsigned int header; 408 409 acpi_add_table(table_offsets, table_data); 410 411 /* NFIT header. */ 412 header = table_data->len; 413 acpi_data_push(table_data, sizeof(NvdimmNfitHeader)); 414 /* NVDIMM device structures. */ 415 g_array_append_vals(table_data, fit_buf->fit->data, fit_buf->fit->len); 416 417 build_header(linker, table_data, 418 (void *)(table_data->data + header), "NFIT", 419 sizeof(NvdimmNfitHeader) + fit_buf->fit->len, 1, NULL, NULL); 420 } 421 422 #define NVDIMM_DSM_MEMORY_SIZE 4096 423 424 struct NvdimmDsmIn { 425 uint32_t handle; 426 uint32_t revision; 427 uint32_t function; 428 /* the remaining size in the page is used by arg3. */ 429 union { 430 uint8_t arg3[4084]; 431 }; 432 } QEMU_PACKED; 433 typedef struct NvdimmDsmIn NvdimmDsmIn; 434 QEMU_BUILD_BUG_ON(sizeof(NvdimmDsmIn) != NVDIMM_DSM_MEMORY_SIZE); 435 436 struct NvdimmDsmOut { 437 /* the size of buffer filled by QEMU. */ 438 uint32_t len; 439 uint8_t data[4092]; 440 } QEMU_PACKED; 441 typedef struct NvdimmDsmOut NvdimmDsmOut; 442 QEMU_BUILD_BUG_ON(sizeof(NvdimmDsmOut) != NVDIMM_DSM_MEMORY_SIZE); 443 444 struct NvdimmDsmFunc0Out { 445 /* the size of buffer filled by QEMU. */ 446 uint32_t len; 447 uint32_t supported_func; 448 } QEMU_PACKED; 449 typedef struct NvdimmDsmFunc0Out NvdimmDsmFunc0Out; 450 451 struct NvdimmDsmFuncNoPayloadOut { 452 /* the size of buffer filled by QEMU. */ 453 uint32_t len; 454 uint32_t func_ret_status; 455 } QEMU_PACKED; 456 typedef struct NvdimmDsmFuncNoPayloadOut NvdimmDsmFuncNoPayloadOut; 457 458 struct NvdimmFuncGetLabelSizeOut { 459 /* the size of buffer filled by QEMU. */ 460 uint32_t len; 461 uint32_t func_ret_status; /* return status code. */ 462 uint32_t label_size; /* the size of label data area. */ 463 /* 464 * Maximum size of the namespace label data length supported by 465 * the platform in Get/Set Namespace Label Data functions. 466 */ 467 uint32_t max_xfer; 468 } QEMU_PACKED; 469 typedef struct NvdimmFuncGetLabelSizeOut NvdimmFuncGetLabelSizeOut; 470 QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncGetLabelSizeOut) > NVDIMM_DSM_MEMORY_SIZE); 471 472 struct NvdimmFuncGetLabelDataIn { 473 uint32_t offset; /* the offset in the namespace label data area. */ 474 uint32_t length; /* the size of data is to be read via the function. */ 475 } QEMU_PACKED; 476 typedef struct NvdimmFuncGetLabelDataIn NvdimmFuncGetLabelDataIn; 477 QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncGetLabelDataIn) + 478 offsetof(NvdimmDsmIn, arg3) > NVDIMM_DSM_MEMORY_SIZE); 479 480 struct NvdimmFuncGetLabelDataOut { 481 /* the size of buffer filled by QEMU. */ 482 uint32_t len; 483 uint32_t func_ret_status; /* return status code. */ 484 uint8_t out_buf[]; /* the data got via Get Namesapce Label function. */ 485 } QEMU_PACKED; 486 typedef struct NvdimmFuncGetLabelDataOut NvdimmFuncGetLabelDataOut; 487 QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncGetLabelDataOut) > NVDIMM_DSM_MEMORY_SIZE); 488 489 struct NvdimmFuncSetLabelDataIn { 490 uint32_t offset; /* the offset in the namespace label data area. */ 491 uint32_t length; /* the size of data is to be written via the function. */ 492 uint8_t in_buf[]; /* the data written to label data area. */ 493 } QEMU_PACKED; 494 typedef struct NvdimmFuncSetLabelDataIn NvdimmFuncSetLabelDataIn; 495 QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncSetLabelDataIn) + 496 offsetof(NvdimmDsmIn, arg3) > NVDIMM_DSM_MEMORY_SIZE); 497 498 struct NvdimmFuncReadFITIn { 499 uint32_t offset; /* the offset into FIT buffer. */ 500 } QEMU_PACKED; 501 typedef struct NvdimmFuncReadFITIn NvdimmFuncReadFITIn; 502 QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncReadFITIn) + 503 offsetof(NvdimmDsmIn, arg3) > NVDIMM_DSM_MEMORY_SIZE); 504 505 struct NvdimmFuncReadFITOut { 506 /* the size of buffer filled by QEMU. */ 507 uint32_t len; 508 uint32_t func_ret_status; /* return status code. */ 509 uint8_t fit[]; /* the FIT data. */ 510 } QEMU_PACKED; 511 typedef struct NvdimmFuncReadFITOut NvdimmFuncReadFITOut; 512 QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncReadFITOut) > NVDIMM_DSM_MEMORY_SIZE); 513 514 static void 515 nvdimm_dsm_function0(uint32_t supported_func, hwaddr dsm_mem_addr) 516 { 517 NvdimmDsmFunc0Out func0 = { 518 .len = cpu_to_le32(sizeof(func0)), 519 .supported_func = cpu_to_le32(supported_func), 520 }; 521 cpu_physical_memory_write(dsm_mem_addr, &func0, sizeof(func0)); 522 } 523 524 static void 525 nvdimm_dsm_no_payload(uint32_t func_ret_status, hwaddr dsm_mem_addr) 526 { 527 NvdimmDsmFuncNoPayloadOut out = { 528 .len = cpu_to_le32(sizeof(out)), 529 .func_ret_status = cpu_to_le32(func_ret_status), 530 }; 531 cpu_physical_memory_write(dsm_mem_addr, &out, sizeof(out)); 532 } 533 534 #define NVDIMM_DSM_RET_STATUS_SUCCESS 0 /* Success */ 535 #define NVDIMM_DSM_RET_STATUS_UNSUPPORT 1 /* Not Supported */ 536 #define NVDIMM_DSM_RET_STATUS_NOMEMDEV 2 /* Non-Existing Memory Device */ 537 #define NVDIMM_DSM_RET_STATUS_INVALID 3 /* Invalid Input Parameters */ 538 #define NVDIMM_DSM_RET_STATUS_FIT_CHANGED 0x100 /* FIT Changed */ 539 540 #define NVDIMM_QEMU_RSVD_HANDLE_ROOT 0x10000 541 542 /* Read FIT data, defined in docs/specs/acpi_nvdimm.txt. */ 543 static void nvdimm_dsm_func_read_fit(NVDIMMState *state, NvdimmDsmIn *in, 544 hwaddr dsm_mem_addr) 545 { 546 NvdimmFitBuffer *fit_buf = &state->fit_buf; 547 NvdimmFuncReadFITIn *read_fit; 548 NvdimmFuncReadFITOut *read_fit_out; 549 GArray *fit; 550 uint32_t read_len = 0, func_ret_status; 551 int size; 552 553 read_fit = (NvdimmFuncReadFITIn *)in->arg3; 554 read_fit->offset = le32_to_cpu(read_fit->offset); 555 556 fit = fit_buf->fit; 557 558 nvdimm_debug("Read FIT: offset %#x FIT size %#x Dirty %s.\n", 559 read_fit->offset, fit->len, fit_buf->dirty ? "Yes" : "No"); 560 561 if (read_fit->offset > fit->len) { 562 func_ret_status = NVDIMM_DSM_RET_STATUS_INVALID; 563 goto exit; 564 } 565 566 /* It is the first time to read FIT. */ 567 if (!read_fit->offset) { 568 fit_buf->dirty = false; 569 } else if (fit_buf->dirty) { /* FIT has been changed during RFIT. */ 570 func_ret_status = NVDIMM_DSM_RET_STATUS_FIT_CHANGED; 571 goto exit; 572 } 573 574 func_ret_status = NVDIMM_DSM_RET_STATUS_SUCCESS; 575 read_len = MIN(fit->len - read_fit->offset, 576 NVDIMM_DSM_MEMORY_SIZE - sizeof(NvdimmFuncReadFITOut)); 577 578 exit: 579 size = sizeof(NvdimmFuncReadFITOut) + read_len; 580 read_fit_out = g_malloc(size); 581 582 read_fit_out->len = cpu_to_le32(size); 583 read_fit_out->func_ret_status = cpu_to_le32(func_ret_status); 584 memcpy(read_fit_out->fit, fit->data + read_fit->offset, read_len); 585 586 cpu_physical_memory_write(dsm_mem_addr, read_fit_out, size); 587 588 g_free(read_fit_out); 589 } 590 591 static void 592 nvdimm_dsm_handle_reserved_root_method(NVDIMMState *state, 593 NvdimmDsmIn *in, hwaddr dsm_mem_addr) 594 { 595 switch (in->function) { 596 case 0x0: 597 nvdimm_dsm_function0(0x1 | 1 << 1 /* Read FIT */, dsm_mem_addr); 598 return; 599 case 0x1 /* Read FIT */: 600 nvdimm_dsm_func_read_fit(state, in, dsm_mem_addr); 601 return; 602 } 603 604 nvdimm_dsm_no_payload(NVDIMM_DSM_RET_STATUS_UNSUPPORT, dsm_mem_addr); 605 } 606 607 static void nvdimm_dsm_root(NvdimmDsmIn *in, hwaddr dsm_mem_addr) 608 { 609 /* 610 * function 0 is called to inquire which functions are supported by 611 * OSPM 612 */ 613 if (!in->function) { 614 nvdimm_dsm_function0(0 /* No function supported other than 615 function 0 */, dsm_mem_addr); 616 return; 617 } 618 619 /* No function except function 0 is supported yet. */ 620 nvdimm_dsm_no_payload(NVDIMM_DSM_RET_STATUS_UNSUPPORT, dsm_mem_addr); 621 } 622 623 /* 624 * the max transfer size is the max size transferred by both a 625 * 'Get Namespace Label Data' function and a 'Set Namespace Label Data' 626 * function. 627 */ 628 static uint32_t nvdimm_get_max_xfer_label_size(void) 629 { 630 uint32_t max_get_size, max_set_size, dsm_memory_size; 631 632 dsm_memory_size = NVDIMM_DSM_MEMORY_SIZE; 633 634 /* 635 * the max data ACPI can read one time which is transferred by 636 * the response of 'Get Namespace Label Data' function. 637 */ 638 max_get_size = dsm_memory_size - sizeof(NvdimmFuncGetLabelDataOut); 639 640 /* 641 * the max data ACPI can write one time which is transferred by 642 * 'Set Namespace Label Data' function. 643 */ 644 max_set_size = dsm_memory_size - offsetof(NvdimmDsmIn, arg3) - 645 sizeof(NvdimmFuncSetLabelDataIn); 646 647 return MIN(max_get_size, max_set_size); 648 } 649 650 /* 651 * DSM Spec Rev1 4.4 Get Namespace Label Size (Function Index 4). 652 * 653 * It gets the size of Namespace Label data area and the max data size 654 * that Get/Set Namespace Label Data functions can transfer. 655 */ 656 static void nvdimm_dsm_label_size(NVDIMMDevice *nvdimm, hwaddr dsm_mem_addr) 657 { 658 NvdimmFuncGetLabelSizeOut label_size_out = { 659 .len = cpu_to_le32(sizeof(label_size_out)), 660 }; 661 uint32_t label_size, mxfer; 662 663 label_size = nvdimm->label_size; 664 mxfer = nvdimm_get_max_xfer_label_size(); 665 666 nvdimm_debug("label_size %#x, max_xfer %#x.\n", label_size, mxfer); 667 668 label_size_out.func_ret_status = cpu_to_le32(NVDIMM_DSM_RET_STATUS_SUCCESS); 669 label_size_out.label_size = cpu_to_le32(label_size); 670 label_size_out.max_xfer = cpu_to_le32(mxfer); 671 672 cpu_physical_memory_write(dsm_mem_addr, &label_size_out, 673 sizeof(label_size_out)); 674 } 675 676 static uint32_t nvdimm_rw_label_data_check(NVDIMMDevice *nvdimm, 677 uint32_t offset, uint32_t length) 678 { 679 uint32_t ret = NVDIMM_DSM_RET_STATUS_INVALID; 680 681 if (offset + length < offset) { 682 nvdimm_debug("offset %#x + length %#x is overflow.\n", offset, 683 length); 684 return ret; 685 } 686 687 if (nvdimm->label_size < offset + length) { 688 nvdimm_debug("position %#x is beyond label data (len = %" PRIx64 ").\n", 689 offset + length, nvdimm->label_size); 690 return ret; 691 } 692 693 if (length > nvdimm_get_max_xfer_label_size()) { 694 nvdimm_debug("length (%#x) is larger than max_xfer (%#x).\n", 695 length, nvdimm_get_max_xfer_label_size()); 696 return ret; 697 } 698 699 return NVDIMM_DSM_RET_STATUS_SUCCESS; 700 } 701 702 /* 703 * DSM Spec Rev1 4.5 Get Namespace Label Data (Function Index 5). 704 */ 705 static void nvdimm_dsm_get_label_data(NVDIMMDevice *nvdimm, NvdimmDsmIn *in, 706 hwaddr dsm_mem_addr) 707 { 708 NVDIMMClass *nvc = NVDIMM_GET_CLASS(nvdimm); 709 NvdimmFuncGetLabelDataIn *get_label_data; 710 NvdimmFuncGetLabelDataOut *get_label_data_out; 711 uint32_t status; 712 int size; 713 714 get_label_data = (NvdimmFuncGetLabelDataIn *)in->arg3; 715 get_label_data->offset = le32_to_cpu(get_label_data->offset); 716 get_label_data->length = le32_to_cpu(get_label_data->length); 717 718 nvdimm_debug("Read Label Data: offset %#x length %#x.\n", 719 get_label_data->offset, get_label_data->length); 720 721 status = nvdimm_rw_label_data_check(nvdimm, get_label_data->offset, 722 get_label_data->length); 723 if (status != NVDIMM_DSM_RET_STATUS_SUCCESS) { 724 nvdimm_dsm_no_payload(status, dsm_mem_addr); 725 return; 726 } 727 728 size = sizeof(*get_label_data_out) + get_label_data->length; 729 assert(size <= NVDIMM_DSM_MEMORY_SIZE); 730 get_label_data_out = g_malloc(size); 731 732 get_label_data_out->len = cpu_to_le32(size); 733 get_label_data_out->func_ret_status = 734 cpu_to_le32(NVDIMM_DSM_RET_STATUS_SUCCESS); 735 nvc->read_label_data(nvdimm, get_label_data_out->out_buf, 736 get_label_data->length, get_label_data->offset); 737 738 cpu_physical_memory_write(dsm_mem_addr, get_label_data_out, size); 739 g_free(get_label_data_out); 740 } 741 742 /* 743 * DSM Spec Rev1 4.6 Set Namespace Label Data (Function Index 6). 744 */ 745 static void nvdimm_dsm_set_label_data(NVDIMMDevice *nvdimm, NvdimmDsmIn *in, 746 hwaddr dsm_mem_addr) 747 { 748 NVDIMMClass *nvc = NVDIMM_GET_CLASS(nvdimm); 749 NvdimmFuncSetLabelDataIn *set_label_data; 750 uint32_t status; 751 752 set_label_data = (NvdimmFuncSetLabelDataIn *)in->arg3; 753 754 set_label_data->offset = le32_to_cpu(set_label_data->offset); 755 set_label_data->length = le32_to_cpu(set_label_data->length); 756 757 nvdimm_debug("Write Label Data: offset %#x length %#x.\n", 758 set_label_data->offset, set_label_data->length); 759 760 status = nvdimm_rw_label_data_check(nvdimm, set_label_data->offset, 761 set_label_data->length); 762 if (status != NVDIMM_DSM_RET_STATUS_SUCCESS) { 763 nvdimm_dsm_no_payload(status, dsm_mem_addr); 764 return; 765 } 766 767 assert(offsetof(NvdimmDsmIn, arg3) + sizeof(*set_label_data) + 768 set_label_data->length <= NVDIMM_DSM_MEMORY_SIZE); 769 770 nvc->write_label_data(nvdimm, set_label_data->in_buf, 771 set_label_data->length, set_label_data->offset); 772 nvdimm_dsm_no_payload(NVDIMM_DSM_RET_STATUS_SUCCESS, dsm_mem_addr); 773 } 774 775 static void nvdimm_dsm_device(NvdimmDsmIn *in, hwaddr dsm_mem_addr) 776 { 777 NVDIMMDevice *nvdimm = nvdimm_get_device_by_handle(in->handle); 778 779 /* See the comments in nvdimm_dsm_root(). */ 780 if (!in->function) { 781 uint32_t supported_func = 0; 782 783 if (nvdimm && nvdimm->label_size) { 784 supported_func |= 0x1 /* Bit 0 indicates whether there is 785 support for any functions other 786 than function 0. */ | 787 1 << 4 /* Get Namespace Label Size */ | 788 1 << 5 /* Get Namespace Label Data */ | 789 1 << 6 /* Set Namespace Label Data */; 790 } 791 nvdimm_dsm_function0(supported_func, dsm_mem_addr); 792 return; 793 } 794 795 if (!nvdimm) { 796 nvdimm_dsm_no_payload(NVDIMM_DSM_RET_STATUS_NOMEMDEV, 797 dsm_mem_addr); 798 return; 799 } 800 801 /* Encode DSM function according to DSM Spec Rev1. */ 802 switch (in->function) { 803 case 4 /* Get Namespace Label Size */: 804 if (nvdimm->label_size) { 805 nvdimm_dsm_label_size(nvdimm, dsm_mem_addr); 806 return; 807 } 808 break; 809 case 5 /* Get Namespace Label Data */: 810 if (nvdimm->label_size) { 811 nvdimm_dsm_get_label_data(nvdimm, in, dsm_mem_addr); 812 return; 813 } 814 break; 815 case 0x6 /* Set Namespace Label Data */: 816 if (nvdimm->label_size) { 817 nvdimm_dsm_set_label_data(nvdimm, in, dsm_mem_addr); 818 return; 819 } 820 break; 821 } 822 823 nvdimm_dsm_no_payload(NVDIMM_DSM_RET_STATUS_UNSUPPORT, dsm_mem_addr); 824 } 825 826 static uint64_t 827 nvdimm_dsm_read(void *opaque, hwaddr addr, unsigned size) 828 { 829 nvdimm_debug("BUG: we never read _DSM IO Port.\n"); 830 return 0; 831 } 832 833 static void 834 nvdimm_dsm_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) 835 { 836 NVDIMMState *state = opaque; 837 NvdimmDsmIn *in; 838 hwaddr dsm_mem_addr = val; 839 840 nvdimm_debug("dsm memory address %#" HWADDR_PRIx ".\n", dsm_mem_addr); 841 842 /* 843 * The DSM memory is mapped to guest address space so an evil guest 844 * can change its content while we are doing DSM emulation. Avoid 845 * this by copying DSM memory to QEMU local memory. 846 */ 847 in = g_new(NvdimmDsmIn, 1); 848 cpu_physical_memory_read(dsm_mem_addr, in, sizeof(*in)); 849 850 in->revision = le32_to_cpu(in->revision); 851 in->function = le32_to_cpu(in->function); 852 in->handle = le32_to_cpu(in->handle); 853 854 nvdimm_debug("Revision %#x Handler %#x Function %#x.\n", in->revision, 855 in->handle, in->function); 856 857 if (in->revision != 0x1 /* Currently we only support DSM Spec Rev1. */) { 858 nvdimm_debug("Revision %#x is not supported, expect %#x.\n", 859 in->revision, 0x1); 860 nvdimm_dsm_no_payload(NVDIMM_DSM_RET_STATUS_UNSUPPORT, dsm_mem_addr); 861 goto exit; 862 } 863 864 if (in->handle == NVDIMM_QEMU_RSVD_HANDLE_ROOT) { 865 nvdimm_dsm_handle_reserved_root_method(state, in, dsm_mem_addr); 866 goto exit; 867 } 868 869 /* Handle 0 is reserved for NVDIMM Root Device. */ 870 if (!in->handle) { 871 nvdimm_dsm_root(in, dsm_mem_addr); 872 goto exit; 873 } 874 875 nvdimm_dsm_device(in, dsm_mem_addr); 876 877 exit: 878 g_free(in); 879 } 880 881 static const MemoryRegionOps nvdimm_dsm_ops = { 882 .read = nvdimm_dsm_read, 883 .write = nvdimm_dsm_write, 884 .endianness = DEVICE_LITTLE_ENDIAN, 885 .valid = { 886 .min_access_size = 4, 887 .max_access_size = 4, 888 }, 889 }; 890 891 void nvdimm_acpi_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev) 892 { 893 if (dev->hotplugged) { 894 acpi_send_event(DEVICE(hotplug_dev), ACPI_NVDIMM_HOTPLUG_STATUS); 895 } 896 } 897 898 void nvdimm_init_acpi_state(NVDIMMState *state, MemoryRegion *io, 899 struct AcpiGenericAddress dsm_io, 900 FWCfgState *fw_cfg, Object *owner) 901 { 902 state->dsm_io = dsm_io; 903 memory_region_init_io(&state->io_mr, owner, &nvdimm_dsm_ops, state, 904 "nvdimm-acpi-io", dsm_io.bit_width >> 3); 905 memory_region_add_subregion(io, dsm_io.address, &state->io_mr); 906 907 state->dsm_mem = g_array_new(false, true /* clear */, 1); 908 acpi_data_push(state->dsm_mem, sizeof(NvdimmDsmIn)); 909 fw_cfg_add_file(fw_cfg, NVDIMM_DSM_MEM_FILE, state->dsm_mem->data, 910 state->dsm_mem->len); 911 912 nvdimm_init_fit_buffer(&state->fit_buf); 913 } 914 915 #define NVDIMM_COMMON_DSM "NCAL" 916 #define NVDIMM_ACPI_MEM_ADDR "MEMA" 917 918 #define NVDIMM_DSM_MEMORY "NRAM" 919 #define NVDIMM_DSM_IOPORT "NPIO" 920 921 #define NVDIMM_DSM_NOTIFY "NTFI" 922 #define NVDIMM_DSM_HANDLE "HDLE" 923 #define NVDIMM_DSM_REVISION "REVS" 924 #define NVDIMM_DSM_FUNCTION "FUNC" 925 #define NVDIMM_DSM_ARG3 "FARG" 926 927 #define NVDIMM_DSM_OUT_BUF_SIZE "RLEN" 928 #define NVDIMM_DSM_OUT_BUF "ODAT" 929 930 #define NVDIMM_DSM_RFIT_STATUS "RSTA" 931 932 #define NVDIMM_QEMU_RSVD_UUID "648B9CF2-CDA1-4312-8AD9-49C4AF32BD62" 933 934 static void nvdimm_build_common_dsm(Aml *dev, 935 NVDIMMState *nvdimm_state) 936 { 937 Aml *method, *ifctx, *function, *handle, *uuid, *dsm_mem, *elsectx2; 938 Aml *elsectx, *unsupport, *unpatched, *expected_uuid, *uuid_invalid; 939 Aml *pckg, *pckg_index, *pckg_buf, *field, *dsm_out_buf, *dsm_out_buf_size; 940 Aml *whilectx, *offset; 941 uint8_t byte_list[1]; 942 AmlRegionSpace rs; 943 944 method = aml_method(NVDIMM_COMMON_DSM, 5, AML_SERIALIZED); 945 uuid = aml_arg(0); 946 function = aml_arg(2); 947 handle = aml_arg(4); 948 dsm_mem = aml_local(6); 949 dsm_out_buf = aml_local(7); 950 951 aml_append(method, aml_store(aml_name(NVDIMM_ACPI_MEM_ADDR), dsm_mem)); 952 953 if (nvdimm_state->dsm_io.space_id == AML_AS_SYSTEM_IO) { 954 rs = AML_SYSTEM_IO; 955 } else { 956 rs = AML_SYSTEM_MEMORY; 957 } 958 959 /* map DSM memory and IO into ACPI namespace. */ 960 aml_append(method, aml_operation_region(NVDIMM_DSM_IOPORT, rs, 961 aml_int(nvdimm_state->dsm_io.address), 962 nvdimm_state->dsm_io.bit_width >> 3)); 963 aml_append(method, aml_operation_region(NVDIMM_DSM_MEMORY, 964 AML_SYSTEM_MEMORY, dsm_mem, sizeof(NvdimmDsmIn))); 965 966 /* 967 * DSM notifier: 968 * NVDIMM_DSM_NOTIFY: write the address of DSM memory and notify QEMU to 969 * emulate the access. 970 * 971 * It is the IO port so that accessing them will cause VM-exit, the 972 * control will be transferred to QEMU. 973 */ 974 field = aml_field(NVDIMM_DSM_IOPORT, AML_DWORD_ACC, AML_NOLOCK, 975 AML_PRESERVE); 976 aml_append(field, aml_named_field(NVDIMM_DSM_NOTIFY, 977 nvdimm_state->dsm_io.bit_width)); 978 aml_append(method, field); 979 980 /* 981 * DSM input: 982 * NVDIMM_DSM_HANDLE: store device's handle, it's zero if the _DSM call 983 * happens on NVDIMM Root Device. 984 * NVDIMM_DSM_REVISION: store the Arg1 of _DSM call. 985 * NVDIMM_DSM_FUNCTION: store the Arg2 of _DSM call. 986 * NVDIMM_DSM_ARG3: store the Arg3 of _DSM call which is a Package 987 * containing function-specific arguments. 988 * 989 * They are RAM mapping on host so that these accesses never cause 990 * VM-EXIT. 991 */ 992 field = aml_field(NVDIMM_DSM_MEMORY, AML_DWORD_ACC, AML_NOLOCK, 993 AML_PRESERVE); 994 aml_append(field, aml_named_field(NVDIMM_DSM_HANDLE, 995 sizeof(typeof_field(NvdimmDsmIn, handle)) * BITS_PER_BYTE)); 996 aml_append(field, aml_named_field(NVDIMM_DSM_REVISION, 997 sizeof(typeof_field(NvdimmDsmIn, revision)) * BITS_PER_BYTE)); 998 aml_append(field, aml_named_field(NVDIMM_DSM_FUNCTION, 999 sizeof(typeof_field(NvdimmDsmIn, function)) * BITS_PER_BYTE)); 1000 aml_append(field, aml_named_field(NVDIMM_DSM_ARG3, 1001 (sizeof(NvdimmDsmIn) - offsetof(NvdimmDsmIn, arg3)) * BITS_PER_BYTE)); 1002 aml_append(method, field); 1003 1004 /* 1005 * DSM output: 1006 * NVDIMM_DSM_OUT_BUF_SIZE: the size of the buffer filled by QEMU. 1007 * NVDIMM_DSM_OUT_BUF: the buffer QEMU uses to store the result. 1008 * 1009 * Since the page is reused by both input and out, the input data 1010 * will be lost after storing new result into ODAT so we should fetch 1011 * all the input data before writing the result. 1012 */ 1013 field = aml_field(NVDIMM_DSM_MEMORY, AML_DWORD_ACC, AML_NOLOCK, 1014 AML_PRESERVE); 1015 aml_append(field, aml_named_field(NVDIMM_DSM_OUT_BUF_SIZE, 1016 sizeof(typeof_field(NvdimmDsmOut, len)) * BITS_PER_BYTE)); 1017 aml_append(field, aml_named_field(NVDIMM_DSM_OUT_BUF, 1018 (sizeof(NvdimmDsmOut) - offsetof(NvdimmDsmOut, data)) * BITS_PER_BYTE)); 1019 aml_append(method, field); 1020 1021 /* 1022 * do not support any method if DSM memory address has not been 1023 * patched. 1024 */ 1025 unpatched = aml_equal(dsm_mem, aml_int(0x0)); 1026 1027 expected_uuid = aml_local(0); 1028 1029 ifctx = aml_if(aml_equal(handle, aml_int(0x0))); 1030 aml_append(ifctx, aml_store( 1031 aml_touuid("2F10E7A4-9E91-11E4-89D3-123B93F75CBA") 1032 /* UUID for NVDIMM Root Device */, expected_uuid)); 1033 aml_append(method, ifctx); 1034 elsectx = aml_else(); 1035 ifctx = aml_if(aml_equal(handle, aml_int(NVDIMM_QEMU_RSVD_HANDLE_ROOT))); 1036 aml_append(ifctx, aml_store(aml_touuid(NVDIMM_QEMU_RSVD_UUID 1037 /* UUID for QEMU internal use */), expected_uuid)); 1038 aml_append(elsectx, ifctx); 1039 elsectx2 = aml_else(); 1040 aml_append(elsectx2, aml_store( 1041 aml_touuid("4309AC30-0D11-11E4-9191-0800200C9A66") 1042 /* UUID for NVDIMM Devices */, expected_uuid)); 1043 aml_append(elsectx, elsectx2); 1044 aml_append(method, elsectx); 1045 1046 uuid_invalid = aml_lnot(aml_equal(uuid, expected_uuid)); 1047 1048 unsupport = aml_if(aml_or(unpatched, uuid_invalid, NULL)); 1049 1050 /* 1051 * function 0 is called to inquire what functions are supported by 1052 * OSPM 1053 */ 1054 ifctx = aml_if(aml_equal(function, aml_int(0))); 1055 byte_list[0] = 0 /* No function Supported */; 1056 aml_append(ifctx, aml_return(aml_buffer(1, byte_list))); 1057 aml_append(unsupport, ifctx); 1058 1059 /* No function is supported yet. */ 1060 byte_list[0] = NVDIMM_DSM_RET_STATUS_UNSUPPORT; 1061 aml_append(unsupport, aml_return(aml_buffer(1, byte_list))); 1062 aml_append(method, unsupport); 1063 1064 /* 1065 * The HDLE indicates the DSM function is issued from which device, 1066 * it reserves 0 for root device and is the handle for NVDIMM devices. 1067 * See the comments in nvdimm_slot_to_handle(). 1068 */ 1069 aml_append(method, aml_store(handle, aml_name(NVDIMM_DSM_HANDLE))); 1070 aml_append(method, aml_store(aml_arg(1), aml_name(NVDIMM_DSM_REVISION))); 1071 aml_append(method, aml_store(function, aml_name(NVDIMM_DSM_FUNCTION))); 1072 1073 /* 1074 * The fourth parameter (Arg3) of _DSM is a package which contains 1075 * a buffer, the layout of the buffer is specified by UUID (Arg0), 1076 * Revision ID (Arg1) and Function Index (Arg2) which are documented 1077 * in the DSM Spec. 1078 */ 1079 pckg = aml_arg(3); 1080 ifctx = aml_if(aml_and(aml_equal(aml_object_type(pckg), 1081 aml_int(4 /* Package */)) /* It is a Package? */, 1082 aml_equal(aml_sizeof(pckg), aml_int(1)) /* 1 element? */, 1083 NULL)); 1084 1085 pckg_index = aml_local(2); 1086 pckg_buf = aml_local(3); 1087 aml_append(ifctx, aml_store(aml_index(pckg, aml_int(0)), pckg_index)); 1088 aml_append(ifctx, aml_store(aml_derefof(pckg_index), pckg_buf)); 1089 aml_append(ifctx, aml_store(pckg_buf, aml_name(NVDIMM_DSM_ARG3))); 1090 aml_append(method, ifctx); 1091 1092 /* 1093 * tell QEMU about the real address of DSM memory, then QEMU 1094 * gets the control and fills the result in DSM memory. 1095 */ 1096 aml_append(method, aml_store(dsm_mem, aml_name(NVDIMM_DSM_NOTIFY))); 1097 1098 dsm_out_buf_size = aml_local(1); 1099 /* RLEN is not included in the payload returned to guest. */ 1100 aml_append(method, aml_subtract(aml_name(NVDIMM_DSM_OUT_BUF_SIZE), 1101 aml_int(4), dsm_out_buf_size)); 1102 1103 /* 1104 * As per ACPI spec 6.3, Table 19-419 Object Conversion Rules, if 1105 * the Buffer Field <= to the size of an Integer (in bits), it will 1106 * be treated as an integer. Moreover, the integer size depends on 1107 * DSDT tables revision number. If revision number is < 2, integer 1108 * size is 32 bits, otherwise it is 64 bits. 1109 * Because of this CreateField() canot be used if RLEN < Integer Size. 1110 * 1111 * Also please note that APCI ASL operator SizeOf() doesn't support 1112 * Integer and there isn't any other way to figure out the Integer 1113 * size. Hence we assume 8 byte as Integer size and if RLEN < 8 bytes, 1114 * build dsm_out_buf byte by byte. 1115 */ 1116 ifctx = aml_if(aml_lless(dsm_out_buf_size, aml_int(8))); 1117 offset = aml_local(2); 1118 aml_append(ifctx, aml_store(aml_int(0), offset)); 1119 aml_append(ifctx, aml_name_decl("TBUF", aml_buffer(1, NULL))); 1120 aml_append(ifctx, aml_store(aml_buffer(0, NULL), dsm_out_buf)); 1121 1122 whilectx = aml_while(aml_lless(offset, dsm_out_buf_size)); 1123 /* Copy 1 byte at offset from ODAT to temporary buffer(TBUF). */ 1124 aml_append(whilectx, aml_store(aml_derefof(aml_index( 1125 aml_name(NVDIMM_DSM_OUT_BUF), offset)), 1126 aml_index(aml_name("TBUF"), aml_int(0)))); 1127 aml_append(whilectx, aml_concatenate(dsm_out_buf, aml_name("TBUF"), 1128 dsm_out_buf)); 1129 aml_append(whilectx, aml_increment(offset)); 1130 aml_append(ifctx, whilectx); 1131 1132 aml_append(ifctx, aml_return(dsm_out_buf)); 1133 aml_append(method, ifctx); 1134 1135 /* If RLEN >= Integer size, just use CreateField() operator */ 1136 aml_append(method, aml_store(aml_shiftleft(dsm_out_buf_size, aml_int(3)), 1137 dsm_out_buf_size)); 1138 aml_append(method, aml_create_field(aml_name(NVDIMM_DSM_OUT_BUF), 1139 aml_int(0), dsm_out_buf_size, "OBUF")); 1140 aml_append(method, aml_return(aml_name("OBUF"))); 1141 1142 aml_append(dev, method); 1143 } 1144 1145 static void nvdimm_build_device_dsm(Aml *dev, uint32_t handle) 1146 { 1147 Aml *method; 1148 1149 method = aml_method("_DSM", 4, AML_NOTSERIALIZED); 1150 aml_append(method, aml_return(aml_call5(NVDIMM_COMMON_DSM, aml_arg(0), 1151 aml_arg(1), aml_arg(2), aml_arg(3), 1152 aml_int(handle)))); 1153 aml_append(dev, method); 1154 } 1155 1156 static void nvdimm_build_fit(Aml *dev) 1157 { 1158 Aml *method, *pkg, *buf, *buf_size, *offset, *call_result; 1159 Aml *whilectx, *ifcond, *ifctx, *elsectx, *fit; 1160 1161 buf = aml_local(0); 1162 buf_size = aml_local(1); 1163 fit = aml_local(2); 1164 1165 aml_append(dev, aml_name_decl(NVDIMM_DSM_RFIT_STATUS, aml_int(0))); 1166 1167 /* build helper function, RFIT. */ 1168 method = aml_method("RFIT", 1, AML_SERIALIZED); 1169 aml_append(method, aml_name_decl("OFST", aml_int(0))); 1170 1171 /* prepare input package. */ 1172 pkg = aml_package(1); 1173 aml_append(method, aml_store(aml_arg(0), aml_name("OFST"))); 1174 aml_append(pkg, aml_name("OFST")); 1175 1176 /* call Read_FIT function. */ 1177 call_result = aml_call5(NVDIMM_COMMON_DSM, 1178 aml_touuid(NVDIMM_QEMU_RSVD_UUID), 1179 aml_int(1) /* Revision 1 */, 1180 aml_int(0x1) /* Read FIT */, 1181 pkg, aml_int(NVDIMM_QEMU_RSVD_HANDLE_ROOT)); 1182 aml_append(method, aml_store(call_result, buf)); 1183 1184 /* handle _DSM result. */ 1185 aml_append(method, aml_create_dword_field(buf, 1186 aml_int(0) /* offset at byte 0 */, "STAU")); 1187 1188 aml_append(method, aml_store(aml_name("STAU"), 1189 aml_name(NVDIMM_DSM_RFIT_STATUS))); 1190 1191 /* if something is wrong during _DSM. */ 1192 ifcond = aml_equal(aml_int(NVDIMM_DSM_RET_STATUS_SUCCESS), 1193 aml_name("STAU")); 1194 ifctx = aml_if(aml_lnot(ifcond)); 1195 aml_append(ifctx, aml_return(aml_buffer(0, NULL))); 1196 aml_append(method, ifctx); 1197 1198 aml_append(method, aml_store(aml_sizeof(buf), buf_size)); 1199 aml_append(method, aml_subtract(buf_size, 1200 aml_int(4) /* the size of "STAU" */, 1201 buf_size)); 1202 1203 /* if we read the end of fit. */ 1204 ifctx = aml_if(aml_equal(buf_size, aml_int(0))); 1205 aml_append(ifctx, aml_return(aml_buffer(0, NULL))); 1206 aml_append(method, ifctx); 1207 1208 aml_append(method, aml_create_field(buf, 1209 aml_int(4 * BITS_PER_BYTE), /* offset at byte 4.*/ 1210 aml_shiftleft(buf_size, aml_int(3)), "BUFF")); 1211 aml_append(method, aml_return(aml_name("BUFF"))); 1212 aml_append(dev, method); 1213 1214 /* build _FIT. */ 1215 method = aml_method("_FIT", 0, AML_SERIALIZED); 1216 offset = aml_local(3); 1217 1218 aml_append(method, aml_store(aml_buffer(0, NULL), fit)); 1219 aml_append(method, aml_store(aml_int(0), offset)); 1220 1221 whilectx = aml_while(aml_int(1)); 1222 aml_append(whilectx, aml_store(aml_call1("RFIT", offset), buf)); 1223 aml_append(whilectx, aml_store(aml_sizeof(buf), buf_size)); 1224 1225 /* 1226 * if fit buffer was changed during RFIT, read from the beginning 1227 * again. 1228 */ 1229 ifctx = aml_if(aml_equal(aml_name(NVDIMM_DSM_RFIT_STATUS), 1230 aml_int(NVDIMM_DSM_RET_STATUS_FIT_CHANGED))); 1231 aml_append(ifctx, aml_store(aml_buffer(0, NULL), fit)); 1232 aml_append(ifctx, aml_store(aml_int(0), offset)); 1233 aml_append(whilectx, ifctx); 1234 1235 elsectx = aml_else(); 1236 1237 /* finish fit read if no data is read out. */ 1238 ifctx = aml_if(aml_equal(buf_size, aml_int(0))); 1239 aml_append(ifctx, aml_return(fit)); 1240 aml_append(elsectx, ifctx); 1241 1242 /* update the offset. */ 1243 aml_append(elsectx, aml_add(offset, buf_size, offset)); 1244 /* append the data we read out to the fit buffer. */ 1245 aml_append(elsectx, aml_concatenate(fit, buf, fit)); 1246 aml_append(whilectx, elsectx); 1247 aml_append(method, whilectx); 1248 1249 aml_append(dev, method); 1250 } 1251 1252 static void nvdimm_build_nvdimm_devices(Aml *root_dev, uint32_t ram_slots) 1253 { 1254 uint32_t slot; 1255 1256 for (slot = 0; slot < ram_slots; slot++) { 1257 uint32_t handle = nvdimm_slot_to_handle(slot); 1258 Aml *nvdimm_dev; 1259 1260 nvdimm_dev = aml_device("NV%02X", slot); 1261 1262 /* 1263 * ACPI 6.0: 9.20 NVDIMM Devices: 1264 * 1265 * _ADR object that is used to supply OSPM with unique address 1266 * of the NVDIMM device. This is done by returning the NFIT Device 1267 * handle that is used to identify the associated entries in ACPI 1268 * table NFIT or _FIT. 1269 */ 1270 aml_append(nvdimm_dev, aml_name_decl("_ADR", aml_int(handle))); 1271 1272 nvdimm_build_device_dsm(nvdimm_dev, handle); 1273 aml_append(root_dev, nvdimm_dev); 1274 } 1275 } 1276 1277 static void nvdimm_build_ssdt(GArray *table_offsets, GArray *table_data, 1278 BIOSLinker *linker, 1279 NVDIMMState *nvdimm_state, 1280 uint32_t ram_slots) 1281 { 1282 Aml *ssdt, *sb_scope, *dev; 1283 int mem_addr_offset, nvdimm_ssdt; 1284 1285 acpi_add_table(table_offsets, table_data); 1286 1287 ssdt = init_aml_allocator(); 1288 acpi_data_push(ssdt->buf, sizeof(AcpiTableHeader)); 1289 1290 sb_scope = aml_scope("\\_SB"); 1291 1292 dev = aml_device("NVDR"); 1293 1294 /* 1295 * ACPI 6.0: 9.20 NVDIMM Devices: 1296 * 1297 * The ACPI Name Space device uses _HID of ACPI0012 to identify the root 1298 * NVDIMM interface device. Platform firmware is required to contain one 1299 * such device in _SB scope if NVDIMMs support is exposed by platform to 1300 * OSPM. 1301 * For each NVDIMM present or intended to be supported by platform, 1302 * platform firmware also exposes an ACPI Namespace Device under the 1303 * root device. 1304 */ 1305 aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0012"))); 1306 1307 nvdimm_build_common_dsm(dev, nvdimm_state); 1308 1309 /* 0 is reserved for root device. */ 1310 nvdimm_build_device_dsm(dev, 0); 1311 nvdimm_build_fit(dev); 1312 1313 nvdimm_build_nvdimm_devices(dev, ram_slots); 1314 1315 aml_append(sb_scope, dev); 1316 aml_append(ssdt, sb_scope); 1317 1318 nvdimm_ssdt = table_data->len; 1319 1320 /* copy AML table into ACPI tables blob and patch header there */ 1321 g_array_append_vals(table_data, ssdt->buf->data, ssdt->buf->len); 1322 mem_addr_offset = build_append_named_dword(table_data, 1323 NVDIMM_ACPI_MEM_ADDR); 1324 1325 bios_linker_loader_alloc(linker, 1326 NVDIMM_DSM_MEM_FILE, nvdimm_state->dsm_mem, 1327 sizeof(NvdimmDsmIn), false /* high memory */); 1328 bios_linker_loader_add_pointer(linker, 1329 ACPI_BUILD_TABLE_FILE, mem_addr_offset, sizeof(uint32_t), 1330 NVDIMM_DSM_MEM_FILE, 0); 1331 build_header(linker, table_data, 1332 (void *)(table_data->data + nvdimm_ssdt), 1333 "SSDT", table_data->len - nvdimm_ssdt, 1, NULL, "NVDIMM"); 1334 free_aml_allocator(); 1335 } 1336 1337 void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data, 1338 BIOSLinker *linker, NVDIMMState *state, 1339 uint32_t ram_slots) 1340 { 1341 GSList *device_list; 1342 1343 /* no nvdimm device can be plugged. */ 1344 if (!ram_slots) { 1345 return; 1346 } 1347 1348 nvdimm_build_ssdt(table_offsets, table_data, linker, state, 1349 ram_slots); 1350 1351 device_list = nvdimm_get_device_list(); 1352 /* no NVDIMM device is plugged. */ 1353 if (!device_list) { 1354 return; 1355 } 1356 1357 nvdimm_build_nfit(state, table_offsets, table_data, linker); 1358 g_slist_free(device_list); 1359 } 1360