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_table_nfit
)
424 + 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
;
431 t
->nfit_buf
= test_alloc(t
, nfit_size
, &t
->nfit_dma
);
434 t
->nfit_size
= nfit_size
;
436 t
->spa_set
[0] = test_alloc_coherent(t
, SPA0_SIZE
, &t
->spa_set_dma
[0]);
440 t
->spa_set
[1] = test_alloc_coherent(t
, SPA1_SIZE
, &t
->spa_set_dma
[1]);
444 t
->spa_set
[2] = test_alloc_coherent(t
, SPA0_SIZE
, &t
->spa_set_dma
[2]);
448 for (i
= 0; i
< NUM_DCR
; i
++) {
449 t
->dimm
[i
] = test_alloc(t
, DIMM_SIZE
, &t
->dimm_dma
[i
]);
453 t
->label
[i
] = test_alloc(t
, LABEL_SIZE
, &t
->label_dma
[i
]);
456 sprintf(t
->label
[i
], "label%d", i
);
458 t
->flush
[i
] = test_alloc(t
, 8, &t
->flush_dma
[i
]);
463 for (i
= 0; i
< NUM_DCR
; i
++) {
464 t
->dcr
[i
] = test_alloc(t
, LABEL_SIZE
, &t
->dcr_dma
[i
]);
472 static int nfit_test1_alloc(struct nfit_test
*t
)
474 size_t nfit_size
= sizeof(struct acpi_table_nfit
)
475 + 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_test_init_header(struct acpi_table_nfit
*nfit
, size_t size
)
493 memcpy(nfit
->header
.signature
, ACPI_SIG_NFIT
, 4);
494 nfit
->header
.length
= size
;
495 nfit
->header
.revision
= 1;
496 memcpy(nfit
->header
.oem_id
, "LIBND", 6);
497 memcpy(nfit
->header
.oem_table_id
, "TEST", 5);
498 nfit
->header
.oem_revision
= 1;
499 memcpy(nfit
->header
.asl_compiler_id
, "TST", 4);
500 nfit
->header
.asl_compiler_revision
= 1;
503 static void nfit_test0_setup(struct nfit_test
*t
)
505 struct nvdimm_bus_descriptor
*nd_desc
;
506 struct acpi_nfit_desc
*acpi_desc
;
507 struct acpi_nfit_memory_map
*memdev
;
508 void *nfit_buf
= t
->nfit_buf
;
509 size_t size
= t
->nfit_size
;
510 struct acpi_nfit_system_address
*spa
;
511 struct acpi_nfit_control_region
*dcr
;
512 struct acpi_nfit_data_region
*bdw
;
513 struct acpi_nfit_flush_address
*flush
;
516 nfit_test_init_header(nfit_buf
, size
);
519 * spa0 (interleave first half of dimm0 and dimm1, note storage
520 * does not actually alias the related block-data-window
523 spa
= nfit_buf
+ sizeof(struct acpi_table_nfit
);
524 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
525 spa
->header
.length
= sizeof(*spa
);
526 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
527 spa
->range_index
= 0+1;
528 spa
->address
= t
->spa_set_dma
[0];
529 spa
->length
= SPA0_SIZE
;
532 * spa1 (interleave last half of the 4 DIMMS, note storage
533 * does not actually alias the related block-data-window
536 spa
= nfit_buf
+ sizeof(struct acpi_table_nfit
) + sizeof(*spa
);
537 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
538 spa
->header
.length
= sizeof(*spa
);
539 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
540 spa
->range_index
= 1+1;
541 spa
->address
= t
->spa_set_dma
[1];
542 spa
->length
= SPA1_SIZE
;
544 /* spa2 (dcr0) dimm0 */
545 spa
= nfit_buf
+ sizeof(struct acpi_table_nfit
) + sizeof(*spa
) * 2;
546 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
547 spa
->header
.length
= sizeof(*spa
);
548 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
549 spa
->range_index
= 2+1;
550 spa
->address
= t
->dcr_dma
[0];
551 spa
->length
= DCR_SIZE
;
553 /* spa3 (dcr1) dimm1 */
554 spa
= nfit_buf
+ sizeof(struct acpi_table_nfit
) + sizeof(*spa
) * 3;
555 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
556 spa
->header
.length
= sizeof(*spa
);
557 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
558 spa
->range_index
= 3+1;
559 spa
->address
= t
->dcr_dma
[1];
560 spa
->length
= DCR_SIZE
;
562 /* spa4 (dcr2) dimm2 */
563 spa
= nfit_buf
+ sizeof(struct acpi_table_nfit
) + sizeof(*spa
) * 4;
564 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
565 spa
->header
.length
= sizeof(*spa
);
566 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
567 spa
->range_index
= 4+1;
568 spa
->address
= t
->dcr_dma
[2];
569 spa
->length
= DCR_SIZE
;
571 /* spa5 (dcr3) dimm3 */
572 spa
= nfit_buf
+ sizeof(struct acpi_table_nfit
) + sizeof(*spa
) * 5;
573 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
574 spa
->header
.length
= sizeof(*spa
);
575 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
576 spa
->range_index
= 5+1;
577 spa
->address
= t
->dcr_dma
[3];
578 spa
->length
= DCR_SIZE
;
580 /* spa6 (bdw for dcr0) dimm0 */
581 spa
= nfit_buf
+ sizeof(struct acpi_table_nfit
) + sizeof(*spa
) * 6;
582 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
583 spa
->header
.length
= sizeof(*spa
);
584 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
585 spa
->range_index
= 6+1;
586 spa
->address
= t
->dimm_dma
[0];
587 spa
->length
= DIMM_SIZE
;
589 /* spa7 (bdw for dcr1) dimm1 */
590 spa
= nfit_buf
+ sizeof(struct acpi_table_nfit
) + sizeof(*spa
) * 7;
591 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
592 spa
->header
.length
= sizeof(*spa
);
593 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
594 spa
->range_index
= 7+1;
595 spa
->address
= t
->dimm_dma
[1];
596 spa
->length
= DIMM_SIZE
;
598 /* spa8 (bdw for dcr2) dimm2 */
599 spa
= nfit_buf
+ sizeof(struct acpi_table_nfit
) + sizeof(*spa
) * 8;
600 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
601 spa
->header
.length
= sizeof(*spa
);
602 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
603 spa
->range_index
= 8+1;
604 spa
->address
= t
->dimm_dma
[2];
605 spa
->length
= DIMM_SIZE
;
607 /* spa9 (bdw for dcr3) dimm3 */
608 spa
= nfit_buf
+ sizeof(struct acpi_table_nfit
) + sizeof(*spa
) * 9;
609 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
610 spa
->header
.length
= sizeof(*spa
);
611 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
612 spa
->range_index
= 9+1;
613 spa
->address
= t
->dimm_dma
[3];
614 spa
->length
= DIMM_SIZE
;
616 offset
= sizeof(struct acpi_table_nfit
) + sizeof(*spa
) * 10;
617 /* mem-region0 (spa0, dimm0) */
618 memdev
= nfit_buf
+ offset
;
619 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
620 memdev
->header
.length
= sizeof(*memdev
);
621 memdev
->device_handle
= handle
[0];
622 memdev
->physical_id
= 0;
623 memdev
->region_id
= 0;
624 memdev
->range_index
= 0+1;
625 memdev
->region_index
= 0+1;
626 memdev
->region_size
= SPA0_SIZE
/2;
627 memdev
->region_offset
= t
->spa_set_dma
[0];
629 memdev
->interleave_index
= 0;
630 memdev
->interleave_ways
= 2;
632 /* mem-region1 (spa0, dimm1) */
633 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
);
634 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
635 memdev
->header
.length
= sizeof(*memdev
);
636 memdev
->device_handle
= handle
[1];
637 memdev
->physical_id
= 1;
638 memdev
->region_id
= 0;
639 memdev
->range_index
= 0+1;
640 memdev
->region_index
= 1+1;
641 memdev
->region_size
= SPA0_SIZE
/2;
642 memdev
->region_offset
= t
->spa_set_dma
[0] + SPA0_SIZE
/2;
644 memdev
->interleave_index
= 0;
645 memdev
->interleave_ways
= 2;
647 /* mem-region2 (spa1, dimm0) */
648 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 2;
649 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
650 memdev
->header
.length
= sizeof(*memdev
);
651 memdev
->device_handle
= handle
[0];
652 memdev
->physical_id
= 0;
653 memdev
->region_id
= 1;
654 memdev
->range_index
= 1+1;
655 memdev
->region_index
= 0+1;
656 memdev
->region_size
= SPA1_SIZE
/4;
657 memdev
->region_offset
= t
->spa_set_dma
[1];
658 memdev
->address
= SPA0_SIZE
/2;
659 memdev
->interleave_index
= 0;
660 memdev
->interleave_ways
= 4;
662 /* mem-region3 (spa1, dimm1) */
663 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 3;
664 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
665 memdev
->header
.length
= sizeof(*memdev
);
666 memdev
->device_handle
= handle
[1];
667 memdev
->physical_id
= 1;
668 memdev
->region_id
= 1;
669 memdev
->range_index
= 1+1;
670 memdev
->region_index
= 1+1;
671 memdev
->region_size
= SPA1_SIZE
/4;
672 memdev
->region_offset
= t
->spa_set_dma
[1] + SPA1_SIZE
/4;
673 memdev
->address
= SPA0_SIZE
/2;
674 memdev
->interleave_index
= 0;
675 memdev
->interleave_ways
= 4;
677 /* mem-region4 (spa1, dimm2) */
678 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 4;
679 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
680 memdev
->header
.length
= sizeof(*memdev
);
681 memdev
->device_handle
= handle
[2];
682 memdev
->physical_id
= 2;
683 memdev
->region_id
= 0;
684 memdev
->range_index
= 1+1;
685 memdev
->region_index
= 2+1;
686 memdev
->region_size
= SPA1_SIZE
/4;
687 memdev
->region_offset
= t
->spa_set_dma
[1] + 2*SPA1_SIZE
/4;
688 memdev
->address
= SPA0_SIZE
/2;
689 memdev
->interleave_index
= 0;
690 memdev
->interleave_ways
= 4;
692 /* mem-region5 (spa1, dimm3) */
693 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 5;
694 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
695 memdev
->header
.length
= sizeof(*memdev
);
696 memdev
->device_handle
= handle
[3];
697 memdev
->physical_id
= 3;
698 memdev
->region_id
= 0;
699 memdev
->range_index
= 1+1;
700 memdev
->region_index
= 3+1;
701 memdev
->region_size
= SPA1_SIZE
/4;
702 memdev
->region_offset
= t
->spa_set_dma
[1] + 3*SPA1_SIZE
/4;
703 memdev
->address
= SPA0_SIZE
/2;
704 memdev
->interleave_index
= 0;
705 memdev
->interleave_ways
= 4;
707 /* mem-region6 (spa/dcr0, dimm0) */
708 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 6;
709 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
710 memdev
->header
.length
= sizeof(*memdev
);
711 memdev
->device_handle
= handle
[0];
712 memdev
->physical_id
= 0;
713 memdev
->region_id
= 0;
714 memdev
->range_index
= 2+1;
715 memdev
->region_index
= 0+1;
716 memdev
->region_size
= 0;
717 memdev
->region_offset
= 0;
719 memdev
->interleave_index
= 0;
720 memdev
->interleave_ways
= 1;
722 /* mem-region7 (spa/dcr1, dimm1) */
723 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 7;
724 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
725 memdev
->header
.length
= sizeof(*memdev
);
726 memdev
->device_handle
= handle
[1];
727 memdev
->physical_id
= 1;
728 memdev
->region_id
= 0;
729 memdev
->range_index
= 3+1;
730 memdev
->region_index
= 1+1;
731 memdev
->region_size
= 0;
732 memdev
->region_offset
= 0;
734 memdev
->interleave_index
= 0;
735 memdev
->interleave_ways
= 1;
737 /* mem-region8 (spa/dcr2, dimm2) */
738 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 8;
739 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
740 memdev
->header
.length
= sizeof(*memdev
);
741 memdev
->device_handle
= handle
[2];
742 memdev
->physical_id
= 2;
743 memdev
->region_id
= 0;
744 memdev
->range_index
= 4+1;
745 memdev
->region_index
= 2+1;
746 memdev
->region_size
= 0;
747 memdev
->region_offset
= 0;
749 memdev
->interleave_index
= 0;
750 memdev
->interleave_ways
= 1;
752 /* mem-region9 (spa/dcr3, dimm3) */
753 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 9;
754 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
755 memdev
->header
.length
= sizeof(*memdev
);
756 memdev
->device_handle
= handle
[3];
757 memdev
->physical_id
= 3;
758 memdev
->region_id
= 0;
759 memdev
->range_index
= 5+1;
760 memdev
->region_index
= 3+1;
761 memdev
->region_size
= 0;
762 memdev
->region_offset
= 0;
764 memdev
->interleave_index
= 0;
765 memdev
->interleave_ways
= 1;
767 /* mem-region10 (spa/bdw0, dimm0) */
768 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 10;
769 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
770 memdev
->header
.length
= sizeof(*memdev
);
771 memdev
->device_handle
= handle
[0];
772 memdev
->physical_id
= 0;
773 memdev
->region_id
= 0;
774 memdev
->range_index
= 6+1;
775 memdev
->region_index
= 0+1;
776 memdev
->region_size
= 0;
777 memdev
->region_offset
= 0;
779 memdev
->interleave_index
= 0;
780 memdev
->interleave_ways
= 1;
782 /* mem-region11 (spa/bdw1, dimm1) */
783 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 11;
784 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
785 memdev
->header
.length
= sizeof(*memdev
);
786 memdev
->device_handle
= handle
[1];
787 memdev
->physical_id
= 1;
788 memdev
->region_id
= 0;
789 memdev
->range_index
= 7+1;
790 memdev
->region_index
= 1+1;
791 memdev
->region_size
= 0;
792 memdev
->region_offset
= 0;
794 memdev
->interleave_index
= 0;
795 memdev
->interleave_ways
= 1;
797 /* mem-region12 (spa/bdw2, dimm2) */
798 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 12;
799 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
800 memdev
->header
.length
= sizeof(*memdev
);
801 memdev
->device_handle
= handle
[2];
802 memdev
->physical_id
= 2;
803 memdev
->region_id
= 0;
804 memdev
->range_index
= 8+1;
805 memdev
->region_index
= 2+1;
806 memdev
->region_size
= 0;
807 memdev
->region_offset
= 0;
809 memdev
->interleave_index
= 0;
810 memdev
->interleave_ways
= 1;
812 /* mem-region13 (spa/dcr3, dimm3) */
813 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 13;
814 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
815 memdev
->header
.length
= sizeof(*memdev
);
816 memdev
->device_handle
= handle
[3];
817 memdev
->physical_id
= 3;
818 memdev
->region_id
= 0;
819 memdev
->range_index
= 9+1;
820 memdev
->region_index
= 3+1;
821 memdev
->region_size
= 0;
822 memdev
->region_offset
= 0;
824 memdev
->interleave_index
= 0;
825 memdev
->interleave_ways
= 1;
827 offset
= offset
+ sizeof(struct acpi_nfit_memory_map
) * 14;
828 /* dcr-descriptor0 */
829 dcr
= nfit_buf
+ offset
;
830 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
831 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
832 dcr
->region_index
= 0+1;
833 dcr
->vendor_id
= 0xabcd;
835 dcr
->revision_id
= 1;
836 dcr
->serial_number
= ~handle
[0];
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;
844 /* dcr-descriptor1 */
845 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
);
846 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
847 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
848 dcr
->region_index
= 1+1;
849 dcr
->vendor_id
= 0xabcd;
851 dcr
->revision_id
= 1;
852 dcr
->serial_number
= ~handle
[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;
860 /* dcr-descriptor2 */
861 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
) * 2;
862 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
863 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
864 dcr
->region_index
= 2+1;
865 dcr
->vendor_id
= 0xabcd;
867 dcr
->revision_id
= 1;
868 dcr
->serial_number
= ~handle
[2];
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;
876 /* dcr-descriptor3 */
877 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
) * 3;
878 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
879 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
880 dcr
->region_index
= 3+1;
881 dcr
->vendor_id
= 0xabcd;
883 dcr
->revision_id
= 1;
884 dcr
->serial_number
= ~handle
[3];
886 dcr
->window_size
= DCR_SIZE
;
887 dcr
->command_offset
= 0;
888 dcr
->command_size
= 8;
889 dcr
->status_offset
= 8;
890 dcr
->status_size
= 4;
892 offset
= offset
+ sizeof(struct acpi_nfit_control_region
) * 4;
893 /* bdw0 (spa/dcr0, dimm0) */
894 bdw
= nfit_buf
+ offset
;
895 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
896 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
897 bdw
->region_index
= 0+1;
900 bdw
->size
= BDW_SIZE
;
901 bdw
->capacity
= DIMM_SIZE
;
902 bdw
->start_address
= 0;
904 /* bdw1 (spa/dcr1, dimm1) */
905 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
);
906 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
907 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
908 bdw
->region_index
= 1+1;
911 bdw
->size
= BDW_SIZE
;
912 bdw
->capacity
= DIMM_SIZE
;
913 bdw
->start_address
= 0;
915 /* bdw2 (spa/dcr2, dimm2) */
916 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
) * 2;
917 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
918 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
919 bdw
->region_index
= 2+1;
922 bdw
->size
= BDW_SIZE
;
923 bdw
->capacity
= DIMM_SIZE
;
924 bdw
->start_address
= 0;
926 /* bdw3 (spa/dcr3, dimm3) */
927 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
) * 3;
928 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
929 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
930 bdw
->region_index
= 3+1;
933 bdw
->size
= BDW_SIZE
;
934 bdw
->capacity
= DIMM_SIZE
;
935 bdw
->start_address
= 0;
937 offset
= offset
+ sizeof(struct acpi_nfit_data_region
) * 4;
939 flush
= nfit_buf
+ offset
;
940 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
941 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
942 flush
->device_handle
= handle
[0];
943 flush
->hint_count
= 1;
944 flush
->hint_address
[0] = t
->flush_dma
[0];
947 flush
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_flush_address
) * 1;
948 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
949 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
950 flush
->device_handle
= handle
[1];
951 flush
->hint_count
= 1;
952 flush
->hint_address
[0] = t
->flush_dma
[1];
955 flush
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_flush_address
) * 2;
956 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
957 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
958 flush
->device_handle
= handle
[2];
959 flush
->hint_count
= 1;
960 flush
->hint_address
[0] = t
->flush_dma
[2];
963 flush
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_flush_address
) * 3;
964 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
965 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
966 flush
->device_handle
= handle
[3];
967 flush
->hint_count
= 1;
968 flush
->hint_address
[0] = t
->flush_dma
[3];
970 if (t
->setup_hotplug
) {
971 offset
= offset
+ sizeof(struct acpi_nfit_flush_address
) * 4;
972 /* dcr-descriptor4 */
973 dcr
= nfit_buf
+ offset
;
974 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
975 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
976 dcr
->region_index
= 4+1;
977 dcr
->vendor_id
= 0xabcd;
979 dcr
->revision_id
= 1;
980 dcr
->serial_number
= ~handle
[4];
982 dcr
->window_size
= DCR_SIZE
;
983 dcr
->command_offset
= 0;
984 dcr
->command_size
= 8;
985 dcr
->status_offset
= 8;
986 dcr
->status_size
= 4;
988 offset
= offset
+ sizeof(struct acpi_nfit_control_region
);
989 /* bdw4 (spa/dcr4, dimm4) */
990 bdw
= nfit_buf
+ offset
;
991 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
992 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
993 bdw
->region_index
= 4+1;
996 bdw
->size
= BDW_SIZE
;
997 bdw
->capacity
= DIMM_SIZE
;
998 bdw
->start_address
= 0;
1000 offset
= offset
+ sizeof(struct acpi_nfit_data_region
);
1001 /* spa10 (dcr4) dimm4 */
1002 spa
= nfit_buf
+ offset
;
1003 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1004 spa
->header
.length
= sizeof(*spa
);
1005 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
1006 spa
->range_index
= 10+1;
1007 spa
->address
= t
->dcr_dma
[4];
1008 spa
->length
= DCR_SIZE
;
1011 * spa11 (single-dimm interleave for hotplug, note storage
1012 * does not actually alias the related block-data-window
1015 spa
= nfit_buf
+ offset
+ sizeof(*spa
);
1016 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1017 spa
->header
.length
= sizeof(*spa
);
1018 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
1019 spa
->range_index
= 11+1;
1020 spa
->address
= t
->spa_set_dma
[2];
1021 spa
->length
= SPA0_SIZE
;
1023 /* spa12 (bdw for dcr4) dimm4 */
1024 spa
= nfit_buf
+ offset
+ sizeof(*spa
) * 2;
1025 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1026 spa
->header
.length
= sizeof(*spa
);
1027 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
1028 spa
->range_index
= 12+1;
1029 spa
->address
= t
->dimm_dma
[4];
1030 spa
->length
= DIMM_SIZE
;
1032 offset
= offset
+ sizeof(*spa
) * 3;
1033 /* mem-region14 (spa/dcr4, dimm4) */
1034 memdev
= nfit_buf
+ offset
;
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
= 10+1;
1041 memdev
->region_index
= 4+1;
1042 memdev
->region_size
= 0;
1043 memdev
->region_offset
= 0;
1044 memdev
->address
= 0;
1045 memdev
->interleave_index
= 0;
1046 memdev
->interleave_ways
= 1;
1048 /* mem-region15 (spa0, dimm4) */
1049 memdev
= nfit_buf
+ offset
+
1050 sizeof(struct acpi_nfit_memory_map
);
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
= 11+1;
1057 memdev
->region_index
= 4+1;
1058 memdev
->region_size
= SPA0_SIZE
;
1059 memdev
->region_offset
= t
->spa_set_dma
[2];
1060 memdev
->address
= 0;
1061 memdev
->interleave_index
= 0;
1062 memdev
->interleave_ways
= 1;
1064 /* mem-region16 (spa/dcr4, dimm4) */
1065 memdev
= nfit_buf
+ offset
+
1066 sizeof(struct acpi_nfit_memory_map
) * 2;
1067 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1068 memdev
->header
.length
= sizeof(*memdev
);
1069 memdev
->device_handle
= handle
[4];
1070 memdev
->physical_id
= 4;
1071 memdev
->region_id
= 0;
1072 memdev
->range_index
= 12+1;
1073 memdev
->region_index
= 4+1;
1074 memdev
->region_size
= 0;
1075 memdev
->region_offset
= 0;
1076 memdev
->address
= 0;
1077 memdev
->interleave_index
= 0;
1078 memdev
->interleave_ways
= 1;
1080 offset
= offset
+ sizeof(struct acpi_nfit_memory_map
) * 3;
1081 /* flush3 (dimm4) */
1082 flush
= nfit_buf
+ offset
;
1083 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1084 flush
->header
.length
= sizeof(struct acpi_nfit_flush_address
);
1085 flush
->device_handle
= handle
[4];
1086 flush
->hint_count
= 1;
1087 flush
->hint_address
[0] = t
->flush_dma
[4];
1090 acpi_desc
= &t
->acpi_desc
;
1091 set_bit(ND_CMD_GET_CONFIG_SIZE
, &acpi_desc
->dimm_dsm_force_en
);
1092 set_bit(ND_CMD_GET_CONFIG_DATA
, &acpi_desc
->dimm_dsm_force_en
);
1093 set_bit(ND_CMD_SET_CONFIG_DATA
, &acpi_desc
->dimm_dsm_force_en
);
1094 set_bit(ND_CMD_ARS_CAP
, &acpi_desc
->bus_dsm_force_en
);
1095 set_bit(ND_CMD_ARS_START
, &acpi_desc
->bus_dsm_force_en
);
1096 set_bit(ND_CMD_ARS_STATUS
, &acpi_desc
->bus_dsm_force_en
);
1097 nd_desc
= &acpi_desc
->nd_desc
;
1098 nd_desc
->ndctl
= nfit_test_ctl
;
1101 static void nfit_test1_setup(struct nfit_test
*t
)
1103 size_t size
= t
->nfit_size
, offset
;
1104 void *nfit_buf
= t
->nfit_buf
;
1105 struct acpi_nfit_memory_map
*memdev
;
1106 struct acpi_nfit_control_region
*dcr
;
1107 struct acpi_nfit_system_address
*spa
;
1109 nfit_test_init_header(nfit_buf
, size
);
1111 offset
= sizeof(struct acpi_table_nfit
);
1112 /* spa0 (flat range with no bdw aliasing) */
1113 spa
= nfit_buf
+ offset
;
1114 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1115 spa
->header
.length
= sizeof(*spa
);
1116 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
1117 spa
->range_index
= 0+1;
1118 spa
->address
= t
->spa_set_dma
[0];
1119 spa
->length
= SPA2_SIZE
;
1121 offset
+= sizeof(*spa
);
1122 /* mem-region0 (spa0, dimm0) */
1123 memdev
= nfit_buf
+ offset
;
1124 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1125 memdev
->header
.length
= sizeof(*memdev
);
1126 memdev
->device_handle
= 0;
1127 memdev
->physical_id
= 0;
1128 memdev
->region_id
= 0;
1129 memdev
->range_index
= 0+1;
1130 memdev
->region_index
= 0+1;
1131 memdev
->region_size
= SPA2_SIZE
;
1132 memdev
->region_offset
= 0;
1133 memdev
->address
= 0;
1134 memdev
->interleave_index
= 0;
1135 memdev
->interleave_ways
= 1;
1136 memdev
->flags
= ACPI_NFIT_MEM_SAVE_FAILED
| ACPI_NFIT_MEM_RESTORE_FAILED
1137 | ACPI_NFIT_MEM_FLUSH_FAILED
| ACPI_NFIT_MEM_HEALTH_OBSERVED
1138 | ACPI_NFIT_MEM_NOT_ARMED
;
1140 offset
+= sizeof(*memdev
);
1141 /* dcr-descriptor0 */
1142 dcr
= nfit_buf
+ offset
;
1143 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1144 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
1145 dcr
->region_index
= 0+1;
1146 dcr
->vendor_id
= 0xabcd;
1148 dcr
->revision_id
= 1;
1149 dcr
->serial_number
= ~0;
1152 dcr
->window_size
= 0;
1153 dcr
->command_offset
= 0;
1154 dcr
->command_size
= 0;
1155 dcr
->status_offset
= 0;
1156 dcr
->status_size
= 0;
1159 static int nfit_test_blk_do_io(struct nd_blk_region
*ndbr
, resource_size_t dpa
,
1160 void *iobuf
, u64 len
, int rw
)
1162 struct nfit_blk
*nfit_blk
= ndbr
->blk_provider_data
;
1163 struct nfit_blk_mmio
*mmio
= &nfit_blk
->mmio
[BDW
];
1164 struct nd_region
*nd_region
= &ndbr
->nd_region
;
1167 lane
= nd_region_acquire_lane(nd_region
);
1169 memcpy(mmio
->addr
.base
+ dpa
, iobuf
, len
);
1171 memcpy(iobuf
, mmio
->addr
.base
+ dpa
, len
);
1173 /* give us some some coverage of the mmio_flush_range() API */
1174 mmio_flush_range(mmio
->addr
.base
+ dpa
, len
);
1176 nd_region_release_lane(nd_region
, lane
);
1181 static int nfit_test_probe(struct platform_device
*pdev
)
1183 struct nvdimm_bus_descriptor
*nd_desc
;
1184 struct acpi_nfit_desc
*acpi_desc
;
1185 struct device
*dev
= &pdev
->dev
;
1186 struct nfit_test
*nfit_test
;
1189 nfit_test
= to_nfit_test(&pdev
->dev
);
1192 if (nfit_test
->num_dcr
) {
1193 int num
= nfit_test
->num_dcr
;
1195 nfit_test
->dimm
= devm_kcalloc(dev
, num
, sizeof(void *),
1197 nfit_test
->dimm_dma
= devm_kcalloc(dev
, num
, sizeof(dma_addr_t
),
1199 nfit_test
->flush
= devm_kcalloc(dev
, num
, sizeof(void *),
1201 nfit_test
->flush_dma
= devm_kcalloc(dev
, num
, sizeof(dma_addr_t
),
1203 nfit_test
->label
= devm_kcalloc(dev
, num
, sizeof(void *),
1205 nfit_test
->label_dma
= devm_kcalloc(dev
, num
,
1206 sizeof(dma_addr_t
), GFP_KERNEL
);
1207 nfit_test
->dcr
= devm_kcalloc(dev
, num
,
1208 sizeof(struct nfit_test_dcr
*), GFP_KERNEL
);
1209 nfit_test
->dcr_dma
= devm_kcalloc(dev
, num
,
1210 sizeof(dma_addr_t
), GFP_KERNEL
);
1211 if (nfit_test
->dimm
&& nfit_test
->dimm_dma
&& nfit_test
->label
1212 && nfit_test
->label_dma
&& nfit_test
->dcr
1213 && nfit_test
->dcr_dma
&& nfit_test
->flush
1214 && nfit_test
->flush_dma
)
1220 if (nfit_test
->num_pm
) {
1221 int num
= nfit_test
->num_pm
;
1223 nfit_test
->spa_set
= devm_kcalloc(dev
, num
, sizeof(void *),
1225 nfit_test
->spa_set_dma
= devm_kcalloc(dev
, num
,
1226 sizeof(dma_addr_t
), GFP_KERNEL
);
1227 if (nfit_test
->spa_set
&& nfit_test
->spa_set_dma
)
1233 /* per-nfit specific alloc */
1234 if (nfit_test
->alloc(nfit_test
))
1237 nfit_test
->setup(nfit_test
);
1238 acpi_desc
= &nfit_test
->acpi_desc
;
1239 acpi_desc
->dev
= &pdev
->dev
;
1240 acpi_desc
->nfit
= nfit_test
->nfit_buf
;
1241 acpi_desc
->blk_do_io
= nfit_test_blk_do_io
;
1242 nd_desc
= &acpi_desc
->nd_desc
;
1243 nd_desc
->attr_groups
= acpi_nfit_attribute_groups
;
1244 acpi_desc
->nvdimm_bus
= nvdimm_bus_register(&pdev
->dev
, nd_desc
);
1245 if (!acpi_desc
->nvdimm_bus
)
1248 INIT_LIST_HEAD(&acpi_desc
->spa_maps
);
1249 INIT_LIST_HEAD(&acpi_desc
->spas
);
1250 INIT_LIST_HEAD(&acpi_desc
->dcrs
);
1251 INIT_LIST_HEAD(&acpi_desc
->bdws
);
1252 INIT_LIST_HEAD(&acpi_desc
->idts
);
1253 INIT_LIST_HEAD(&acpi_desc
->flushes
);
1254 INIT_LIST_HEAD(&acpi_desc
->memdevs
);
1255 INIT_LIST_HEAD(&acpi_desc
->dimms
);
1256 mutex_init(&acpi_desc
->spa_map_mutex
);
1257 mutex_init(&acpi_desc
->init_mutex
);
1259 rc
= acpi_nfit_init(acpi_desc
, nfit_test
->nfit_size
);
1261 nvdimm_bus_unregister(acpi_desc
->nvdimm_bus
);
1265 if (nfit_test
->setup
!= nfit_test0_setup
)
1268 nfit_test
->setup_hotplug
= 1;
1269 nfit_test
->setup(nfit_test
);
1271 rc
= acpi_nfit_init(acpi_desc
, nfit_test
->nfit_size
);
1273 nvdimm_bus_unregister(acpi_desc
->nvdimm_bus
);
1280 static int nfit_test_remove(struct platform_device
*pdev
)
1282 struct nfit_test
*nfit_test
= to_nfit_test(&pdev
->dev
);
1283 struct acpi_nfit_desc
*acpi_desc
= &nfit_test
->acpi_desc
;
1285 nvdimm_bus_unregister(acpi_desc
->nvdimm_bus
);
1290 static void nfit_test_release(struct device
*dev
)
1292 struct nfit_test
*nfit_test
= to_nfit_test(dev
);
1297 static const struct platform_device_id nfit_test_id
[] = {
1302 static struct platform_driver nfit_test_driver
= {
1303 .probe
= nfit_test_probe
,
1304 .remove
= nfit_test_remove
,
1306 .name
= KBUILD_MODNAME
,
1308 .id_table
= nfit_test_id
,
1311 #ifdef CONFIG_CMA_SIZE_MBYTES
1312 #define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
1314 #define CMA_SIZE_MBYTES 0
1317 static __init
int nfit_test_init(void)
1321 nfit_test_setup(nfit_test_lookup
);
1323 for (i
= 0; i
< NUM_NFITS
; i
++) {
1324 struct nfit_test
*nfit_test
;
1325 struct platform_device
*pdev
;
1328 nfit_test
= kzalloc(sizeof(*nfit_test
), GFP_KERNEL
);
1333 INIT_LIST_HEAD(&nfit_test
->resources
);
1336 nfit_test
->num_pm
= NUM_PM
;
1337 nfit_test
->num_dcr
= NUM_DCR
;
1338 nfit_test
->alloc
= nfit_test0_alloc
;
1339 nfit_test
->setup
= nfit_test0_setup
;
1342 nfit_test
->num_pm
= 1;
1343 nfit_test
->alloc
= nfit_test1_alloc
;
1344 nfit_test
->setup
= nfit_test1_setup
;
1350 pdev
= &nfit_test
->pdev
;
1351 pdev
->name
= KBUILD_MODNAME
;
1353 pdev
->dev
.release
= nfit_test_release
;
1354 rc
= platform_device_register(pdev
);
1356 put_device(&pdev
->dev
);
1360 rc
= dma_coerce_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(64));
1364 instances
[i
] = nfit_test
;
1370 buf
= dma_alloc_coherent(&pdev
->dev
, SZ_128M
, &dma
,
1374 dev_warn(&pdev
->dev
, "need 128M of free cma\n");
1377 dma_free_coherent(&pdev
->dev
, SZ_128M
, buf
, dma
);
1381 rc
= platform_driver_register(&nfit_test_driver
);
1387 for (i
= 0; i
< NUM_NFITS
; i
++)
1389 platform_device_unregister(&instances
[i
]->pdev
);
1390 nfit_test_teardown();
1394 static __exit
void nfit_test_exit(void)
1398 platform_driver_unregister(&nfit_test_driver
);
1399 for (i
= 0; i
< NUM_NFITS
; i
++)
1400 platform_device_unregister(&instances
[i
]->pdev
);
1401 nfit_test_teardown();
1404 module_init(nfit_test_init
);
1405 module_exit(nfit_test_exit
);
1406 MODULE_LICENSE("GPL v2");
1407 MODULE_AUTHOR("Intel Corporation");