linux/drivers/acpi/nfit.h
<<
>>
Prefs
   1/*
   2 * NVDIMM Firmware Interface Table - NFIT
   3 *
   4 * 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 */
  15#ifndef __NFIT_H__
  16#define __NFIT_H__
  17#include <linux/libnvdimm.h>
  18#include <linux/types.h>
  19#include <linux/uuid.h>
  20#include <linux/acpi.h>
  21#include <acpi/acuuid.h>
  22
  23#define UUID_NFIT_BUS "2f10e7a4-9e91-11e4-89d3-123b93f75cba"
  24#define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66"
  25#define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \
  26                | ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \
  27                | ACPI_NFIT_MEM_ARMED)
  28
  29enum nfit_uuids {
  30        NFIT_SPA_VOLATILE,
  31        NFIT_SPA_PM,
  32        NFIT_SPA_DCR,
  33        NFIT_SPA_BDW,
  34        NFIT_SPA_VDISK,
  35        NFIT_SPA_VCD,
  36        NFIT_SPA_PDISK,
  37        NFIT_SPA_PCD,
  38        NFIT_DEV_BUS,
  39        NFIT_DEV_DIMM,
  40        NFIT_UUID_MAX,
  41};
  42
  43enum {
  44        ND_BLK_READ_FLUSH = 1,
  45        ND_BLK_DCR_LATCH = 2,
  46};
  47
  48struct nfit_spa {
  49        struct acpi_nfit_system_address *spa;
  50        struct list_head list;
  51};
  52
  53struct nfit_dcr {
  54        struct acpi_nfit_control_region *dcr;
  55        struct list_head list;
  56};
  57
  58struct nfit_bdw {
  59        struct acpi_nfit_data_region *bdw;
  60        struct list_head list;
  61};
  62
  63struct nfit_idt {
  64        struct acpi_nfit_interleave *idt;
  65        struct list_head list;
  66};
  67
  68struct nfit_flush {
  69        struct acpi_nfit_flush_address *flush;
  70        struct list_head list;
  71};
  72
  73struct nfit_memdev {
  74        struct acpi_nfit_memory_map *memdev;
  75        struct list_head list;
  76};
  77
  78/* assembled tables for a given dimm/memory-device */
  79struct nfit_mem {
  80        struct nvdimm *nvdimm;
  81        struct acpi_nfit_memory_map *memdev_dcr;
  82        struct acpi_nfit_memory_map *memdev_pmem;
  83        struct acpi_nfit_memory_map *memdev_bdw;
  84        struct acpi_nfit_control_region *dcr;
  85        struct acpi_nfit_data_region *bdw;
  86        struct acpi_nfit_system_address *spa_dcr;
  87        struct acpi_nfit_system_address *spa_bdw;
  88        struct acpi_nfit_interleave *idt_dcr;
  89        struct acpi_nfit_interleave *idt_bdw;
  90        struct nfit_flush *nfit_flush;
  91        struct list_head list;
  92        struct acpi_device *adev;
  93        unsigned long dsm_mask;
  94};
  95
  96struct acpi_nfit_desc {
  97        struct nvdimm_bus_descriptor nd_desc;
  98        struct acpi_table_nfit *nfit;
  99        struct mutex spa_map_mutex;
 100        struct list_head spa_maps;
 101        struct list_head memdevs;
 102        struct list_head flushes;
 103        struct list_head dimms;
 104        struct list_head spas;
 105        struct list_head dcrs;
 106        struct list_head bdws;
 107        struct list_head idts;
 108        struct nvdimm_bus *nvdimm_bus;
 109        struct device *dev;
 110        unsigned long dimm_dsm_force_en;
 111        unsigned long bus_dsm_force_en;
 112        int (*blk_do_io)(struct nd_blk_region *ndbr, resource_size_t dpa,
 113                        void *iobuf, u64 len, int rw);
 114};
 115
 116enum nd_blk_mmio_selector {
 117        BDW,
 118        DCR,
 119};
 120
 121struct nd_blk_addr {
 122        union {
 123                void __iomem *base;
 124                void __pmem  *aperture;
 125        };
 126};
 127
 128struct nfit_blk {
 129        struct nfit_blk_mmio {
 130                struct nd_blk_addr addr;
 131                u64 size;
 132                u64 base_offset;
 133                u32 line_size;
 134                u32 num_lines;
 135                u32 table_size;
 136                struct acpi_nfit_interleave *idt;
 137                struct acpi_nfit_system_address *spa;
 138        } mmio[2];
 139        struct nd_region *nd_region;
 140        u64 bdw_offset; /* post interleave offset */
 141        u64 stat_offset;
 142        u64 cmd_offset;
 143        void __iomem *nvdimm_flush;
 144        u32 dimm_flags;
 145};
 146
 147enum spa_map_type {
 148        SPA_MAP_CONTROL,
 149        SPA_MAP_APERTURE,
 150};
 151
 152struct nfit_spa_mapping {
 153        struct acpi_nfit_desc *acpi_desc;
 154        struct acpi_nfit_system_address *spa;
 155        struct list_head list;
 156        struct kref kref;
 157        enum spa_map_type type;
 158        struct nd_blk_addr addr;
 159};
 160
 161static inline struct nfit_spa_mapping *to_spa_map(struct kref *kref)
 162{
 163        return container_of(kref, struct nfit_spa_mapping, kref);
 164}
 165
 166static inline struct acpi_nfit_memory_map *__to_nfit_memdev(
 167                struct nfit_mem *nfit_mem)
 168{
 169        if (nfit_mem->memdev_dcr)
 170                return nfit_mem->memdev_dcr;
 171        return nfit_mem->memdev_pmem;
 172}
 173
 174static inline struct acpi_nfit_desc *to_acpi_desc(
 175                struct nvdimm_bus_descriptor *nd_desc)
 176{
 177        return container_of(nd_desc, struct acpi_nfit_desc, nd_desc);
 178}
 179
 180const u8 *to_nfit_uuid(enum nfit_uuids id);
 181int acpi_nfit_init(struct acpi_nfit_desc *nfit, acpi_size sz);
 182extern const struct attribute_group *acpi_nfit_attribute_groups[];
 183#endif /* __NFIT_H__ */
 184