xref: /openbmc/linux/tools/testing/nvdimm/test/nfit.c (revision f471f1a7d0aa58c609e665514010650b2afa24b6)
1 /*
2  * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  */
13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #include <linux/platform_device.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/libnvdimm.h>
17 #include <linux/vmalloc.h>
18 #include <linux/device.h>
19 #include <linux/module.h>
20 #include <linux/mutex.h>
21 #include <linux/ndctl.h>
22 #include <linux/sizes.h>
23 #include <linux/list.h>
24 #include <linux/slab.h>
25 #include <nfit.h>
26 #include <nd.h>
27 #include "nfit_test.h"
28 
29 /*
30  * Generate an NFIT table to describe the following topology:
31  *
32  * BUS0: Interleaved PMEM regions, and aliasing with BLK regions
33  *
34  *                     (a)                       (b)            DIMM   BLK-REGION
35  *           +----------+--------------+----------+---------+
36  * +------+  |  blk2.0  |     pm0.0    |  blk2.1  |  pm1.0  |    0      region2
37  * | imc0 +--+- - - - - region0 - - - -+----------+         +
38  * +--+---+  |  blk3.0  |     pm0.0    |  blk3.1  |  pm1.0  |    1      region3
39  *    |      +----------+--------------v----------v         v
40  * +--+---+                            |                    |
41  * | cpu0 |                                    region1
42  * +--+---+                            |                    |
43  *    |      +-------------------------^----------^         ^
44  * +--+---+  |                 blk4.0             |  pm1.0  |    2      region4
45  * | imc1 +--+-------------------------+----------+         +
46  * +------+  |                 blk5.0             |  pm1.0  |    3      region5
47  *           +-------------------------+----------+-+-------+
48  *
49  * +--+---+
50  * | cpu1 |
51  * +--+---+                   (Hotplug DIMM)
52  *    |      +----------------------------------------------+
53  * +--+---+  |                 blk6.0/pm7.0                 |    4      region6/7
54  * | imc0 +--+----------------------------------------------+
55  * +------+
56  *
57  *
58  * *) In this layout we have four dimms and two memory controllers in one
59  *    socket.  Each unique interface (BLK or PMEM) to DPA space
60  *    is identified by a region device with a dynamically assigned id.
61  *
62  * *) The first portion of dimm0 and dimm1 are interleaved as REGION0.
63  *    A single PMEM namespace "pm0.0" is created using half of the
64  *    REGION0 SPA-range.  REGION0 spans dimm0 and dimm1.  PMEM namespace
65  *    allocate from from the bottom of a region.  The unallocated
66  *    portion of REGION0 aliases with REGION2 and REGION3.  That
67  *    unallacted capacity is reclaimed as BLK namespaces ("blk2.0" and
68  *    "blk3.0") starting at the base of each DIMM to offset (a) in those
69  *    DIMMs.  "pm0.0", "blk2.0" and "blk3.0" are free-form readable
70  *    names that can be assigned to a namespace.
71  *
72  * *) In the last portion of dimm0 and dimm1 we have an interleaved
73  *    SPA range, REGION1, that spans those two dimms as well as dimm2
74  *    and dimm3.  Some of REGION1 allocated to a PMEM namespace named
75  *    "pm1.0" the rest is reclaimed in 4 BLK namespaces (for each
76  *    dimm in the interleave set), "blk2.1", "blk3.1", "blk4.0", and
77  *    "blk5.0".
78  *
79  * *) The portion of dimm2 and dimm3 that do not participate in the
80  *    REGION1 interleaved SPA range (i.e. the DPA address below offset
81  *    (b) are also included in the "blk4.0" and "blk5.0" namespaces.
82  *    Note, that BLK namespaces need not be contiguous in DPA-space, and
83  *    can consume aliased capacity from multiple interleave sets.
84  *
85  * BUS1: Legacy NVDIMM (single contiguous range)
86  *
87  *  region2
88  * +---------------------+
89  * |---------------------|
90  * ||       pm2.0       ||
91  * |---------------------|
92  * +---------------------+
93  *
94  * *) A NFIT-table may describe a simple system-physical-address range
95  *    with no BLK aliasing.  This type of region may optionally
96  *    reference an NVDIMM.
97  */
98 enum {
99 	NUM_PM  = 3,
100 	NUM_DCR = 5,
101 	NUM_BDW = NUM_DCR,
102 	NUM_SPA = NUM_PM + NUM_DCR + NUM_BDW,
103 	NUM_MEM = NUM_DCR + NUM_BDW + 2 /* spa0 iset */ + 4 /* spa1 iset */,
104 	DIMM_SIZE = SZ_32M,
105 	LABEL_SIZE = SZ_128K,
106 	SPA0_SIZE = DIMM_SIZE,
107 	SPA1_SIZE = DIMM_SIZE*2,
108 	SPA2_SIZE = DIMM_SIZE,
109 	BDW_SIZE = 64 << 8,
110 	DCR_SIZE = 12,
111 	NUM_NFITS = 2, /* permit testing multiple NFITs per system */
112 };
113 
114 struct nfit_test_dcr {
115 	__le64 bdw_addr;
116 	__le32 bdw_status;
117 	__u8 aperature[BDW_SIZE];
118 };
119 
120 #define NFIT_DIMM_HANDLE(node, socket, imc, chan, dimm) \
121 	(((node & 0xfff) << 16) | ((socket & 0xf) << 12) \
122 	 | ((imc & 0xf) << 8) | ((chan & 0xf) << 4) | (dimm & 0xf))
123 
124 static u32 handle[NUM_DCR] = {
125 	[0] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 0),
126 	[1] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 1),
127 	[2] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 0),
128 	[3] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 1),
129 	[4] = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0),
130 };
131 
132 struct nfit_test {
133 	struct acpi_nfit_desc acpi_desc;
134 	struct platform_device pdev;
135 	struct list_head resources;
136 	void *nfit_buf;
137 	dma_addr_t nfit_dma;
138 	size_t nfit_size;
139 	int num_dcr;
140 	int num_pm;
141 	void **dimm;
142 	dma_addr_t *dimm_dma;
143 	void **flush;
144 	dma_addr_t *flush_dma;
145 	void **label;
146 	dma_addr_t *label_dma;
147 	void **spa_set;
148 	dma_addr_t *spa_set_dma;
149 	struct nfit_test_dcr **dcr;
150 	dma_addr_t *dcr_dma;
151 	int (*alloc)(struct nfit_test *t);
152 	void (*setup)(struct nfit_test *t);
153 	int setup_hotplug;
154 	struct ars_state {
155 		struct nd_cmd_ars_status *ars_status;
156 		unsigned long deadline;
157 		spinlock_t lock;
158 	} ars_state;
159 };
160 
161 static struct nfit_test *to_nfit_test(struct device *dev)
162 {
163 	struct platform_device *pdev = to_platform_device(dev);
164 
165 	return container_of(pdev, struct nfit_test, pdev);
166 }
167 
168 static int nfit_test_cmd_get_config_size(struct nd_cmd_get_config_size *nd_cmd,
169 		unsigned int buf_len)
170 {
171 	if (buf_len < sizeof(*nd_cmd))
172 		return -EINVAL;
173 
174 	nd_cmd->status = 0;
175 	nd_cmd->config_size = LABEL_SIZE;
176 	nd_cmd->max_xfer = SZ_4K;
177 
178 	return 0;
179 }
180 
181 static int nfit_test_cmd_get_config_data(struct nd_cmd_get_config_data_hdr
182 		*nd_cmd, unsigned int buf_len, void *label)
183 {
184 	unsigned int len, offset = nd_cmd->in_offset;
185 	int rc;
186 
187 	if (buf_len < sizeof(*nd_cmd))
188 		return -EINVAL;
189 	if (offset >= LABEL_SIZE)
190 		return -EINVAL;
191 	if (nd_cmd->in_length + sizeof(*nd_cmd) > buf_len)
192 		return -EINVAL;
193 
194 	nd_cmd->status = 0;
195 	len = min(nd_cmd->in_length, LABEL_SIZE - offset);
196 	memcpy(nd_cmd->out_buf, label + offset, len);
197 	rc = buf_len - sizeof(*nd_cmd) - len;
198 
199 	return rc;
200 }
201 
202 static int nfit_test_cmd_set_config_data(struct nd_cmd_set_config_hdr *nd_cmd,
203 		unsigned int buf_len, void *label)
204 {
205 	unsigned int len, offset = nd_cmd->in_offset;
206 	u32 *status;
207 	int rc;
208 
209 	if (buf_len < sizeof(*nd_cmd))
210 		return -EINVAL;
211 	if (offset >= LABEL_SIZE)
212 		return -EINVAL;
213 	if (nd_cmd->in_length + sizeof(*nd_cmd) + 4 > buf_len)
214 		return -EINVAL;
215 
216 	status = (void *)nd_cmd + nd_cmd->in_length + sizeof(*nd_cmd);
217 	*status = 0;
218 	len = min(nd_cmd->in_length, LABEL_SIZE - offset);
219 	memcpy(label + offset, nd_cmd->in_buf, len);
220 	rc = buf_len - sizeof(*nd_cmd) - (len + 4);
221 
222 	return rc;
223 }
224 
225 #define NFIT_TEST_ARS_RECORDS 4
226 
227 static int nfit_test_cmd_ars_cap(struct nd_cmd_ars_cap *nd_cmd,
228 		unsigned int buf_len)
229 {
230 	if (buf_len < sizeof(*nd_cmd))
231 		return -EINVAL;
232 
233 	nd_cmd->max_ars_out = sizeof(struct nd_cmd_ars_status)
234 		+ NFIT_TEST_ARS_RECORDS * sizeof(struct nd_ars_record);
235 	nd_cmd->status = (ND_ARS_PERSISTENT | ND_ARS_VOLATILE) << 16;
236 
237 	return 0;
238 }
239 
240 /*
241  * Initialize the ars_state to return an ars_result 1 second in the future with
242  * a 4K error range in the middle of the requested address range.
243  */
244 static void post_ars_status(struct ars_state *ars_state, u64 addr, u64 len)
245 {
246 	struct nd_cmd_ars_status *ars_status;
247 	struct nd_ars_record *ars_record;
248 
249 	ars_state->deadline = jiffies + 1*HZ;
250 	ars_status = ars_state->ars_status;
251 	ars_status->status = 0;
252 	ars_status->out_length = sizeof(struct nd_cmd_ars_status)
253 		+ sizeof(struct nd_ars_record);
254 	ars_status->address = addr;
255 	ars_status->length = len;
256 	ars_status->type = ND_ARS_PERSISTENT;
257 	ars_status->num_records = 1;
258 	ars_record = &ars_status->records[0];
259 	ars_record->handle = 0;
260 	ars_record->err_address = addr + len / 2;
261 	ars_record->length = SZ_4K;
262 }
263 
264 static int nfit_test_cmd_ars_start(struct ars_state *ars_state,
265 		struct nd_cmd_ars_start *ars_start, unsigned int buf_len,
266 		int *cmd_rc)
267 {
268 	if (buf_len < sizeof(*ars_start))
269 		return -EINVAL;
270 
271 	spin_lock(&ars_state->lock);
272 	if (time_before(jiffies, ars_state->deadline)) {
273 		ars_start->status = NFIT_ARS_START_BUSY;
274 		*cmd_rc = -EBUSY;
275 	} else {
276 		ars_start->status = 0;
277 		ars_start->scrub_time = 1;
278 		post_ars_status(ars_state, ars_start->address,
279 				ars_start->length);
280 		*cmd_rc = 0;
281 	}
282 	spin_unlock(&ars_state->lock);
283 
284 	return 0;
285 }
286 
287 static int nfit_test_cmd_ars_status(struct ars_state *ars_state,
288 		struct nd_cmd_ars_status *ars_status, unsigned int buf_len,
289 		int *cmd_rc)
290 {
291 	if (buf_len < ars_state->ars_status->out_length)
292 		return -EINVAL;
293 
294 	spin_lock(&ars_state->lock);
295 	if (time_before(jiffies, ars_state->deadline)) {
296 		memset(ars_status, 0, buf_len);
297 		ars_status->status = NFIT_ARS_STATUS_BUSY;
298 		ars_status->out_length = sizeof(*ars_status);
299 		*cmd_rc = -EBUSY;
300 	} else {
301 		memcpy(ars_status, ars_state->ars_status,
302 				ars_state->ars_status->out_length);
303 		*cmd_rc = 0;
304 	}
305 	spin_unlock(&ars_state->lock);
306 	return 0;
307 }
308 
309 static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
310 		struct nvdimm *nvdimm, unsigned int cmd, void *buf,
311 		unsigned int buf_len, int *cmd_rc)
312 {
313 	struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
314 	struct nfit_test *t = container_of(acpi_desc, typeof(*t), acpi_desc);
315 	int i, rc = 0, __cmd_rc;
316 
317 	if (!cmd_rc)
318 		cmd_rc = &__cmd_rc;
319 	*cmd_rc = 0;
320 
321 	if (nvdimm) {
322 		struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
323 
324 		if (!nfit_mem || !test_bit(cmd, &nfit_mem->dsm_mask))
325 			return -ENOTTY;
326 
327 		/* lookup label space for the given dimm */
328 		for (i = 0; i < ARRAY_SIZE(handle); i++)
329 			if (__to_nfit_memdev(nfit_mem)->device_handle ==
330 					handle[i])
331 				break;
332 		if (i >= ARRAY_SIZE(handle))
333 			return -ENXIO;
334 
335 		switch (cmd) {
336 		case ND_CMD_GET_CONFIG_SIZE:
337 			rc = nfit_test_cmd_get_config_size(buf, buf_len);
338 			break;
339 		case ND_CMD_GET_CONFIG_DATA:
340 			rc = nfit_test_cmd_get_config_data(buf, buf_len,
341 				t->label[i]);
342 			break;
343 		case ND_CMD_SET_CONFIG_DATA:
344 			rc = nfit_test_cmd_set_config_data(buf, buf_len,
345 				t->label[i]);
346 			break;
347 		default:
348 			return -ENOTTY;
349 		}
350 	} else {
351 		struct ars_state *ars_state = &t->ars_state;
352 
353 		if (!nd_desc || !test_bit(cmd, &nd_desc->dsm_mask))
354 			return -ENOTTY;
355 
356 		switch (cmd) {
357 		case ND_CMD_ARS_CAP:
358 			rc = nfit_test_cmd_ars_cap(buf, buf_len);
359 			break;
360 		case ND_CMD_ARS_START:
361 			rc = nfit_test_cmd_ars_start(ars_state, buf, buf_len,
362 					cmd_rc);
363 			break;
364 		case ND_CMD_ARS_STATUS:
365 			rc = nfit_test_cmd_ars_status(ars_state, buf, buf_len,
366 					cmd_rc);
367 			break;
368 		default:
369 			return -ENOTTY;
370 		}
371 	}
372 
373 	return rc;
374 }
375 
376 static DEFINE_SPINLOCK(nfit_test_lock);
377 static struct nfit_test *instances[NUM_NFITS];
378 
379 static void release_nfit_res(void *data)
380 {
381 	struct nfit_test_resource *nfit_res = data;
382 	struct resource *res = nfit_res->res;
383 
384 	spin_lock(&nfit_test_lock);
385 	list_del(&nfit_res->list);
386 	spin_unlock(&nfit_test_lock);
387 
388 	if (is_vmalloc_addr(nfit_res->buf))
389 		vfree(nfit_res->buf);
390 	else
391 		dma_free_coherent(nfit_res->dev, resource_size(res),
392 				nfit_res->buf, res->start);
393 	kfree(res);
394 	kfree(nfit_res);
395 }
396 
397 static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,
398 		void *buf)
399 {
400 	struct device *dev = &t->pdev.dev;
401 	struct resource *res = kzalloc(sizeof(*res) * 2, GFP_KERNEL);
402 	struct nfit_test_resource *nfit_res = kzalloc(sizeof(*nfit_res),
403 			GFP_KERNEL);
404 	int rc;
405 
406 	if (!res || !buf || !nfit_res)
407 		goto err;
408 	rc = devm_add_action(dev, release_nfit_res, nfit_res);
409 	if (rc)
410 		goto err;
411 	INIT_LIST_HEAD(&nfit_res->list);
412 	memset(buf, 0, size);
413 	nfit_res->dev = dev;
414 	nfit_res->buf = buf;
415 	nfit_res->res = res;
416 	res->start = *dma;
417 	res->end = *dma + size - 1;
418 	res->name = "NFIT";
419 	spin_lock(&nfit_test_lock);
420 	list_add(&nfit_res->list, &t->resources);
421 	spin_unlock(&nfit_test_lock);
422 
423 	return nfit_res->buf;
424  err:
425 	if (buf && !is_vmalloc_addr(buf))
426 		dma_free_coherent(dev, size, buf, *dma);
427 	else if (buf)
428 		vfree(buf);
429 	kfree(res);
430 	kfree(nfit_res);
431 	return NULL;
432 }
433 
434 static void *test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma)
435 {
436 	void *buf = vmalloc(size);
437 
438 	*dma = (unsigned long) buf;
439 	return __test_alloc(t, size, dma, buf);
440 }
441 
442 static void *test_alloc_coherent(struct nfit_test *t, size_t size,
443 		dma_addr_t *dma)
444 {
445 	struct device *dev = &t->pdev.dev;
446 	void *buf = dma_alloc_coherent(dev, size, dma, GFP_KERNEL);
447 
448 	return __test_alloc(t, size, dma, buf);
449 }
450 
451 static struct nfit_test_resource *nfit_test_lookup(resource_size_t addr)
452 {
453 	int i;
454 
455 	for (i = 0; i < ARRAY_SIZE(instances); i++) {
456 		struct nfit_test_resource *n, *nfit_res = NULL;
457 		struct nfit_test *t = instances[i];
458 
459 		if (!t)
460 			continue;
461 		spin_lock(&nfit_test_lock);
462 		list_for_each_entry(n, &t->resources, list) {
463 			if (addr >= n->res->start && (addr < n->res->start
464 						+ resource_size(n->res))) {
465 				nfit_res = n;
466 				break;
467 			} else if (addr >= (unsigned long) n->buf
468 					&& (addr < (unsigned long) n->buf
469 						+ resource_size(n->res))) {
470 				nfit_res = n;
471 				break;
472 			}
473 		}
474 		spin_unlock(&nfit_test_lock);
475 		if (nfit_res)
476 			return nfit_res;
477 	}
478 
479 	return NULL;
480 }
481 
482 static int ars_state_init(struct device *dev, struct ars_state *ars_state)
483 {
484 	ars_state->ars_status = devm_kzalloc(dev,
485 			sizeof(struct nd_cmd_ars_status)
486 			+ sizeof(struct nd_ars_record) * NFIT_TEST_ARS_RECORDS,
487 			GFP_KERNEL);
488 	if (!ars_state->ars_status)
489 		return -ENOMEM;
490 	spin_lock_init(&ars_state->lock);
491 	return 0;
492 }
493 
494 static int nfit_test0_alloc(struct nfit_test *t)
495 {
496 	size_t nfit_size = sizeof(struct acpi_nfit_system_address) * NUM_SPA
497 			+ sizeof(struct acpi_nfit_memory_map) * NUM_MEM
498 			+ sizeof(struct acpi_nfit_control_region) * NUM_DCR
499 			+ offsetof(struct acpi_nfit_control_region,
500 					window_size) * NUM_DCR
501 			+ sizeof(struct acpi_nfit_data_region) * NUM_BDW
502 			+ sizeof(struct acpi_nfit_flush_address) * NUM_DCR;
503 	int i;
504 
505 	t->nfit_buf = test_alloc(t, nfit_size, &t->nfit_dma);
506 	if (!t->nfit_buf)
507 		return -ENOMEM;
508 	t->nfit_size = nfit_size;
509 
510 	t->spa_set[0] = test_alloc_coherent(t, SPA0_SIZE, &t->spa_set_dma[0]);
511 	if (!t->spa_set[0])
512 		return -ENOMEM;
513 
514 	t->spa_set[1] = test_alloc_coherent(t, SPA1_SIZE, &t->spa_set_dma[1]);
515 	if (!t->spa_set[1])
516 		return -ENOMEM;
517 
518 	t->spa_set[2] = test_alloc_coherent(t, SPA0_SIZE, &t->spa_set_dma[2]);
519 	if (!t->spa_set[2])
520 		return -ENOMEM;
521 
522 	for (i = 0; i < NUM_DCR; i++) {
523 		t->dimm[i] = test_alloc(t, DIMM_SIZE, &t->dimm_dma[i]);
524 		if (!t->dimm[i])
525 			return -ENOMEM;
526 
527 		t->label[i] = test_alloc(t, LABEL_SIZE, &t->label_dma[i]);
528 		if (!t->label[i])
529 			return -ENOMEM;
530 		sprintf(t->label[i], "label%d", i);
531 
532 		t->flush[i] = test_alloc(t, 8, &t->flush_dma[i]);
533 		if (!t->flush[i])
534 			return -ENOMEM;
535 	}
536 
537 	for (i = 0; i < NUM_DCR; i++) {
538 		t->dcr[i] = test_alloc(t, LABEL_SIZE, &t->dcr_dma[i]);
539 		if (!t->dcr[i])
540 			return -ENOMEM;
541 	}
542 
543 	return ars_state_init(&t->pdev.dev, &t->ars_state);
544 }
545 
546 static int nfit_test1_alloc(struct nfit_test *t)
547 {
548 	size_t nfit_size = sizeof(struct acpi_nfit_system_address)
549 		+ sizeof(struct acpi_nfit_memory_map)
550 		+ offsetof(struct acpi_nfit_control_region, window_size);
551 
552 	t->nfit_buf = test_alloc(t, nfit_size, &t->nfit_dma);
553 	if (!t->nfit_buf)
554 		return -ENOMEM;
555 	t->nfit_size = nfit_size;
556 
557 	t->spa_set[0] = test_alloc_coherent(t, SPA2_SIZE, &t->spa_set_dma[0]);
558 	if (!t->spa_set[0])
559 		return -ENOMEM;
560 
561 	return ars_state_init(&t->pdev.dev, &t->ars_state);
562 }
563 
564 static void nfit_test0_setup(struct nfit_test *t)
565 {
566 	struct acpi_nfit_desc *acpi_desc;
567 	struct acpi_nfit_memory_map *memdev;
568 	void *nfit_buf = t->nfit_buf;
569 	struct acpi_nfit_system_address *spa;
570 	struct acpi_nfit_control_region *dcr;
571 	struct acpi_nfit_data_region *bdw;
572 	struct acpi_nfit_flush_address *flush;
573 	unsigned int offset;
574 
575 	/*
576 	 * spa0 (interleave first half of dimm0 and dimm1, note storage
577 	 * does not actually alias the related block-data-window
578 	 * regions)
579 	 */
580 	spa = nfit_buf;
581 	spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
582 	spa->header.length = sizeof(*spa);
583 	memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16);
584 	spa->range_index = 0+1;
585 	spa->address = t->spa_set_dma[0];
586 	spa->length = SPA0_SIZE;
587 
588 	/*
589 	 * spa1 (interleave last half of the 4 DIMMS, note storage
590 	 * does not actually alias the related block-data-window
591 	 * regions)
592 	 */
593 	spa = nfit_buf + sizeof(*spa);
594 	spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
595 	spa->header.length = sizeof(*spa);
596 	memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16);
597 	spa->range_index = 1+1;
598 	spa->address = t->spa_set_dma[1];
599 	spa->length = SPA1_SIZE;
600 
601 	/* spa2 (dcr0) dimm0 */
602 	spa = nfit_buf + sizeof(*spa) * 2;
603 	spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
604 	spa->header.length = sizeof(*spa);
605 	memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
606 	spa->range_index = 2+1;
607 	spa->address = t->dcr_dma[0];
608 	spa->length = DCR_SIZE;
609 
610 	/* spa3 (dcr1) dimm1 */
611 	spa = nfit_buf + sizeof(*spa) * 3;
612 	spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
613 	spa->header.length = sizeof(*spa);
614 	memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
615 	spa->range_index = 3+1;
616 	spa->address = t->dcr_dma[1];
617 	spa->length = DCR_SIZE;
618 
619 	/* spa4 (dcr2) dimm2 */
620 	spa = nfit_buf + sizeof(*spa) * 4;
621 	spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
622 	spa->header.length = sizeof(*spa);
623 	memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
624 	spa->range_index = 4+1;
625 	spa->address = t->dcr_dma[2];
626 	spa->length = DCR_SIZE;
627 
628 	/* spa5 (dcr3) dimm3 */
629 	spa = nfit_buf + sizeof(*spa) * 5;
630 	spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
631 	spa->header.length = sizeof(*spa);
632 	memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
633 	spa->range_index = 5+1;
634 	spa->address = t->dcr_dma[3];
635 	spa->length = DCR_SIZE;
636 
637 	/* spa6 (bdw for dcr0) dimm0 */
638 	spa = nfit_buf + sizeof(*spa) * 6;
639 	spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
640 	spa->header.length = sizeof(*spa);
641 	memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
642 	spa->range_index = 6+1;
643 	spa->address = t->dimm_dma[0];
644 	spa->length = DIMM_SIZE;
645 
646 	/* spa7 (bdw for dcr1) dimm1 */
647 	spa = nfit_buf + sizeof(*spa) * 7;
648 	spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
649 	spa->header.length = sizeof(*spa);
650 	memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
651 	spa->range_index = 7+1;
652 	spa->address = t->dimm_dma[1];
653 	spa->length = DIMM_SIZE;
654 
655 	/* spa8 (bdw for dcr2) dimm2 */
656 	spa = nfit_buf + sizeof(*spa) * 8;
657 	spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
658 	spa->header.length = sizeof(*spa);
659 	memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
660 	spa->range_index = 8+1;
661 	spa->address = t->dimm_dma[2];
662 	spa->length = DIMM_SIZE;
663 
664 	/* spa9 (bdw for dcr3) dimm3 */
665 	spa = nfit_buf + sizeof(*spa) * 9;
666 	spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
667 	spa->header.length = sizeof(*spa);
668 	memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
669 	spa->range_index = 9+1;
670 	spa->address = t->dimm_dma[3];
671 	spa->length = DIMM_SIZE;
672 
673 	offset = sizeof(*spa) * 10;
674 	/* mem-region0 (spa0, dimm0) */
675 	memdev = nfit_buf + offset;
676 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
677 	memdev->header.length = sizeof(*memdev);
678 	memdev->device_handle = handle[0];
679 	memdev->physical_id = 0;
680 	memdev->region_id = 0;
681 	memdev->range_index = 0+1;
682 	memdev->region_index = 4+1;
683 	memdev->region_size = SPA0_SIZE/2;
684 	memdev->region_offset = t->spa_set_dma[0];
685 	memdev->address = 0;
686 	memdev->interleave_index = 0;
687 	memdev->interleave_ways = 2;
688 
689 	/* mem-region1 (spa0, dimm1) */
690 	memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map);
691 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
692 	memdev->header.length = sizeof(*memdev);
693 	memdev->device_handle = handle[1];
694 	memdev->physical_id = 1;
695 	memdev->region_id = 0;
696 	memdev->range_index = 0+1;
697 	memdev->region_index = 5+1;
698 	memdev->region_size = SPA0_SIZE/2;
699 	memdev->region_offset = t->spa_set_dma[0] + SPA0_SIZE/2;
700 	memdev->address = 0;
701 	memdev->interleave_index = 0;
702 	memdev->interleave_ways = 2;
703 
704 	/* mem-region2 (spa1, dimm0) */
705 	memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 2;
706 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
707 	memdev->header.length = sizeof(*memdev);
708 	memdev->device_handle = handle[0];
709 	memdev->physical_id = 0;
710 	memdev->region_id = 1;
711 	memdev->range_index = 1+1;
712 	memdev->region_index = 4+1;
713 	memdev->region_size = SPA1_SIZE/4;
714 	memdev->region_offset = t->spa_set_dma[1];
715 	memdev->address = SPA0_SIZE/2;
716 	memdev->interleave_index = 0;
717 	memdev->interleave_ways = 4;
718 
719 	/* mem-region3 (spa1, dimm1) */
720 	memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 3;
721 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
722 	memdev->header.length = sizeof(*memdev);
723 	memdev->device_handle = handle[1];
724 	memdev->physical_id = 1;
725 	memdev->region_id = 1;
726 	memdev->range_index = 1+1;
727 	memdev->region_index = 5+1;
728 	memdev->region_size = SPA1_SIZE/4;
729 	memdev->region_offset = t->spa_set_dma[1] + SPA1_SIZE/4;
730 	memdev->address = SPA0_SIZE/2;
731 	memdev->interleave_index = 0;
732 	memdev->interleave_ways = 4;
733 
734 	/* mem-region4 (spa1, dimm2) */
735 	memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 4;
736 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
737 	memdev->header.length = sizeof(*memdev);
738 	memdev->device_handle = handle[2];
739 	memdev->physical_id = 2;
740 	memdev->region_id = 0;
741 	memdev->range_index = 1+1;
742 	memdev->region_index = 6+1;
743 	memdev->region_size = SPA1_SIZE/4;
744 	memdev->region_offset = t->spa_set_dma[1] + 2*SPA1_SIZE/4;
745 	memdev->address = SPA0_SIZE/2;
746 	memdev->interleave_index = 0;
747 	memdev->interleave_ways = 4;
748 
749 	/* mem-region5 (spa1, dimm3) */
750 	memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 5;
751 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
752 	memdev->header.length = sizeof(*memdev);
753 	memdev->device_handle = handle[3];
754 	memdev->physical_id = 3;
755 	memdev->region_id = 0;
756 	memdev->range_index = 1+1;
757 	memdev->region_index = 7+1;
758 	memdev->region_size = SPA1_SIZE/4;
759 	memdev->region_offset = t->spa_set_dma[1] + 3*SPA1_SIZE/4;
760 	memdev->address = SPA0_SIZE/2;
761 	memdev->interleave_index = 0;
762 	memdev->interleave_ways = 4;
763 
764 	/* mem-region6 (spa/dcr0, dimm0) */
765 	memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 6;
766 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
767 	memdev->header.length = sizeof(*memdev);
768 	memdev->device_handle = handle[0];
769 	memdev->physical_id = 0;
770 	memdev->region_id = 0;
771 	memdev->range_index = 2+1;
772 	memdev->region_index = 0+1;
773 	memdev->region_size = 0;
774 	memdev->region_offset = 0;
775 	memdev->address = 0;
776 	memdev->interleave_index = 0;
777 	memdev->interleave_ways = 1;
778 
779 	/* mem-region7 (spa/dcr1, dimm1) */
780 	memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 7;
781 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
782 	memdev->header.length = sizeof(*memdev);
783 	memdev->device_handle = handle[1];
784 	memdev->physical_id = 1;
785 	memdev->region_id = 0;
786 	memdev->range_index = 3+1;
787 	memdev->region_index = 1+1;
788 	memdev->region_size = 0;
789 	memdev->region_offset = 0;
790 	memdev->address = 0;
791 	memdev->interleave_index = 0;
792 	memdev->interleave_ways = 1;
793 
794 	/* mem-region8 (spa/dcr2, dimm2) */
795 	memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 8;
796 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
797 	memdev->header.length = sizeof(*memdev);
798 	memdev->device_handle = handle[2];
799 	memdev->physical_id = 2;
800 	memdev->region_id = 0;
801 	memdev->range_index = 4+1;
802 	memdev->region_index = 2+1;
803 	memdev->region_size = 0;
804 	memdev->region_offset = 0;
805 	memdev->address = 0;
806 	memdev->interleave_index = 0;
807 	memdev->interleave_ways = 1;
808 
809 	/* mem-region9 (spa/dcr3, dimm3) */
810 	memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 9;
811 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
812 	memdev->header.length = sizeof(*memdev);
813 	memdev->device_handle = handle[3];
814 	memdev->physical_id = 3;
815 	memdev->region_id = 0;
816 	memdev->range_index = 5+1;
817 	memdev->region_index = 3+1;
818 	memdev->region_size = 0;
819 	memdev->region_offset = 0;
820 	memdev->address = 0;
821 	memdev->interleave_index = 0;
822 	memdev->interleave_ways = 1;
823 
824 	/* mem-region10 (spa/bdw0, dimm0) */
825 	memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 10;
826 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
827 	memdev->header.length = sizeof(*memdev);
828 	memdev->device_handle = handle[0];
829 	memdev->physical_id = 0;
830 	memdev->region_id = 0;
831 	memdev->range_index = 6+1;
832 	memdev->region_index = 0+1;
833 	memdev->region_size = 0;
834 	memdev->region_offset = 0;
835 	memdev->address = 0;
836 	memdev->interleave_index = 0;
837 	memdev->interleave_ways = 1;
838 
839 	/* mem-region11 (spa/bdw1, dimm1) */
840 	memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 11;
841 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
842 	memdev->header.length = sizeof(*memdev);
843 	memdev->device_handle = handle[1];
844 	memdev->physical_id = 1;
845 	memdev->region_id = 0;
846 	memdev->range_index = 7+1;
847 	memdev->region_index = 1+1;
848 	memdev->region_size = 0;
849 	memdev->region_offset = 0;
850 	memdev->address = 0;
851 	memdev->interleave_index = 0;
852 	memdev->interleave_ways = 1;
853 
854 	/* mem-region12 (spa/bdw2, dimm2) */
855 	memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 12;
856 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
857 	memdev->header.length = sizeof(*memdev);
858 	memdev->device_handle = handle[2];
859 	memdev->physical_id = 2;
860 	memdev->region_id = 0;
861 	memdev->range_index = 8+1;
862 	memdev->region_index = 2+1;
863 	memdev->region_size = 0;
864 	memdev->region_offset = 0;
865 	memdev->address = 0;
866 	memdev->interleave_index = 0;
867 	memdev->interleave_ways = 1;
868 
869 	/* mem-region13 (spa/dcr3, dimm3) */
870 	memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 13;
871 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
872 	memdev->header.length = sizeof(*memdev);
873 	memdev->device_handle = handle[3];
874 	memdev->physical_id = 3;
875 	memdev->region_id = 0;
876 	memdev->range_index = 9+1;
877 	memdev->region_index = 3+1;
878 	memdev->region_size = 0;
879 	memdev->region_offset = 0;
880 	memdev->address = 0;
881 	memdev->interleave_index = 0;
882 	memdev->interleave_ways = 1;
883 
884 	offset = offset + sizeof(struct acpi_nfit_memory_map) * 14;
885 	/* dcr-descriptor0: blk */
886 	dcr = nfit_buf + offset;
887 	dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
888 	dcr->header.length = sizeof(struct acpi_nfit_control_region);
889 	dcr->region_index = 0+1;
890 	dcr->vendor_id = 0xabcd;
891 	dcr->device_id = 0;
892 	dcr->revision_id = 1;
893 	dcr->serial_number = ~handle[0];
894 	dcr->code = NFIT_FIC_BLK;
895 	dcr->windows = 1;
896 	dcr->window_size = DCR_SIZE;
897 	dcr->command_offset = 0;
898 	dcr->command_size = 8;
899 	dcr->status_offset = 8;
900 	dcr->status_size = 4;
901 
902 	/* dcr-descriptor1: blk */
903 	dcr = nfit_buf + offset + sizeof(struct acpi_nfit_control_region);
904 	dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
905 	dcr->header.length = sizeof(struct acpi_nfit_control_region);
906 	dcr->region_index = 1+1;
907 	dcr->vendor_id = 0xabcd;
908 	dcr->device_id = 0;
909 	dcr->revision_id = 1;
910 	dcr->serial_number = ~handle[1];
911 	dcr->code = NFIT_FIC_BLK;
912 	dcr->windows = 1;
913 	dcr->window_size = DCR_SIZE;
914 	dcr->command_offset = 0;
915 	dcr->command_size = 8;
916 	dcr->status_offset = 8;
917 	dcr->status_size = 4;
918 
919 	/* dcr-descriptor2: blk */
920 	dcr = nfit_buf + offset + sizeof(struct acpi_nfit_control_region) * 2;
921 	dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
922 	dcr->header.length = sizeof(struct acpi_nfit_control_region);
923 	dcr->region_index = 2+1;
924 	dcr->vendor_id = 0xabcd;
925 	dcr->device_id = 0;
926 	dcr->revision_id = 1;
927 	dcr->serial_number = ~handle[2];
928 	dcr->code = NFIT_FIC_BLK;
929 	dcr->windows = 1;
930 	dcr->window_size = DCR_SIZE;
931 	dcr->command_offset = 0;
932 	dcr->command_size = 8;
933 	dcr->status_offset = 8;
934 	dcr->status_size = 4;
935 
936 	/* dcr-descriptor3: blk */
937 	dcr = nfit_buf + offset + sizeof(struct acpi_nfit_control_region) * 3;
938 	dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
939 	dcr->header.length = sizeof(struct acpi_nfit_control_region);
940 	dcr->region_index = 3+1;
941 	dcr->vendor_id = 0xabcd;
942 	dcr->device_id = 0;
943 	dcr->revision_id = 1;
944 	dcr->serial_number = ~handle[3];
945 	dcr->code = NFIT_FIC_BLK;
946 	dcr->windows = 1;
947 	dcr->window_size = DCR_SIZE;
948 	dcr->command_offset = 0;
949 	dcr->command_size = 8;
950 	dcr->status_offset = 8;
951 	dcr->status_size = 4;
952 
953 	offset = offset + sizeof(struct acpi_nfit_control_region) * 4;
954 	/* dcr-descriptor0: pmem */
955 	dcr = nfit_buf + offset;
956 	dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
957 	dcr->header.length = offsetof(struct acpi_nfit_control_region,
958 			window_size);
959 	dcr->region_index = 4+1;
960 	dcr->vendor_id = 0xabcd;
961 	dcr->device_id = 0;
962 	dcr->revision_id = 1;
963 	dcr->serial_number = ~handle[0];
964 	dcr->code = NFIT_FIC_BYTEN;
965 	dcr->windows = 0;
966 
967 	/* dcr-descriptor1: pmem */
968 	dcr = nfit_buf + offset + offsetof(struct acpi_nfit_control_region,
969 			window_size);
970 	dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
971 	dcr->header.length = offsetof(struct acpi_nfit_control_region,
972 			window_size);
973 	dcr->region_index = 5+1;
974 	dcr->vendor_id = 0xabcd;
975 	dcr->device_id = 0;
976 	dcr->revision_id = 1;
977 	dcr->serial_number = ~handle[1];
978 	dcr->code = NFIT_FIC_BYTEN;
979 	dcr->windows = 0;
980 
981 	/* dcr-descriptor2: pmem */
982 	dcr = nfit_buf + offset + offsetof(struct acpi_nfit_control_region,
983 			window_size) * 2;
984 	dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
985 	dcr->header.length = offsetof(struct acpi_nfit_control_region,
986 			window_size);
987 	dcr->region_index = 6+1;
988 	dcr->vendor_id = 0xabcd;
989 	dcr->device_id = 0;
990 	dcr->revision_id = 1;
991 	dcr->serial_number = ~handle[2];
992 	dcr->code = NFIT_FIC_BYTEN;
993 	dcr->windows = 0;
994 
995 	/* dcr-descriptor3: pmem */
996 	dcr = nfit_buf + offset + offsetof(struct acpi_nfit_control_region,
997 			window_size) * 3;
998 	dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
999 	dcr->header.length = offsetof(struct acpi_nfit_control_region,
1000 			window_size);
1001 	dcr->region_index = 7+1;
1002 	dcr->vendor_id = 0xabcd;
1003 	dcr->device_id = 0;
1004 	dcr->revision_id = 1;
1005 	dcr->serial_number = ~handle[3];
1006 	dcr->code = NFIT_FIC_BYTEN;
1007 	dcr->windows = 0;
1008 
1009 	offset = offset + offsetof(struct acpi_nfit_control_region,
1010 			window_size) * 4;
1011 	/* bdw0 (spa/dcr0, dimm0) */
1012 	bdw = nfit_buf + offset;
1013 	bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1014 	bdw->header.length = sizeof(struct acpi_nfit_data_region);
1015 	bdw->region_index = 0+1;
1016 	bdw->windows = 1;
1017 	bdw->offset = 0;
1018 	bdw->size = BDW_SIZE;
1019 	bdw->capacity = DIMM_SIZE;
1020 	bdw->start_address = 0;
1021 
1022 	/* bdw1 (spa/dcr1, dimm1) */
1023 	bdw = nfit_buf + offset + sizeof(struct acpi_nfit_data_region);
1024 	bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1025 	bdw->header.length = sizeof(struct acpi_nfit_data_region);
1026 	bdw->region_index = 1+1;
1027 	bdw->windows = 1;
1028 	bdw->offset = 0;
1029 	bdw->size = BDW_SIZE;
1030 	bdw->capacity = DIMM_SIZE;
1031 	bdw->start_address = 0;
1032 
1033 	/* bdw2 (spa/dcr2, dimm2) */
1034 	bdw = nfit_buf + offset + sizeof(struct acpi_nfit_data_region) * 2;
1035 	bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1036 	bdw->header.length = sizeof(struct acpi_nfit_data_region);
1037 	bdw->region_index = 2+1;
1038 	bdw->windows = 1;
1039 	bdw->offset = 0;
1040 	bdw->size = BDW_SIZE;
1041 	bdw->capacity = DIMM_SIZE;
1042 	bdw->start_address = 0;
1043 
1044 	/* bdw3 (spa/dcr3, dimm3) */
1045 	bdw = nfit_buf + offset + sizeof(struct acpi_nfit_data_region) * 3;
1046 	bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1047 	bdw->header.length = sizeof(struct acpi_nfit_data_region);
1048 	bdw->region_index = 3+1;
1049 	bdw->windows = 1;
1050 	bdw->offset = 0;
1051 	bdw->size = BDW_SIZE;
1052 	bdw->capacity = DIMM_SIZE;
1053 	bdw->start_address = 0;
1054 
1055 	offset = offset + sizeof(struct acpi_nfit_data_region) * 4;
1056 	/* flush0 (dimm0) */
1057 	flush = nfit_buf + offset;
1058 	flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1059 	flush->header.length = sizeof(struct acpi_nfit_flush_address);
1060 	flush->device_handle = handle[0];
1061 	flush->hint_count = 1;
1062 	flush->hint_address[0] = t->flush_dma[0];
1063 
1064 	/* flush1 (dimm1) */
1065 	flush = nfit_buf + offset + sizeof(struct acpi_nfit_flush_address) * 1;
1066 	flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1067 	flush->header.length = sizeof(struct acpi_nfit_flush_address);
1068 	flush->device_handle = handle[1];
1069 	flush->hint_count = 1;
1070 	flush->hint_address[0] = t->flush_dma[1];
1071 
1072 	/* flush2 (dimm2) */
1073 	flush = nfit_buf + offset + sizeof(struct acpi_nfit_flush_address) * 2;
1074 	flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1075 	flush->header.length = sizeof(struct acpi_nfit_flush_address);
1076 	flush->device_handle = handle[2];
1077 	flush->hint_count = 1;
1078 	flush->hint_address[0] = t->flush_dma[2];
1079 
1080 	/* flush3 (dimm3) */
1081 	flush = nfit_buf + offset + sizeof(struct acpi_nfit_flush_address) * 3;
1082 	flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1083 	flush->header.length = sizeof(struct acpi_nfit_flush_address);
1084 	flush->device_handle = handle[3];
1085 	flush->hint_count = 1;
1086 	flush->hint_address[0] = t->flush_dma[3];
1087 
1088 	if (t->setup_hotplug) {
1089 		offset = offset + sizeof(struct acpi_nfit_flush_address) * 4;
1090 		/* dcr-descriptor4: blk */
1091 		dcr = nfit_buf + offset;
1092 		dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1093 		dcr->header.length = sizeof(struct acpi_nfit_control_region);
1094 		dcr->region_index = 8+1;
1095 		dcr->vendor_id = 0xabcd;
1096 		dcr->device_id = 0;
1097 		dcr->revision_id = 1;
1098 		dcr->serial_number = ~handle[4];
1099 		dcr->code = NFIT_FIC_BLK;
1100 		dcr->windows = 1;
1101 		dcr->window_size = DCR_SIZE;
1102 		dcr->command_offset = 0;
1103 		dcr->command_size = 8;
1104 		dcr->status_offset = 8;
1105 		dcr->status_size = 4;
1106 
1107 		offset = offset + sizeof(struct acpi_nfit_control_region);
1108 		/* dcr-descriptor4: pmem */
1109 		dcr = nfit_buf + offset;
1110 		dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1111 		dcr->header.length = offsetof(struct acpi_nfit_control_region,
1112 				window_size);
1113 		dcr->region_index = 9+1;
1114 		dcr->vendor_id = 0xabcd;
1115 		dcr->device_id = 0;
1116 		dcr->revision_id = 1;
1117 		dcr->serial_number = ~handle[4];
1118 		dcr->code = NFIT_FIC_BYTEN;
1119 		dcr->windows = 0;
1120 
1121 		offset = offset + offsetof(struct acpi_nfit_control_region,
1122 				window_size);
1123 		/* bdw4 (spa/dcr4, dimm4) */
1124 		bdw = nfit_buf + offset;
1125 		bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
1126 		bdw->header.length = sizeof(struct acpi_nfit_data_region);
1127 		bdw->region_index = 8+1;
1128 		bdw->windows = 1;
1129 		bdw->offset = 0;
1130 		bdw->size = BDW_SIZE;
1131 		bdw->capacity = DIMM_SIZE;
1132 		bdw->start_address = 0;
1133 
1134 		offset = offset + sizeof(struct acpi_nfit_data_region);
1135 		/* spa10 (dcr4) dimm4 */
1136 		spa = nfit_buf + offset;
1137 		spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1138 		spa->header.length = sizeof(*spa);
1139 		memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
1140 		spa->range_index = 10+1;
1141 		spa->address = t->dcr_dma[4];
1142 		spa->length = DCR_SIZE;
1143 
1144 		/*
1145 		 * spa11 (single-dimm interleave for hotplug, note storage
1146 		 * does not actually alias the related block-data-window
1147 		 * regions)
1148 		 */
1149 		spa = nfit_buf + offset + sizeof(*spa);
1150 		spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1151 		spa->header.length = sizeof(*spa);
1152 		memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16);
1153 		spa->range_index = 11+1;
1154 		spa->address = t->spa_set_dma[2];
1155 		spa->length = SPA0_SIZE;
1156 
1157 		/* spa12 (bdw for dcr4) dimm4 */
1158 		spa = nfit_buf + offset + sizeof(*spa) * 2;
1159 		spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1160 		spa->header.length = sizeof(*spa);
1161 		memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
1162 		spa->range_index = 12+1;
1163 		spa->address = t->dimm_dma[4];
1164 		spa->length = DIMM_SIZE;
1165 
1166 		offset = offset + sizeof(*spa) * 3;
1167 		/* mem-region14 (spa/dcr4, dimm4) */
1168 		memdev = nfit_buf + offset;
1169 		memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1170 		memdev->header.length = sizeof(*memdev);
1171 		memdev->device_handle = handle[4];
1172 		memdev->physical_id = 4;
1173 		memdev->region_id = 0;
1174 		memdev->range_index = 10+1;
1175 		memdev->region_index = 8+1;
1176 		memdev->region_size = 0;
1177 		memdev->region_offset = 0;
1178 		memdev->address = 0;
1179 		memdev->interleave_index = 0;
1180 		memdev->interleave_ways = 1;
1181 
1182 		/* mem-region15 (spa0, dimm4) */
1183 		memdev = nfit_buf + offset +
1184 				sizeof(struct acpi_nfit_memory_map);
1185 		memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1186 		memdev->header.length = sizeof(*memdev);
1187 		memdev->device_handle = handle[4];
1188 		memdev->physical_id = 4;
1189 		memdev->region_id = 0;
1190 		memdev->range_index = 11+1;
1191 		memdev->region_index = 9+1;
1192 		memdev->region_size = SPA0_SIZE;
1193 		memdev->region_offset = t->spa_set_dma[2];
1194 		memdev->address = 0;
1195 		memdev->interleave_index = 0;
1196 		memdev->interleave_ways = 1;
1197 
1198 		/* mem-region16 (spa/bdw4, dimm4) */
1199 		memdev = nfit_buf + offset +
1200 				sizeof(struct acpi_nfit_memory_map) * 2;
1201 		memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1202 		memdev->header.length = sizeof(*memdev);
1203 		memdev->device_handle = handle[4];
1204 		memdev->physical_id = 4;
1205 		memdev->region_id = 0;
1206 		memdev->range_index = 12+1;
1207 		memdev->region_index = 8+1;
1208 		memdev->region_size = 0;
1209 		memdev->region_offset = 0;
1210 		memdev->address = 0;
1211 		memdev->interleave_index = 0;
1212 		memdev->interleave_ways = 1;
1213 
1214 		offset = offset + sizeof(struct acpi_nfit_memory_map) * 3;
1215 		/* flush3 (dimm4) */
1216 		flush = nfit_buf + offset;
1217 		flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1218 		flush->header.length = sizeof(struct acpi_nfit_flush_address);
1219 		flush->device_handle = handle[4];
1220 		flush->hint_count = 1;
1221 		flush->hint_address[0] = t->flush_dma[4];
1222 	}
1223 
1224 	post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA0_SIZE);
1225 
1226 	acpi_desc = &t->acpi_desc;
1227 	set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_dsm_force_en);
1228 	set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en);
1229 	set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en);
1230 	set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_dsm_force_en);
1231 	set_bit(ND_CMD_ARS_START, &acpi_desc->bus_dsm_force_en);
1232 	set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_dsm_force_en);
1233 }
1234 
1235 static void nfit_test1_setup(struct nfit_test *t)
1236 {
1237 	size_t offset;
1238 	void *nfit_buf = t->nfit_buf;
1239 	struct acpi_nfit_memory_map *memdev;
1240 	struct acpi_nfit_control_region *dcr;
1241 	struct acpi_nfit_system_address *spa;
1242 	struct acpi_nfit_desc *acpi_desc;
1243 
1244 	offset = 0;
1245 	/* spa0 (flat range with no bdw aliasing) */
1246 	spa = nfit_buf + offset;
1247 	spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1248 	spa->header.length = sizeof(*spa);
1249 	memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16);
1250 	spa->range_index = 0+1;
1251 	spa->address = t->spa_set_dma[0];
1252 	spa->length = SPA2_SIZE;
1253 
1254 	offset += sizeof(*spa);
1255 	/* mem-region0 (spa0, dimm0) */
1256 	memdev = nfit_buf + offset;
1257 	memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
1258 	memdev->header.length = sizeof(*memdev);
1259 	memdev->device_handle = 0;
1260 	memdev->physical_id = 0;
1261 	memdev->region_id = 0;
1262 	memdev->range_index = 0+1;
1263 	memdev->region_index = 0+1;
1264 	memdev->region_size = SPA2_SIZE;
1265 	memdev->region_offset = 0;
1266 	memdev->address = 0;
1267 	memdev->interleave_index = 0;
1268 	memdev->interleave_ways = 1;
1269 	memdev->flags = ACPI_NFIT_MEM_SAVE_FAILED | ACPI_NFIT_MEM_RESTORE_FAILED
1270 		| ACPI_NFIT_MEM_FLUSH_FAILED | ACPI_NFIT_MEM_HEALTH_OBSERVED
1271 		| ACPI_NFIT_MEM_NOT_ARMED;
1272 
1273 	offset += sizeof(*memdev);
1274 	/* dcr-descriptor0 */
1275 	dcr = nfit_buf + offset;
1276 	dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1277 	dcr->header.length = offsetof(struct acpi_nfit_control_region,
1278 			window_size);
1279 	dcr->region_index = 0+1;
1280 	dcr->vendor_id = 0xabcd;
1281 	dcr->device_id = 0;
1282 	dcr->revision_id = 1;
1283 	dcr->serial_number = ~0;
1284 	dcr->code = NFIT_FIC_BYTE;
1285 	dcr->windows = 0;
1286 
1287 	post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA2_SIZE);
1288 
1289 	acpi_desc = &t->acpi_desc;
1290 	set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_dsm_force_en);
1291 	set_bit(ND_CMD_ARS_START, &acpi_desc->bus_dsm_force_en);
1292 	set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_dsm_force_en);
1293 }
1294 
1295 static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa,
1296 		void *iobuf, u64 len, int rw)
1297 {
1298 	struct nfit_blk *nfit_blk = ndbr->blk_provider_data;
1299 	struct nfit_blk_mmio *mmio = &nfit_blk->mmio[BDW];
1300 	struct nd_region *nd_region = &ndbr->nd_region;
1301 	unsigned int lane;
1302 
1303 	lane = nd_region_acquire_lane(nd_region);
1304 	if (rw)
1305 		memcpy(mmio->addr.base + dpa, iobuf, len);
1306 	else {
1307 		memcpy(iobuf, mmio->addr.base + dpa, len);
1308 
1309 		/* give us some some coverage of the mmio_flush_range() API */
1310 		mmio_flush_range(mmio->addr.base + dpa, len);
1311 	}
1312 	nd_region_release_lane(nd_region, lane);
1313 
1314 	return 0;
1315 }
1316 
1317 static int nfit_test_probe(struct platform_device *pdev)
1318 {
1319 	struct nvdimm_bus_descriptor *nd_desc;
1320 	struct acpi_nfit_desc *acpi_desc;
1321 	struct device *dev = &pdev->dev;
1322 	struct nfit_test *nfit_test;
1323 	int rc;
1324 
1325 	nfit_test = to_nfit_test(&pdev->dev);
1326 
1327 	/* common alloc */
1328 	if (nfit_test->num_dcr) {
1329 		int num = nfit_test->num_dcr;
1330 
1331 		nfit_test->dimm = devm_kcalloc(dev, num, sizeof(void *),
1332 				GFP_KERNEL);
1333 		nfit_test->dimm_dma = devm_kcalloc(dev, num, sizeof(dma_addr_t),
1334 				GFP_KERNEL);
1335 		nfit_test->flush = devm_kcalloc(dev, num, sizeof(void *),
1336 				GFP_KERNEL);
1337 		nfit_test->flush_dma = devm_kcalloc(dev, num, sizeof(dma_addr_t),
1338 				GFP_KERNEL);
1339 		nfit_test->label = devm_kcalloc(dev, num, sizeof(void *),
1340 				GFP_KERNEL);
1341 		nfit_test->label_dma = devm_kcalloc(dev, num,
1342 				sizeof(dma_addr_t), GFP_KERNEL);
1343 		nfit_test->dcr = devm_kcalloc(dev, num,
1344 				sizeof(struct nfit_test_dcr *), GFP_KERNEL);
1345 		nfit_test->dcr_dma = devm_kcalloc(dev, num,
1346 				sizeof(dma_addr_t), GFP_KERNEL);
1347 		if (nfit_test->dimm && nfit_test->dimm_dma && nfit_test->label
1348 				&& nfit_test->label_dma && nfit_test->dcr
1349 				&& nfit_test->dcr_dma && nfit_test->flush
1350 				&& nfit_test->flush_dma)
1351 			/* pass */;
1352 		else
1353 			return -ENOMEM;
1354 	}
1355 
1356 	if (nfit_test->num_pm) {
1357 		int num = nfit_test->num_pm;
1358 
1359 		nfit_test->spa_set = devm_kcalloc(dev, num, sizeof(void *),
1360 				GFP_KERNEL);
1361 		nfit_test->spa_set_dma = devm_kcalloc(dev, num,
1362 				sizeof(dma_addr_t), GFP_KERNEL);
1363 		if (nfit_test->spa_set && nfit_test->spa_set_dma)
1364 			/* pass */;
1365 		else
1366 			return -ENOMEM;
1367 	}
1368 
1369 	/* per-nfit specific alloc */
1370 	if (nfit_test->alloc(nfit_test))
1371 		return -ENOMEM;
1372 
1373 	nfit_test->setup(nfit_test);
1374 	acpi_desc = &nfit_test->acpi_desc;
1375 	acpi_nfit_desc_init(acpi_desc, &pdev->dev);
1376 	acpi_desc->nfit = nfit_test->nfit_buf;
1377 	acpi_desc->blk_do_io = nfit_test_blk_do_io;
1378 	nd_desc = &acpi_desc->nd_desc;
1379 	nd_desc->provider_name = NULL;
1380 	nd_desc->ndctl = nfit_test_ctl;
1381 	acpi_desc->nvdimm_bus = nvdimm_bus_register(&pdev->dev, nd_desc);
1382 	if (!acpi_desc->nvdimm_bus)
1383 		return -ENXIO;
1384 
1385 	rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_size);
1386 	if (rc) {
1387 		nvdimm_bus_unregister(acpi_desc->nvdimm_bus);
1388 		return rc;
1389 	}
1390 
1391 	if (nfit_test->setup != nfit_test0_setup)
1392 		return 0;
1393 
1394 	nfit_test->setup_hotplug = 1;
1395 	nfit_test->setup(nfit_test);
1396 
1397 	rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_size);
1398 	if (rc) {
1399 		nvdimm_bus_unregister(acpi_desc->nvdimm_bus);
1400 		return rc;
1401 	}
1402 
1403 	return 0;
1404 }
1405 
1406 static int nfit_test_remove(struct platform_device *pdev)
1407 {
1408 	struct nfit_test *nfit_test = to_nfit_test(&pdev->dev);
1409 	struct acpi_nfit_desc *acpi_desc = &nfit_test->acpi_desc;
1410 
1411 	nvdimm_bus_unregister(acpi_desc->nvdimm_bus);
1412 
1413 	return 0;
1414 }
1415 
1416 static void nfit_test_release(struct device *dev)
1417 {
1418 	struct nfit_test *nfit_test = to_nfit_test(dev);
1419 
1420 	kfree(nfit_test);
1421 }
1422 
1423 static const struct platform_device_id nfit_test_id[] = {
1424 	{ KBUILD_MODNAME },
1425 	{ },
1426 };
1427 
1428 static struct platform_driver nfit_test_driver = {
1429 	.probe = nfit_test_probe,
1430 	.remove = nfit_test_remove,
1431 	.driver = {
1432 		.name = KBUILD_MODNAME,
1433 	},
1434 	.id_table = nfit_test_id,
1435 };
1436 
1437 #ifdef CONFIG_CMA_SIZE_MBYTES
1438 #define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
1439 #else
1440 #define CMA_SIZE_MBYTES 0
1441 #endif
1442 
1443 static __init int nfit_test_init(void)
1444 {
1445 	int rc, i;
1446 
1447 	nfit_test_setup(nfit_test_lookup);
1448 
1449 	for (i = 0; i < NUM_NFITS; i++) {
1450 		struct nfit_test *nfit_test;
1451 		struct platform_device *pdev;
1452 		static int once;
1453 
1454 		nfit_test = kzalloc(sizeof(*nfit_test), GFP_KERNEL);
1455 		if (!nfit_test) {
1456 			rc = -ENOMEM;
1457 			goto err_register;
1458 		}
1459 		INIT_LIST_HEAD(&nfit_test->resources);
1460 		switch (i) {
1461 		case 0:
1462 			nfit_test->num_pm = NUM_PM;
1463 			nfit_test->num_dcr = NUM_DCR;
1464 			nfit_test->alloc = nfit_test0_alloc;
1465 			nfit_test->setup = nfit_test0_setup;
1466 			break;
1467 		case 1:
1468 			nfit_test->num_pm = 1;
1469 			nfit_test->alloc = nfit_test1_alloc;
1470 			nfit_test->setup = nfit_test1_setup;
1471 			break;
1472 		default:
1473 			rc = -EINVAL;
1474 			goto err_register;
1475 		}
1476 		pdev = &nfit_test->pdev;
1477 		pdev->name = KBUILD_MODNAME;
1478 		pdev->id = i;
1479 		pdev->dev.release = nfit_test_release;
1480 		rc = platform_device_register(pdev);
1481 		if (rc) {
1482 			put_device(&pdev->dev);
1483 			goto err_register;
1484 		}
1485 
1486 		rc = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
1487 		if (rc)
1488 			goto err_register;
1489 
1490 		instances[i] = nfit_test;
1491 
1492 		if (!once++) {
1493 			dma_addr_t dma;
1494 			void *buf;
1495 
1496 			buf = dma_alloc_coherent(&pdev->dev, SZ_128M, &dma,
1497 					GFP_KERNEL);
1498 			if (!buf) {
1499 				rc = -ENOMEM;
1500 				dev_warn(&pdev->dev, "need 128M of free cma\n");
1501 				goto err_register;
1502 			}
1503 			dma_free_coherent(&pdev->dev, SZ_128M, buf, dma);
1504 		}
1505 	}
1506 
1507 	rc = platform_driver_register(&nfit_test_driver);
1508 	if (rc)
1509 		goto err_register;
1510 	return 0;
1511 
1512  err_register:
1513 	for (i = 0; i < NUM_NFITS; i++)
1514 		if (instances[i])
1515 			platform_device_unregister(&instances[i]->pdev);
1516 	nfit_test_teardown();
1517 	return rc;
1518 }
1519 
1520 static __exit void nfit_test_exit(void)
1521 {
1522 	int i;
1523 
1524 	platform_driver_unregister(&nfit_test_driver);
1525 	for (i = 0; i < NUM_NFITS; i++)
1526 		platform_device_unregister(&instances[i]->pdev);
1527 	nfit_test_teardown();
1528 }
1529 
1530 module_init(nfit_test_init);
1531 module_exit(nfit_test_exit);
1532 MODULE_LICENSE("GPL v2");
1533 MODULE_AUTHOR("Intel Corporation");
1534