cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

nvdimm.c (47988B)


      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}