15c42eef2SXiao Guangrong /* 25c42eef2SXiao Guangrong * Non-Volatile Dual In-line Memory Module Virtualization Implementation 35c42eef2SXiao Guangrong * 45c42eef2SXiao Guangrong * Copyright(C) 2015 Intel Corporation. 55c42eef2SXiao Guangrong * 65c42eef2SXiao Guangrong * Author: 75c42eef2SXiao Guangrong * Xiao Guangrong <guangrong.xiao@linux.intel.com> 85c42eef2SXiao Guangrong * 95c42eef2SXiao Guangrong * NVDIMM specifications and some documents can be found at: 105c42eef2SXiao Guangrong * NVDIMM ACPI device and NFIT are introduced in ACPI 6: 115c42eef2SXiao Guangrong * http://www.uefi.org/sites/default/files/resources/ACPI_6.0.pdf 125c42eef2SXiao Guangrong * NVDIMM Namespace specification: 135c42eef2SXiao Guangrong * http://pmem.io/documents/NVDIMM_Namespace_Spec.pdf 145c42eef2SXiao Guangrong * DSM Interface Example: 155c42eef2SXiao Guangrong * http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf 165c42eef2SXiao Guangrong * Driver Writer's Guide: 175c42eef2SXiao Guangrong * http://pmem.io/documents/NVDIMM_Driver_Writers_Guide.pdf 185c42eef2SXiao Guangrong * 195c42eef2SXiao Guangrong * This work is licensed under the terms of the GNU GPL, version 2 or later. 205c42eef2SXiao Guangrong * See the COPYING file in the top-level directory. 215c42eef2SXiao Guangrong */ 225c42eef2SXiao Guangrong 235c42eef2SXiao Guangrong #ifndef QEMU_NVDIMM_H 245c42eef2SXiao Guangrong #define QEMU_NVDIMM_H 255c42eef2SXiao Guangrong 265c42eef2SXiao Guangrong #include "hw/mem/pc-dimm.h" 270e9b9edaSIgor Mammedov #include "hw/acpi/bios-linker-loader.h" 286c5627bbSShivaprasad G Bhat #include "qemu/uuid.h" 295c94b826SKwangwoo Lee #include "hw/acpi/aml-build.h" 30db1015e9SEduardo Habkost #include "qom/object.h" 315c42eef2SXiao Guangrong 32d6fb213aSXiao Guangrong /* 33d6fb213aSXiao Guangrong * The minimum label data size is required by NVDIMM Namespace 34d6fb213aSXiao Guangrong * specification, see the chapter 2 Namespaces: 35d6fb213aSXiao Guangrong * "NVDIMMs following the NVDIMM Block Mode Specification use an area 36d6fb213aSXiao Guangrong * at least 128KB in size, which holds around 1000 labels." 37d6fb213aSXiao Guangrong */ 38d6fb213aSXiao Guangrong #define MIN_NAMESPACE_LABEL_SIZE (128UL << 10) 39d6fb213aSXiao Guangrong 405c42eef2SXiao Guangrong #define TYPE_NVDIMM "nvdimm" 41a489d195SEduardo Habkost OBJECT_DECLARE_TYPE(NVDIMMDevice, NVDIMMClass, NVDIMM) 42da6789c2SHaozhong Zhang 431a97a478SRoss Zwisler #define NVDIMM_LABEL_SIZE_PROP "label-size" 446c5627bbSShivaprasad G Bhat #define NVDIMM_UUID_PROP "uuid" 45cb836434SHaozhong Zhang #define NVDIMM_UNARMED_PROP "unarmed" 46da6789c2SHaozhong Zhang 47d6fb213aSXiao Guangrong struct NVDIMMDevice { 48d6fb213aSXiao Guangrong /* private */ 49d6fb213aSXiao Guangrong PCDIMMDevice parent_obj; 50d6fb213aSXiao Guangrong 51d6fb213aSXiao Guangrong /* public */ 52d6fb213aSXiao Guangrong 53d6fb213aSXiao Guangrong /* 54d6fb213aSXiao Guangrong * the size of label data in NVDIMM device which is presented to 55d6fb213aSXiao Guangrong * guest via __DSM "Get Namespace Label Size" function. 56d6fb213aSXiao Guangrong */ 57d6fb213aSXiao Guangrong uint64_t label_size; 58d6fb213aSXiao Guangrong 59d6fb213aSXiao Guangrong /* 60d6fb213aSXiao Guangrong * the address of label data which is read by __DSM "Get Namespace 61d6fb213aSXiao Guangrong * Label Data" function and written by __DSM "Set Namespace Label 62d6fb213aSXiao Guangrong * Data" function. 63d6fb213aSXiao Guangrong */ 64d6fb213aSXiao Guangrong void *label_data; 65d6fb213aSXiao Guangrong 66d6fb213aSXiao Guangrong /* 67d6fb213aSXiao Guangrong * it's the PMEM region in NVDIMM device, which is presented to 68d6fb213aSXiao Guangrong * guest via ACPI NFIT and _FIT method if NVDIMM hotplug is supported. 69d6fb213aSXiao Guangrong */ 70eb7fd4d0SDavid Hildenbrand MemoryRegion *nvdimm_mr; 71cb836434SHaozhong Zhang 72cb836434SHaozhong Zhang /* 73cb836434SHaozhong Zhang * The 'on' value results in the unarmed flag set in ACPI NFIT, 74cb836434SHaozhong Zhang * which can be used to notify guest implicitly that the host 75cb836434SHaozhong Zhang * backend (e.g., files on HDD, /dev/pmemX, etc.) cannot guarantee 76cb836434SHaozhong Zhang * the guest write persistence. 77cb836434SHaozhong Zhang */ 78cb836434SHaozhong Zhang bool unarmed; 796c5627bbSShivaprasad G Bhat 806c5627bbSShivaprasad G Bhat /* 81*3a125839SDavid Hildenbrand * Whether our DIMM is backed by ROM, and even label data cannot be 82*3a125839SDavid Hildenbrand * written. If set, implies that "unarmed" is also set. 83*3a125839SDavid Hildenbrand */ 84*3a125839SDavid Hildenbrand bool readonly; 85*3a125839SDavid Hildenbrand 86*3a125839SDavid Hildenbrand /* 876c5627bbSShivaprasad G Bhat * The PPC64 - spapr requires each nvdimm device have a uuid. 886c5627bbSShivaprasad G Bhat */ 896c5627bbSShivaprasad G Bhat QemuUUID uuid; 90d6fb213aSXiao Guangrong }; 91d6fb213aSXiao Guangrong 92d6fb213aSXiao Guangrong struct NVDIMMClass { 93d6fb213aSXiao Guangrong /* private */ 94d6fb213aSXiao Guangrong PCDIMMDeviceClass parent_class; 95d6fb213aSXiao Guangrong 96d6fb213aSXiao Guangrong /* public */ 97d6fb213aSXiao Guangrong 98d6fb213aSXiao Guangrong /* read @size bytes from NVDIMM label data at @offset into @buf. */ 99d6fb213aSXiao Guangrong void (*read_label_data)(NVDIMMDevice *nvdimm, void *buf, 100d6fb213aSXiao Guangrong uint64_t size, uint64_t offset); 101d6fb213aSXiao Guangrong /* write @size bytes from @buf to NVDIMM label data at @offset. */ 102d6fb213aSXiao Guangrong void (*write_label_data)(NVDIMMDevice *nvdimm, const void *buf, 103d6fb213aSXiao Guangrong uint64_t size, uint64_t offset); 1043e35960bSShivaprasad G Bhat void (*realize)(NVDIMMDevice *nvdimm, Error **errp); 1053e35960bSShivaprasad G Bhat void (*unrealize)(NVDIMMDevice *nvdimm); 106d6fb213aSXiao Guangrong }; 10787252e1bSXiao Guangrong 1085fe79386SXiao Guangrong #define NVDIMM_DSM_MEM_FILE "etc/acpi/nvdimm-mem" 1095fe79386SXiao Guangrong 1105fe79386SXiao Guangrong /* 1115fe79386SXiao Guangrong * 32 bits IO port starting from 0x0a18 in guest is reserved for 1125fe79386SXiao Guangrong * NVDIMM ACPI emulation. 1135fe79386SXiao Guangrong */ 1145fe79386SXiao Guangrong #define NVDIMM_ACPI_IO_BASE 0x0a18 1155fe79386SXiao Guangrong #define NVDIMM_ACPI_IO_LEN 4 1165fe79386SXiao Guangrong 11775b0713eSXiao Guangrong /* 11812f86b5bSXiao Guangrong * NvdimmFitBuffer: 11912f86b5bSXiao Guangrong * @fit: FIT structures for present NVDIMMs. It is updated when 12012f86b5bSXiao Guangrong * the NVDIMM device is plugged or unplugged. 12112f86b5bSXiao Guangrong * @dirty: It allows OSPM to detect change and restart read in 12212f86b5bSXiao Guangrong * progress if there is any. 12375b0713eSXiao Guangrong */ 12475b0713eSXiao Guangrong struct NvdimmFitBuffer { 12575b0713eSXiao Guangrong GArray *fit; 12675b0713eSXiao Guangrong bool dirty; 12775b0713eSXiao Guangrong }; 12875b0713eSXiao Guangrong typedef struct NvdimmFitBuffer NvdimmFitBuffer; 12975b0713eSXiao Guangrong 130c1404bdeSEric Auger struct NVDIMMState { 1315fe79386SXiao Guangrong /* detect if NVDIMM support is enabled. */ 1325fe79386SXiao Guangrong bool is_enabled; 1335fe79386SXiao Guangrong 1345fe79386SXiao Guangrong /* the data of the fw_cfg file NVDIMM_DSM_MEM_FILE. */ 1355fe79386SXiao Guangrong GArray *dsm_mem; 13675b0713eSXiao Guangrong 13775b0713eSXiao Guangrong NvdimmFitBuffer fit_buf; 13875b0713eSXiao Guangrong 1395fe79386SXiao Guangrong /* the IO region used by OSPM to transfer control to QEMU. */ 1405fe79386SXiao Guangrong MemoryRegion io_mr; 1419ab3aad2SRoss Zwisler 1429ab3aad2SRoss Zwisler /* 1439ab3aad2SRoss Zwisler * Platform capabilities, section 5.2.25.9 of ACPI 6.2 Errata A 1449ab3aad2SRoss Zwisler */ 14511c39b5cSRoss Zwisler int32_t persistence; 14611c39b5cSRoss Zwisler char *persistence_string; 1475c94b826SKwangwoo Lee struct AcpiGenericAddress dsm_io; 1485fe79386SXiao Guangrong }; 149c1404bdeSEric Auger typedef struct NVDIMMState NVDIMMState; 1505fe79386SXiao Guangrong 151c1404bdeSEric Auger void nvdimm_init_acpi_state(NVDIMMState *state, MemoryRegion *io, 1525c94b826SKwangwoo Lee struct AcpiGenericAddress dsm_io, 1535fe79386SXiao Guangrong FWCfgState *fw_cfg, Object *owner); 154c3b0cf6eSVishal Verma void nvdimm_build_srat(GArray *table_data); 15587252e1bSXiao Guangrong void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data, 156c1404bdeSEric Auger BIOSLinker *linker, NVDIMMState *state, 157602b4582SMarian Postevca uint32_t ram_slots, const char *oem_id, 158602b4582SMarian Postevca const char *oem_table_id); 159c1404bdeSEric Auger void nvdimm_plug(NVDIMMState *state); 16075f27498SXiao Guangrong void nvdimm_acpi_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev); 1615c42eef2SXiao Guangrong #endif 162