linux/drivers/acpi/nfit/nfit.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * NVDIMM Firmware Interface Table - NFIT
   4 *
   5 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
   6 */
   7#ifndef __NFIT_H__
   8#define __NFIT_H__
   9#include <linux/workqueue.h>
  10#include <linux/libnvdimm.h>
  11#include <linux/ndctl.h>
  12#include <linux/types.h>
  13#include <linux/acpi.h>
  14#include <acpi/acuuid.h>
  15
  16/* ACPI 6.1 */
  17#define UUID_NFIT_BUS "2f10e7a4-9e91-11e4-89d3-123b93f75cba"
  18
  19/* https://pmem.io/documents/NVDIMM_DSM_Interface-V1.6.pdf */
  20#define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66"
  21#define UUID_INTEL_BUS "c7d8acd4-2df8-4b82-9f65-a325335af149"
  22
  23/* https://github.com/HewlettPackard/hpe-nvm/blob/master/Documentation/ */
  24#define UUID_NFIT_DIMM_N_HPE1 "9002c334-acf3-4c0e-9642-a235f0d53bc6"
  25#define UUID_NFIT_DIMM_N_HPE2 "5008664b-b758-41a0-a03c-27c2f2d04f7e"
  26
  27/* https://msdn.microsoft.com/library/windows/hardware/mt604741 */
  28#define UUID_NFIT_DIMM_N_MSFT "1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"
  29
  30/* http://www.uefi.org/RFIC_LIST (see "Virtual NVDIMM 0x1901") */
  31#define UUID_NFIT_DIMM_N_HYPERV "5746c5f2-a9a2-4264-ad0e-e4ddc9e09e80"
  32
  33#define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \
  34                | ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \
  35                | ACPI_NFIT_MEM_NOT_ARMED | ACPI_NFIT_MEM_MAP_FAILED)
  36
  37#define NVDIMM_CMD_MAX 31
  38
  39#define NVDIMM_STANDARD_CMDMASK \
  40(1 << ND_CMD_SMART | 1 << ND_CMD_SMART_THRESHOLD | 1 << ND_CMD_DIMM_FLAGS \
  41 | 1 << ND_CMD_GET_CONFIG_SIZE | 1 << ND_CMD_GET_CONFIG_DATA \
  42 | 1 << ND_CMD_SET_CONFIG_DATA | 1 << ND_CMD_VENDOR_EFFECT_LOG_SIZE \
  43 | 1 << ND_CMD_VENDOR_EFFECT_LOG | 1 << ND_CMD_VENDOR)
  44
  45/*
  46 * Command numbers that the kernel needs to know about to handle
  47 * non-default DSM revision ids
  48 */
  49enum nvdimm_family_cmds {
  50        NVDIMM_INTEL_LATCH_SHUTDOWN = 10,
  51        NVDIMM_INTEL_GET_MODES = 11,
  52        NVDIMM_INTEL_GET_FWINFO = 12,
  53        NVDIMM_INTEL_START_FWUPDATE = 13,
  54        NVDIMM_INTEL_SEND_FWUPDATE = 14,
  55        NVDIMM_INTEL_FINISH_FWUPDATE = 15,
  56        NVDIMM_INTEL_QUERY_FWUPDATE = 16,
  57        NVDIMM_INTEL_SET_THRESHOLD = 17,
  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,
  71};
  72
  73enum 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)
  91
  92#define NVDIMM_INTEL_CMDMASK \
  93(NVDIMM_STANDARD_CMDMASK | 1 << NVDIMM_INTEL_GET_MODES \
  94 | 1 << NVDIMM_INTEL_GET_FWINFO | 1 << NVDIMM_INTEL_START_FWUPDATE \
  95 | 1 << NVDIMM_INTEL_SEND_FWUPDATE | 1 << NVDIMM_INTEL_FINISH_FWUPDATE \
  96 | 1 << NVDIMM_INTEL_QUERY_FWUPDATE | 1 << NVDIMM_INTEL_SET_THRESHOLD \
  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)
 102
 103enum nfit_uuids {
 104        /* for simplicity alias the uuid index with the family id */
 105        NFIT_DEV_DIMM = NVDIMM_FAMILY_INTEL,
 106        NFIT_DEV_DIMM_N_HPE1 = NVDIMM_FAMILY_HPE1,
 107        NFIT_DEV_DIMM_N_HPE2 = NVDIMM_FAMILY_HPE2,
 108        NFIT_DEV_DIMM_N_MSFT = NVDIMM_FAMILY_MSFT,
 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,
 115        NFIT_SPA_VOLATILE,
 116        NFIT_SPA_PM,
 117        NFIT_SPA_DCR,
 118        NFIT_SPA_BDW,
 119        NFIT_SPA_VDISK,
 120        NFIT_SPA_VCD,
 121        NFIT_SPA_PDISK,
 122        NFIT_SPA_PCD,
 123        NFIT_DEV_BUS,
 124        NFIT_UUID_MAX,
 125};
 126
 127/*
 128 * Region format interface codes are stored with the interface as the
 129 * LSB and the function as the MSB.
 130 */
 131#define NFIT_FIC_BYTE cpu_to_le16(0x101) /* byte-addressable energy backed */
 132#define NFIT_FIC_BLK cpu_to_le16(0x201) /* block-addressable non-energy backed */
 133#define NFIT_FIC_BYTEN cpu_to_le16(0x301) /* byte-addressable non-energy backed */
 134
 135enum {
 136        NFIT_BLK_READ_FLUSH = 1,
 137        NFIT_BLK_DCR_LATCH = 2,
 138        NFIT_ARS_STATUS_DONE = 0,
 139        NFIT_ARS_STATUS_BUSY = 1 << 16,
 140        NFIT_ARS_STATUS_NONE = 2 << 16,
 141        NFIT_ARS_STATUS_INTR = 3 << 16,
 142        NFIT_ARS_START_BUSY = 6,
 143        NFIT_ARS_CAP_NONE = 1,
 144        NFIT_ARS_F_OVERFLOW = 1,
 145        NFIT_ARS_TIMEOUT = 90,
 146};
 147
 148enum nfit_root_notifiers {
 149        NFIT_NOTIFY_UPDATE = 0x80,
 150        NFIT_NOTIFY_UC_MEMORY_ERROR = 0x81,
 151};
 152
 153enum nfit_dimm_notifiers {
 154        NFIT_NOTIFY_DIMM_HEALTH = 0x81,
 155};
 156
 157enum nfit_ars_state {
 158        ARS_REQ_SHORT,
 159        ARS_REQ_LONG,
 160        ARS_FAILED,
 161};
 162
 163struct nfit_spa {
 164        struct list_head list;
 165        struct nd_region *nd_region;
 166        unsigned long ars_state;
 167        u32 clear_err_unit;
 168        u32 max_ars;
 169        struct acpi_nfit_system_address spa[];
 170};
 171
 172struct nfit_dcr {
 173        struct list_head list;
 174        struct acpi_nfit_control_region dcr[];
 175};
 176
 177struct nfit_bdw {
 178        struct list_head list;
 179        struct acpi_nfit_data_region bdw[];
 180};
 181
 182struct nfit_idt {
 183        struct list_head list;
 184        struct acpi_nfit_interleave idt[];
 185};
 186
 187struct nfit_flush {
 188        struct list_head list;
 189        struct acpi_nfit_flush_address flush[];
 190};
 191
 192struct nfit_memdev {
 193        struct list_head list;
 194        struct acpi_nfit_memory_map memdev[];
 195};
 196
 197enum 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
 205
 206/* assembled tables for a given dimm/memory-device */
 207struct nfit_mem {
 208        struct nvdimm *nvdimm;
 209        struct acpi_nfit_memory_map *memdev_dcr;
 210        struct acpi_nfit_memory_map *memdev_pmem;
 211        struct acpi_nfit_memory_map *memdev_bdw;
 212        struct acpi_nfit_control_region *dcr;
 213        struct acpi_nfit_data_region *bdw;
 214        struct acpi_nfit_system_address *spa_dcr;
 215        struct acpi_nfit_system_address *spa_bdw;
 216        struct acpi_nfit_interleave *idt_dcr;
 217        struct acpi_nfit_interleave *idt_bdw;
 218        struct kernfs_node *flags_attr;
 219        struct nfit_flush *nfit_flush;
 220        struct list_head list;
 221        struct acpi_device *adev;
 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];
 227        struct resource *flush_wpq;
 228        unsigned long dsm_mask;
 229        unsigned long flags;
 230        u32 dirty_shutdown;
 231        int family;
 232};
 233
 234enum scrub_flags {
 235        ARS_BUSY,
 236        ARS_CANCEL,
 237        ARS_VALID,
 238        ARS_POLL,
 239};
 240
 241struct acpi_nfit_desc {
 242        struct nvdimm_bus_descriptor nd_desc;
 243        struct acpi_table_header acpi_header;
 244        struct mutex init_mutex;
 245        struct list_head memdevs;
 246        struct list_head flushes;
 247        struct list_head dimms;
 248        struct list_head spas;
 249        struct list_head dcrs;
 250        struct list_head bdws;
 251        struct list_head idts;
 252        struct nvdimm_bus *nvdimm_bus;
 253        struct device *dev;
 254        struct nd_cmd_ars_status *ars_status;
 255        struct nfit_spa *scrub_spa;
 256        struct delayed_work dwork;
 257        struct list_head list;
 258        struct kernfs_node *scrub_count_state;
 259        unsigned int max_ars;
 260        unsigned int scrub_count;
 261        unsigned int scrub_mode;
 262        unsigned long scrub_flags;
 263        unsigned long dimm_cmd_force_en;
 264        unsigned long bus_cmd_force_en;
 265        unsigned long bus_dsm_mask;
 266        unsigned long family_dsm_mask[NVDIMM_BUS_FAMILY_MAX + 1];
 267        unsigned int platform_cap;
 268        unsigned int scrub_tmo;
 269        int (*blk_do_io)(struct nd_blk_region *ndbr, resource_size_t dpa,
 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;
 276};
 277
 278enum scrub_mode {
 279        HW_ERROR_SCRUB_OFF,
 280        HW_ERROR_SCRUB_ON,
 281};
 282
 283enum nd_blk_mmio_selector {
 284        BDW,
 285        DCR,
 286};
 287
 288struct nd_blk_addr {
 289        union {
 290                void __iomem *base;
 291                void *aperture;
 292        };
 293};
 294
 295struct nfit_blk {
 296        struct nfit_blk_mmio {
 297                struct nd_blk_addr addr;
 298                u64 size;
 299                u64 base_offset;
 300                u32 line_size;
 301                u32 num_lines;
 302                u32 table_size;
 303                struct acpi_nfit_interleave *idt;
 304                struct acpi_nfit_system_address *spa;
 305        } mmio[2];
 306        struct nd_region *nd_region;
 307        u64 bdw_offset; /* post interleave offset */
 308        u64 stat_offset;
 309        u64 cmd_offset;
 310        u32 dimm_flags;
 311};
 312
 313extern struct list_head acpi_descs;
 314extern struct mutex acpi_desc_lock;
 315int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc,
 316                enum nfit_ars_state req_type);
 317
 318#ifdef CONFIG_X86_MCE
 319void nfit_mce_register(void);
 320void nfit_mce_unregister(void);
 321#else
 322static inline void nfit_mce_register(void)
 323{
 324}
 325static inline void nfit_mce_unregister(void)
 326{
 327}
 328#endif
 329
 330int nfit_spa_type(struct acpi_nfit_system_address *spa);
 331
 332static inline struct acpi_nfit_memory_map *__to_nfit_memdev(
 333                struct nfit_mem *nfit_mem)
 334{
 335        if (nfit_mem->memdev_dcr)
 336                return nfit_mem->memdev_dcr;
 337        return nfit_mem->memdev_pmem;
 338}
 339
 340static inline struct acpi_nfit_desc *to_acpi_desc(
 341                struct nvdimm_bus_descriptor *nd_desc)
 342{
 343        return container_of(nd_desc, struct acpi_nfit_desc, nd_desc);
 344}
 345
 346#ifdef CONFIG_PROVE_LOCKING
 347static inline void nfit_device_lock(struct device *dev)
 348{
 349        device_lock(dev);
 350        mutex_lock(&dev->lockdep_mutex);
 351}
 352
 353static inline void nfit_device_unlock(struct device *dev)
 354{
 355        mutex_unlock(&dev->lockdep_mutex);
 356        device_unlock(dev);
 357}
 358#else
 359static inline void nfit_device_lock(struct device *dev)
 360{
 361        device_lock(dev);
 362}
 363
 364static inline void nfit_device_unlock(struct device *dev)
 365{
 366        device_unlock(dev);
 367}
 368#endif
 369
 370const guid_t *to_nfit_uuid(enum nfit_uuids id);
 371int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *nfit, acpi_size sz);
 372void acpi_nfit_shutdown(void *data);
 373void __acpi_nfit_notify(struct device *dev, acpi_handle handle, u32 event);
 374void __acpi_nvdimm_notify(struct device *dev, u32 event);
 375int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
 376                unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc);
 377void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev);
 378bool intel_fwa_supported(struct nvdimm_bus *nvdimm_bus);
 379extern struct device_attribute dev_attr_firmware_activate_noidle;
 380#endif /* __NFIT_H__ */
 381