nfit.h 3.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 * NVDIMM Firmware Interface Table - NFIT
 *
 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */
#ifndef __NFIT_H__
#define __NFIT_H__
#include <linux/libnvdimm.h>
#include <linux/types.h>
#include <linux/uuid.h>
#include <linux/acpi.h>
#include <acpi/acuuid.h>

#define UUID_NFIT_BUS "2f10e7a4-9e91-11e4-89d3-123b93f75cba"
#define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66"
25 26 27
#define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \
		| ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \
		| ACPI_NFIT_MEM_ARMED)
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

enum nfit_uuids {
	NFIT_SPA_VOLATILE,
	NFIT_SPA_PM,
	NFIT_SPA_DCR,
	NFIT_SPA_BDW,
	NFIT_SPA_VDISK,
	NFIT_SPA_VCD,
	NFIT_SPA_PDISK,
	NFIT_SPA_PCD,
	NFIT_DEV_BUS,
	NFIT_DEV_DIMM,
	NFIT_UUID_MAX,
};

struct nfit_spa {
	struct acpi_nfit_system_address *spa;
	struct list_head list;
};

struct nfit_dcr {
	struct acpi_nfit_control_region *dcr;
	struct list_head list;
};

struct nfit_bdw {
	struct acpi_nfit_data_region *bdw;
	struct list_head list;
};

58 59 60 61 62
struct nfit_idt {
	struct acpi_nfit_interleave *idt;
	struct list_head list;
};

63 64 65 66 67 68 69
struct nfit_memdev {
	struct acpi_nfit_memory_map *memdev;
	struct list_head list;
};

/* assembled tables for a given dimm/memory-device */
struct nfit_mem {
70
	struct nvdimm *nvdimm;
71 72
	struct acpi_nfit_memory_map *memdev_dcr;
	struct acpi_nfit_memory_map *memdev_pmem;
73
	struct acpi_nfit_memory_map *memdev_bdw;
74 75 76 77
	struct acpi_nfit_control_region *dcr;
	struct acpi_nfit_data_region *bdw;
	struct acpi_nfit_system_address *spa_dcr;
	struct acpi_nfit_system_address *spa_bdw;
78 79
	struct acpi_nfit_interleave *idt_dcr;
	struct acpi_nfit_interleave *idt_bdw;
80
	struct list_head list;
81 82
	struct acpi_device *adev;
	unsigned long dsm_mask;
83 84 85 86 87
};

struct acpi_nfit_desc {
	struct nvdimm_bus_descriptor nd_desc;
	struct acpi_table_nfit *nfit;
88 89
	struct mutex spa_map_mutex;
	struct list_head spa_maps;
90 91 92 93 94
	struct list_head memdevs;
	struct list_head dimms;
	struct list_head spas;
	struct list_head dcrs;
	struct list_head bdws;
95
	struct list_head idts;
96 97
	struct nvdimm_bus *nvdimm_bus;
	struct device *dev;
98
	unsigned long dimm_dsm_force_en;
99 100
	int (*blk_do_io)(struct nd_blk_region *ndbr, resource_size_t dpa,
			void *iobuf, u64 len, int rw);
101 102
};

103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
enum nd_blk_mmio_selector {
	BDW,
	DCR,
};

struct nfit_blk {
	struct nfit_blk_mmio {
		union {
			void __iomem *base;
			void *aperture;
		};
		u64 size;
		u64 base_offset;
		u32 line_size;
		u32 num_lines;
		u32 table_size;
		struct acpi_nfit_interleave *idt;
		struct acpi_nfit_system_address *spa;
	} mmio[2];
	struct nd_region *nd_region;
	u64 bdw_offset; /* post interleave offset */
	u64 stat_offset;
	u64 cmd_offset;
};

struct nfit_spa_mapping {
	struct acpi_nfit_desc *acpi_desc;
	struct acpi_nfit_system_address *spa;
	struct list_head list;
	struct kref kref;
	void __iomem *iomem;
};

static inline struct nfit_spa_mapping *to_spa_map(struct kref *kref)
{
	return container_of(kref, struct nfit_spa_mapping, kref);
}

141 142 143 144 145 146 147
static inline struct acpi_nfit_memory_map *__to_nfit_memdev(
		struct nfit_mem *nfit_mem)
{
	if (nfit_mem->memdev_dcr)
		return nfit_mem->memdev_dcr;
	return nfit_mem->memdev_pmem;
}
148 149 150 151 152 153

static inline struct acpi_nfit_desc *to_acpi_desc(
		struct nvdimm_bus_descriptor *nd_desc)
{
	return container_of(nd_desc, struct acpi_nfit_desc, nd_desc);
}
154 155 156 157

const u8 *to_nfit_uuid(enum nfit_uuids id);
int acpi_nfit_init(struct acpi_nfit_desc *nfit, acpi_size sz);
extern const struct attribute_group *acpi_nfit_attribute_groups[];
158
#endif /* __NFIT_H__ */