xref: /openbmc/qemu/include/hw/mem/nvdimm.h (revision 4907644841e3200aea6475c0f72d3d987e9f3d93)
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