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;
256 static int nfit_test_ctl(struct nvdimm_bus_descriptor
*nd_desc
,
257 struct nvdimm
*nvdimm
, unsigned int cmd
, void *buf
,
258 unsigned int buf_len
)
260 struct acpi_nfit_desc
*acpi_desc
= to_acpi_desc(nd_desc
);
261 struct nfit_test
*t
= container_of(acpi_desc
, typeof(*t
), acpi_desc
);
265 struct nfit_mem
*nfit_mem
= nvdimm_provider_data(nvdimm
);
267 if (!nfit_mem
|| !test_bit(cmd
, &nfit_mem
->dsm_mask
))
270 /* lookup label space for the given dimm */
271 for (i
= 0; i
< ARRAY_SIZE(handle
); i
++)
272 if (__to_nfit_memdev(nfit_mem
)->device_handle
==
275 if (i
>= ARRAY_SIZE(handle
))
279 case ND_CMD_GET_CONFIG_SIZE
:
280 rc
= nfit_test_cmd_get_config_size(buf
, buf_len
);
282 case ND_CMD_GET_CONFIG_DATA
:
283 rc
= nfit_test_cmd_get_config_data(buf
, buf_len
,
286 case ND_CMD_SET_CONFIG_DATA
:
287 rc
= nfit_test_cmd_set_config_data(buf
, buf_len
,
294 if (!nd_desc
|| !test_bit(cmd
, &nd_desc
->dsm_mask
))
299 rc
= nfit_test_cmd_ars_cap(buf
, buf_len
);
301 case ND_CMD_ARS_START
:
302 rc
= nfit_test_cmd_ars_start(buf
, buf_len
);
304 case ND_CMD_ARS_STATUS
:
305 rc
= nfit_test_cmd_ars_status(buf
, buf_len
);
315 static DEFINE_SPINLOCK(nfit_test_lock
);
316 static struct nfit_test
*instances
[NUM_NFITS
];
318 static void release_nfit_res(void *data
)
320 struct nfit_test_resource
*nfit_res
= data
;
321 struct resource
*res
= nfit_res
->res
;
323 spin_lock(&nfit_test_lock
);
324 list_del(&nfit_res
->list
);
325 spin_unlock(&nfit_test_lock
);
327 if (is_vmalloc_addr(nfit_res
->buf
))
328 vfree(nfit_res
->buf
);
330 dma_free_coherent(nfit_res
->dev
, resource_size(res
),
331 nfit_res
->buf
, res
->start
);
336 static void *__test_alloc(struct nfit_test
*t
, size_t size
, dma_addr_t
*dma
,
339 struct device
*dev
= &t
->pdev
.dev
;
340 struct resource
*res
= kzalloc(sizeof(*res
) * 2, GFP_KERNEL
);
341 struct nfit_test_resource
*nfit_res
= kzalloc(sizeof(*nfit_res
),
345 if (!res
|| !buf
|| !nfit_res
)
347 rc
= devm_add_action(dev
, release_nfit_res
, nfit_res
);
350 INIT_LIST_HEAD(&nfit_res
->list
);
351 memset(buf
, 0, size
);
356 res
->end
= *dma
+ size
- 1;
358 spin_lock(&nfit_test_lock
);
359 list_add(&nfit_res
->list
, &t
->resources
);
360 spin_unlock(&nfit_test_lock
);
362 return nfit_res
->buf
;
364 if (buf
&& !is_vmalloc_addr(buf
))
365 dma_free_coherent(dev
, size
, buf
, *dma
);
373 static void *test_alloc(struct nfit_test
*t
, size_t size
, dma_addr_t
*dma
)
375 void *buf
= vmalloc(size
);
377 *dma
= (unsigned long) buf
;
378 return __test_alloc(t
, size
, dma
, buf
);
381 static void *test_alloc_coherent(struct nfit_test
*t
, size_t size
,
384 struct device
*dev
= &t
->pdev
.dev
;
385 void *buf
= dma_alloc_coherent(dev
, size
, dma
, GFP_KERNEL
);
387 return __test_alloc(t
, size
, dma
, buf
);
390 static struct nfit_test_resource
*nfit_test_lookup(resource_size_t addr
)
394 for (i
= 0; i
< ARRAY_SIZE(instances
); i
++) {
395 struct nfit_test_resource
*n
, *nfit_res
= NULL
;
396 struct nfit_test
*t
= instances
[i
];
400 spin_lock(&nfit_test_lock
);
401 list_for_each_entry(n
, &t
->resources
, list
) {
402 if (addr
>= n
->res
->start
&& (addr
< n
->res
->start
403 + resource_size(n
->res
))) {
406 } else if (addr
>= (unsigned long) n
->buf
407 && (addr
< (unsigned long) n
->buf
408 + resource_size(n
->res
))) {
413 spin_unlock(&nfit_test_lock
);
421 static int nfit_test0_alloc(struct nfit_test
*t
)
423 size_t nfit_size
= sizeof(struct acpi_nfit_system_address
) * NUM_SPA
424 + sizeof(struct acpi_nfit_memory_map
) * NUM_MEM
425 + sizeof(struct acpi_nfit_control_region
) * NUM_DCR
426 + sizeof(struct acpi_nfit_data_region
) * NUM_BDW
427 + sizeof(struct acpi_nfit_flush_address
) * NUM_DCR
;
430 t
->nfit_buf
= test_alloc(t
, nfit_size
, &t
->nfit_dma
);
433 t
->nfit_size
= nfit_size
;
435 t
->spa_set
[0] = test_alloc_coherent(t
, SPA0_SIZE
, &t
->spa_set_dma
[0]);
439 t
->spa_set
[1] = test_alloc_coherent(t
, SPA1_SIZE
, &t
->spa_set_dma
[1]);
443 t
->spa_set
[2] = test_alloc_coherent(t
, SPA0_SIZE
, &t
->spa_set_dma
[2]);
447 for (i
= 0; i
< NUM_DCR
; i
++) {
448 t
->dimm
[i
] = test_alloc(t
, DIMM_SIZE
, &t
->dimm_dma
[i
]);
452 t
->label
[i
] = test_alloc(t
, LABEL_SIZE
, &t
->label_dma
[i
]);
455 sprintf(t
->label
[i
], "label%d", i
);
457 t
->flush
[i
] = test_alloc(t
, 8, &t
->flush_dma
[i
]);
462 for (i
= 0; i
< NUM_DCR
; i
++) {
463 t
->dcr
[i
] = test_alloc(t
, LABEL_SIZE
, &t
->dcr_dma
[i
]);
471 static int nfit_test1_alloc(struct nfit_test
*t
)
473 size_t nfit_size
= sizeof(struct acpi_nfit_system_address
)
474 + sizeof(struct acpi_nfit_memory_map
)
475 + sizeof(struct acpi_nfit_control_region
);
477 t
->nfit_buf
= test_alloc(t
, nfit_size
, &t
->nfit_dma
);
480 t
->nfit_size
= nfit_size
;
482 t
->spa_set
[0] = test_alloc_coherent(t
, SPA2_SIZE
, &t
->spa_set_dma
[0]);
489 static void nfit_test0_setup(struct nfit_test
*t
)
491 struct nvdimm_bus_descriptor
*nd_desc
;
492 struct acpi_nfit_desc
*acpi_desc
;
493 struct acpi_nfit_memory_map
*memdev
;
494 void *nfit_buf
= t
->nfit_buf
;
495 struct acpi_nfit_system_address
*spa
;
496 struct acpi_nfit_control_region
*dcr
;
497 struct acpi_nfit_data_region
*bdw
;
498 struct acpi_nfit_flush_address
*flush
;
502 * spa0 (interleave first half of dimm0 and dimm1, note storage
503 * does not actually alias the related block-data-window
507 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
508 spa
->header
.length
= sizeof(*spa
);
509 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
510 spa
->range_index
= 0+1;
511 spa
->address
= t
->spa_set_dma
[0];
512 spa
->length
= SPA0_SIZE
;
515 * spa1 (interleave last half of the 4 DIMMS, note storage
516 * does not actually alias the related block-data-window
519 spa
= nfit_buf
+ sizeof(*spa
);
520 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
521 spa
->header
.length
= sizeof(*spa
);
522 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
523 spa
->range_index
= 1+1;
524 spa
->address
= t
->spa_set_dma
[1];
525 spa
->length
= SPA1_SIZE
;
527 /* spa2 (dcr0) dimm0 */
528 spa
= nfit_buf
+ sizeof(*spa
) * 2;
529 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
530 spa
->header
.length
= sizeof(*spa
);
531 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
532 spa
->range_index
= 2+1;
533 spa
->address
= t
->dcr_dma
[0];
534 spa
->length
= DCR_SIZE
;
536 /* spa3 (dcr1) dimm1 */
537 spa
= nfit_buf
+ sizeof(*spa
) * 3;
538 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
539 spa
->header
.length
= sizeof(*spa
);
540 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
541 spa
->range_index
= 3+1;
542 spa
->address
= t
->dcr_dma
[1];
543 spa
->length
= DCR_SIZE
;
545 /* spa4 (dcr2) dimm2 */
546 spa
= nfit_buf
+ sizeof(*spa
) * 4;
547 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
548 spa
->header
.length
= sizeof(*spa
);
549 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
550 spa
->range_index
= 4+1;
551 spa
->address
= t
->dcr_dma
[2];
552 spa
->length
= DCR_SIZE
;
554 /* spa5 (dcr3) dimm3 */
555 spa
= nfit_buf
+ sizeof(*spa
) * 5;
556 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
557 spa
->header
.length
= sizeof(*spa
);
558 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
559 spa
->range_index
= 5+1;
560 spa
->address
= t
->dcr_dma
[3];
561 spa
->length
= DCR_SIZE
;
563 /* spa6 (bdw for dcr0) dimm0 */
564 spa
= nfit_buf
+ sizeof(*spa
) * 6;
565 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
566 spa
->header
.length
= sizeof(*spa
);
567 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
568 spa
->range_index
= 6+1;
569 spa
->address
= t
->dimm_dma
[0];
570 spa
->length
= DIMM_SIZE
;
572 /* spa7 (bdw for dcr1) dimm1 */
573 spa
= nfit_buf
+ sizeof(*spa
) * 7;
574 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
575 spa
->header
.length
= sizeof(*spa
);
576 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
577 spa
->range_index
= 7+1;
578 spa
->address
= t
->dimm_dma
[1];
579 spa
->length
= DIMM_SIZE
;
581 /* spa8 (bdw for dcr2) dimm2 */
582 spa
= nfit_buf
+ sizeof(*spa
) * 8;
583 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
584 spa
->header
.length
= sizeof(*spa
);
585 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
586 spa
->range_index
= 8+1;
587 spa
->address
= t
->dimm_dma
[2];
588 spa
->length
= DIMM_SIZE
;
590 /* spa9 (bdw for dcr3) dimm3 */
591 spa
= nfit_buf
+ sizeof(*spa
) * 9;
592 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
593 spa
->header
.length
= sizeof(*spa
);
594 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
595 spa
->range_index
= 9+1;
596 spa
->address
= t
->dimm_dma
[3];
597 spa
->length
= DIMM_SIZE
;
599 offset
= sizeof(*spa
) * 10;
600 /* mem-region0 (spa0, dimm0) */
601 memdev
= nfit_buf
+ offset
;
602 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
603 memdev
->header
.length
= sizeof(*memdev
);
604 memdev
->device_handle
= handle
[0];
605 memdev
->physical_id
= 0;
606 memdev
->region_id
= 0;
607 memdev
->range_index
= 0+1;
608 memdev
->region_index
= 0+1;
609 memdev
->region_size
= SPA0_SIZE
/2;
610 memdev
->region_offset
= t
->spa_set_dma
[0];
612 memdev
->interleave_index
= 0;
613 memdev
->interleave_ways
= 2;
615 /* mem-region1 (spa0, dimm1) */
616 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
);
617 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
618 memdev
->header
.length
= sizeof(*memdev
);
619 memdev
->device_handle
= handle
[1];
620 memdev
->physical_id
= 1;
621 memdev
->region_id
= 0;
622 memdev
->range_index
= 0+1;
623 memdev
->region_index
= 1+1;
624 memdev
->region_size
= SPA0_SIZE
/2;
625 memdev
->region_offset
= t
->spa_set_dma
[0] + SPA0_SIZE
/2;
627 memdev
->interleave_index
= 0;
628 memdev
->interleave_ways
= 2;
630 /* mem-region2 (spa1, dimm0) */
631 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 2;
632 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
633 memdev
->header
.length
= sizeof(*memdev
);
634 memdev
->device_handle
= handle
[0];
635 memdev
->physical_id
= 0;
636 memdev
->region_id
= 1;
637 memdev
->range_index
= 1+1;
638 memdev
->region_index
= 0+1;
639 memdev
->region_size
= SPA1_SIZE
/4;
640 memdev
->region_offset
= t
->spa_set_dma
[1];
641 memdev
->address
= SPA0_SIZE
/2;
642 memdev
->interleave_index
= 0;
643 memdev
->interleave_ways
= 4;
645 /* mem-region3 (spa1, dimm1) */
646 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 3;
647 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
648 memdev
->header
.length
= sizeof(*memdev
);
649 memdev
->device_handle
= handle
[1];
650 memdev
->physical_id
= 1;
651 memdev
->region_id
= 1;
652 memdev
->range_index
= 1+1;
653 memdev
->region_index
= 1+1;
654 memdev
->region_size
= SPA1_SIZE
/4;
655 memdev
->region_offset
= t
->spa_set_dma
[1] + SPA1_SIZE
/4;
656 memdev
->address
= SPA0_SIZE
/2;
657 memdev
->interleave_index
= 0;
658 memdev
->interleave_ways
= 4;
660 /* mem-region4 (spa1, dimm2) */
661 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 4;
662 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
663 memdev
->header
.length
= sizeof(*memdev
);
664 memdev
->device_handle
= handle
[2];
665 memdev
->physical_id
= 2;
666 memdev
->region_id
= 0;
667 memdev
->range_index
= 1+1;
668 memdev
->region_index
= 2+1;
669 memdev
->region_size
= SPA1_SIZE
/4;
670 memdev
->region_offset
= t
->spa_set_dma
[1] + 2*SPA1_SIZE
/4;
671 memdev
->address
= SPA0_SIZE
/2;
672 memdev
->interleave_index
= 0;
673 memdev
->interleave_ways
= 4;
675 /* mem-region5 (spa1, dimm3) */
676 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 5;
677 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
678 memdev
->header
.length
= sizeof(*memdev
);
679 memdev
->device_handle
= handle
[3];
680 memdev
->physical_id
= 3;
681 memdev
->region_id
= 0;
682 memdev
->range_index
= 1+1;
683 memdev
->region_index
= 3+1;
684 memdev
->region_size
= SPA1_SIZE
/4;
685 memdev
->region_offset
= t
->spa_set_dma
[1] + 3*SPA1_SIZE
/4;
686 memdev
->address
= SPA0_SIZE
/2;
687 memdev
->interleave_index
= 0;
688 memdev
->interleave_ways
= 4;
690 /* mem-region6 (spa/dcr0, dimm0) */
691 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 6;
692 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
693 memdev
->header
.length
= sizeof(*memdev
);
694 memdev
->device_handle
= handle
[0];
695 memdev
->physical_id
= 0;
696 memdev
->region_id
= 0;
697 memdev
->range_index
= 2+1;
698 memdev
->region_index
= 0+1;
699 memdev
->region_size
= 0;
700 memdev
->region_offset
= 0;
702 memdev
->interleave_index
= 0;
703 memdev
->interleave_ways
= 1;
705 /* mem-region7 (spa/dcr1, dimm1) */
706 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 7;
707 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
708 memdev
->header
.length
= sizeof(*memdev
);
709 memdev
->device_handle
= handle
[1];
710 memdev
->physical_id
= 1;
711 memdev
->region_id
= 0;
712 memdev
->range_index
= 3+1;
713 memdev
->region_index
= 1+1;
714 memdev
->region_size
= 0;
715 memdev
->region_offset
= 0;
717 memdev
->interleave_index
= 0;
718 memdev
->interleave_ways
= 1;
720 /* mem-region8 (spa/dcr2, dimm2) */
721 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 8;
722 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
723 memdev
->header
.length
= sizeof(*memdev
);
724 memdev
->device_handle
= handle
[2];
725 memdev
->physical_id
= 2;
726 memdev
->region_id
= 0;
727 memdev
->range_index
= 4+1;
728 memdev
->region_index
= 2+1;
729 memdev
->region_size
= 0;
730 memdev
->region_offset
= 0;
732 memdev
->interleave_index
= 0;
733 memdev
->interleave_ways
= 1;
735 /* mem-region9 (spa/dcr3, dimm3) */
736 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 9;
737 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
738 memdev
->header
.length
= sizeof(*memdev
);
739 memdev
->device_handle
= handle
[3];
740 memdev
->physical_id
= 3;
741 memdev
->region_id
= 0;
742 memdev
->range_index
= 5+1;
743 memdev
->region_index
= 3+1;
744 memdev
->region_size
= 0;
745 memdev
->region_offset
= 0;
747 memdev
->interleave_index
= 0;
748 memdev
->interleave_ways
= 1;
750 /* mem-region10 (spa/bdw0, dimm0) */
751 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 10;
752 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
753 memdev
->header
.length
= sizeof(*memdev
);
754 memdev
->device_handle
= handle
[0];
755 memdev
->physical_id
= 0;
756 memdev
->region_id
= 0;
757 memdev
->range_index
= 6+1;
758 memdev
->region_index
= 0+1;
759 memdev
->region_size
= 0;
760 memdev
->region_offset
= 0;
762 memdev
->interleave_index
= 0;
763 memdev
->interleave_ways
= 1;
765 /* mem-region11 (spa/bdw1, dimm1) */
766 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 11;
767 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
768 memdev
->header
.length
= sizeof(*memdev
);
769 memdev
->device_handle
= handle
[1];
770 memdev
->physical_id
= 1;
771 memdev
->region_id
= 0;
772 memdev
->range_index
= 7+1;
773 memdev
->region_index
= 1+1;
774 memdev
->region_size
= 0;
775 memdev
->region_offset
= 0;
777 memdev
->interleave_index
= 0;
778 memdev
->interleave_ways
= 1;
780 /* mem-region12 (spa/bdw2, dimm2) */
781 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 12;
782 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
783 memdev
->header
.length
= sizeof(*memdev
);
784 memdev
->device_handle
= handle
[2];
785 memdev
->physical_id
= 2;
786 memdev
->region_id
= 0;
787 memdev
->range_index
= 8+1;
788 memdev
->region_index
= 2+1;
789 memdev
->region_size
= 0;
790 memdev
->region_offset
= 0;
792 memdev
->interleave_index
= 0;
793 memdev
->interleave_ways
= 1;
795 /* mem-region13 (spa/dcr3, dimm3) */
796 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 13;
797 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
798 memdev
->header
.length
= sizeof(*memdev
);
799 memdev
->device_handle
= handle
[3];
800 memdev
->physical_id
= 3;
801 memdev
->region_id
= 0;
802 memdev
->range_index
= 9+1;
803 memdev
->region_index
= 3+1;
804 memdev
->region_size
= 0;
805 memdev
->region_offset
= 0;
807 memdev
->interleave_index
= 0;
808 memdev
->interleave_ways
= 1;
810 offset
= offset
+ sizeof(struct acpi_nfit_memory_map
) * 14;
811 /* dcr-descriptor0 */
812 dcr
= nfit_buf
+ offset
;
813 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
814 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
815 dcr
->region_index
= 0+1;
816 dcr
->vendor_id
= 0xabcd;
818 dcr
->revision_id
= 1;
819 dcr
->serial_number
= ~handle
[0];
821 dcr
->window_size
= DCR_SIZE
;
822 dcr
->command_offset
= 0;
823 dcr
->command_size
= 8;
824 dcr
->status_offset
= 8;
825 dcr
->status_size
= 4;
827 /* dcr-descriptor1 */
828 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
);
829 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
830 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
831 dcr
->region_index
= 1+1;
832 dcr
->vendor_id
= 0xabcd;
834 dcr
->revision_id
= 1;
835 dcr
->serial_number
= ~handle
[1];
837 dcr
->window_size
= DCR_SIZE
;
838 dcr
->command_offset
= 0;
839 dcr
->command_size
= 8;
840 dcr
->status_offset
= 8;
841 dcr
->status_size
= 4;
843 /* dcr-descriptor2 */
844 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
) * 2;
845 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
846 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
847 dcr
->region_index
= 2+1;
848 dcr
->vendor_id
= 0xabcd;
850 dcr
->revision_id
= 1;
851 dcr
->serial_number
= ~handle
[2];
853 dcr
->window_size
= DCR_SIZE
;
854 dcr
->command_offset
= 0;
855 dcr
->command_size
= 8;
856 dcr
->status_offset
= 8;
857 dcr
->status_size
= 4;
859 /* dcr-descriptor3 */
860 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
) * 3;
861 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
862 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
863 dcr
->region_index
= 3+1;
864 dcr
->vendor_id
= 0xabcd;
866 dcr
->revision_id
= 1;
867 dcr
->serial_number
= ~handle
[3];
869 dcr
->window_size
= DCR_SIZE
;
870 dcr
->command_offset
= 0;
871 dcr
->command_size
= 8;
872 dcr
->status_offset
= 8;
873 dcr
->status_size
= 4;
875 offset
= offset
+ sizeof(struct acpi_nfit_control_region
) * 4;
876 /* bdw0 (spa/dcr0, dimm0) */
877 bdw
= nfit_buf
+ offset
;
878 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
879 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
880 bdw
->region_index
= 0+1;
883 bdw
->size
= BDW_SIZE
;
884 bdw
->capacity
= DIMM_SIZE
;
885 bdw
->start_address
= 0;
887 /* bdw1 (spa/dcr1, dimm1) */
888 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
);
889 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
890 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
891 bdw
->region_index
= 1+1;
894 bdw
->size
= BDW_SIZE
;
895 bdw
->capacity
= DIMM_SIZE
;
896 bdw
->start_address
= 0;
898 /* bdw2 (spa/dcr2, dimm2) */
899 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
) * 2;
900 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
901 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
902 bdw
->region_index
= 2+1;
905 bdw
->size
= BDW_SIZE
;
906 bdw
->capacity
= DIMM_SIZE
;
907 bdw
->start_address
= 0;
909 /* bdw3 (spa/dcr3, dimm3) */
910 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
) * 3;
911 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
912 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
913 bdw
->region_index
= 3+1;
916 bdw
->size
= BDW_SIZE
;
917 bdw
->capacity
= DIMM_SIZE
;
918 bdw
->start_address
= 0;
920 offset
= offset
+ sizeof(struct acpi_nfit_data_region
) * 4;
922 flush
= nfit_buf
+ offset
;
923 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
924 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
925 flush
->device_handle
= handle
[0];
926 flush
->hint_count
= 1;
927 flush
->hint_address
[0] = t
->flush_dma
[0];
930 flush
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_flush_address
) * 1;
931 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
932 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
933 flush
->device_handle
= handle
[1];
934 flush
->hint_count
= 1;
935 flush
->hint_address
[0] = t
->flush_dma
[1];
938 flush
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_flush_address
) * 2;
939 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
940 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
941 flush
->device_handle
= handle
[2];
942 flush
->hint_count
= 1;
943 flush
->hint_address
[0] = t
->flush_dma
[2];
946 flush
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_flush_address
) * 3;
947 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
948 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
949 flush
->device_handle
= handle
[3];
950 flush
->hint_count
= 1;
951 flush
->hint_address
[0] = t
->flush_dma
[3];
953 if (t
->setup_hotplug
) {
954 offset
= offset
+ sizeof(struct acpi_nfit_flush_address
) * 4;
955 /* dcr-descriptor4 */
956 dcr
= nfit_buf
+ offset
;
957 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
958 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
959 dcr
->region_index
= 4+1;
960 dcr
->vendor_id
= 0xabcd;
962 dcr
->revision_id
= 1;
963 dcr
->serial_number
= ~handle
[4];
965 dcr
->window_size
= DCR_SIZE
;
966 dcr
->command_offset
= 0;
967 dcr
->command_size
= 8;
968 dcr
->status_offset
= 8;
969 dcr
->status_size
= 4;
971 offset
= offset
+ sizeof(struct acpi_nfit_control_region
);
972 /* bdw4 (spa/dcr4, dimm4) */
973 bdw
= nfit_buf
+ offset
;
974 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
975 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
976 bdw
->region_index
= 4+1;
979 bdw
->size
= BDW_SIZE
;
980 bdw
->capacity
= DIMM_SIZE
;
981 bdw
->start_address
= 0;
983 offset
= offset
+ sizeof(struct acpi_nfit_data_region
);
984 /* spa10 (dcr4) dimm4 */
985 spa
= nfit_buf
+ offset
;
986 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
987 spa
->header
.length
= sizeof(*spa
);
988 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
989 spa
->range_index
= 10+1;
990 spa
->address
= t
->dcr_dma
[4];
991 spa
->length
= DCR_SIZE
;
994 * spa11 (single-dimm interleave for hotplug, note storage
995 * does not actually alias the related block-data-window
998 spa
= nfit_buf
+ offset
+ sizeof(*spa
);
999 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1000 spa
->header
.length
= sizeof(*spa
);
1001 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
1002 spa
->range_index
= 11+1;
1003 spa
->address
= t
->spa_set_dma
[2];
1004 spa
->length
= SPA0_SIZE
;
1006 /* spa12 (bdw for dcr4) dimm4 */
1007 spa
= nfit_buf
+ offset
+ sizeof(*spa
) * 2;
1008 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1009 spa
->header
.length
= sizeof(*spa
);
1010 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
1011 spa
->range_index
= 12+1;
1012 spa
->address
= t
->dimm_dma
[4];
1013 spa
->length
= DIMM_SIZE
;
1015 offset
= offset
+ sizeof(*spa
) * 3;
1016 /* mem-region14 (spa/dcr4, dimm4) */
1017 memdev
= nfit_buf
+ offset
;
1018 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1019 memdev
->header
.length
= sizeof(*memdev
);
1020 memdev
->device_handle
= handle
[4];
1021 memdev
->physical_id
= 4;
1022 memdev
->region_id
= 0;
1023 memdev
->range_index
= 10+1;
1024 memdev
->region_index
= 4+1;
1025 memdev
->region_size
= 0;
1026 memdev
->region_offset
= 0;
1027 memdev
->address
= 0;
1028 memdev
->interleave_index
= 0;
1029 memdev
->interleave_ways
= 1;
1031 /* mem-region15 (spa0, dimm4) */
1032 memdev
= nfit_buf
+ offset
+
1033 sizeof(struct acpi_nfit_memory_map
);
1034 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1035 memdev
->header
.length
= sizeof(*memdev
);
1036 memdev
->device_handle
= handle
[4];
1037 memdev
->physical_id
= 4;
1038 memdev
->region_id
= 0;
1039 memdev
->range_index
= 11+1;
1040 memdev
->region_index
= 4+1;
1041 memdev
->region_size
= SPA0_SIZE
;
1042 memdev
->region_offset
= t
->spa_set_dma
[2];
1043 memdev
->address
= 0;
1044 memdev
->interleave_index
= 0;
1045 memdev
->interleave_ways
= 1;
1047 /* mem-region16 (spa/dcr4, dimm4) */
1048 memdev
= nfit_buf
+ offset
+
1049 sizeof(struct acpi_nfit_memory_map
) * 2;
1050 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1051 memdev
->header
.length
= sizeof(*memdev
);
1052 memdev
->device_handle
= handle
[4];
1053 memdev
->physical_id
= 4;
1054 memdev
->region_id
= 0;
1055 memdev
->range_index
= 12+1;
1056 memdev
->region_index
= 4+1;
1057 memdev
->region_size
= 0;
1058 memdev
->region_offset
= 0;
1059 memdev
->address
= 0;
1060 memdev
->interleave_index
= 0;
1061 memdev
->interleave_ways
= 1;
1063 offset
= offset
+ sizeof(struct acpi_nfit_memory_map
) * 3;
1064 /* flush3 (dimm4) */
1065 flush
= nfit_buf
+ offset
;
1066 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1067 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
1068 flush
->device_handle
= handle
[4];
1069 flush
->hint_count
= 1;
1070 flush
->hint_address
[0] = t
->flush_dma
[4];
1073 acpi_desc
= &t
->acpi_desc
;
1074 set_bit(ND_CMD_GET_CONFIG_SIZE
, &acpi_desc
->dimm_dsm_force_en
);
1075 set_bit(ND_CMD_GET_CONFIG_DATA
, &acpi_desc
->dimm_dsm_force_en
);
1076 set_bit(ND_CMD_SET_CONFIG_DATA
, &acpi_desc
->dimm_dsm_force_en
);
1077 set_bit(ND_CMD_ARS_CAP
, &acpi_desc
->bus_dsm_force_en
);
1078 set_bit(ND_CMD_ARS_START
, &acpi_desc
->bus_dsm_force_en
);
1079 set_bit(ND_CMD_ARS_STATUS
, &acpi_desc
->bus_dsm_force_en
);
1080 nd_desc
= &acpi_desc
->nd_desc
;
1081 nd_desc
->ndctl
= nfit_test_ctl
;
1084 static void nfit_test1_setup(struct nfit_test
*t
)
1087 void *nfit_buf
= t
->nfit_buf
;
1088 struct acpi_nfit_memory_map
*memdev
;
1089 struct acpi_nfit_control_region
*dcr
;
1090 struct acpi_nfit_system_address
*spa
;
1093 /* spa0 (flat range with no bdw aliasing) */
1094 spa
= nfit_buf
+ offset
;
1095 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1096 spa
->header
.length
= sizeof(*spa
);
1097 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
1098 spa
->range_index
= 0+1;
1099 spa
->address
= t
->spa_set_dma
[0];
1100 spa
->length
= SPA2_SIZE
;
1102 offset
+= sizeof(*spa
);
1103 /* mem-region0 (spa0, dimm0) */
1104 memdev
= nfit_buf
+ offset
;
1105 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1106 memdev
->header
.length
= sizeof(*memdev
);
1107 memdev
->device_handle
= 0;
1108 memdev
->physical_id
= 0;
1109 memdev
->region_id
= 0;
1110 memdev
->range_index
= 0+1;
1111 memdev
->region_index
= 0+1;
1112 memdev
->region_size
= SPA2_SIZE
;
1113 memdev
->region_offset
= 0;
1114 memdev
->address
= 0;
1115 memdev
->interleave_index
= 0;
1116 memdev
->interleave_ways
= 1;
1117 memdev
->flags
= ACPI_NFIT_MEM_SAVE_FAILED
| ACPI_NFIT_MEM_RESTORE_FAILED
1118 | ACPI_NFIT_MEM_FLUSH_FAILED
| ACPI_NFIT_MEM_HEALTH_OBSERVED
1119 | ACPI_NFIT_MEM_NOT_ARMED
;
1121 offset
+= sizeof(*memdev
);
1122 /* dcr-descriptor0 */
1123 dcr
= nfit_buf
+ offset
;
1124 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1125 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
1126 dcr
->region_index
= 0+1;
1127 dcr
->vendor_id
= 0xabcd;
1129 dcr
->revision_id
= 1;
1130 dcr
->serial_number
= ~0;
1133 dcr
->window_size
= 0;
1134 dcr
->command_offset
= 0;
1135 dcr
->command_size
= 0;
1136 dcr
->status_offset
= 0;
1137 dcr
->status_size
= 0;
1140 static int nfit_test_blk_do_io(struct nd_blk_region
*ndbr
, resource_size_t dpa
,
1141 void *iobuf
, u64 len
, int rw
)
1143 struct nfit_blk
*nfit_blk
= ndbr
->blk_provider_data
;
1144 struct nfit_blk_mmio
*mmio
= &nfit_blk
->mmio
[BDW
];
1145 struct nd_region
*nd_region
= &ndbr
->nd_region
;
1148 lane
= nd_region_acquire_lane(nd_region
);
1150 memcpy(mmio
->addr
.base
+ dpa
, iobuf
, len
);
1152 memcpy(iobuf
, mmio
->addr
.base
+ dpa
, len
);
1154 /* give us some some coverage of the mmio_flush_range() API */
1155 mmio_flush_range(mmio
->addr
.base
+ dpa
, len
);
1157 nd_region_release_lane(nd_region
, lane
);
1162 static int nfit_test_probe(struct platform_device
*pdev
)
1164 struct nvdimm_bus_descriptor
*nd_desc
;
1165 struct acpi_nfit_desc
*acpi_desc
;
1166 struct device
*dev
= &pdev
->dev
;
1167 struct nfit_test
*nfit_test
;
1170 nfit_test
= to_nfit_test(&pdev
->dev
);
1173 if (nfit_test
->num_dcr
) {
1174 int num
= nfit_test
->num_dcr
;
1176 nfit_test
->dimm
= devm_kcalloc(dev
, num
, sizeof(void *),
1178 nfit_test
->dimm_dma
= devm_kcalloc(dev
, num
, sizeof(dma_addr_t
),
1180 nfit_test
->flush
= devm_kcalloc(dev
, num
, sizeof(void *),
1182 nfit_test
->flush_dma
= devm_kcalloc(dev
, num
, sizeof(dma_addr_t
),
1184 nfit_test
->label
= devm_kcalloc(dev
, num
, sizeof(void *),
1186 nfit_test
->label_dma
= devm_kcalloc(dev
, num
,
1187 sizeof(dma_addr_t
), GFP_KERNEL
);
1188 nfit_test
->dcr
= devm_kcalloc(dev
, num
,
1189 sizeof(struct nfit_test_dcr
*), GFP_KERNEL
);
1190 nfit_test
->dcr_dma
= devm_kcalloc(dev
, num
,
1191 sizeof(dma_addr_t
), GFP_KERNEL
);
1192 if (nfit_test
->dimm
&& nfit_test
->dimm_dma
&& nfit_test
->label
1193 && nfit_test
->label_dma
&& nfit_test
->dcr
1194 && nfit_test
->dcr_dma
&& nfit_test
->flush
1195 && nfit_test
->flush_dma
)
1201 if (nfit_test
->num_pm
) {
1202 int num
= nfit_test
->num_pm
;
1204 nfit_test
->spa_set
= devm_kcalloc(dev
, num
, sizeof(void *),
1206 nfit_test
->spa_set_dma
= devm_kcalloc(dev
, num
,
1207 sizeof(dma_addr_t
), GFP_KERNEL
);
1208 if (nfit_test
->spa_set
&& nfit_test
->spa_set_dma
)
1214 /* per-nfit specific alloc */
1215 if (nfit_test
->alloc(nfit_test
))
1218 nfit_test
->setup(nfit_test
);
1219 acpi_desc
= &nfit_test
->acpi_desc
;
1220 acpi_desc
->dev
= &pdev
->dev
;
1221 acpi_desc
->nfit
= nfit_test
->nfit_buf
;
1222 acpi_desc
->blk_do_io
= nfit_test_blk_do_io
;
1223 nd_desc
= &acpi_desc
->nd_desc
;
1224 nd_desc
->attr_groups
= acpi_nfit_attribute_groups
;
1225 acpi_desc
->nvdimm_bus
= nvdimm_bus_register(&pdev
->dev
, nd_desc
);
1226 if (!acpi_desc
->nvdimm_bus
)
1229 INIT_LIST_HEAD(&acpi_desc
->spa_maps
);
1230 INIT_LIST_HEAD(&acpi_desc
->spas
);
1231 INIT_LIST_HEAD(&acpi_desc
->dcrs
);
1232 INIT_LIST_HEAD(&acpi_desc
->bdws
);
1233 INIT_LIST_HEAD(&acpi_desc
->idts
);
1234 INIT_LIST_HEAD(&acpi_desc
->flushes
);
1235 INIT_LIST_HEAD(&acpi_desc
->memdevs
);
1236 INIT_LIST_HEAD(&acpi_desc
->dimms
);
1237 mutex_init(&acpi_desc
->spa_map_mutex
);
1238 mutex_init(&acpi_desc
->init_mutex
);
1240 rc
= acpi_nfit_init(acpi_desc
, nfit_test
->nfit_size
);
1242 nvdimm_bus_unregister(acpi_desc
->nvdimm_bus
);
1246 if (nfit_test
->setup
!= nfit_test0_setup
)
1249 nfit_test
->setup_hotplug
= 1;
1250 nfit_test
->setup(nfit_test
);
1252 rc
= acpi_nfit_init(acpi_desc
, nfit_test
->nfit_size
);
1254 nvdimm_bus_unregister(acpi_desc
->nvdimm_bus
);
1261 static int nfit_test_remove(struct platform_device
*pdev
)
1263 struct nfit_test
*nfit_test
= to_nfit_test(&pdev
->dev
);
1264 struct acpi_nfit_desc
*acpi_desc
= &nfit_test
->acpi_desc
;
1266 nvdimm_bus_unregister(acpi_desc
->nvdimm_bus
);
1271 static void nfit_test_release(struct device
*dev
)
1273 struct nfit_test
*nfit_test
= to_nfit_test(dev
);
1278 static const struct platform_device_id nfit_test_id
[] = {
1283 static struct platform_driver nfit_test_driver
= {
1284 .probe
= nfit_test_probe
,
1285 .remove
= nfit_test_remove
,
1287 .name
= KBUILD_MODNAME
,
1289 .id_table
= nfit_test_id
,
1292 #ifdef CONFIG_CMA_SIZE_MBYTES
1293 #define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
1295 #define CMA_SIZE_MBYTES 0
1298 static __init
int nfit_test_init(void)
1302 nfit_test_setup(nfit_test_lookup
);
1304 for (i
= 0; i
< NUM_NFITS
; i
++) {
1305 struct nfit_test
*nfit_test
;
1306 struct platform_device
*pdev
;
1309 nfit_test
= kzalloc(sizeof(*nfit_test
), GFP_KERNEL
);
1314 INIT_LIST_HEAD(&nfit_test
->resources
);
1317 nfit_test
->num_pm
= NUM_PM
;
1318 nfit_test
->num_dcr
= NUM_DCR
;
1319 nfit_test
->alloc
= nfit_test0_alloc
;
1320 nfit_test
->setup
= nfit_test0_setup
;
1323 nfit_test
->num_pm
= 1;
1324 nfit_test
->alloc
= nfit_test1_alloc
;
1325 nfit_test
->setup
= nfit_test1_setup
;
1331 pdev
= &nfit_test
->pdev
;
1332 pdev
->name
= KBUILD_MODNAME
;
1334 pdev
->dev
.release
= nfit_test_release
;
1335 rc
= platform_device_register(pdev
);
1337 put_device(&pdev
->dev
);
1341 rc
= dma_coerce_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(64));
1345 instances
[i
] = nfit_test
;
1351 buf
= dma_alloc_coherent(&pdev
->dev
, SZ_128M
, &dma
,
1355 dev_warn(&pdev
->dev
, "need 128M of free cma\n");
1358 dma_free_coherent(&pdev
->dev
, SZ_128M
, buf
, dma
);
1362 rc
= platform_driver_register(&nfit_test_driver
);
1368 for (i
= 0; i
< NUM_NFITS
; i
++)
1370 platform_device_unregister(&instances
[i
]->pdev
);
1371 nfit_test_teardown();
1375 static __exit
void nfit_test_exit(void)
1379 platform_driver_unregister(&nfit_test_driver
);
1380 for (i
= 0; i
< NUM_NFITS
; i
++)
1381 platform_device_unregister(&instances
[i
]->pdev
);
1382 nfit_test_teardown();
1385 module_init(nfit_test_init
);
1386 module_exit(nfit_test_exit
);
1387 MODULE_LICENSE("GPL v2");
1388 MODULE_AUTHOR("Intel Corporation");