| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * NVDIMM Firmware Interface Table - NFIT |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. |
|---|
| 5 | | - * |
|---|
| 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. |
|---|
| 9 | | - * |
|---|
| 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. |
|---|
| 14 | 6 | */ |
|---|
| 15 | 7 | #ifndef __NFIT_H__ |
|---|
| 16 | 8 | #define __NFIT_H__ |
|---|
| .. | .. |
|---|
| 24 | 16 | /* ACPI 6.1 */ |
|---|
| 25 | 17 | #define UUID_NFIT_BUS "2f10e7a4-9e91-11e4-89d3-123b93f75cba" |
|---|
| 26 | 18 | |
|---|
| 27 | | -/* http://pmem.io/documents/NVDIMM_DSM_Interface-V1.6.pdf */ |
|---|
| 19 | +/* https://pmem.io/documents/NVDIMM_DSM_Interface-V1.6.pdf */ |
|---|
| 28 | 20 | #define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66" |
|---|
| 21 | +#define UUID_INTEL_BUS "c7d8acd4-2df8-4b82-9f65-a325335af149" |
|---|
| 29 | 22 | |
|---|
| 30 | 23 | /* https://github.com/HewlettPackard/hpe-nvm/blob/master/Documentation/ */ |
|---|
| 31 | 24 | #define UUID_NFIT_DIMM_N_HPE1 "9002c334-acf3-4c0e-9642-a235f0d53bc6" |
|---|
| .. | .. |
|---|
| 41 | 34 | | ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \ |
|---|
| 42 | 35 | | ACPI_NFIT_MEM_NOT_ARMED | ACPI_NFIT_MEM_MAP_FAILED) |
|---|
| 43 | 36 | |
|---|
| 44 | | -#define NVDIMM_FAMILY_MAX NVDIMM_FAMILY_HYPERV |
|---|
| 37 | +#define NVDIMM_CMD_MAX 31 |
|---|
| 45 | 38 | |
|---|
| 46 | 39 | #define NVDIMM_STANDARD_CMDMASK \ |
|---|
| 47 | 40 | (1 << ND_CMD_SMART | 1 << ND_CMD_SMART_THRESHOLD | 1 << ND_CMD_DIMM_FLAGS \ |
|---|
| .. | .. |
|---|
| 63 | 56 | NVDIMM_INTEL_QUERY_FWUPDATE = 16, |
|---|
| 64 | 57 | NVDIMM_INTEL_SET_THRESHOLD = 17, |
|---|
| 65 | 58 | NVDIMM_INTEL_INJECT_ERROR = 18, |
|---|
| 59 | + NVDIMM_INTEL_GET_SECURITY_STATE = 19, |
|---|
| 60 | + NVDIMM_INTEL_SET_PASSPHRASE = 20, |
|---|
| 61 | + NVDIMM_INTEL_DISABLE_PASSPHRASE = 21, |
|---|
| 62 | + NVDIMM_INTEL_UNLOCK_UNIT = 22, |
|---|
| 63 | + NVDIMM_INTEL_FREEZE_LOCK = 23, |
|---|
| 64 | + NVDIMM_INTEL_SECURE_ERASE = 24, |
|---|
| 65 | + NVDIMM_INTEL_OVERWRITE = 25, |
|---|
| 66 | + NVDIMM_INTEL_QUERY_OVERWRITE = 26, |
|---|
| 67 | + NVDIMM_INTEL_SET_MASTER_PASSPHRASE = 27, |
|---|
| 68 | + NVDIMM_INTEL_MASTER_SECURE_ERASE = 28, |
|---|
| 69 | + NVDIMM_INTEL_FW_ACTIVATE_DIMMINFO = 29, |
|---|
| 70 | + NVDIMM_INTEL_FW_ACTIVATE_ARM = 30, |
|---|
| 66 | 71 | }; |
|---|
| 72 | + |
|---|
| 73 | +enum nvdimm_bus_family_cmds { |
|---|
| 74 | + NVDIMM_BUS_INTEL_FW_ACTIVATE_BUSINFO = 1, |
|---|
| 75 | + NVDIMM_BUS_INTEL_FW_ACTIVATE = 2, |
|---|
| 76 | +}; |
|---|
| 77 | + |
|---|
| 78 | +#define NVDIMM_INTEL_SECURITY_CMDMASK \ |
|---|
| 79 | +(1 << NVDIMM_INTEL_GET_SECURITY_STATE | 1 << NVDIMM_INTEL_SET_PASSPHRASE \ |
|---|
| 80 | +| 1 << NVDIMM_INTEL_DISABLE_PASSPHRASE | 1 << NVDIMM_INTEL_UNLOCK_UNIT \ |
|---|
| 81 | +| 1 << NVDIMM_INTEL_FREEZE_LOCK | 1 << NVDIMM_INTEL_SECURE_ERASE \ |
|---|
| 82 | +| 1 << NVDIMM_INTEL_OVERWRITE | 1 << NVDIMM_INTEL_QUERY_OVERWRITE \ |
|---|
| 83 | +| 1 << NVDIMM_INTEL_SET_MASTER_PASSPHRASE \ |
|---|
| 84 | +| 1 << NVDIMM_INTEL_MASTER_SECURE_ERASE) |
|---|
| 85 | + |
|---|
| 86 | +#define NVDIMM_INTEL_FW_ACTIVATE_CMDMASK \ |
|---|
| 87 | +(1 << NVDIMM_INTEL_FW_ACTIVATE_DIMMINFO | 1 << NVDIMM_INTEL_FW_ACTIVATE_ARM) |
|---|
| 88 | + |
|---|
| 89 | +#define NVDIMM_BUS_INTEL_FW_ACTIVATE_CMDMASK \ |
|---|
| 90 | +(1 << NVDIMM_BUS_INTEL_FW_ACTIVATE_BUSINFO | 1 << NVDIMM_BUS_INTEL_FW_ACTIVATE) |
|---|
| 67 | 91 | |
|---|
| 68 | 92 | #define NVDIMM_INTEL_CMDMASK \ |
|---|
| 69 | 93 | (NVDIMM_STANDARD_CMDMASK | 1 << NVDIMM_INTEL_GET_MODES \ |
|---|
| 70 | 94 | | 1 << NVDIMM_INTEL_GET_FWINFO | 1 << NVDIMM_INTEL_START_FWUPDATE \ |
|---|
| 71 | 95 | | 1 << NVDIMM_INTEL_SEND_FWUPDATE | 1 << NVDIMM_INTEL_FINISH_FWUPDATE \ |
|---|
| 72 | 96 | | 1 << NVDIMM_INTEL_QUERY_FWUPDATE | 1 << NVDIMM_INTEL_SET_THRESHOLD \ |
|---|
| 73 | | - | 1 << NVDIMM_INTEL_INJECT_ERROR | 1 << NVDIMM_INTEL_LATCH_SHUTDOWN) |
|---|
| 97 | + | 1 << NVDIMM_INTEL_INJECT_ERROR | 1 << NVDIMM_INTEL_LATCH_SHUTDOWN \ |
|---|
| 98 | + | NVDIMM_INTEL_SECURITY_CMDMASK | NVDIMM_INTEL_FW_ACTIVATE_CMDMASK) |
|---|
| 99 | + |
|---|
| 100 | +#define NVDIMM_INTEL_DENY_CMDMASK \ |
|---|
| 101 | +(NVDIMM_INTEL_SECURITY_CMDMASK | NVDIMM_INTEL_FW_ACTIVATE_CMDMASK) |
|---|
| 74 | 102 | |
|---|
| 75 | 103 | enum nfit_uuids { |
|---|
| 76 | 104 | /* for simplicity alias the uuid index with the family id */ |
|---|
| .. | .. |
|---|
| 79 | 107 | NFIT_DEV_DIMM_N_HPE2 = NVDIMM_FAMILY_HPE2, |
|---|
| 80 | 108 | NFIT_DEV_DIMM_N_MSFT = NVDIMM_FAMILY_MSFT, |
|---|
| 81 | 109 | NFIT_DEV_DIMM_N_HYPERV = NVDIMM_FAMILY_HYPERV, |
|---|
| 110 | + /* |
|---|
| 111 | + * to_nfit_bus_uuid() expects to translate bus uuid family ids |
|---|
| 112 | + * to a UUID index using NVDIMM_FAMILY_MAX as an offset |
|---|
| 113 | + */ |
|---|
| 114 | + NFIT_BUS_INTEL = NVDIMM_FAMILY_MAX + NVDIMM_BUS_FAMILY_INTEL, |
|---|
| 82 | 115 | NFIT_SPA_VOLATILE, |
|---|
| 83 | 116 | NFIT_SPA_PM, |
|---|
| 84 | 117 | NFIT_SPA_DCR, |
|---|
| .. | .. |
|---|
| 133 | 166 | unsigned long ars_state; |
|---|
| 134 | 167 | u32 clear_err_unit; |
|---|
| 135 | 168 | u32 max_ars; |
|---|
| 136 | | - struct acpi_nfit_system_address spa[0]; |
|---|
| 169 | + struct acpi_nfit_system_address spa[]; |
|---|
| 137 | 170 | }; |
|---|
| 138 | 171 | |
|---|
| 139 | 172 | struct nfit_dcr { |
|---|
| 140 | 173 | struct list_head list; |
|---|
| 141 | | - struct acpi_nfit_control_region dcr[0]; |
|---|
| 174 | + struct acpi_nfit_control_region dcr[]; |
|---|
| 142 | 175 | }; |
|---|
| 143 | 176 | |
|---|
| 144 | 177 | struct nfit_bdw { |
|---|
| 145 | 178 | struct list_head list; |
|---|
| 146 | | - struct acpi_nfit_data_region bdw[0]; |
|---|
| 179 | + struct acpi_nfit_data_region bdw[]; |
|---|
| 147 | 180 | }; |
|---|
| 148 | 181 | |
|---|
| 149 | 182 | struct nfit_idt { |
|---|
| 150 | 183 | struct list_head list; |
|---|
| 151 | | - struct acpi_nfit_interleave idt[0]; |
|---|
| 184 | + struct acpi_nfit_interleave idt[]; |
|---|
| 152 | 185 | }; |
|---|
| 153 | 186 | |
|---|
| 154 | 187 | struct nfit_flush { |
|---|
| 155 | 188 | struct list_head list; |
|---|
| 156 | | - struct acpi_nfit_flush_address flush[0]; |
|---|
| 189 | + struct acpi_nfit_flush_address flush[]; |
|---|
| 157 | 190 | }; |
|---|
| 158 | 191 | |
|---|
| 159 | 192 | struct nfit_memdev { |
|---|
| 160 | 193 | struct list_head list; |
|---|
| 161 | | - struct acpi_nfit_memory_map memdev[0]; |
|---|
| 194 | + struct acpi_nfit_memory_map memdev[]; |
|---|
| 162 | 195 | }; |
|---|
| 196 | + |
|---|
| 197 | +enum nfit_mem_flags { |
|---|
| 198 | + NFIT_MEM_LSR, |
|---|
| 199 | + NFIT_MEM_LSW, |
|---|
| 200 | + NFIT_MEM_DIRTY, |
|---|
| 201 | + NFIT_MEM_DIRTY_COUNT, |
|---|
| 202 | +}; |
|---|
| 203 | + |
|---|
| 204 | +#define NFIT_DIMM_ID_LEN 22 |
|---|
| 163 | 205 | |
|---|
| 164 | 206 | /* assembled tables for a given dimm/memory-device */ |
|---|
| 165 | 207 | struct nfit_mem { |
|---|
| .. | .. |
|---|
| 178 | 220 | struct list_head list; |
|---|
| 179 | 221 | struct acpi_device *adev; |
|---|
| 180 | 222 | struct acpi_nfit_desc *acpi_desc; |
|---|
| 223 | + enum nvdimm_fwa_state fwa_state; |
|---|
| 224 | + enum nvdimm_fwa_result fwa_result; |
|---|
| 225 | + int fwa_count; |
|---|
| 226 | + char id[NFIT_DIMM_ID_LEN+1]; |
|---|
| 181 | 227 | struct resource *flush_wpq; |
|---|
| 182 | 228 | unsigned long dsm_mask; |
|---|
| 229 | + unsigned long flags; |
|---|
| 230 | + u32 dirty_shutdown; |
|---|
| 183 | 231 | int family; |
|---|
| 184 | | - bool has_lsr; |
|---|
| 185 | | - bool has_lsw; |
|---|
| 186 | 232 | }; |
|---|
| 187 | 233 | |
|---|
| 188 | 234 | enum scrub_flags { |
|---|
| .. | .. |
|---|
| 216 | 262 | unsigned long scrub_flags; |
|---|
| 217 | 263 | unsigned long dimm_cmd_force_en; |
|---|
| 218 | 264 | unsigned long bus_cmd_force_en; |
|---|
| 219 | | - unsigned long bus_nfit_cmd_force_en; |
|---|
| 265 | + unsigned long bus_dsm_mask; |
|---|
| 266 | + unsigned long family_dsm_mask[NVDIMM_BUS_FAMILY_MAX + 1]; |
|---|
| 220 | 267 | unsigned int platform_cap; |
|---|
| 221 | 268 | unsigned int scrub_tmo; |
|---|
| 222 | 269 | int (*blk_do_io)(struct nd_blk_region *ndbr, resource_size_t dpa, |
|---|
| 223 | 270 | void *iobuf, u64 len, int rw); |
|---|
| 271 | + enum nvdimm_fwa_state fwa_state; |
|---|
| 272 | + enum nvdimm_fwa_capability fwa_cap; |
|---|
| 273 | + int fwa_count; |
|---|
| 274 | + bool fwa_noidle; |
|---|
| 275 | + bool fwa_nosuspend; |
|---|
| 224 | 276 | }; |
|---|
| 225 | 277 | |
|---|
| 226 | 278 | enum scrub_mode { |
|---|
| .. | .. |
|---|
| 291 | 343 | return container_of(nd_desc, struct acpi_nfit_desc, nd_desc); |
|---|
| 292 | 344 | } |
|---|
| 293 | 345 | |
|---|
| 346 | +#ifdef CONFIG_PROVE_LOCKING |
|---|
| 347 | +static inline void nfit_device_lock(struct device *dev) |
|---|
| 348 | +{ |
|---|
| 349 | + device_lock(dev); |
|---|
| 350 | + mutex_lock(&dev->lockdep_mutex); |
|---|
| 351 | +} |
|---|
| 352 | + |
|---|
| 353 | +static inline void nfit_device_unlock(struct device *dev) |
|---|
| 354 | +{ |
|---|
| 355 | + mutex_unlock(&dev->lockdep_mutex); |
|---|
| 356 | + device_unlock(dev); |
|---|
| 357 | +} |
|---|
| 358 | +#else |
|---|
| 359 | +static inline void nfit_device_lock(struct device *dev) |
|---|
| 360 | +{ |
|---|
| 361 | + device_lock(dev); |
|---|
| 362 | +} |
|---|
| 363 | + |
|---|
| 364 | +static inline void nfit_device_unlock(struct device *dev) |
|---|
| 365 | +{ |
|---|
| 366 | + device_unlock(dev); |
|---|
| 367 | +} |
|---|
| 368 | +#endif |
|---|
| 369 | + |
|---|
| 294 | 370 | const guid_t *to_nfit_uuid(enum nfit_uuids id); |
|---|
| 295 | 371 | int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *nfit, acpi_size sz); |
|---|
| 296 | 372 | void acpi_nfit_shutdown(void *data); |
|---|
| .. | .. |
|---|
| 299 | 375 | int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, |
|---|
| 300 | 376 | unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc); |
|---|
| 301 | 377 | void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev); |
|---|
| 378 | +bool intel_fwa_supported(struct nvdimm_bus *nvdimm_bus); |
|---|
| 379 | +extern struct device_attribute dev_attr_firmware_activate_noidle; |
|---|
| 302 | 380 | #endif /* __NFIT_H__ */ |
|---|