nvdimm.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Non-Volatile Dual In-line Memory Module Virtualization Implementation
  3. *
  4. * Copyright(C) 2015 Intel Corporation.
  5. *
  6. * Author:
  7. * Xiao Guangrong <guangrong.xiao@linux.intel.com>
  8. *
  9. * NVDIMM specifications and some documents can be found at:
  10. * NVDIMM ACPI device and NFIT are introduced in ACPI 6:
  11. * http://www.uefi.org/sites/default/files/resources/ACPI_6.0.pdf
  12. * NVDIMM Namespace specification:
  13. * http://pmem.io/documents/NVDIMM_Namespace_Spec.pdf
  14. * DSM Interface Example:
  15. * http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf
  16. * Driver Writer's Guide:
  17. * http://pmem.io/documents/NVDIMM_Driver_Writers_Guide.pdf
  18. *
  19. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  20. * See the COPYING file in the top-level directory.
  21. */
  22. #ifndef QEMU_NVDIMM_H
  23. #define QEMU_NVDIMM_H
  24. #include "hw/mem/pc-dimm.h"
  25. #include "hw/acpi/bios-linker-loader.h"
  26. #include "qemu/uuid.h"
  27. #include "hw/acpi/aml-build.h"
  28. #include "qom/object.h"
  29. /*
  30. * The minimum label data size is required by NVDIMM Namespace
  31. * specification, see the chapter 2 Namespaces:
  32. * "NVDIMMs following the NVDIMM Block Mode Specification use an area
  33. * at least 128KB in size, which holds around 1000 labels."
  34. */
  35. #define MIN_NAMESPACE_LABEL_SIZE (128UL << 10)
  36. #define TYPE_NVDIMM "nvdimm"
  37. OBJECT_DECLARE_TYPE(NVDIMMDevice, NVDIMMClass, NVDIMM)
  38. #define NVDIMM_LABEL_SIZE_PROP "label-size"
  39. #define NVDIMM_UUID_PROP "uuid"
  40. #define NVDIMM_UNARMED_PROP "unarmed"
  41. struct NVDIMMDevice {
  42. /* private */
  43. PCDIMMDevice parent_obj;
  44. /* public */
  45. /*
  46. * the size of label data in NVDIMM device which is presented to
  47. * guest via __DSM "Get Namespace Label Size" function.
  48. */
  49. uint64_t label_size;
  50. /*
  51. * the address of label data which is read by __DSM "Get Namespace
  52. * Label Data" function and written by __DSM "Set Namespace Label
  53. * Data" function.
  54. */
  55. void *label_data;
  56. /*
  57. * it's the PMEM region in NVDIMM device, which is presented to
  58. * guest via ACPI NFIT and _FIT method if NVDIMM hotplug is supported.
  59. */
  60. MemoryRegion *nvdimm_mr;
  61. /*
  62. * The 'on' value results in the unarmed flag set in ACPI NFIT,
  63. * which can be used to notify guest implicitly that the host
  64. * backend (e.g., files on HDD, /dev/pmemX, etc.) cannot guarantee
  65. * the guest write persistence.
  66. */
  67. bool unarmed;
  68. /*
  69. * Whether our DIMM is backed by ROM, and even label data cannot be
  70. * written. If set, implies that "unarmed" is also set.
  71. */
  72. bool readonly;
  73. /*
  74. * The PPC64 - spapr requires each nvdimm device have a uuid.
  75. */
  76. QemuUUID uuid;
  77. };
  78. struct NVDIMMClass {
  79. /* private */
  80. PCDIMMDeviceClass parent_class;
  81. /* public */
  82. /* read @size bytes from NVDIMM label data at @offset into @buf. */
  83. void (*read_label_data)(NVDIMMDevice *nvdimm, void *buf,
  84. uint64_t size, uint64_t offset);
  85. /* write @size bytes from @buf to NVDIMM label data at @offset. */
  86. void (*write_label_data)(NVDIMMDevice *nvdimm, const void *buf,
  87. uint64_t size, uint64_t offset);
  88. void (*realize)(NVDIMMDevice *nvdimm, Error **errp);
  89. void (*unrealize)(NVDIMMDevice *nvdimm);
  90. };
  91. #define NVDIMM_DSM_MEM_FILE "etc/acpi/nvdimm-mem"
  92. /*
  93. * 32 bits IO port starting from 0x0a18 in guest is reserved for
  94. * NVDIMM ACPI emulation.
  95. */
  96. #define NVDIMM_ACPI_IO_BASE 0x0a18
  97. #define NVDIMM_ACPI_IO_LEN 4
  98. /*
  99. * NvdimmFitBuffer:
  100. * @fit: FIT structures for present NVDIMMs. It is updated when
  101. * the NVDIMM device is plugged or unplugged.
  102. * @dirty: It allows OSPM to detect change and restart read in
  103. * progress if there is any.
  104. */
  105. struct NvdimmFitBuffer {
  106. GArray *fit;
  107. bool dirty;
  108. };
  109. typedef struct NvdimmFitBuffer NvdimmFitBuffer;
  110. struct NVDIMMState {
  111. /* detect if NVDIMM support is enabled. */
  112. bool is_enabled;
  113. /* the data of the fw_cfg file NVDIMM_DSM_MEM_FILE. */
  114. GArray *dsm_mem;
  115. NvdimmFitBuffer fit_buf;
  116. /* the IO region used by OSPM to transfer control to QEMU. */
  117. MemoryRegion io_mr;
  118. /*
  119. * Platform capabilities, section 5.2.25.9 of ACPI 6.2 Errata A
  120. */
  121. int32_t persistence;
  122. char *persistence_string;
  123. struct AcpiGenericAddress dsm_io;
  124. };
  125. typedef struct NVDIMMState NVDIMMState;
  126. void nvdimm_init_acpi_state(NVDIMMState *state, MemoryRegion *io,
  127. struct AcpiGenericAddress dsm_io,
  128. FWCfgState *fw_cfg, Object *owner);
  129. void nvdimm_build_srat(GArray *table_data);
  130. void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data,
  131. BIOSLinker *linker, NVDIMMState *state,
  132. uint32_t ram_slots, const char *oem_id,
  133. const char *oem_table_id);
  134. void nvdimm_plug(NVDIMMState *state);
  135. void nvdimm_acpi_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev);
  136. #endif