2 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
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.
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.
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>
27 #include "nfit_test.h"
30 * Generate an NFIT table to describe the following topology:
32 * BUS0: Interleaved PMEM regions, and aliasing with BLK regions
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
43 * | +-------------------------^----------^ ^
44 * +--+---+ | blk4.0 | pm1.0 | 2 region4
45 * | imc1 +--+-------------------------+----------+ +
46 * +------+ | blk5.0 | pm1.0 | 3 region5
47 * +-------------------------+----------+-+-------+
51 * +--+---+ (Hotplug DIMM)
52 * | +----------------------------------------------+
53 * +--+---+ | blk6.0/pm7.0 | 4 region6/7
54 * | imc0 +--+----------------------------------------------+
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.
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.
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
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.
85 * BUS1: Legacy NVDIMM (single contiguous range)
88 * +---------------------+
89 * |---------------------|
91 * |---------------------|
92 * +---------------------+
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.
102 NUM_SPA
= NUM_PM
+ NUM_DCR
+ NUM_BDW
,
103 NUM_MEM
= NUM_DCR
+ NUM_BDW
+ 2 /* spa0 iset */ + 4 /* spa1 iset */,
105 LABEL_SIZE
= SZ_128K
,
106 SPA0_SIZE
= DIMM_SIZE
,
107 SPA1_SIZE
= DIMM_SIZE
*2,
108 SPA2_SIZE
= DIMM_SIZE
,
111 NUM_NFITS
= 2, /* permit testing multiple NFITs per system */
114 struct nfit_test_dcr
{
117 __u8 aperature
[BDW_SIZE
];
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))
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),
133 struct acpi_nfit_desc acpi_desc
;
134 struct platform_device pdev
;
135 struct list_head resources
;
142 dma_addr_t
*dimm_dma
;
144 dma_addr_t
*flush_dma
;
146 dma_addr_t
*label_dma
;
148 dma_addr_t
*spa_set_dma
;
149 struct nfit_test_dcr
**dcr
;
151 int (*alloc
)(struct nfit_test
*t
);
152 void (*setup
)(struct nfit_test
*t
);
156 static struct nfit_test
*to_nfit_test(struct device
*dev
)
158 struct platform_device
*pdev
= to_platform_device(dev
);
160 return container_of(pdev
, struct nfit_test
, pdev
);
163 static int nfit_test_cmd_get_config_size(struct nd_cmd_get_config_size
*nd_cmd
,
164 unsigned int buf_len
)
166 if (buf_len
< sizeof(*nd_cmd
))
170 nd_cmd
->config_size
= LABEL_SIZE
;
171 nd_cmd
->max_xfer
= SZ_4K
;
176 static int nfit_test_cmd_get_config_data(struct nd_cmd_get_config_data_hdr
177 *nd_cmd
, unsigned int buf_len
, void *label
)
179 unsigned int len
, offset
= nd_cmd
->in_offset
;
182 if (buf_len
< sizeof(*nd_cmd
))
184 if (offset
>= LABEL_SIZE
)
186 if (nd_cmd
->in_length
+ sizeof(*nd_cmd
) > buf_len
)
190 len
= min(nd_cmd
->in_length
, LABEL_SIZE
- offset
);
191 memcpy(nd_cmd
->out_buf
, label
+ offset
, len
);
192 rc
= buf_len
- sizeof(*nd_cmd
) - len
;
197 static int nfit_test_cmd_set_config_data(struct nd_cmd_set_config_hdr
*nd_cmd
,
198 unsigned int buf_len
, void *label
)
200 unsigned int len
, offset
= nd_cmd
->in_offset
;
204 if (buf_len
< sizeof(*nd_cmd
))
206 if (offset
>= LABEL_SIZE
)
208 if (nd_cmd
->in_length
+ sizeof(*nd_cmd
) + 4 > buf_len
)
211 status
= (void *)nd_cmd
+ nd_cmd
->in_length
+ sizeof(*nd_cmd
);
213 len
= min(nd_cmd
->in_length
, LABEL_SIZE
- offset
);
214 memcpy(label
+ offset
, nd_cmd
->in_buf
, len
);
215 rc
= buf_len
- sizeof(*nd_cmd
) - (len
+ 4);
220 static int nfit_test_cmd_ars_cap(struct nd_cmd_ars_cap
*nd_cmd
,
221 unsigned int buf_len
)
223 if (buf_len
< sizeof(*nd_cmd
))
226 nd_cmd
->max_ars_out
= 256;
227 nd_cmd
->status
= (ND_ARS_PERSISTENT
| ND_ARS_VOLATILE
) << 16;
232 static int nfit_test_cmd_ars_start(struct nd_cmd_ars_start
*nd_cmd
,
233 unsigned int buf_len
)
235 if (buf_len
< sizeof(*nd_cmd
))
243 static int nfit_test_cmd_ars_status(struct nd_cmd_ars_status
*nd_cmd
,
244 unsigned int buf_len
)
246 if (buf_len
< sizeof(*nd_cmd
))
249 nd_cmd
->out_length
= 256;
250 nd_cmd
->num_records
= 0;
252 nd_cmd
->length
= -1ULL;
258 static int nfit_test_ctl(struct nvdimm_bus_descriptor
*nd_desc
,
259 struct nvdimm
*nvdimm
, unsigned int cmd
, void *buf
,
260 unsigned int buf_len
)
262 struct acpi_nfit_desc
*acpi_desc
= to_acpi_desc(nd_desc
);
263 struct nfit_test
*t
= container_of(acpi_desc
, typeof(*t
), acpi_desc
);
267 struct nfit_mem
*nfit_mem
= nvdimm_provider_data(nvdimm
);
269 if (!nfit_mem
|| !test_bit(cmd
, &nfit_mem
->dsm_mask
))
272 /* lookup label space for the given dimm */
273 for (i
= 0; i
< ARRAY_SIZE(handle
); i
++)
274 if (__to_nfit_memdev(nfit_mem
)->device_handle
==
277 if (i
>= ARRAY_SIZE(handle
))
281 case ND_CMD_GET_CONFIG_SIZE
:
282 rc
= nfit_test_cmd_get_config_size(buf
, buf_len
);
284 case ND_CMD_GET_CONFIG_DATA
:
285 rc
= nfit_test_cmd_get_config_data(buf
, buf_len
,
288 case ND_CMD_SET_CONFIG_DATA
:
289 rc
= nfit_test_cmd_set_config_data(buf
, buf_len
,
296 if (!nd_desc
|| !test_bit(cmd
, &nd_desc
->dsm_mask
))
301 rc
= nfit_test_cmd_ars_cap(buf
, buf_len
);
303 case ND_CMD_ARS_START
:
304 rc
= nfit_test_cmd_ars_start(buf
, buf_len
);
306 case ND_CMD_ARS_STATUS
:
307 rc
= nfit_test_cmd_ars_status(buf
, buf_len
);
317 static DEFINE_SPINLOCK(nfit_test_lock
);
318 static struct nfit_test
*instances
[NUM_NFITS
];
320 static void release_nfit_res(void *data
)
322 struct nfit_test_resource
*nfit_res
= data
;
323 struct resource
*res
= nfit_res
->res
;
325 spin_lock(&nfit_test_lock
);
326 list_del(&nfit_res
->list
);
327 spin_unlock(&nfit_test_lock
);
329 if (is_vmalloc_addr(nfit_res
->buf
))
330 vfree(nfit_res
->buf
);
332 dma_free_coherent(nfit_res
->dev
, resource_size(res
),
333 nfit_res
->buf
, res
->start
);
338 static void *__test_alloc(struct nfit_test
*t
, size_t size
, dma_addr_t
*dma
,
341 struct device
*dev
= &t
->pdev
.dev
;
342 struct resource
*res
= kzalloc(sizeof(*res
) * 2, GFP_KERNEL
);
343 struct nfit_test_resource
*nfit_res
= kzalloc(sizeof(*nfit_res
),
347 if (!res
|| !buf
|| !nfit_res
)
349 rc
= devm_add_action(dev
, release_nfit_res
, nfit_res
);
352 INIT_LIST_HEAD(&nfit_res
->list
);
353 memset(buf
, 0, size
);
358 res
->end
= *dma
+ size
- 1;
360 spin_lock(&nfit_test_lock
);
361 list_add(&nfit_res
->list
, &t
->resources
);
362 spin_unlock(&nfit_test_lock
);
364 return nfit_res
->buf
;
366 if (buf
&& !is_vmalloc_addr(buf
))
367 dma_free_coherent(dev
, size
, buf
, *dma
);
375 static void *test_alloc(struct nfit_test
*t
, size_t size
, dma_addr_t
*dma
)
377 void *buf
= vmalloc(size
);
379 *dma
= (unsigned long) buf
;
380 return __test_alloc(t
, size
, dma
, buf
);
383 static void *test_alloc_coherent(struct nfit_test
*t
, size_t size
,
386 struct device
*dev
= &t
->pdev
.dev
;
387 void *buf
= dma_alloc_coherent(dev
, size
, dma
, GFP_KERNEL
);
389 return __test_alloc(t
, size
, dma
, buf
);
392 static struct nfit_test_resource
*nfit_test_lookup(resource_size_t addr
)
396 for (i
= 0; i
< ARRAY_SIZE(instances
); i
++) {
397 struct nfit_test_resource
*n
, *nfit_res
= NULL
;
398 struct nfit_test
*t
= instances
[i
];
402 spin_lock(&nfit_test_lock
);
403 list_for_each_entry(n
, &t
->resources
, list
) {
404 if (addr
>= n
->res
->start
&& (addr
< n
->res
->start
405 + resource_size(n
->res
))) {
408 } else if (addr
>= (unsigned long) n
->buf
409 && (addr
< (unsigned long) n
->buf
410 + resource_size(n
->res
))) {
415 spin_unlock(&nfit_test_lock
);
423 static int nfit_test0_alloc(struct nfit_test
*t
)
425 size_t nfit_size
= sizeof(struct acpi_nfit_system_address
) * NUM_SPA
426 + sizeof(struct acpi_nfit_memory_map
) * NUM_MEM
427 + sizeof(struct acpi_nfit_control_region
) * NUM_DCR
428 + sizeof(struct acpi_nfit_data_region
) * NUM_BDW
429 + sizeof(struct acpi_nfit_flush_address
) * NUM_DCR
;
432 t
->nfit_buf
= test_alloc(t
, nfit_size
, &t
->nfit_dma
);
435 t
->nfit_size
= nfit_size
;
437 t
->spa_set
[0] = test_alloc_coherent(t
, SPA0_SIZE
, &t
->spa_set_dma
[0]);
441 t
->spa_set
[1] = test_alloc_coherent(t
, SPA1_SIZE
, &t
->spa_set_dma
[1]);
445 t
->spa_set
[2] = test_alloc_coherent(t
, SPA0_SIZE
, &t
->spa_set_dma
[2]);
449 for (i
= 0; i
< NUM_DCR
; i
++) {
450 t
->dimm
[i
] = test_alloc(t
, DIMM_SIZE
, &t
->dimm_dma
[i
]);
454 t
->label
[i
] = test_alloc(t
, LABEL_SIZE
, &t
->label_dma
[i
]);
457 sprintf(t
->label
[i
], "label%d", i
);
459 t
->flush
[i
] = test_alloc(t
, 8, &t
->flush_dma
[i
]);
464 for (i
= 0; i
< NUM_DCR
; i
++) {
465 t
->dcr
[i
] = test_alloc(t
, LABEL_SIZE
, &t
->dcr_dma
[i
]);
473 static int nfit_test1_alloc(struct nfit_test
*t
)
475 size_t nfit_size
= sizeof(struct acpi_nfit_system_address
)
476 + sizeof(struct acpi_nfit_memory_map
)
477 + sizeof(struct acpi_nfit_control_region
);
479 t
->nfit_buf
= test_alloc(t
, nfit_size
, &t
->nfit_dma
);
482 t
->nfit_size
= nfit_size
;
484 t
->spa_set
[0] = test_alloc_coherent(t
, SPA2_SIZE
, &t
->spa_set_dma
[0]);
491 static void nfit_test0_setup(struct nfit_test
*t
)
493 struct nvdimm_bus_descriptor
*nd_desc
;
494 struct acpi_nfit_desc
*acpi_desc
;
495 struct acpi_nfit_memory_map
*memdev
;
496 void *nfit_buf
= t
->nfit_buf
;
497 struct acpi_nfit_system_address
*spa
;
498 struct acpi_nfit_control_region
*dcr
;
499 struct acpi_nfit_data_region
*bdw
;
500 struct acpi_nfit_flush_address
*flush
;
504 * spa0 (interleave first half of dimm0 and dimm1, note storage
505 * does not actually alias the related block-data-window
509 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
510 spa
->header
.length
= sizeof(*spa
);
511 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
512 spa
->range_index
= 0+1;
513 spa
->address
= t
->spa_set_dma
[0];
514 spa
->length
= SPA0_SIZE
;
517 * spa1 (interleave last half of the 4 DIMMS, note storage
518 * does not actually alias the related block-data-window
521 spa
= nfit_buf
+ sizeof(*spa
);
522 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
523 spa
->header
.length
= sizeof(*spa
);
524 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
525 spa
->range_index
= 1+1;
526 spa
->address
= t
->spa_set_dma
[1];
527 spa
->length
= SPA1_SIZE
;
529 /* spa2 (dcr0) dimm0 */
530 spa
= nfit_buf
+ sizeof(*spa
) * 2;
531 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
532 spa
->header
.length
= sizeof(*spa
);
533 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
534 spa
->range_index
= 2+1;
535 spa
->address
= t
->dcr_dma
[0];
536 spa
->length
= DCR_SIZE
;
538 /* spa3 (dcr1) dimm1 */
539 spa
= nfit_buf
+ sizeof(*spa
) * 3;
540 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
541 spa
->header
.length
= sizeof(*spa
);
542 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
543 spa
->range_index
= 3+1;
544 spa
->address
= t
->dcr_dma
[1];
545 spa
->length
= DCR_SIZE
;
547 /* spa4 (dcr2) dimm2 */
548 spa
= nfit_buf
+ sizeof(*spa
) * 4;
549 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
550 spa
->header
.length
= sizeof(*spa
);
551 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
552 spa
->range_index
= 4+1;
553 spa
->address
= t
->dcr_dma
[2];
554 spa
->length
= DCR_SIZE
;
556 /* spa5 (dcr3) dimm3 */
557 spa
= nfit_buf
+ sizeof(*spa
) * 5;
558 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
559 spa
->header
.length
= sizeof(*spa
);
560 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
561 spa
->range_index
= 5+1;
562 spa
->address
= t
->dcr_dma
[3];
563 spa
->length
= DCR_SIZE
;
565 /* spa6 (bdw for dcr0) dimm0 */
566 spa
= nfit_buf
+ sizeof(*spa
) * 6;
567 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
568 spa
->header
.length
= sizeof(*spa
);
569 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
570 spa
->range_index
= 6+1;
571 spa
->address
= t
->dimm_dma
[0];
572 spa
->length
= DIMM_SIZE
;
574 /* spa7 (bdw for dcr1) dimm1 */
575 spa
= nfit_buf
+ sizeof(*spa
) * 7;
576 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
577 spa
->header
.length
= sizeof(*spa
);
578 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
579 spa
->range_index
= 7+1;
580 spa
->address
= t
->dimm_dma
[1];
581 spa
->length
= DIMM_SIZE
;
583 /* spa8 (bdw for dcr2) dimm2 */
584 spa
= nfit_buf
+ sizeof(*spa
) * 8;
585 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
586 spa
->header
.length
= sizeof(*spa
);
587 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
588 spa
->range_index
= 8+1;
589 spa
->address
= t
->dimm_dma
[2];
590 spa
->length
= DIMM_SIZE
;
592 /* spa9 (bdw for dcr3) dimm3 */
593 spa
= nfit_buf
+ sizeof(*spa
) * 9;
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_BDW
), 16);
597 spa
->range_index
= 9+1;
598 spa
->address
= t
->dimm_dma
[3];
599 spa
->length
= DIMM_SIZE
;
601 offset
= sizeof(*spa
) * 10;
602 /* mem-region0 (spa0, dimm0) */
603 memdev
= nfit_buf
+ offset
;
604 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
605 memdev
->header
.length
= sizeof(*memdev
);
606 memdev
->device_handle
= handle
[0];
607 memdev
->physical_id
= 0;
608 memdev
->region_id
= 0;
609 memdev
->range_index
= 0+1;
610 memdev
->region_index
= 0+1;
611 memdev
->region_size
= SPA0_SIZE
/2;
612 memdev
->region_offset
= t
->spa_set_dma
[0];
614 memdev
->interleave_index
= 0;
615 memdev
->interleave_ways
= 2;
617 /* mem-region1 (spa0, dimm1) */
618 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
);
619 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
620 memdev
->header
.length
= sizeof(*memdev
);
621 memdev
->device_handle
= handle
[1];
622 memdev
->physical_id
= 1;
623 memdev
->region_id
= 0;
624 memdev
->range_index
= 0+1;
625 memdev
->region_index
= 1+1;
626 memdev
->region_size
= SPA0_SIZE
/2;
627 memdev
->region_offset
= t
->spa_set_dma
[0] + SPA0_SIZE
/2;
629 memdev
->interleave_index
= 0;
630 memdev
->interleave_ways
= 2;
632 /* mem-region2 (spa1, dimm0) */
633 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 2;
634 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
635 memdev
->header
.length
= sizeof(*memdev
);
636 memdev
->device_handle
= handle
[0];
637 memdev
->physical_id
= 0;
638 memdev
->region_id
= 1;
639 memdev
->range_index
= 1+1;
640 memdev
->region_index
= 0+1;
641 memdev
->region_size
= SPA1_SIZE
/4;
642 memdev
->region_offset
= t
->spa_set_dma
[1];
643 memdev
->address
= SPA0_SIZE
/2;
644 memdev
->interleave_index
= 0;
645 memdev
->interleave_ways
= 4;
647 /* mem-region3 (spa1, dimm1) */
648 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 3;
649 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
650 memdev
->header
.length
= sizeof(*memdev
);
651 memdev
->device_handle
= handle
[1];
652 memdev
->physical_id
= 1;
653 memdev
->region_id
= 1;
654 memdev
->range_index
= 1+1;
655 memdev
->region_index
= 1+1;
656 memdev
->region_size
= SPA1_SIZE
/4;
657 memdev
->region_offset
= t
->spa_set_dma
[1] + SPA1_SIZE
/4;
658 memdev
->address
= SPA0_SIZE
/2;
659 memdev
->interleave_index
= 0;
660 memdev
->interleave_ways
= 4;
662 /* mem-region4 (spa1, dimm2) */
663 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 4;
664 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
665 memdev
->header
.length
= sizeof(*memdev
);
666 memdev
->device_handle
= handle
[2];
667 memdev
->physical_id
= 2;
668 memdev
->region_id
= 0;
669 memdev
->range_index
= 1+1;
670 memdev
->region_index
= 2+1;
671 memdev
->region_size
= SPA1_SIZE
/4;
672 memdev
->region_offset
= t
->spa_set_dma
[1] + 2*SPA1_SIZE
/4;
673 memdev
->address
= SPA0_SIZE
/2;
674 memdev
->interleave_index
= 0;
675 memdev
->interleave_ways
= 4;
677 /* mem-region5 (spa1, dimm3) */
678 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 5;
679 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
680 memdev
->header
.length
= sizeof(*memdev
);
681 memdev
->device_handle
= handle
[3];
682 memdev
->physical_id
= 3;
683 memdev
->region_id
= 0;
684 memdev
->range_index
= 1+1;
685 memdev
->region_index
= 3+1;
686 memdev
->region_size
= SPA1_SIZE
/4;
687 memdev
->region_offset
= t
->spa_set_dma
[1] + 3*SPA1_SIZE
/4;
688 memdev
->address
= SPA0_SIZE
/2;
689 memdev
->interleave_index
= 0;
690 memdev
->interleave_ways
= 4;
692 /* mem-region6 (spa/dcr0, dimm0) */
693 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 6;
694 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
695 memdev
->header
.length
= sizeof(*memdev
);
696 memdev
->device_handle
= handle
[0];
697 memdev
->physical_id
= 0;
698 memdev
->region_id
= 0;
699 memdev
->range_index
= 2+1;
700 memdev
->region_index
= 0+1;
701 memdev
->region_size
= 0;
702 memdev
->region_offset
= 0;
704 memdev
->interleave_index
= 0;
705 memdev
->interleave_ways
= 1;
707 /* mem-region7 (spa/dcr1, dimm1) */
708 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 7;
709 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
710 memdev
->header
.length
= sizeof(*memdev
);
711 memdev
->device_handle
= handle
[1];
712 memdev
->physical_id
= 1;
713 memdev
->region_id
= 0;
714 memdev
->range_index
= 3+1;
715 memdev
->region_index
= 1+1;
716 memdev
->region_size
= 0;
717 memdev
->region_offset
= 0;
719 memdev
->interleave_index
= 0;
720 memdev
->interleave_ways
= 1;
722 /* mem-region8 (spa/dcr2, dimm2) */
723 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 8;
724 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
725 memdev
->header
.length
= sizeof(*memdev
);
726 memdev
->device_handle
= handle
[2];
727 memdev
->physical_id
= 2;
728 memdev
->region_id
= 0;
729 memdev
->range_index
= 4+1;
730 memdev
->region_index
= 2+1;
731 memdev
->region_size
= 0;
732 memdev
->region_offset
= 0;
734 memdev
->interleave_index
= 0;
735 memdev
->interleave_ways
= 1;
737 /* mem-region9 (spa/dcr3, dimm3) */
738 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 9;
739 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
740 memdev
->header
.length
= sizeof(*memdev
);
741 memdev
->device_handle
= handle
[3];
742 memdev
->physical_id
= 3;
743 memdev
->region_id
= 0;
744 memdev
->range_index
= 5+1;
745 memdev
->region_index
= 3+1;
746 memdev
->region_size
= 0;
747 memdev
->region_offset
= 0;
749 memdev
->interleave_index
= 0;
750 memdev
->interleave_ways
= 1;
752 /* mem-region10 (spa/bdw0, dimm0) */
753 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 10;
754 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
755 memdev
->header
.length
= sizeof(*memdev
);
756 memdev
->device_handle
= handle
[0];
757 memdev
->physical_id
= 0;
758 memdev
->region_id
= 0;
759 memdev
->range_index
= 6+1;
760 memdev
->region_index
= 0+1;
761 memdev
->region_size
= 0;
762 memdev
->region_offset
= 0;
764 memdev
->interleave_index
= 0;
765 memdev
->interleave_ways
= 1;
767 /* mem-region11 (spa/bdw1, dimm1) */
768 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 11;
769 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
770 memdev
->header
.length
= sizeof(*memdev
);
771 memdev
->device_handle
= handle
[1];
772 memdev
->physical_id
= 1;
773 memdev
->region_id
= 0;
774 memdev
->range_index
= 7+1;
775 memdev
->region_index
= 1+1;
776 memdev
->region_size
= 0;
777 memdev
->region_offset
= 0;
779 memdev
->interleave_index
= 0;
780 memdev
->interleave_ways
= 1;
782 /* mem-region12 (spa/bdw2, dimm2) */
783 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 12;
784 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
785 memdev
->header
.length
= sizeof(*memdev
);
786 memdev
->device_handle
= handle
[2];
787 memdev
->physical_id
= 2;
788 memdev
->region_id
= 0;
789 memdev
->range_index
= 8+1;
790 memdev
->region_index
= 2+1;
791 memdev
->region_size
= 0;
792 memdev
->region_offset
= 0;
794 memdev
->interleave_index
= 0;
795 memdev
->interleave_ways
= 1;
797 /* mem-region13 (spa/dcr3, dimm3) */
798 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 13;
799 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
800 memdev
->header
.length
= sizeof(*memdev
);
801 memdev
->device_handle
= handle
[3];
802 memdev
->physical_id
= 3;
803 memdev
->region_id
= 0;
804 memdev
->range_index
= 9+1;
805 memdev
->region_index
= 3+1;
806 memdev
->region_size
= 0;
807 memdev
->region_offset
= 0;
809 memdev
->interleave_index
= 0;
810 memdev
->interleave_ways
= 1;
812 offset
= offset
+ sizeof(struct acpi_nfit_memory_map
) * 14;
813 /* dcr-descriptor0 */
814 dcr
= nfit_buf
+ offset
;
815 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
816 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
817 dcr
->region_index
= 0+1;
818 dcr
->vendor_id
= 0xabcd;
820 dcr
->revision_id
= 1;
821 dcr
->serial_number
= ~handle
[0];
823 dcr
->window_size
= DCR_SIZE
;
824 dcr
->command_offset
= 0;
825 dcr
->command_size
= 8;
826 dcr
->status_offset
= 8;
827 dcr
->status_size
= 4;
829 /* dcr-descriptor1 */
830 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
);
831 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
832 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
833 dcr
->region_index
= 1+1;
834 dcr
->vendor_id
= 0xabcd;
836 dcr
->revision_id
= 1;
837 dcr
->serial_number
= ~handle
[1];
839 dcr
->window_size
= DCR_SIZE
;
840 dcr
->command_offset
= 0;
841 dcr
->command_size
= 8;
842 dcr
->status_offset
= 8;
843 dcr
->status_size
= 4;
845 /* dcr-descriptor2 */
846 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
) * 2;
847 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
848 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
849 dcr
->region_index
= 2+1;
850 dcr
->vendor_id
= 0xabcd;
852 dcr
->revision_id
= 1;
853 dcr
->serial_number
= ~handle
[2];
855 dcr
->window_size
= DCR_SIZE
;
856 dcr
->command_offset
= 0;
857 dcr
->command_size
= 8;
858 dcr
->status_offset
= 8;
859 dcr
->status_size
= 4;
861 /* dcr-descriptor3 */
862 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
) * 3;
863 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
864 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
865 dcr
->region_index
= 3+1;
866 dcr
->vendor_id
= 0xabcd;
868 dcr
->revision_id
= 1;
869 dcr
->serial_number
= ~handle
[3];
871 dcr
->window_size
= DCR_SIZE
;
872 dcr
->command_offset
= 0;
873 dcr
->command_size
= 8;
874 dcr
->status_offset
= 8;
875 dcr
->status_size
= 4;
877 offset
= offset
+ sizeof(struct acpi_nfit_control_region
) * 4;
878 /* bdw0 (spa/dcr0, dimm0) */
879 bdw
= nfit_buf
+ offset
;
880 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
881 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
882 bdw
->region_index
= 0+1;
885 bdw
->size
= BDW_SIZE
;
886 bdw
->capacity
= DIMM_SIZE
;
887 bdw
->start_address
= 0;
889 /* bdw1 (spa/dcr1, dimm1) */
890 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
);
891 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
892 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
893 bdw
->region_index
= 1+1;
896 bdw
->size
= BDW_SIZE
;
897 bdw
->capacity
= DIMM_SIZE
;
898 bdw
->start_address
= 0;
900 /* bdw2 (spa/dcr2, dimm2) */
901 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
) * 2;
902 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
903 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
904 bdw
->region_index
= 2+1;
907 bdw
->size
= BDW_SIZE
;
908 bdw
->capacity
= DIMM_SIZE
;
909 bdw
->start_address
= 0;
911 /* bdw3 (spa/dcr3, dimm3) */
912 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
) * 3;
913 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
914 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
915 bdw
->region_index
= 3+1;
918 bdw
->size
= BDW_SIZE
;
919 bdw
->capacity
= DIMM_SIZE
;
920 bdw
->start_address
= 0;
922 offset
= offset
+ sizeof(struct acpi_nfit_data_region
) * 4;
924 flush
= nfit_buf
+ offset
;
925 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
926 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
927 flush
->device_handle
= handle
[0];
928 flush
->hint_count
= 1;
929 flush
->hint_address
[0] = t
->flush_dma
[0];
932 flush
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_flush_address
) * 1;
933 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
934 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
935 flush
->device_handle
= handle
[1];
936 flush
->hint_count
= 1;
937 flush
->hint_address
[0] = t
->flush_dma
[1];
940 flush
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_flush_address
) * 2;
941 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
942 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
943 flush
->device_handle
= handle
[2];
944 flush
->hint_count
= 1;
945 flush
->hint_address
[0] = t
->flush_dma
[2];
948 flush
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_flush_address
) * 3;
949 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
950 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
951 flush
->device_handle
= handle
[3];
952 flush
->hint_count
= 1;
953 flush
->hint_address
[0] = t
->flush_dma
[3];
955 if (t
->setup_hotplug
) {
956 offset
= offset
+ sizeof(struct acpi_nfit_flush_address
) * 4;
957 /* dcr-descriptor4 */
958 dcr
= nfit_buf
+ offset
;
959 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
960 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
961 dcr
->region_index
= 4+1;
962 dcr
->vendor_id
= 0xabcd;
964 dcr
->revision_id
= 1;
965 dcr
->serial_number
= ~handle
[4];
967 dcr
->window_size
= DCR_SIZE
;
968 dcr
->command_offset
= 0;
969 dcr
->command_size
= 8;
970 dcr
->status_offset
= 8;
971 dcr
->status_size
= 4;
973 offset
= offset
+ sizeof(struct acpi_nfit_control_region
);
974 /* bdw4 (spa/dcr4, dimm4) */
975 bdw
= nfit_buf
+ offset
;
976 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
977 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
978 bdw
->region_index
= 4+1;
981 bdw
->size
= BDW_SIZE
;
982 bdw
->capacity
= DIMM_SIZE
;
983 bdw
->start_address
= 0;
985 offset
= offset
+ sizeof(struct acpi_nfit_data_region
);
986 /* spa10 (dcr4) dimm4 */
987 spa
= nfit_buf
+ offset
;
988 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
989 spa
->header
.length
= sizeof(*spa
);
990 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
991 spa
->range_index
= 10+1;
992 spa
->address
= t
->dcr_dma
[4];
993 spa
->length
= DCR_SIZE
;
996 * spa11 (single-dimm interleave for hotplug, note storage
997 * does not actually alias the related block-data-window
1000 spa
= nfit_buf
+ offset
+ sizeof(*spa
);
1001 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1002 spa
->header
.length
= sizeof(*spa
);
1003 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
1004 spa
->range_index
= 11+1;
1005 spa
->address
= t
->spa_set_dma
[2];
1006 spa
->length
= SPA0_SIZE
;
1008 /* spa12 (bdw for dcr4) dimm4 */
1009 spa
= nfit_buf
+ offset
+ sizeof(*spa
) * 2;
1010 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1011 spa
->header
.length
= sizeof(*spa
);
1012 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
1013 spa
->range_index
= 12+1;
1014 spa
->address
= t
->dimm_dma
[4];
1015 spa
->length
= DIMM_SIZE
;
1017 offset
= offset
+ sizeof(*spa
) * 3;
1018 /* mem-region14 (spa/dcr4, dimm4) */
1019 memdev
= nfit_buf
+ offset
;
1020 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1021 memdev
->header
.length
= sizeof(*memdev
);
1022 memdev
->device_handle
= handle
[4];
1023 memdev
->physical_id
= 4;
1024 memdev
->region_id
= 0;
1025 memdev
->range_index
= 10+1;
1026 memdev
->region_index
= 4+1;
1027 memdev
->region_size
= 0;
1028 memdev
->region_offset
= 0;
1029 memdev
->address
= 0;
1030 memdev
->interleave_index
= 0;
1031 memdev
->interleave_ways
= 1;
1033 /* mem-region15 (spa0, dimm4) */
1034 memdev
= nfit_buf
+ offset
+
1035 sizeof(struct acpi_nfit_memory_map
);
1036 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1037 memdev
->header
.length
= sizeof(*memdev
);
1038 memdev
->device_handle
= handle
[4];
1039 memdev
->physical_id
= 4;
1040 memdev
->region_id
= 0;
1041 memdev
->range_index
= 11+1;
1042 memdev
->region_index
= 4+1;
1043 memdev
->region_size
= SPA0_SIZE
;
1044 memdev
->region_offset
= t
->spa_set_dma
[2];
1045 memdev
->address
= 0;
1046 memdev
->interleave_index
= 0;
1047 memdev
->interleave_ways
= 1;
1049 /* mem-region16 (spa/dcr4, dimm4) */
1050 memdev
= nfit_buf
+ offset
+
1051 sizeof(struct acpi_nfit_memory_map
) * 2;
1052 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1053 memdev
->header
.length
= sizeof(*memdev
);
1054 memdev
->device_handle
= handle
[4];
1055 memdev
->physical_id
= 4;
1056 memdev
->region_id
= 0;
1057 memdev
->range_index
= 12+1;
1058 memdev
->region_index
= 4+1;
1059 memdev
->region_size
= 0;
1060 memdev
->region_offset
= 0;
1061 memdev
->address
= 0;
1062 memdev
->interleave_index
= 0;
1063 memdev
->interleave_ways
= 1;
1065 offset
= offset
+ sizeof(struct acpi_nfit_memory_map
) * 3;
1066 /* flush3 (dimm4) */
1067 flush
= nfit_buf
+ offset
;
1068 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1069 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
1070 flush
->device_handle
= handle
[4];
1071 flush
->hint_count
= 1;
1072 flush
->hint_address
[0] = t
->flush_dma
[4];
1075 acpi_desc
= &t
->acpi_desc
;
1076 set_bit(ND_CMD_GET_CONFIG_SIZE
, &acpi_desc
->dimm_dsm_force_en
);
1077 set_bit(ND_CMD_GET_CONFIG_DATA
, &acpi_desc
->dimm_dsm_force_en
);
1078 set_bit(ND_CMD_SET_CONFIG_DATA
, &acpi_desc
->dimm_dsm_force_en
);
1079 set_bit(ND_CMD_ARS_CAP
, &acpi_desc
->bus_dsm_force_en
);
1080 set_bit(ND_CMD_ARS_START
, &acpi_desc
->bus_dsm_force_en
);
1081 set_bit(ND_CMD_ARS_STATUS
, &acpi_desc
->bus_dsm_force_en
);
1082 nd_desc
= &acpi_desc
->nd_desc
;
1083 nd_desc
->ndctl
= nfit_test_ctl
;
1086 static void nfit_test1_setup(struct nfit_test
*t
)
1089 void *nfit_buf
= t
->nfit_buf
;
1090 struct acpi_nfit_memory_map
*memdev
;
1091 struct acpi_nfit_control_region
*dcr
;
1092 struct acpi_nfit_system_address
*spa
;
1093 struct nvdimm_bus_descriptor
*nd_desc
;
1094 struct acpi_nfit_desc
*acpi_desc
;
1097 /* spa0 (flat range with no bdw aliasing) */
1098 spa
= nfit_buf
+ offset
;
1099 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1100 spa
->header
.length
= sizeof(*spa
);
1101 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
1102 spa
->range_index
= 0+1;
1103 spa
->address
= t
->spa_set_dma
[0];
1104 spa
->length
= SPA2_SIZE
;
1106 offset
+= sizeof(*spa
);
1107 /* mem-region0 (spa0, dimm0) */
1108 memdev
= nfit_buf
+ offset
;
1109 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1110 memdev
->header
.length
= sizeof(*memdev
);
1111 memdev
->device_handle
= 0;
1112 memdev
->physical_id
= 0;
1113 memdev
->region_id
= 0;
1114 memdev
->range_index
= 0+1;
1115 memdev
->region_index
= 0+1;
1116 memdev
->region_size
= SPA2_SIZE
;
1117 memdev
->region_offset
= 0;
1118 memdev
->address
= 0;
1119 memdev
->interleave_index
= 0;
1120 memdev
->interleave_ways
= 1;
1121 memdev
->flags
= ACPI_NFIT_MEM_SAVE_FAILED
| ACPI_NFIT_MEM_RESTORE_FAILED
1122 | ACPI_NFIT_MEM_FLUSH_FAILED
| ACPI_NFIT_MEM_HEALTH_OBSERVED
1123 | ACPI_NFIT_MEM_NOT_ARMED
;
1125 offset
+= sizeof(*memdev
);
1126 /* dcr-descriptor0 */
1127 dcr
= nfit_buf
+ offset
;
1128 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1129 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
1130 dcr
->region_index
= 0+1;
1131 dcr
->vendor_id
= 0xabcd;
1133 dcr
->revision_id
= 1;
1134 dcr
->serial_number
= ~0;
1137 dcr
->window_size
= 0;
1138 dcr
->command_offset
= 0;
1139 dcr
->command_size
= 0;
1140 dcr
->status_offset
= 0;
1141 dcr
->status_size
= 0;
1143 acpi_desc
= &t
->acpi_desc
;
1144 set_bit(ND_CMD_ARS_CAP
, &acpi_desc
->bus_dsm_force_en
);
1145 set_bit(ND_CMD_ARS_START
, &acpi_desc
->bus_dsm_force_en
);
1146 set_bit(ND_CMD_ARS_STATUS
, &acpi_desc
->bus_dsm_force_en
);
1147 nd_desc
= &acpi_desc
->nd_desc
;
1148 nd_desc
->ndctl
= nfit_test_ctl
;
1151 static int nfit_test_blk_do_io(struct nd_blk_region
*ndbr
, resource_size_t dpa
,
1152 void *iobuf
, u64 len
, int rw
)
1154 struct nfit_blk
*nfit_blk
= ndbr
->blk_provider_data
;
1155 struct nfit_blk_mmio
*mmio
= &nfit_blk
->mmio
[BDW
];
1156 struct nd_region
*nd_region
= &ndbr
->nd_region
;
1159 lane
= nd_region_acquire_lane(nd_region
);
1161 memcpy(mmio
->addr
.base
+ dpa
, iobuf
, len
);
1163 memcpy(iobuf
, mmio
->addr
.base
+ dpa
, len
);
1165 /* give us some some coverage of the mmio_flush_range() API */
1166 mmio_flush_range(mmio
->addr
.base
+ dpa
, len
);
1168 nd_region_release_lane(nd_region
, lane
);
1173 static int nfit_test_probe(struct platform_device
*pdev
)
1175 struct nvdimm_bus_descriptor
*nd_desc
;
1176 struct acpi_nfit_desc
*acpi_desc
;
1177 struct device
*dev
= &pdev
->dev
;
1178 struct nfit_test
*nfit_test
;
1181 nfit_test
= to_nfit_test(&pdev
->dev
);
1184 if (nfit_test
->num_dcr
) {
1185 int num
= nfit_test
->num_dcr
;
1187 nfit_test
->dimm
= devm_kcalloc(dev
, num
, sizeof(void *),
1189 nfit_test
->dimm_dma
= devm_kcalloc(dev
, num
, sizeof(dma_addr_t
),
1191 nfit_test
->flush
= devm_kcalloc(dev
, num
, sizeof(void *),
1193 nfit_test
->flush_dma
= devm_kcalloc(dev
, num
, sizeof(dma_addr_t
),
1195 nfit_test
->label
= devm_kcalloc(dev
, num
, sizeof(void *),
1197 nfit_test
->label_dma
= devm_kcalloc(dev
, num
,
1198 sizeof(dma_addr_t
), GFP_KERNEL
);
1199 nfit_test
->dcr
= devm_kcalloc(dev
, num
,
1200 sizeof(struct nfit_test_dcr
*), GFP_KERNEL
);
1201 nfit_test
->dcr_dma
= devm_kcalloc(dev
, num
,
1202 sizeof(dma_addr_t
), GFP_KERNEL
);
1203 if (nfit_test
->dimm
&& nfit_test
->dimm_dma
&& nfit_test
->label
1204 && nfit_test
->label_dma
&& nfit_test
->dcr
1205 && nfit_test
->dcr_dma
&& nfit_test
->flush
1206 && nfit_test
->flush_dma
)
1212 if (nfit_test
->num_pm
) {
1213 int num
= nfit_test
->num_pm
;
1215 nfit_test
->spa_set
= devm_kcalloc(dev
, num
, sizeof(void *),
1217 nfit_test
->spa_set_dma
= devm_kcalloc(dev
, num
,
1218 sizeof(dma_addr_t
), GFP_KERNEL
);
1219 if (nfit_test
->spa_set
&& nfit_test
->spa_set_dma
)
1225 /* per-nfit specific alloc */
1226 if (nfit_test
->alloc(nfit_test
))
1229 nfit_test
->setup(nfit_test
);
1230 acpi_desc
= &nfit_test
->acpi_desc
;
1231 acpi_desc
->dev
= &pdev
->dev
;
1232 acpi_desc
->nfit
= nfit_test
->nfit_buf
;
1233 acpi_desc
->blk_do_io
= nfit_test_blk_do_io
;
1234 nd_desc
= &acpi_desc
->nd_desc
;
1235 nd_desc
->attr_groups
= acpi_nfit_attribute_groups
;
1236 acpi_desc
->nvdimm_bus
= nvdimm_bus_register(&pdev
->dev
, nd_desc
);
1237 if (!acpi_desc
->nvdimm_bus
)
1240 INIT_LIST_HEAD(&acpi_desc
->spa_maps
);
1241 INIT_LIST_HEAD(&acpi_desc
->spas
);
1242 INIT_LIST_HEAD(&acpi_desc
->dcrs
);
1243 INIT_LIST_HEAD(&acpi_desc
->bdws
);
1244 INIT_LIST_HEAD(&acpi_desc
->idts
);
1245 INIT_LIST_HEAD(&acpi_desc
->flushes
);
1246 INIT_LIST_HEAD(&acpi_desc
->memdevs
);
1247 INIT_LIST_HEAD(&acpi_desc
->dimms
);
1248 mutex_init(&acpi_desc
->spa_map_mutex
);
1249 mutex_init(&acpi_desc
->init_mutex
);
1251 rc
= acpi_nfit_init(acpi_desc
, nfit_test
->nfit_size
);
1253 nvdimm_bus_unregister(acpi_desc
->nvdimm_bus
);
1257 if (nfit_test
->setup
!= nfit_test0_setup
)
1260 nfit_test
->setup_hotplug
= 1;
1261 nfit_test
->setup(nfit_test
);
1263 rc
= acpi_nfit_init(acpi_desc
, nfit_test
->nfit_size
);
1265 nvdimm_bus_unregister(acpi_desc
->nvdimm_bus
);
1272 static int nfit_test_remove(struct platform_device
*pdev
)
1274 struct nfit_test
*nfit_test
= to_nfit_test(&pdev
->dev
);
1275 struct acpi_nfit_desc
*acpi_desc
= &nfit_test
->acpi_desc
;
1277 nvdimm_bus_unregister(acpi_desc
->nvdimm_bus
);
1282 static void nfit_test_release(struct device
*dev
)
1284 struct nfit_test
*nfit_test
= to_nfit_test(dev
);
1289 static const struct platform_device_id nfit_test_id
[] = {
1294 static struct platform_driver nfit_test_driver
= {
1295 .probe
= nfit_test_probe
,
1296 .remove
= nfit_test_remove
,
1298 .name
= KBUILD_MODNAME
,
1300 .id_table
= nfit_test_id
,
1303 #ifdef CONFIG_CMA_SIZE_MBYTES
1304 #define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
1306 #define CMA_SIZE_MBYTES 0
1309 static __init
int nfit_test_init(void)
1313 nfit_test_setup(nfit_test_lookup
);
1315 for (i
= 0; i
< NUM_NFITS
; i
++) {
1316 struct nfit_test
*nfit_test
;
1317 struct platform_device
*pdev
;
1320 nfit_test
= kzalloc(sizeof(*nfit_test
), GFP_KERNEL
);
1325 INIT_LIST_HEAD(&nfit_test
->resources
);
1328 nfit_test
->num_pm
= NUM_PM
;
1329 nfit_test
->num_dcr
= NUM_DCR
;
1330 nfit_test
->alloc
= nfit_test0_alloc
;
1331 nfit_test
->setup
= nfit_test0_setup
;
1334 nfit_test
->num_pm
= 1;
1335 nfit_test
->alloc
= nfit_test1_alloc
;
1336 nfit_test
->setup
= nfit_test1_setup
;
1342 pdev
= &nfit_test
->pdev
;
1343 pdev
->name
= KBUILD_MODNAME
;
1345 pdev
->dev
.release
= nfit_test_release
;
1346 rc
= platform_device_register(pdev
);
1348 put_device(&pdev
->dev
);
1352 rc
= dma_coerce_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(64));
1356 instances
[i
] = nfit_test
;
1362 buf
= dma_alloc_coherent(&pdev
->dev
, SZ_128M
, &dma
,
1366 dev_warn(&pdev
->dev
, "need 128M of free cma\n");
1369 dma_free_coherent(&pdev
->dev
, SZ_128M
, buf
, dma
);
1373 rc
= platform_driver_register(&nfit_test_driver
);
1379 for (i
= 0; i
< NUM_NFITS
; i
++)
1381 platform_device_unregister(&instances
[i
]->pdev
);
1382 nfit_test_teardown();
1386 static __exit
void nfit_test_exit(void)
1390 platform_driver_unregister(&nfit_test_driver
);
1391 for (i
= 0; i
< NUM_NFITS
; i
++)
1392 platform_device_unregister(&instances
[i
]->pdev
);
1393 nfit_test_teardown();
1396 module_init(nfit_test_init
);
1397 module_exit(nfit_test_exit
);
1398 MODULE_LICENSE("GPL v2");
1399 MODULE_AUTHOR("Intel Corporation");