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