15b497af4SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
24a826c83SDan Williams /*
34a826c83SDan Williams * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
44a826c83SDan Williams */
54a826c83SDan Williams #ifndef __LABEL_H__
64a826c83SDan Williams #define __LABEL_H__
74a826c83SDan Williams
84a826c83SDan Williams #include <linux/ndctl.h>
94a826c83SDan Williams #include <linux/sizes.h>
10564e871aSDan Williams #include <linux/uuid.h>
114a826c83SDan Williams #include <linux/io.h>
124a826c83SDan Williams
134a826c83SDan Williams enum {
144a826c83SDan Williams NSINDEX_SIG_LEN = 16,
154a826c83SDan Williams NSINDEX_ALIGN = 256,
164a826c83SDan Williams NSINDEX_SEQ_MASK = 0x3,
174a826c83SDan Williams NSLABEL_UUID_LEN = 16,
184a826c83SDan Williams NSLABEL_NAME_LEN = 64,
194a826c83SDan Williams NSLABEL_FLAG_ROLABEL = 0x1, /* read-only label */
204a826c83SDan Williams NSLABEL_FLAG_LOCAL = 0x2, /* DIMM-local namespace */
214a826c83SDan Williams NSLABEL_FLAG_BTT = 0x4, /* namespace contains a BTT */
224a826c83SDan Williams NSLABEL_FLAG_UPDATING = 0x8, /* label being updated */
234a826c83SDan Williams BTT_ALIGN = 4096, /* all btt structures */
244a826c83SDan Williams BTTINFO_SIG_LEN = 16,
254a826c83SDan Williams BTTINFO_UUID_LEN = 16,
264a826c83SDan Williams BTTINFO_FLAG_ERROR = 0x1, /* error state (read-only) */
274a826c83SDan Williams BTTINFO_MAJOR_VERSION = 1,
2836de6f51SToshi Kani ND_LABEL_MIN_SIZE = 256 * 4, /* see sizeof_namespace_index() */
294a826c83SDan Williams ND_LABEL_ID_SIZE = 50,
30f524bf27SDan Williams ND_NSINDEX_INIT = 0x1,
314a826c83SDan Williams };
324a826c83SDan Williams
334a826c83SDan Williams /**
344a826c83SDan Williams * struct nd_namespace_index - label set superblock
354a826c83SDan Williams * @sig: NAMESPACE_INDEX\0
364a826c83SDan Williams * @flags: placeholder
37999c993aSDan Williams * @labelsize: log2 size (v1 labels 128 bytes v2 labels 256 bytes)
384a826c83SDan Williams * @seq: sequence number for this index
394a826c83SDan Williams * @myoff: offset of this index in label area
404a826c83SDan Williams * @mysize: size of this index struct
414a826c83SDan Williams * @otheroff: offset of other index
424a826c83SDan Williams * @labeloff: offset of first label slot
434a826c83SDan Williams * @nslot: total number of label slots
444a826c83SDan Williams * @major: label area major version
454a826c83SDan Williams * @minor: label area minor version
464a826c83SDan Williams * @checksum: fletcher64 of all fields
47999c993aSDan Williams * @free: bitmap, nlabel bits
484a826c83SDan Williams *
494a826c83SDan Williams * The size of free[] is rounded up so the total struct size is a
504a826c83SDan Williams * multiple of NSINDEX_ALIGN bytes. Any bits this allocates beyond
514a826c83SDan Williams * nlabel bits must be zero.
524a826c83SDan Williams */
534a826c83SDan Williams struct nd_namespace_index {
544a826c83SDan Williams u8 sig[NSINDEX_SIG_LEN];
55564e871aSDan Williams u8 flags[3];
56564e871aSDan Williams u8 labelsize;
574a826c83SDan Williams __le32 seq;
584a826c83SDan Williams __le64 myoff;
594a826c83SDan Williams __le64 mysize;
604a826c83SDan Williams __le64 otheroff;
614a826c83SDan Williams __le64 labeloff;
624a826c83SDan Williams __le32 nslot;
634a826c83SDan Williams __le16 major;
644a826c83SDan Williams __le16 minor;
654a826c83SDan Williams __le64 checksum;
661e361632SGustavo A. R. Silva u8 free[];
674a826c83SDan Williams };
684a826c83SDan Williams
694a826c83SDan Williams /**
70540ccaa2SDan Williams * struct cxl_region_label - CXL 2.0 Table 211
71540ccaa2SDan Williams * @type: uuid identifying this label format (region)
72540ccaa2SDan Williams * @uuid: uuid for the region this label describes
73540ccaa2SDan Williams * @flags: NSLABEL_FLAG_UPDATING (all other flags reserved)
74540ccaa2SDan Williams * @nlabel: 1 per interleave-way in the region
75540ccaa2SDan Williams * @position: this label's position in the set
76540ccaa2SDan Williams * @dpa: start address in device-local capacity for this label
77540ccaa2SDan Williams * @rawsize: size of this label's contribution to region
78540ccaa2SDan Williams * @hpa: mandatory system physical address to map this region
79540ccaa2SDan Williams * @slot: slot id of this label in label area
80540ccaa2SDan Williams * @ig: interleave granularity (1 << @ig) * 256 bytes
81540ccaa2SDan Williams * @align: alignment in SZ_256M blocks
82540ccaa2SDan Williams * @reserved: reserved
83540ccaa2SDan Williams * @checksum: fletcher64 sum of this label
84540ccaa2SDan Williams */
85540ccaa2SDan Williams struct cxl_region_label {
86540ccaa2SDan Williams u8 type[NSLABEL_UUID_LEN];
87540ccaa2SDan Williams u8 uuid[NSLABEL_UUID_LEN];
88540ccaa2SDan Williams __le32 flags;
89540ccaa2SDan Williams __le16 nlabel;
90540ccaa2SDan Williams __le16 position;
91540ccaa2SDan Williams __le64 dpa;
92540ccaa2SDan Williams __le64 rawsize;
93540ccaa2SDan Williams __le64 hpa;
94540ccaa2SDan Williams __le32 slot;
95540ccaa2SDan Williams __le32 ig;
96540ccaa2SDan Williams __le32 align;
97540ccaa2SDan Williams u8 reserved[0xac];
98540ccaa2SDan Williams __le64 checksum;
99540ccaa2SDan Williams };
100540ccaa2SDan Williams
101540ccaa2SDan Williams /**
1025af96835SDan Williams * struct nvdimm_efi_label - namespace superblock
1034a826c83SDan Williams * @uuid: UUID per RFC 4122
1044a826c83SDan Williams * @name: optional name (NULL-terminated)
1054a826c83SDan Williams * @flags: see NSLABEL_FLAG_*
1064a826c83SDan Williams * @nlabel: num labels to describe this ns
1074a826c83SDan Williams * @position: labels position in set
1084a826c83SDan Williams * @isetcookie: interleave set cookie
1094a826c83SDan Williams * @lbasize: LBA size in bytes or 0 for pmem
1104a826c83SDan Williams * @dpa: DPA of NVM range on this DIMM
1114a826c83SDan Williams * @rawsize: size of namespace
1124a826c83SDan Williams * @slot: slot of this label in label area
113999c993aSDan Williams * @align: physical address alignment of the namespace
114999c993aSDan Williams * @reserved: reserved
115999c993aSDan Williams * @type_guid: copy of struct acpi_nfit_system_address.range_guid
116999c993aSDan Williams * @abstraction_guid: personality id (btt, btt2, fsdax, devdax....)
117999c993aSDan Williams * @reserved2: reserved
118999c993aSDan Williams * @checksum: fletcher64 sum of this object
1194a826c83SDan Williams */
1205af96835SDan Williams struct nvdimm_efi_label {
1214a826c83SDan Williams u8 uuid[NSLABEL_UUID_LEN];
1224a826c83SDan Williams u8 name[NSLABEL_NAME_LEN];
1234a826c83SDan Williams __le32 flags;
1244a826c83SDan Williams __le16 nlabel;
1254a826c83SDan Williams __le16 position;
1264a826c83SDan Williams __le64 isetcookie;
1274a826c83SDan Williams __le64 lbasize;
1284a826c83SDan Williams __le64 dpa;
1294a826c83SDan Williams __le64 rawsize;
1304a826c83SDan Williams __le32 slot;
131564e871aSDan Williams /*
132564e871aSDan Williams * Accessing fields past this point should be gated by a
1335af96835SDan Williams * efi_namespace_label_has() check.
134564e871aSDan Williams */
135564e871aSDan Williams u8 align;
136564e871aSDan Williams u8 reserved[3];
137564e871aSDan Williams guid_t type_guid;
138564e871aSDan Williams guid_t abstraction_guid;
139564e871aSDan Williams u8 reserved2[88];
140564e871aSDan Williams __le64 checksum;
1414a826c83SDan Williams };
1424a826c83SDan Williams
1435af96835SDan Williams /**
1445af96835SDan Williams * struct nvdimm_cxl_label - CXL 2.0 Table 212
1455af96835SDan Williams * @type: uuid identifying this label format (namespace)
1465af96835SDan Williams * @uuid: uuid for the namespace this label describes
1475af96835SDan Williams * @name: friendly name for the namespace
1485af96835SDan Williams * @flags: NSLABEL_FLAG_UPDATING (all other flags reserved)
1495af96835SDan Williams * @nrange: discontiguous namespace support
1505af96835SDan Williams * @position: this label's position in the set
1515af96835SDan Williams * @dpa: start address in device-local capacity for this label
1525af96835SDan Williams * @rawsize: size of this label's contribution to namespace
1535af96835SDan Williams * @slot: slot id of this label in label area
1545af96835SDan Williams * @align: alignment in SZ_256M blocks
1555af96835SDan Williams * @region_uuid: host interleave set identifier
1565af96835SDan Williams * @abstraction_uuid: personality driver for this namespace
1575af96835SDan Williams * @lbasize: address geometry for disk-like personalities
1585af96835SDan Williams * @reserved: reserved
1595af96835SDan Williams * @checksum: fletcher64 sum of this label
1605af96835SDan Williams */
1615af96835SDan Williams struct nvdimm_cxl_label {
1625af96835SDan Williams u8 type[NSLABEL_UUID_LEN];
1635af96835SDan Williams u8 uuid[NSLABEL_UUID_LEN];
1645af96835SDan Williams u8 name[NSLABEL_NAME_LEN];
1655af96835SDan Williams __le32 flags;
1665af96835SDan Williams __le16 nrange;
1675af96835SDan Williams __le16 position;
1685af96835SDan Williams __le64 dpa;
1695af96835SDan Williams __le64 rawsize;
1705af96835SDan Williams __le32 slot;
1715af96835SDan Williams __le32 align;
1725af96835SDan Williams u8 region_uuid[16];
1735af96835SDan Williams u8 abstraction_uuid[16];
1745af96835SDan Williams __le16 lbasize;
1755af96835SDan Williams u8 reserved[0x56];
1765af96835SDan Williams __le64 checksum;
1775af96835SDan Williams };
1785af96835SDan Williams
1795af96835SDan Williams struct nd_namespace_label {
1805af96835SDan Williams union {
1815af96835SDan Williams struct nvdimm_cxl_label cxl;
1825af96835SDan Williams struct nvdimm_efi_label efi;
1835af96835SDan Williams };
1845af96835SDan Williams };
1855af96835SDan Williams
186b3fde74eSDan Williams #define NVDIMM_BTT_GUID "8aed63a2-29a2-4c66-8b12-f05d15d3922a"
18714e49454SVishal Verma #define NVDIMM_BTT2_GUID "18633bfc-1735-4217-8ac9-17239282d3f8"
188b3fde74eSDan Williams #define NVDIMM_PFN_GUID "266400ba-fb9f-4677-bcb0-968f11d0d225"
189b3fde74eSDan Williams #define NVDIMM_DAX_GUID "97a86d9c-3cdd-4eda-986f-5068b4f80088"
190b3fde74eSDan Williams
1915af96835SDan Williams #define CXL_REGION_UUID "529d7c61-da07-47c4-a93f-ecdf2c06f444"
1925af96835SDan Williams #define CXL_NAMESPACE_UUID "68bb2c0a-5a77-4937-9f85-3caf41a0f93c"
1935af96835SDan Williams
1944a826c83SDan Williams /**
1954a826c83SDan Williams * struct nd_label_id - identifier string for dpa allocation
196*3b6c6c03SDan Williams * @id: "pmem-<namespace uuid>"
1974a826c83SDan Williams */
1984a826c83SDan Williams struct nd_label_id {
1994a826c83SDan Williams char id[ND_LABEL_ID_SIZE];
2004a826c83SDan Williams };
2014a826c83SDan Williams
2024a826c83SDan Williams /*
2034a826c83SDan Williams * If the 'best' index is invalid, so is the 'next' index. Otherwise,
2044a826c83SDan Williams * the next index is MOD(index+1, 2)
2054a826c83SDan Williams */
nd_label_next_nsindex(int index)2064a826c83SDan Williams static inline int nd_label_next_nsindex(int index)
2074a826c83SDan Williams {
2084a826c83SDan Williams if (index < 0)
2094a826c83SDan Williams return -1;
2104a826c83SDan Williams
2114a826c83SDan Williams return (index + 1) % 2;
2124a826c83SDan Williams }
2134a826c83SDan Williams
2144a826c83SDan Williams struct nvdimm_drvdata;
2152d657d17SAlexander Duyck int nd_label_data_init(struct nvdimm_drvdata *ndd);
2164a826c83SDan Williams size_t sizeof_namespace_index(struct nvdimm_drvdata *ndd);
217bf9bccc1SDan Williams int nd_label_active_count(struct nvdimm_drvdata *ndd);
218bf9bccc1SDan Williams struct nd_namespace_label *nd_label_active(struct nvdimm_drvdata *ndd, int n);
2190ba1c634SDan Williams u32 nd_label_alloc_slot(struct nvdimm_drvdata *ndd);
2200ba1c634SDan Williams bool nd_label_free_slot(struct nvdimm_drvdata *ndd, u32 slot);
221f524bf27SDan Williams u32 nd_label_nfree(struct nvdimm_drvdata *ndd);
222f524bf27SDan Williams struct nd_region;
223f524bf27SDan Williams struct nd_namespace_pmem;
224f524bf27SDan Williams int nd_pmem_namespace_label_update(struct nd_region *nd_region,
225f524bf27SDan Williams struct nd_namespace_pmem *nspm, resource_size_t size);
2264a826c83SDan Williams #endif /* __LABEL_H__ */
227