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