// SPDX-License-Identifier: GPL-2.0-only
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/genalloc.h>
#include <linux/vmalloc.h>
#include <linux/dma-mapping.h>
#include <linux/list_sort.h>
#include <linux/libnvdimm.h>
#include <linux/ndctl.h>
#include <nd-core.h>
#include <linux/printk.h>
#include <linux/seq_buf.h>
#include "../watermark.h"
#include "nfit_test.h"
#include "ndtest.h"
enum {
DIMM_SIZE = SZ_32M,
LABEL_SIZE = SZ_128K,
NUM_INSTANCES = 2,
NUM_DCR = 4,
NDTEST_MAX_MAPPING = 6,
};
#define NDTEST_SCM_DIMM_CMD_MASK \
((1ul << ND_CMD_GET_CONFIG_SIZE) | \
(1ul << ND_CMD_GET_CONFIG_DATA) | \
(1ul << ND_CMD_SET_CONFIG_DATA) | \
(1ul << ND_CMD_CALL))
#define NFIT_DIMM_HANDLE(node, socket, imc, chan, dimm) \
(((node & 0xfff) << 16) | ((socket & 0xf) << 12) \
| ((imc & 0xf) << 8) | ((chan & 0xf) << 4) | (dimm & 0xf))
static DEFINE_SPINLOCK(ndtest_lock);
static struct ndtest_priv *instances[NUM_INSTANCES];
static struct class *ndtest_dimm_class;
static struct gen_pool *ndtest_pool;
static struct ndtest_dimm dimm_group1[] = {
{
.size = DIMM_SIZE,
.handle = NFIT_DIMM_HANDLE(0, 0, 0, 0, 0),
.uuid_str = "1e5c75d2-b618-11ea-9aa3-507b9ddc0f72",
.physical_id = 0,
.num_formats = 2,
},
{
.size = DIMM_SIZE,
.handle = NFIT_DIMM_HANDLE(0, 0, 0, 0, 1),
.uuid_str = "1c4d43ac-b618-11ea-be80-507b9ddc0f72",
.physical_id = 1,
.num_formats = 2,
},
{
.size = DIMM_SIZE,
.handle = NFIT_DIMM_HANDLE(0, 0, 1, 0, 0),
.uuid_str = "a9f17ffc-b618-11ea-b36d-507b9ddc0f72",
.physical_id = 2,
.num_formats = 2,
},
{
.size = DIMM_SIZE,
.handle = NFIT_DIMM_HANDLE(0, 0, 1, 0, 1),
.uuid_str = "b6b83b22-b618-11ea-8aae-507b9ddc0f72",
.physical_id = 3,
.num_formats = 2,
},
{
.size = DIMM_SIZE,
.handle = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0),
.uuid_str = "bf9baaee-b618-11ea-b181-507b9ddc0f72",
.physical_id = 4,
.num_formats = 2,
},
};
static struct ndtest_dimm dimm_group2[] = {
{
.size = DIMM_SIZE,
.handle = NFIT_DIMM_HANDLE(1, 0, 0, 0, 0),
.uuid_str = "ca0817e2-b618-11ea-9db3-507b9ddc0f72",
.physical_id = 0,
.num_formats = 1,
},
};
static struct ndtest_mapping region0_mapping[] = {
{
.dimm = 0,
.position = 0,
.start = 0,
.size = SZ_16M,
},
{
.dimm = 1,
.position = 1,
.start = 0,
.size = SZ_16M,
}
};
static struct ndtest_mapping region1_mapping[] = {
{
.dimm = 0,
.position = 0,
.start = SZ_16M,
.size = SZ_16M,
},
{
.dimm = 1,
.position = 1,
.start = SZ_16M,
.size = SZ_16M,
},
{
.dimm = 2,
.position = 2,
.start = SZ_16M,
.size = SZ_16M,
},
{
.dimm = 3,
.position = 3,
.start = SZ_16M,
.size = SZ_16M,
},
};
static struct ndtest_mapping region2_mapping[] = {
{
.dimm = 0,
.position = 0,
.start = 0,
.size = DIMM_SIZE,
},
};
static struct ndtest_mapping region3_mapping[] = {
{
.dimm = 1,
.start = 0,
.size = DIMM_SIZE,
}
};
static struct ndtest_mapping region4_mapping[] = {
{
.dimm = 2,
.start = 0,
.size = DIMM_SIZE,
}
};
static struct ndtest_mapping region5_mapping[] = {
{
.dimm = 3,
.start = 0,
.size = DIMM_SIZE,
}
};
static struct ndtest_region bus0_regions[] = {
{
.type = ND_DEVICE_NAMESPACE_PMEM,
.num_mappings = ARRAY_SIZE(region0_mapping),
.mapping = region0_mapping,
.size = DIMM_SIZE,
.range_index = 1,
},
{
.type = ND_DEVICE_NAMESPACE_PMEM,
.num_mappings =