2 * NVDIMM Firmware Interface Table - NFIT
4 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
17 #include <linux/workqueue.h>
18 #include <linux/libnvdimm.h>
19 #include <linux/ndctl.h>
20 #include <linux/types.h>
21 #include <linux/acpi.h>
22 #include <acpi/acuuid.h>
25 #define UUID_NFIT_BUS "2f10e7a4-9e91-11e4-89d3-123b93f75cba"
27 /* http://pmem.io/documents/NVDIMM_DSM_Interface-V1.6.pdf */
28 #define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66"
30 /* https://github.com/HewlettPackard/hpe-nvm/blob/master/Documentation/ */
31 #define UUID_NFIT_DIMM_N_HPE1 "9002c334-acf3-4c0e-9642-a235f0d53bc6"
32 #define UUID_NFIT_DIMM_N_HPE2 "5008664b-b758-41a0-a03c-27c2f2d04f7e"
34 /* https://msdn.microsoft.com/library/windows/hardware/mt604741 */
35 #define UUID_NFIT_DIMM_N_MSFT "1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"
37 #define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \
38 | ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \
39 | ACPI_NFIT_MEM_NOT_ARMED | ACPI_NFIT_MEM_MAP_FAILED)
41 #define NVDIMM_FAMILY_MAX NVDIMM_FAMILY_MSFT
43 #define NVDIMM_STANDARD_CMDMASK \
44 (1 << ND_CMD_SMART | 1 << ND_CMD_SMART_THRESHOLD | 1 << ND_CMD_DIMM_FLAGS \
45 | 1 << ND_CMD_GET_CONFIG_SIZE | 1 << ND_CMD_GET_CONFIG_DATA \
46 | 1 << ND_CMD_SET_CONFIG_DATA | 1 << ND_CMD_VENDOR_EFFECT_LOG_SIZE \
47 | 1 << ND_CMD_VENDOR_EFFECT_LOG | 1 << ND_CMD_VENDOR)
50 * Command numbers that the kernel needs to know about to handle
51 * non-default DSM revision ids
53 enum nvdimm_family_cmds
{
54 NVDIMM_INTEL_LATCH_SHUTDOWN
= 10,
55 NVDIMM_INTEL_GET_MODES
= 11,
56 NVDIMM_INTEL_GET_FWINFO
= 12,
57 NVDIMM_INTEL_START_FWUPDATE
= 13,
58 NVDIMM_INTEL_SEND_FWUPDATE
= 14,
59 NVDIMM_INTEL_FINISH_FWUPDATE
= 15,
60 NVDIMM_INTEL_QUERY_FWUPDATE
= 16,
61 NVDIMM_INTEL_SET_THRESHOLD
= 17,
62 NVDIMM_INTEL_INJECT_ERROR
= 18,
63 NVDIMM_INTEL_GET_SECURITY_STATE
= 19,
64 NVDIMM_INTEL_SET_PASSPHRASE
= 20,
65 NVDIMM_INTEL_DISABLE_PASSPHRASE
= 21,
66 NVDIMM_INTEL_UNLOCK_UNIT
= 22,
67 NVDIMM_INTEL_FREEZE_LOCK
= 23,
68 NVDIMM_INTEL_SECURE_ERASE
= 24,
69 NVDIMM_INTEL_OVERWRITE
= 25,
70 NVDIMM_INTEL_QUERY_OVERWRITE
= 26,
71 NVDIMM_INTEL_SET_MASTER_PASSPHRASE
= 27,
72 NVDIMM_INTEL_MASTER_SECURE_ERASE
= 28,
75 #define NVDIMM_INTEL_SECURITY_CMDMASK \
76 (1 << NVDIMM_INTEL_GET_SECURITY_STATE | 1 << NVDIMM_INTEL_SET_PASSPHRASE \
77 | 1 << NVDIMM_INTEL_DISABLE_PASSPHRASE | 1 << NVDIMM_INTEL_UNLOCK_UNIT \
78 | 1 << NVDIMM_INTEL_FREEZE_LOCK | 1 << NVDIMM_INTEL_SECURE_ERASE \
79 | 1 << NVDIMM_INTEL_OVERWRITE | 1 << NVDIMM_INTEL_QUERY_OVERWRITE \
80 | 1 << NVDIMM_INTEL_SET_MASTER_PASSPHRASE \
81 | 1 << NVDIMM_INTEL_MASTER_SECURE_ERASE)
83 #define NVDIMM_INTEL_CMDMASK \
84 (NVDIMM_STANDARD_CMDMASK | 1 << NVDIMM_INTEL_GET_MODES \
85 | 1 << NVDIMM_INTEL_GET_FWINFO | 1 << NVDIMM_INTEL_START_FWUPDATE \
86 | 1 << NVDIMM_INTEL_SEND_FWUPDATE | 1 << NVDIMM_INTEL_FINISH_FWUPDATE \
87 | 1 << NVDIMM_INTEL_QUERY_FWUPDATE | 1 << NVDIMM_INTEL_SET_THRESHOLD \
88 | 1 << NVDIMM_INTEL_INJECT_ERROR | 1 << NVDIMM_INTEL_LATCH_SHUTDOWN \
89 | NVDIMM_INTEL_SECURITY_CMDMASK)
92 /* for simplicity alias the uuid index with the family id */
93 NFIT_DEV_DIMM
= NVDIMM_FAMILY_INTEL
,
94 NFIT_DEV_DIMM_N_HPE1
= NVDIMM_FAMILY_HPE1
,
95 NFIT_DEV_DIMM_N_HPE2
= NVDIMM_FAMILY_HPE2
,
96 NFIT_DEV_DIMM_N_MSFT
= NVDIMM_FAMILY_MSFT
,
110 * Region format interface codes are stored with the interface as the
111 * LSB and the function as the MSB.
113 #define NFIT_FIC_BYTE cpu_to_le16(0x101) /* byte-addressable energy backed */
114 #define NFIT_FIC_BLK cpu_to_le16(0x201) /* block-addressable non-energy backed */
115 #define NFIT_FIC_BYTEN cpu_to_le16(0x301) /* byte-addressable non-energy backed */
118 NFIT_BLK_READ_FLUSH
= 1,
119 NFIT_BLK_DCR_LATCH
= 2,
120 NFIT_ARS_STATUS_DONE
= 0,
121 NFIT_ARS_STATUS_BUSY
= 1 << 16,
122 NFIT_ARS_STATUS_NONE
= 2 << 16,
123 NFIT_ARS_STATUS_INTR
= 3 << 16,
124 NFIT_ARS_START_BUSY
= 6,
125 NFIT_ARS_CAP_NONE
= 1,
126 NFIT_ARS_F_OVERFLOW
= 1,
127 NFIT_ARS_TIMEOUT
= 90,
130 enum nfit_root_notifiers
{
131 NFIT_NOTIFY_UPDATE
= 0x80,
132 NFIT_NOTIFY_UC_MEMORY_ERROR
= 0x81,
135 enum nfit_dimm_notifiers
{
136 NFIT_NOTIFY_DIMM_HEALTH
= 0x81,
139 enum nfit_ars_state
{
146 struct list_head list
;
147 struct nd_region
*nd_region
;
148 unsigned long ars_state
;
151 struct acpi_nfit_system_address spa
[0];
155 struct list_head list
;
156 struct acpi_nfit_control_region dcr
[0];
160 struct list_head list
;
161 struct acpi_nfit_data_region bdw
[0];
165 struct list_head list
;
166 struct acpi_nfit_interleave idt
[0];
170 struct list_head list
;
171 struct acpi_nfit_flush_address flush
[0];
175 struct list_head list
;
176 struct acpi_nfit_memory_map memdev
[0];
179 enum nfit_mem_flags
{
183 NFIT_MEM_DIRTY_COUNT
,
186 /* assembled tables for a given dimm/memory-device */
188 struct nvdimm
*nvdimm
;
189 struct acpi_nfit_memory_map
*memdev_dcr
;
190 struct acpi_nfit_memory_map
*memdev_pmem
;
191 struct acpi_nfit_memory_map
*memdev_bdw
;
192 struct acpi_nfit_control_region
*dcr
;
193 struct acpi_nfit_data_region
*bdw
;
194 struct acpi_nfit_system_address
*spa_dcr
;
195 struct acpi_nfit_system_address
*spa_bdw
;
196 struct acpi_nfit_interleave
*idt_dcr
;
197 struct acpi_nfit_interleave
*idt_bdw
;
198 struct kernfs_node
*flags_attr
;
199 struct nfit_flush
*nfit_flush
;
200 struct list_head list
;
201 struct acpi_device
*adev
;
202 struct acpi_nfit_desc
*acpi_desc
;
203 struct resource
*flush_wpq
;
204 unsigned long dsm_mask
;
210 struct acpi_nfit_desc
{
211 struct nvdimm_bus_descriptor nd_desc
;
212 struct acpi_table_header acpi_header
;
213 struct mutex init_mutex
;
214 struct list_head memdevs
;
215 struct list_head flushes
;
216 struct list_head dimms
;
217 struct list_head spas
;
218 struct list_head dcrs
;
219 struct list_head bdws
;
220 struct list_head idts
;
221 struct nvdimm_bus
*nvdimm_bus
;
224 struct nd_cmd_ars_status
*ars_status
;
225 struct nfit_spa
*scrub_spa
;
226 struct delayed_work dwork
;
227 struct list_head list
;
228 struct kernfs_node
*scrub_count_state
;
229 unsigned int max_ars
;
230 unsigned int scrub_count
;
231 unsigned int scrub_mode
;
232 unsigned int scrub_busy
:1;
233 unsigned int cancel
:1;
234 unsigned long dimm_cmd_force_en
;
235 unsigned long bus_cmd_force_en
;
236 unsigned long bus_nfit_cmd_force_en
;
237 unsigned int platform_cap
;
238 unsigned int scrub_tmo
;
239 int (*blk_do_io
)(struct nd_blk_region
*ndbr
, resource_size_t dpa
,
240 void *iobuf
, u64 len
, int rw
);
248 enum nd_blk_mmio_selector
{
261 struct nfit_blk_mmio
{
262 struct nd_blk_addr addr
;
268 struct acpi_nfit_interleave
*idt
;
269 struct acpi_nfit_system_address
*spa
;
271 struct nd_region
*nd_region
;
272 u64 bdw_offset
; /* post interleave offset */
278 extern struct list_head acpi_descs
;
279 extern struct mutex acpi_desc_lock
;
280 int acpi_nfit_ars_rescan(struct acpi_nfit_desc
*acpi_desc
,
281 enum nfit_ars_state req_type
);
283 #ifdef CONFIG_X86_MCE
284 void nfit_mce_register(void);
285 void nfit_mce_unregister(void);
287 static inline void nfit_mce_register(void)
290 static inline void nfit_mce_unregister(void)
295 int nfit_spa_type(struct acpi_nfit_system_address
*spa
);
297 static inline struct acpi_nfit_memory_map
*__to_nfit_memdev(
298 struct nfit_mem
*nfit_mem
)
300 if (nfit_mem
->memdev_dcr
)
301 return nfit_mem
->memdev_dcr
;
302 return nfit_mem
->memdev_pmem
;
305 static inline struct acpi_nfit_desc
*to_acpi_desc(
306 struct nvdimm_bus_descriptor
*nd_desc
)
308 return container_of(nd_desc
, struct acpi_nfit_desc
, nd_desc
);
311 const guid_t
*to_nfit_uuid(enum nfit_uuids id
);
312 int acpi_nfit_init(struct acpi_nfit_desc
*acpi_desc
, void *nfit
, acpi_size sz
);
313 void acpi_nfit_shutdown(void *data
);
314 void __acpi_nfit_notify(struct device
*dev
, acpi_handle handle
, u32 event
);
315 void __acpi_nvdimm_notify(struct device
*dev
, u32 event
);
316 int acpi_nfit_ctl(struct nvdimm_bus_descriptor
*nd_desc
, struct nvdimm
*nvdimm
,
317 unsigned int cmd
, void *buf
, unsigned int buf_len
, int *cmd_rc
);
318 void acpi_nfit_desc_init(struct acpi_nfit_desc
*acpi_desc
, struct device
*dev
);
319 #endif /* __NFIT_H__ */