]>
Commit | Line | Data |
---|---|---|
5c42eef2 XG |
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 | ||
23 | #ifndef QEMU_NVDIMM_H | |
24 | #define QEMU_NVDIMM_H | |
25 | ||
26 | #include "hw/mem/pc-dimm.h" | |
0e9b9eda | 27 | #include "hw/acpi/bios-linker-loader.h" |
6c5627bb | 28 | #include "qemu/uuid.h" |
5c94b826 | 29 | #include "hw/acpi/aml-build.h" |
5c42eef2 | 30 | |
f7df22de XG |
31 | #define NVDIMM_DEBUG 0 |
32 | #define nvdimm_debug(fmt, ...) \ | |
33 | do { \ | |
34 | if (NVDIMM_DEBUG) { \ | |
35 | fprintf(stderr, "nvdimm: " fmt, ## __VA_ARGS__); \ | |
36 | } \ | |
37 | } while (0) | |
38 | ||
d6fb213a XG |
39 | /* |
40 | * The minimum label data size is required by NVDIMM Namespace | |
41 | * specification, see the chapter 2 Namespaces: | |
42 | * "NVDIMMs following the NVDIMM Block Mode Specification use an area | |
43 | * at least 128KB in size, which holds around 1000 labels." | |
44 | */ | |
45 | #define MIN_NAMESPACE_LABEL_SIZE (128UL << 10) | |
46 | ||
47 | #define TYPE_NVDIMM "nvdimm" | |
48 | #define NVDIMM(obj) OBJECT_CHECK(NVDIMMDevice, (obj), TYPE_NVDIMM) | |
49 | #define NVDIMM_CLASS(oc) OBJECT_CLASS_CHECK(NVDIMMClass, (oc), TYPE_NVDIMM) | |
50 | #define NVDIMM_GET_CLASS(obj) OBJECT_GET_CLASS(NVDIMMClass, (obj), \ | |
51 | TYPE_NVDIMM) | |
da6789c2 | 52 | |
1a97a478 | 53 | #define NVDIMM_LABEL_SIZE_PROP "label-size" |
6c5627bb | 54 | #define NVDIMM_UUID_PROP "uuid" |
cb836434 | 55 | #define NVDIMM_UNARMED_PROP "unarmed" |
da6789c2 | 56 | |
d6fb213a XG |
57 | struct NVDIMMDevice { |
58 | /* private */ | |
59 | PCDIMMDevice parent_obj; | |
60 | ||
61 | /* public */ | |
62 | ||
63 | /* | |
64 | * the size of label data in NVDIMM device which is presented to | |
65 | * guest via __DSM "Get Namespace Label Size" function. | |
66 | */ | |
67 | uint64_t label_size; | |
68 | ||
69 | /* | |
70 | * the address of label data which is read by __DSM "Get Namespace | |
71 | * Label Data" function and written by __DSM "Set Namespace Label | |
72 | * Data" function. | |
73 | */ | |
74 | void *label_data; | |
75 | ||
76 | /* | |
77 | * it's the PMEM region in NVDIMM device, which is presented to | |
78 | * guest via ACPI NFIT and _FIT method if NVDIMM hotplug is supported. | |
79 | */ | |
eb7fd4d0 | 80 | MemoryRegion *nvdimm_mr; |
cb836434 HZ |
81 | |
82 | /* | |
83 | * The 'on' value results in the unarmed flag set in ACPI NFIT, | |
84 | * which can be used to notify guest implicitly that the host | |
85 | * backend (e.g., files on HDD, /dev/pmemX, etc.) cannot guarantee | |
86 | * the guest write persistence. | |
87 | */ | |
88 | bool unarmed; | |
6c5627bb SB |
89 | |
90 | /* | |
91 | * The PPC64 - spapr requires each nvdimm device have a uuid. | |
92 | */ | |
93 | QemuUUID uuid; | |
d6fb213a XG |
94 | }; |
95 | typedef struct NVDIMMDevice NVDIMMDevice; | |
96 | ||
97 | struct NVDIMMClass { | |
98 | /* private */ | |
99 | PCDIMMDeviceClass parent_class; | |
100 | ||
101 | /* public */ | |
102 | ||
103 | /* read @size bytes from NVDIMM label data at @offset into @buf. */ | |
104 | void (*read_label_data)(NVDIMMDevice *nvdimm, void *buf, | |
105 | uint64_t size, uint64_t offset); | |
106 | /* write @size bytes from @buf to NVDIMM label data at @offset. */ | |
107 | void (*write_label_data)(NVDIMMDevice *nvdimm, const void *buf, | |
108 | uint64_t size, uint64_t offset); | |
109 | }; | |
110 | typedef struct NVDIMMClass NVDIMMClass; | |
87252e1b | 111 | |
5fe79386 XG |
112 | #define NVDIMM_DSM_MEM_FILE "etc/acpi/nvdimm-mem" |
113 | ||
114 | /* | |
115 | * 32 bits IO port starting from 0x0a18 in guest is reserved for | |
116 | * NVDIMM ACPI emulation. | |
117 | */ | |
118 | #define NVDIMM_ACPI_IO_BASE 0x0a18 | |
119 | #define NVDIMM_ACPI_IO_LEN 4 | |
120 | ||
75b0713e | 121 | /* |
12f86b5b XG |
122 | * NvdimmFitBuffer: |
123 | * @fit: FIT structures for present NVDIMMs. It is updated when | |
124 | * the NVDIMM device is plugged or unplugged. | |
125 | * @dirty: It allows OSPM to detect change and restart read in | |
126 | * progress if there is any. | |
75b0713e XG |
127 | */ |
128 | struct NvdimmFitBuffer { | |
75b0713e XG |
129 | GArray *fit; |
130 | bool dirty; | |
131 | }; | |
132 | typedef struct NvdimmFitBuffer NvdimmFitBuffer; | |
133 | ||
c1404bde | 134 | struct NVDIMMState { |
5fe79386 XG |
135 | /* detect if NVDIMM support is enabled. */ |
136 | bool is_enabled; | |
137 | ||
138 | /* the data of the fw_cfg file NVDIMM_DSM_MEM_FILE. */ | |
139 | GArray *dsm_mem; | |
75b0713e XG |
140 | |
141 | NvdimmFitBuffer fit_buf; | |
142 | ||
5fe79386 XG |
143 | /* the IO region used by OSPM to transfer control to QEMU. */ |
144 | MemoryRegion io_mr; | |
9ab3aad2 RZ |
145 | |
146 | /* | |
147 | * Platform capabilities, section 5.2.25.9 of ACPI 6.2 Errata A | |
148 | */ | |
11c39b5c RZ |
149 | int32_t persistence; |
150 | char *persistence_string; | |
5c94b826 | 151 | struct AcpiGenericAddress dsm_io; |
5fe79386 | 152 | }; |
c1404bde | 153 | typedef struct NVDIMMState NVDIMMState; |
5fe79386 | 154 | |
c1404bde | 155 | void nvdimm_init_acpi_state(NVDIMMState *state, MemoryRegion *io, |
5c94b826 | 156 | struct AcpiGenericAddress dsm_io, |
5fe79386 | 157 | FWCfgState *fw_cfg, Object *owner); |
87252e1b | 158 | void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data, |
c1404bde | 159 | BIOSLinker *linker, NVDIMMState *state, |
bdfd065b | 160 | uint32_t ram_slots); |
c1404bde | 161 | void nvdimm_plug(NVDIMMState *state); |
75f27498 | 162 | void nvdimm_acpi_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev); |
5c42eef2 | 163 | #endif |