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