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