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.
103 NUM_SPA
= NUM_PM
+ NUM_DCR
+ NUM_BDW
,
104 NUM_MEM
= NUM_DCR
+ NUM_BDW
+ 2 /* spa0 iset */ + 4 /* spa1 iset */,
106 LABEL_SIZE
= SZ_128K
,
107 SPA_VCD_SIZE
= SZ_4M
,
108 SPA0_SIZE
= DIMM_SIZE
,
109 SPA1_SIZE
= DIMM_SIZE
*2,
110 SPA2_SIZE
= DIMM_SIZE
,
113 NUM_NFITS
= 2, /* permit testing multiple NFITs per system */
116 struct nfit_test_dcr
{
119 __u8 aperature
[BDW_SIZE
];
122 #define NFIT_DIMM_HANDLE(node, socket, imc, chan, dimm) \
123 (((node & 0xfff) << 16) | ((socket & 0xf) << 12) \
124 | ((imc & 0xf) << 8) | ((chan & 0xf) << 4) | (dimm & 0xf))
126 static u32 handle
[NUM_DCR
] = {
127 [0] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 0),
128 [1] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 1),
129 [2] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 0),
130 [3] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 1),
131 [4] = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0),
135 struct acpi_nfit_desc acpi_desc
;
136 struct platform_device pdev
;
137 struct list_head resources
;
144 dma_addr_t
*dimm_dma
;
146 dma_addr_t
*flush_dma
;
148 dma_addr_t
*label_dma
;
150 dma_addr_t
*spa_set_dma
;
151 struct nfit_test_dcr
**dcr
;
153 int (*alloc
)(struct nfit_test
*t
);
154 void (*setup
)(struct nfit_test
*t
);
157 struct nd_cmd_ars_status
*ars_status
;
158 unsigned long deadline
;
163 static struct nfit_test
*to_nfit_test(struct device
*dev
)
165 struct platform_device
*pdev
= to_platform_device(dev
);
167 return container_of(pdev
, struct nfit_test
, pdev
);
170 static int nfit_test_cmd_get_config_size(struct nd_cmd_get_config_size
*nd_cmd
,
171 unsigned int buf_len
)
173 if (buf_len
< sizeof(*nd_cmd
))
177 nd_cmd
->config_size
= LABEL_SIZE
;
178 nd_cmd
->max_xfer
= SZ_4K
;
183 static int nfit_test_cmd_get_config_data(struct nd_cmd_get_config_data_hdr
184 *nd_cmd
, unsigned int buf_len
, void *label
)
186 unsigned int len
, offset
= nd_cmd
->in_offset
;
189 if (buf_len
< sizeof(*nd_cmd
))
191 if (offset
>= LABEL_SIZE
)
193 if (nd_cmd
->in_length
+ sizeof(*nd_cmd
) > buf_len
)
197 len
= min(nd_cmd
->in_length
, LABEL_SIZE
- offset
);
198 memcpy(nd_cmd
->out_buf
, label
+ offset
, len
);
199 rc
= buf_len
- sizeof(*nd_cmd
) - len
;
204 static int nfit_test_cmd_set_config_data(struct nd_cmd_set_config_hdr
*nd_cmd
,
205 unsigned int buf_len
, void *label
)
207 unsigned int len
, offset
= nd_cmd
->in_offset
;
211 if (buf_len
< sizeof(*nd_cmd
))
213 if (offset
>= LABEL_SIZE
)
215 if (nd_cmd
->in_length
+ sizeof(*nd_cmd
) + 4 > buf_len
)
218 status
= (void *)nd_cmd
+ nd_cmd
->in_length
+ sizeof(*nd_cmd
);
220 len
= min(nd_cmd
->in_length
, LABEL_SIZE
- offset
);
221 memcpy(label
+ offset
, nd_cmd
->in_buf
, len
);
222 rc
= buf_len
- sizeof(*nd_cmd
) - (len
+ 4);
227 #define NFIT_TEST_ARS_RECORDS 4
228 #define NFIT_TEST_CLEAR_ERR_UNIT 256
230 static int nfit_test_cmd_ars_cap(struct nd_cmd_ars_cap
*nd_cmd
,
231 unsigned int buf_len
)
233 if (buf_len
< sizeof(*nd_cmd
))
236 nd_cmd
->max_ars_out
= sizeof(struct nd_cmd_ars_status
)
237 + NFIT_TEST_ARS_RECORDS
* sizeof(struct nd_ars_record
);
238 nd_cmd
->status
= (ND_ARS_PERSISTENT
| ND_ARS_VOLATILE
) << 16;
239 nd_cmd
->clear_err_unit
= NFIT_TEST_CLEAR_ERR_UNIT
;
245 * Initialize the ars_state to return an ars_result 1 second in the future with
246 * a 4K error range in the middle of the requested address range.
248 static void post_ars_status(struct ars_state
*ars_state
, u64 addr
, u64 len
)
250 struct nd_cmd_ars_status
*ars_status
;
251 struct nd_ars_record
*ars_record
;
253 ars_state
->deadline
= jiffies
+ 1*HZ
;
254 ars_status
= ars_state
->ars_status
;
255 ars_status
->status
= 0;
256 ars_status
->out_length
= sizeof(struct nd_cmd_ars_status
)
257 + sizeof(struct nd_ars_record
);
258 ars_status
->address
= addr
;
259 ars_status
->length
= len
;
260 ars_status
->type
= ND_ARS_PERSISTENT
;
261 ars_status
->num_records
= 1;
262 ars_record
= &ars_status
->records
[0];
263 ars_record
->handle
= 0;
264 ars_record
->err_address
= addr
+ len
/ 2;
265 ars_record
->length
= SZ_4K
;
268 static int nfit_test_cmd_ars_start(struct ars_state
*ars_state
,
269 struct nd_cmd_ars_start
*ars_start
, unsigned int buf_len
,
272 if (buf_len
< sizeof(*ars_start
))
275 spin_lock(&ars_state
->lock
);
276 if (time_before(jiffies
, ars_state
->deadline
)) {
277 ars_start
->status
= NFIT_ARS_START_BUSY
;
280 ars_start
->status
= 0;
281 ars_start
->scrub_time
= 1;
282 post_ars_status(ars_state
, ars_start
->address
,
286 spin_unlock(&ars_state
->lock
);
291 static int nfit_test_cmd_ars_status(struct ars_state
*ars_state
,
292 struct nd_cmd_ars_status
*ars_status
, unsigned int buf_len
,
295 if (buf_len
< ars_state
->ars_status
->out_length
)
298 spin_lock(&ars_state
->lock
);
299 if (time_before(jiffies
, ars_state
->deadline
)) {
300 memset(ars_status
, 0, buf_len
);
301 ars_status
->status
= NFIT_ARS_STATUS_BUSY
;
302 ars_status
->out_length
= sizeof(*ars_status
);
305 memcpy(ars_status
, ars_state
->ars_status
,
306 ars_state
->ars_status
->out_length
);
309 spin_unlock(&ars_state
->lock
);
313 static int nfit_test_cmd_clear_error(struct nd_cmd_clear_error
*clear_err
,
314 unsigned int buf_len
, int *cmd_rc
)
316 const u64 mask
= NFIT_TEST_CLEAR_ERR_UNIT
- 1;
317 if (buf_len
< sizeof(*clear_err
))
320 if ((clear_err
->address
& mask
) || (clear_err
->length
& mask
))
324 * Report 'all clear' success for all commands even though a new
325 * scrub will find errors again. This is enough to have the
326 * error removed from the 'badblocks' tracking in the pmem
329 clear_err
->status
= 0;
330 clear_err
->cleared
= clear_err
->length
;
335 static int nfit_test_cmd_smart(struct nd_cmd_smart
*smart
, unsigned int buf_len
)
337 static const struct nd_smart_payload smart_data
= {
338 .flags
= ND_SMART_HEALTH_VALID
| ND_SMART_TEMP_VALID
339 | ND_SMART_SPARES_VALID
| ND_SMART_ALARM_VALID
340 | ND_SMART_USED_VALID
| ND_SMART_SHUTDOWN_VALID
,
341 .health
= ND_SMART_NON_CRITICAL_HEALTH
,
342 .temperature
= 23 * 16,
344 .alarm_flags
= ND_SMART_SPARE_TRIP
| ND_SMART_TEMP_TRIP
,
350 if (buf_len
< sizeof(*smart
))
352 memcpy(smart
->data
, &smart_data
, sizeof(smart_data
));
356 static int nfit_test_cmd_smart_threshold(struct nd_cmd_smart_threshold
*smart_t
,
357 unsigned int buf_len
)
359 static const struct nd_smart_threshold_payload smart_t_data
= {
360 .alarm_control
= ND_SMART_SPARE_TRIP
| ND_SMART_TEMP_TRIP
,
361 .temperature
= 40 * 16,
365 if (buf_len
< sizeof(*smart_t
))
367 memcpy(smart_t
->data
, &smart_t_data
, sizeof(smart_t_data
));
371 static int nfit_test_ctl(struct nvdimm_bus_descriptor
*nd_desc
,
372 struct nvdimm
*nvdimm
, unsigned int cmd
, void *buf
,
373 unsigned int buf_len
, int *cmd_rc
)
375 struct acpi_nfit_desc
*acpi_desc
= to_acpi_desc(nd_desc
);
376 struct nfit_test
*t
= container_of(acpi_desc
, typeof(*t
), acpi_desc
);
377 unsigned int func
= cmd
;
378 int i
, rc
= 0, __cmd_rc
;
385 struct nfit_mem
*nfit_mem
= nvdimm_provider_data(nvdimm
);
386 unsigned long cmd_mask
= nvdimm_cmd_mask(nvdimm
);
391 if (cmd
== ND_CMD_CALL
) {
392 struct nd_cmd_pkg
*call_pkg
= buf
;
394 buf_len
= call_pkg
->nd_size_in
+ call_pkg
->nd_size_out
;
395 buf
= (void *) call_pkg
->nd_payload
;
396 func
= call_pkg
->nd_command
;
397 if (call_pkg
->nd_family
!= nfit_mem
->family
)
401 if (!test_bit(cmd
, &cmd_mask
)
402 || !test_bit(func
, &nfit_mem
->dsm_mask
))
405 /* lookup label space for the given dimm */
406 for (i
= 0; i
< ARRAY_SIZE(handle
); i
++)
407 if (__to_nfit_memdev(nfit_mem
)->device_handle
==
410 if (i
>= ARRAY_SIZE(handle
))
414 case ND_CMD_GET_CONFIG_SIZE
:
415 rc
= nfit_test_cmd_get_config_size(buf
, buf_len
);
417 case ND_CMD_GET_CONFIG_DATA
:
418 rc
= nfit_test_cmd_get_config_data(buf
, buf_len
,
421 case ND_CMD_SET_CONFIG_DATA
:
422 rc
= nfit_test_cmd_set_config_data(buf
, buf_len
,
426 rc
= nfit_test_cmd_smart(buf
, buf_len
);
428 case ND_CMD_SMART_THRESHOLD
:
429 rc
= nfit_test_cmd_smart_threshold(buf
, buf_len
);
435 struct ars_state
*ars_state
= &t
->ars_state
;
437 if (!nd_desc
|| !test_bit(cmd
, &nd_desc
->cmd_mask
))
442 rc
= nfit_test_cmd_ars_cap(buf
, buf_len
);
444 case ND_CMD_ARS_START
:
445 rc
= nfit_test_cmd_ars_start(ars_state
, buf
, buf_len
,
448 case ND_CMD_ARS_STATUS
:
449 rc
= nfit_test_cmd_ars_status(ars_state
, buf
, buf_len
,
452 case ND_CMD_CLEAR_ERROR
:
453 rc
= nfit_test_cmd_clear_error(buf
, buf_len
, cmd_rc
);
463 static DEFINE_SPINLOCK(nfit_test_lock
);
464 static struct nfit_test
*instances
[NUM_NFITS
];
466 static void release_nfit_res(void *data
)
468 struct nfit_test_resource
*nfit_res
= data
;
469 struct resource
*res
= nfit_res
->res
;
471 spin_lock(&nfit_test_lock
);
472 list_del(&nfit_res
->list
);
473 spin_unlock(&nfit_test_lock
);
475 vfree(nfit_res
->buf
);
480 static void *__test_alloc(struct nfit_test
*t
, size_t size
, dma_addr_t
*dma
,
483 struct device
*dev
= &t
->pdev
.dev
;
484 struct resource
*res
= kzalloc(sizeof(*res
) * 2, GFP_KERNEL
);
485 struct nfit_test_resource
*nfit_res
= kzalloc(sizeof(*nfit_res
),
489 if (!res
|| !buf
|| !nfit_res
)
491 rc
= devm_add_action(dev
, release_nfit_res
, nfit_res
);
494 INIT_LIST_HEAD(&nfit_res
->list
);
495 memset(buf
, 0, size
);
500 res
->end
= *dma
+ size
- 1;
502 spin_lock(&nfit_test_lock
);
503 list_add(&nfit_res
->list
, &t
->resources
);
504 spin_unlock(&nfit_test_lock
);
506 return nfit_res
->buf
;
515 static void *test_alloc(struct nfit_test
*t
, size_t size
, dma_addr_t
*dma
)
517 void *buf
= vmalloc(size
);
519 *dma
= (unsigned long) buf
;
520 return __test_alloc(t
, size
, dma
, buf
);
523 static struct nfit_test_resource
*nfit_test_lookup(resource_size_t addr
)
527 for (i
= 0; i
< ARRAY_SIZE(instances
); i
++) {
528 struct nfit_test_resource
*n
, *nfit_res
= NULL
;
529 struct nfit_test
*t
= instances
[i
];
533 spin_lock(&nfit_test_lock
);
534 list_for_each_entry(n
, &t
->resources
, list
) {
535 if (addr
>= n
->res
->start
&& (addr
< n
->res
->start
536 + resource_size(n
->res
))) {
539 } else if (addr
>= (unsigned long) n
->buf
540 && (addr
< (unsigned long) n
->buf
541 + resource_size(n
->res
))) {
546 spin_unlock(&nfit_test_lock
);
554 static int ars_state_init(struct device
*dev
, struct ars_state
*ars_state
)
556 ars_state
->ars_status
= devm_kzalloc(dev
,
557 sizeof(struct nd_cmd_ars_status
)
558 + sizeof(struct nd_ars_record
) * NFIT_TEST_ARS_RECORDS
,
560 if (!ars_state
->ars_status
)
562 spin_lock_init(&ars_state
->lock
);
566 static int nfit_test0_alloc(struct nfit_test
*t
)
568 size_t nfit_size
= sizeof(struct acpi_nfit_system_address
) * NUM_SPA
569 + sizeof(struct acpi_nfit_memory_map
) * NUM_MEM
570 + sizeof(struct acpi_nfit_control_region
) * NUM_DCR
571 + offsetof(struct acpi_nfit_control_region
,
572 window_size
) * NUM_DCR
573 + sizeof(struct acpi_nfit_data_region
) * NUM_BDW
574 + (sizeof(struct acpi_nfit_flush_address
)
575 + sizeof(u64
) * NUM_HINTS
) * NUM_DCR
;
578 t
->nfit_buf
= test_alloc(t
, nfit_size
, &t
->nfit_dma
);
581 t
->nfit_size
= nfit_size
;
583 t
->spa_set
[0] = test_alloc(t
, SPA0_SIZE
, &t
->spa_set_dma
[0]);
587 t
->spa_set
[1] = test_alloc(t
, SPA1_SIZE
, &t
->spa_set_dma
[1]);
591 t
->spa_set
[2] = test_alloc(t
, SPA0_SIZE
, &t
->spa_set_dma
[2]);
595 for (i
= 0; i
< NUM_DCR
; i
++) {
596 t
->dimm
[i
] = test_alloc(t
, DIMM_SIZE
, &t
->dimm_dma
[i
]);
600 t
->label
[i
] = test_alloc(t
, LABEL_SIZE
, &t
->label_dma
[i
]);
603 sprintf(t
->label
[i
], "label%d", i
);
605 t
->flush
[i
] = test_alloc(t
, sizeof(u64
) * NUM_HINTS
,
611 for (i
= 0; i
< NUM_DCR
; i
++) {
612 t
->dcr
[i
] = test_alloc(t
, LABEL_SIZE
, &t
->dcr_dma
[i
]);
617 return ars_state_init(&t
->pdev
.dev
, &t
->ars_state
);
620 static int nfit_test1_alloc(struct nfit_test
*t
)
622 size_t nfit_size
= sizeof(struct acpi_nfit_system_address
) * 2
623 + sizeof(struct acpi_nfit_memory_map
)
624 + offsetof(struct acpi_nfit_control_region
, window_size
);
626 t
->nfit_buf
= test_alloc(t
, nfit_size
, &t
->nfit_dma
);
629 t
->nfit_size
= nfit_size
;
631 t
->spa_set
[0] = test_alloc(t
, SPA2_SIZE
, &t
->spa_set_dma
[0]);
635 t
->spa_set
[1] = test_alloc(t
, SPA_VCD_SIZE
, &t
->spa_set_dma
[1]);
639 return ars_state_init(&t
->pdev
.dev
, &t
->ars_state
);
642 static void dcr_common_init(struct acpi_nfit_control_region
*dcr
)
644 dcr
->vendor_id
= 0xabcd;
646 dcr
->revision_id
= 1;
647 dcr
->valid_fields
= 1;
648 dcr
->manufacturing_location
= 0xa;
649 dcr
->manufacturing_date
= cpu_to_be16(2016);
652 static void nfit_test0_setup(struct nfit_test
*t
)
654 const int flush_hint_size
= sizeof(struct acpi_nfit_flush_address
)
655 + (sizeof(u64
) * NUM_HINTS
);
656 struct acpi_nfit_desc
*acpi_desc
;
657 struct acpi_nfit_memory_map
*memdev
;
658 void *nfit_buf
= t
->nfit_buf
;
659 struct acpi_nfit_system_address
*spa
;
660 struct acpi_nfit_control_region
*dcr
;
661 struct acpi_nfit_data_region
*bdw
;
662 struct acpi_nfit_flush_address
*flush
;
663 unsigned int offset
, i
;
666 * spa0 (interleave first half of dimm0 and dimm1, note storage
667 * does not actually alias the related block-data-window
671 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
672 spa
->header
.length
= sizeof(*spa
);
673 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
674 spa
->range_index
= 0+1;
675 spa
->address
= t
->spa_set_dma
[0];
676 spa
->length
= SPA0_SIZE
;
679 * spa1 (interleave last half of the 4 DIMMS, note storage
680 * does not actually alias the related block-data-window
683 spa
= nfit_buf
+ sizeof(*spa
);
684 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
685 spa
->header
.length
= sizeof(*spa
);
686 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
687 spa
->range_index
= 1+1;
688 spa
->address
= t
->spa_set_dma
[1];
689 spa
->length
= SPA1_SIZE
;
691 /* spa2 (dcr0) dimm0 */
692 spa
= nfit_buf
+ sizeof(*spa
) * 2;
693 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
694 spa
->header
.length
= sizeof(*spa
);
695 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
696 spa
->range_index
= 2+1;
697 spa
->address
= t
->dcr_dma
[0];
698 spa
->length
= DCR_SIZE
;
700 /* spa3 (dcr1) dimm1 */
701 spa
= nfit_buf
+ sizeof(*spa
) * 3;
702 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
703 spa
->header
.length
= sizeof(*spa
);
704 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
705 spa
->range_index
= 3+1;
706 spa
->address
= t
->dcr_dma
[1];
707 spa
->length
= DCR_SIZE
;
709 /* spa4 (dcr2) dimm2 */
710 spa
= nfit_buf
+ sizeof(*spa
) * 4;
711 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
712 spa
->header
.length
= sizeof(*spa
);
713 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
714 spa
->range_index
= 4+1;
715 spa
->address
= t
->dcr_dma
[2];
716 spa
->length
= DCR_SIZE
;
718 /* spa5 (dcr3) dimm3 */
719 spa
= nfit_buf
+ sizeof(*spa
) * 5;
720 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
721 spa
->header
.length
= sizeof(*spa
);
722 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
723 spa
->range_index
= 5+1;
724 spa
->address
= t
->dcr_dma
[3];
725 spa
->length
= DCR_SIZE
;
727 /* spa6 (bdw for dcr0) dimm0 */
728 spa
= nfit_buf
+ sizeof(*spa
) * 6;
729 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
730 spa
->header
.length
= sizeof(*spa
);
731 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
732 spa
->range_index
= 6+1;
733 spa
->address
= t
->dimm_dma
[0];
734 spa
->length
= DIMM_SIZE
;
736 /* spa7 (bdw for dcr1) dimm1 */
737 spa
= nfit_buf
+ sizeof(*spa
) * 7;
738 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
739 spa
->header
.length
= sizeof(*spa
);
740 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
741 spa
->range_index
= 7+1;
742 spa
->address
= t
->dimm_dma
[1];
743 spa
->length
= DIMM_SIZE
;
745 /* spa8 (bdw for dcr2) dimm2 */
746 spa
= nfit_buf
+ sizeof(*spa
) * 8;
747 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
748 spa
->header
.length
= sizeof(*spa
);
749 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
750 spa
->range_index
= 8+1;
751 spa
->address
= t
->dimm_dma
[2];
752 spa
->length
= DIMM_SIZE
;
754 /* spa9 (bdw for dcr3) dimm3 */
755 spa
= nfit_buf
+ sizeof(*spa
) * 9;
756 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
757 spa
->header
.length
= sizeof(*spa
);
758 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
759 spa
->range_index
= 9+1;
760 spa
->address
= t
->dimm_dma
[3];
761 spa
->length
= DIMM_SIZE
;
763 offset
= sizeof(*spa
) * 10;
764 /* mem-region0 (spa0, dimm0) */
765 memdev
= nfit_buf
+ offset
;
766 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
767 memdev
->header
.length
= sizeof(*memdev
);
768 memdev
->device_handle
= handle
[0];
769 memdev
->physical_id
= 0;
770 memdev
->region_id
= 0;
771 memdev
->range_index
= 0+1;
772 memdev
->region_index
= 4+1;
773 memdev
->region_size
= SPA0_SIZE
/2;
774 memdev
->region_offset
= t
->spa_set_dma
[0];
776 memdev
->interleave_index
= 0;
777 memdev
->interleave_ways
= 2;
779 /* mem-region1 (spa0, dimm1) */
780 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
);
781 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
782 memdev
->header
.length
= sizeof(*memdev
);
783 memdev
->device_handle
= handle
[1];
784 memdev
->physical_id
= 1;
785 memdev
->region_id
= 0;
786 memdev
->range_index
= 0+1;
787 memdev
->region_index
= 5+1;
788 memdev
->region_size
= SPA0_SIZE
/2;
789 memdev
->region_offset
= t
->spa_set_dma
[0] + SPA0_SIZE
/2;
791 memdev
->interleave_index
= 0;
792 memdev
->interleave_ways
= 2;
794 /* mem-region2 (spa1, dimm0) */
795 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 2;
796 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
797 memdev
->header
.length
= sizeof(*memdev
);
798 memdev
->device_handle
= handle
[0];
799 memdev
->physical_id
= 0;
800 memdev
->region_id
= 1;
801 memdev
->range_index
= 1+1;
802 memdev
->region_index
= 4+1;
803 memdev
->region_size
= SPA1_SIZE
/4;
804 memdev
->region_offset
= t
->spa_set_dma
[1];
805 memdev
->address
= SPA0_SIZE
/2;
806 memdev
->interleave_index
= 0;
807 memdev
->interleave_ways
= 4;
809 /* mem-region3 (spa1, dimm1) */
810 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 3;
811 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
812 memdev
->header
.length
= sizeof(*memdev
);
813 memdev
->device_handle
= handle
[1];
814 memdev
->physical_id
= 1;
815 memdev
->region_id
= 1;
816 memdev
->range_index
= 1+1;
817 memdev
->region_index
= 5+1;
818 memdev
->region_size
= SPA1_SIZE
/4;
819 memdev
->region_offset
= t
->spa_set_dma
[1] + SPA1_SIZE
/4;
820 memdev
->address
= SPA0_SIZE
/2;
821 memdev
->interleave_index
= 0;
822 memdev
->interleave_ways
= 4;
824 /* mem-region4 (spa1, dimm2) */
825 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 4;
826 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
827 memdev
->header
.length
= sizeof(*memdev
);
828 memdev
->device_handle
= handle
[2];
829 memdev
->physical_id
= 2;
830 memdev
->region_id
= 0;
831 memdev
->range_index
= 1+1;
832 memdev
->region_index
= 6+1;
833 memdev
->region_size
= SPA1_SIZE
/4;
834 memdev
->region_offset
= t
->spa_set_dma
[1] + 2*SPA1_SIZE
/4;
835 memdev
->address
= SPA0_SIZE
/2;
836 memdev
->interleave_index
= 0;
837 memdev
->interleave_ways
= 4;
839 /* mem-region5 (spa1, dimm3) */
840 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 5;
841 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
842 memdev
->header
.length
= sizeof(*memdev
);
843 memdev
->device_handle
= handle
[3];
844 memdev
->physical_id
= 3;
845 memdev
->region_id
= 0;
846 memdev
->range_index
= 1+1;
847 memdev
->region_index
= 7+1;
848 memdev
->region_size
= SPA1_SIZE
/4;
849 memdev
->region_offset
= t
->spa_set_dma
[1] + 3*SPA1_SIZE
/4;
850 memdev
->address
= SPA0_SIZE
/2;
851 memdev
->interleave_index
= 0;
852 memdev
->interleave_ways
= 4;
854 /* mem-region6 (spa/dcr0, dimm0) */
855 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 6;
856 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
857 memdev
->header
.length
= sizeof(*memdev
);
858 memdev
->device_handle
= handle
[0];
859 memdev
->physical_id
= 0;
860 memdev
->region_id
= 0;
861 memdev
->range_index
= 2+1;
862 memdev
->region_index
= 0+1;
863 memdev
->region_size
= 0;
864 memdev
->region_offset
= 0;
866 memdev
->interleave_index
= 0;
867 memdev
->interleave_ways
= 1;
869 /* mem-region7 (spa/dcr1, dimm1) */
870 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 7;
871 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
872 memdev
->header
.length
= sizeof(*memdev
);
873 memdev
->device_handle
= handle
[1];
874 memdev
->physical_id
= 1;
875 memdev
->region_id
= 0;
876 memdev
->range_index
= 3+1;
877 memdev
->region_index
= 1+1;
878 memdev
->region_size
= 0;
879 memdev
->region_offset
= 0;
881 memdev
->interleave_index
= 0;
882 memdev
->interleave_ways
= 1;
884 /* mem-region8 (spa/dcr2, dimm2) */
885 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 8;
886 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
887 memdev
->header
.length
= sizeof(*memdev
);
888 memdev
->device_handle
= handle
[2];
889 memdev
->physical_id
= 2;
890 memdev
->region_id
= 0;
891 memdev
->range_index
= 4+1;
892 memdev
->region_index
= 2+1;
893 memdev
->region_size
= 0;
894 memdev
->region_offset
= 0;
896 memdev
->interleave_index
= 0;
897 memdev
->interleave_ways
= 1;
899 /* mem-region9 (spa/dcr3, dimm3) */
900 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 9;
901 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
902 memdev
->header
.length
= sizeof(*memdev
);
903 memdev
->device_handle
= handle
[3];
904 memdev
->physical_id
= 3;
905 memdev
->region_id
= 0;
906 memdev
->range_index
= 5+1;
907 memdev
->region_index
= 3+1;
908 memdev
->region_size
= 0;
909 memdev
->region_offset
= 0;
911 memdev
->interleave_index
= 0;
912 memdev
->interleave_ways
= 1;
914 /* mem-region10 (spa/bdw0, dimm0) */
915 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 10;
916 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
917 memdev
->header
.length
= sizeof(*memdev
);
918 memdev
->device_handle
= handle
[0];
919 memdev
->physical_id
= 0;
920 memdev
->region_id
= 0;
921 memdev
->range_index
= 6+1;
922 memdev
->region_index
= 0+1;
923 memdev
->region_size
= 0;
924 memdev
->region_offset
= 0;
926 memdev
->interleave_index
= 0;
927 memdev
->interleave_ways
= 1;
929 /* mem-region11 (spa/bdw1, dimm1) */
930 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 11;
931 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
932 memdev
->header
.length
= sizeof(*memdev
);
933 memdev
->device_handle
= handle
[1];
934 memdev
->physical_id
= 1;
935 memdev
->region_id
= 0;
936 memdev
->range_index
= 7+1;
937 memdev
->region_index
= 1+1;
938 memdev
->region_size
= 0;
939 memdev
->region_offset
= 0;
941 memdev
->interleave_index
= 0;
942 memdev
->interleave_ways
= 1;
944 /* mem-region12 (spa/bdw2, dimm2) */
945 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 12;
946 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
947 memdev
->header
.length
= sizeof(*memdev
);
948 memdev
->device_handle
= handle
[2];
949 memdev
->physical_id
= 2;
950 memdev
->region_id
= 0;
951 memdev
->range_index
= 8+1;
952 memdev
->region_index
= 2+1;
953 memdev
->region_size
= 0;
954 memdev
->region_offset
= 0;
956 memdev
->interleave_index
= 0;
957 memdev
->interleave_ways
= 1;
959 /* mem-region13 (spa/dcr3, dimm3) */
960 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 13;
961 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
962 memdev
->header
.length
= sizeof(*memdev
);
963 memdev
->device_handle
= handle
[3];
964 memdev
->physical_id
= 3;
965 memdev
->region_id
= 0;
966 memdev
->range_index
= 9+1;
967 memdev
->region_index
= 3+1;
968 memdev
->region_size
= 0;
969 memdev
->region_offset
= 0;
971 memdev
->interleave_index
= 0;
972 memdev
->interleave_ways
= 1;
974 offset
= offset
+ sizeof(struct acpi_nfit_memory_map
) * 14;
975 /* dcr-descriptor0: blk */
976 dcr
= nfit_buf
+ offset
;
977 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
978 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
979 dcr
->region_index
= 0+1;
980 dcr_common_init(dcr
);
981 dcr
->serial_number
= ~handle
[0];
982 dcr
->code
= NFIT_FIC_BLK
;
984 dcr
->window_size
= DCR_SIZE
;
985 dcr
->command_offset
= 0;
986 dcr
->command_size
= 8;
987 dcr
->status_offset
= 8;
988 dcr
->status_size
= 4;
990 /* dcr-descriptor1: blk */
991 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
);
992 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
993 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
994 dcr
->region_index
= 1+1;
995 dcr_common_init(dcr
);
996 dcr
->serial_number
= ~handle
[1];
997 dcr
->code
= NFIT_FIC_BLK
;
999 dcr
->window_size
= DCR_SIZE
;
1000 dcr
->command_offset
= 0;
1001 dcr
->command_size
= 8;
1002 dcr
->status_offset
= 8;
1003 dcr
->status_size
= 4;
1005 /* dcr-descriptor2: blk */
1006 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
) * 2;
1007 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1008 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
1009 dcr
->region_index
= 2+1;
1010 dcr_common_init(dcr
);
1011 dcr
->serial_number
= ~handle
[2];
1012 dcr
->code
= NFIT_FIC_BLK
;
1014 dcr
->window_size
= DCR_SIZE
;
1015 dcr
->command_offset
= 0;
1016 dcr
->command_size
= 8;
1017 dcr
->status_offset
= 8;
1018 dcr
->status_size
= 4;
1020 /* dcr-descriptor3: blk */
1021 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
) * 3;
1022 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1023 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
1024 dcr
->region_index
= 3+1;
1025 dcr_common_init(dcr
);
1026 dcr
->serial_number
= ~handle
[3];
1027 dcr
->code
= NFIT_FIC_BLK
;
1029 dcr
->window_size
= DCR_SIZE
;
1030 dcr
->command_offset
= 0;
1031 dcr
->command_size
= 8;
1032 dcr
->status_offset
= 8;
1033 dcr
->status_size
= 4;
1035 offset
= offset
+ sizeof(struct acpi_nfit_control_region
) * 4;
1036 /* dcr-descriptor0: pmem */
1037 dcr
= nfit_buf
+ offset
;
1038 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1039 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1041 dcr
->region_index
= 4+1;
1042 dcr_common_init(dcr
);
1043 dcr
->serial_number
= ~handle
[0];
1044 dcr
->code
= NFIT_FIC_BYTEN
;
1047 /* dcr-descriptor1: pmem */
1048 dcr
= nfit_buf
+ offset
+ offsetof(struct acpi_nfit_control_region
,
1050 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1051 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1053 dcr
->region_index
= 5+1;
1054 dcr_common_init(dcr
);
1055 dcr
->serial_number
= ~handle
[1];
1056 dcr
->code
= NFIT_FIC_BYTEN
;
1059 /* dcr-descriptor2: pmem */
1060 dcr
= nfit_buf
+ offset
+ offsetof(struct acpi_nfit_control_region
,
1062 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1063 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1065 dcr
->region_index
= 6+1;
1066 dcr_common_init(dcr
);
1067 dcr
->serial_number
= ~handle
[2];
1068 dcr
->code
= NFIT_FIC_BYTEN
;
1071 /* dcr-descriptor3: pmem */
1072 dcr
= nfit_buf
+ offset
+ offsetof(struct acpi_nfit_control_region
,
1074 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1075 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1077 dcr
->region_index
= 7+1;
1078 dcr_common_init(dcr
);
1079 dcr
->serial_number
= ~handle
[3];
1080 dcr
->code
= NFIT_FIC_BYTEN
;
1083 offset
= offset
+ offsetof(struct acpi_nfit_control_region
,
1085 /* bdw0 (spa/dcr0, dimm0) */
1086 bdw
= nfit_buf
+ offset
;
1087 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1088 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1089 bdw
->region_index
= 0+1;
1092 bdw
->size
= BDW_SIZE
;
1093 bdw
->capacity
= DIMM_SIZE
;
1094 bdw
->start_address
= 0;
1096 /* bdw1 (spa/dcr1, dimm1) */
1097 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
);
1098 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1099 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1100 bdw
->region_index
= 1+1;
1103 bdw
->size
= BDW_SIZE
;
1104 bdw
->capacity
= DIMM_SIZE
;
1105 bdw
->start_address
= 0;
1107 /* bdw2 (spa/dcr2, dimm2) */
1108 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
) * 2;
1109 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1110 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1111 bdw
->region_index
= 2+1;
1114 bdw
->size
= BDW_SIZE
;
1115 bdw
->capacity
= DIMM_SIZE
;
1116 bdw
->start_address
= 0;
1118 /* bdw3 (spa/dcr3, dimm3) */
1119 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
) * 3;
1120 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1121 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1122 bdw
->region_index
= 3+1;
1125 bdw
->size
= BDW_SIZE
;
1126 bdw
->capacity
= DIMM_SIZE
;
1127 bdw
->start_address
= 0;
1129 offset
= offset
+ sizeof(struct acpi_nfit_data_region
) * 4;
1130 /* flush0 (dimm0) */
1131 flush
= nfit_buf
+ offset
;
1132 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1133 flush
->header
.length
= flush_hint_size
;
1134 flush
->device_handle
= handle
[0];
1135 flush
->hint_count
= NUM_HINTS
;
1136 for (i
= 0; i
< NUM_HINTS
; i
++)
1137 flush
->hint_address
[i
] = t
->flush_dma
[0] + i
* sizeof(u64
);
1139 /* flush1 (dimm1) */
1140 flush
= nfit_buf
+ offset
+ flush_hint_size
* 1;
1141 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1142 flush
->header
.length
= flush_hint_size
;
1143 flush
->device_handle
= handle
[1];
1144 flush
->hint_count
= NUM_HINTS
;
1145 for (i
= 0; i
< NUM_HINTS
; i
++)
1146 flush
->hint_address
[i
] = t
->flush_dma
[1] + i
* sizeof(u64
);
1148 /* flush2 (dimm2) */
1149 flush
= nfit_buf
+ offset
+ flush_hint_size
* 2;
1150 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1151 flush
->header
.length
= flush_hint_size
;
1152 flush
->device_handle
= handle
[2];
1153 flush
->hint_count
= NUM_HINTS
;
1154 for (i
= 0; i
< NUM_HINTS
; i
++)
1155 flush
->hint_address
[i
] = t
->flush_dma
[2] + i
* sizeof(u64
);
1157 /* flush3 (dimm3) */
1158 flush
= nfit_buf
+ offset
+ flush_hint_size
* 3;
1159 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1160 flush
->header
.length
= flush_hint_size
;
1161 flush
->device_handle
= handle
[3];
1162 flush
->hint_count
= NUM_HINTS
;
1163 for (i
= 0; i
< NUM_HINTS
; i
++)
1164 flush
->hint_address
[i
] = t
->flush_dma
[3] + i
* sizeof(u64
);
1166 if (t
->setup_hotplug
) {
1167 offset
= offset
+ flush_hint_size
* 4;
1168 /* dcr-descriptor4: blk */
1169 dcr
= nfit_buf
+ offset
;
1170 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1171 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
1172 dcr
->region_index
= 8+1;
1173 dcr_common_init(dcr
);
1174 dcr
->serial_number
= ~handle
[4];
1175 dcr
->code
= NFIT_FIC_BLK
;
1177 dcr
->window_size
= DCR_SIZE
;
1178 dcr
->command_offset
= 0;
1179 dcr
->command_size
= 8;
1180 dcr
->status_offset
= 8;
1181 dcr
->status_size
= 4;
1183 offset
= offset
+ sizeof(struct acpi_nfit_control_region
);
1184 /* dcr-descriptor4: pmem */
1185 dcr
= nfit_buf
+ offset
;
1186 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1187 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1189 dcr
->region_index
= 9+1;
1190 dcr_common_init(dcr
);
1191 dcr
->serial_number
= ~handle
[4];
1192 dcr
->code
= NFIT_FIC_BYTEN
;
1195 offset
= offset
+ offsetof(struct acpi_nfit_control_region
,
1197 /* bdw4 (spa/dcr4, dimm4) */
1198 bdw
= nfit_buf
+ offset
;
1199 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1200 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1201 bdw
->region_index
= 8+1;
1204 bdw
->size
= BDW_SIZE
;
1205 bdw
->capacity
= DIMM_SIZE
;
1206 bdw
->start_address
= 0;
1208 offset
= offset
+ sizeof(struct acpi_nfit_data_region
);
1209 /* spa10 (dcr4) dimm4 */
1210 spa
= nfit_buf
+ offset
;
1211 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1212 spa
->header
.length
= sizeof(*spa
);
1213 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
1214 spa
->range_index
= 10+1;
1215 spa
->address
= t
->dcr_dma
[4];
1216 spa
->length
= DCR_SIZE
;
1219 * spa11 (single-dimm interleave for hotplug, note storage
1220 * does not actually alias the related block-data-window
1223 spa
= nfit_buf
+ offset
+ sizeof(*spa
);
1224 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1225 spa
->header
.length
= sizeof(*spa
);
1226 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
1227 spa
->range_index
= 11+1;
1228 spa
->address
= t
->spa_set_dma
[2];
1229 spa
->length
= SPA0_SIZE
;
1231 /* spa12 (bdw for dcr4) dimm4 */
1232 spa
= nfit_buf
+ offset
+ sizeof(*spa
) * 2;
1233 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1234 spa
->header
.length
= sizeof(*spa
);
1235 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
1236 spa
->range_index
= 12+1;
1237 spa
->address
= t
->dimm_dma
[4];
1238 spa
->length
= DIMM_SIZE
;
1240 offset
= offset
+ sizeof(*spa
) * 3;
1241 /* mem-region14 (spa/dcr4, dimm4) */
1242 memdev
= nfit_buf
+ offset
;
1243 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1244 memdev
->header
.length
= sizeof(*memdev
);
1245 memdev
->device_handle
= handle
[4];
1246 memdev
->physical_id
= 4;
1247 memdev
->region_id
= 0;
1248 memdev
->range_index
= 10+1;
1249 memdev
->region_index
= 8+1;
1250 memdev
->region_size
= 0;
1251 memdev
->region_offset
= 0;
1252 memdev
->address
= 0;
1253 memdev
->interleave_index
= 0;
1254 memdev
->interleave_ways
= 1;
1256 /* mem-region15 (spa0, dimm4) */
1257 memdev
= nfit_buf
+ offset
+
1258 sizeof(struct acpi_nfit_memory_map
);
1259 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1260 memdev
->header
.length
= sizeof(*memdev
);
1261 memdev
->device_handle
= handle
[4];
1262 memdev
->physical_id
= 4;
1263 memdev
->region_id
= 0;
1264 memdev
->range_index
= 11+1;
1265 memdev
->region_index
= 9+1;
1266 memdev
->region_size
= SPA0_SIZE
;
1267 memdev
->region_offset
= t
->spa_set_dma
[2];
1268 memdev
->address
= 0;
1269 memdev
->interleave_index
= 0;
1270 memdev
->interleave_ways
= 1;
1272 /* mem-region16 (spa/bdw4, dimm4) */
1273 memdev
= nfit_buf
+ offset
+
1274 sizeof(struct acpi_nfit_memory_map
) * 2;
1275 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1276 memdev
->header
.length
= sizeof(*memdev
);
1277 memdev
->device_handle
= handle
[4];
1278 memdev
->physical_id
= 4;
1279 memdev
->region_id
= 0;
1280 memdev
->range_index
= 12+1;
1281 memdev
->region_index
= 8+1;
1282 memdev
->region_size
= 0;
1283 memdev
->region_offset
= 0;
1284 memdev
->address
= 0;
1285 memdev
->interleave_index
= 0;
1286 memdev
->interleave_ways
= 1;
1288 offset
= offset
+ sizeof(struct acpi_nfit_memory_map
) * 3;
1289 /* flush3 (dimm4) */
1290 flush
= nfit_buf
+ offset
;
1291 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1292 flush
->header
.length
= flush_hint_size
;
1293 flush
->device_handle
= handle
[4];
1294 flush
->hint_count
= NUM_HINTS
;
1295 for (i
= 0; i
< NUM_HINTS
; i
++)
1296 flush
->hint_address
[i
] = t
->flush_dma
[4]
1300 post_ars_status(&t
->ars_state
, t
->spa_set_dma
[0], SPA0_SIZE
);
1302 acpi_desc
= &t
->acpi_desc
;
1303 set_bit(ND_CMD_GET_CONFIG_SIZE
, &acpi_desc
->dimm_cmd_force_en
);
1304 set_bit(ND_CMD_GET_CONFIG_DATA
, &acpi_desc
->dimm_cmd_force_en
);
1305 set_bit(ND_CMD_SET_CONFIG_DATA
, &acpi_desc
->dimm_cmd_force_en
);
1306 set_bit(ND_CMD_SMART
, &acpi_desc
->dimm_cmd_force_en
);
1307 set_bit(ND_CMD_ARS_CAP
, &acpi_desc
->bus_cmd_force_en
);
1308 set_bit(ND_CMD_ARS_START
, &acpi_desc
->bus_cmd_force_en
);
1309 set_bit(ND_CMD_ARS_STATUS
, &acpi_desc
->bus_cmd_force_en
);
1310 set_bit(ND_CMD_CLEAR_ERROR
, &acpi_desc
->bus_cmd_force_en
);
1311 set_bit(ND_CMD_SMART_THRESHOLD
, &acpi_desc
->dimm_cmd_force_en
);
1314 static void nfit_test1_setup(struct nfit_test
*t
)
1317 void *nfit_buf
= t
->nfit_buf
;
1318 struct acpi_nfit_memory_map
*memdev
;
1319 struct acpi_nfit_control_region
*dcr
;
1320 struct acpi_nfit_system_address
*spa
;
1321 struct acpi_nfit_desc
*acpi_desc
;
1324 /* spa0 (flat range with no bdw aliasing) */
1325 spa
= nfit_buf
+ offset
;
1326 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1327 spa
->header
.length
= sizeof(*spa
);
1328 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
1329 spa
->range_index
= 0+1;
1330 spa
->address
= t
->spa_set_dma
[0];
1331 spa
->length
= SPA2_SIZE
;
1333 /* virtual cd region */
1334 spa
= nfit_buf
+ sizeof(*spa
);
1335 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1336 spa
->header
.length
= sizeof(*spa
);
1337 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_VCD
), 16);
1338 spa
->range_index
= 0;
1339 spa
->address
= t
->spa_set_dma
[1];
1340 spa
->length
= SPA_VCD_SIZE
;
1342 offset
+= sizeof(*spa
) * 2;
1343 /* mem-region0 (spa0, dimm0) */
1344 memdev
= nfit_buf
+ offset
;
1345 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1346 memdev
->header
.length
= sizeof(*memdev
);
1347 memdev
->device_handle
= 0;
1348 memdev
->physical_id
= 0;
1349 memdev
->region_id
= 0;
1350 memdev
->range_index
= 0+1;
1351 memdev
->region_index
= 0+1;
1352 memdev
->region_size
= SPA2_SIZE
;
1353 memdev
->region_offset
= 0;
1354 memdev
->address
= 0;
1355 memdev
->interleave_index
= 0;
1356 memdev
->interleave_ways
= 1;
1357 memdev
->flags
= ACPI_NFIT_MEM_SAVE_FAILED
| ACPI_NFIT_MEM_RESTORE_FAILED
1358 | ACPI_NFIT_MEM_FLUSH_FAILED
| ACPI_NFIT_MEM_HEALTH_OBSERVED
1359 | ACPI_NFIT_MEM_NOT_ARMED
;
1361 offset
+= sizeof(*memdev
);
1362 /* dcr-descriptor0 */
1363 dcr
= nfit_buf
+ offset
;
1364 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1365 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1367 dcr
->region_index
= 0+1;
1368 dcr_common_init(dcr
);
1369 dcr
->serial_number
= ~0;
1370 dcr
->code
= NFIT_FIC_BYTE
;
1373 post_ars_status(&t
->ars_state
, t
->spa_set_dma
[0], SPA2_SIZE
);
1375 acpi_desc
= &t
->acpi_desc
;
1376 set_bit(ND_CMD_ARS_CAP
, &acpi_desc
->bus_cmd_force_en
);
1377 set_bit(ND_CMD_ARS_START
, &acpi_desc
->bus_cmd_force_en
);
1378 set_bit(ND_CMD_ARS_STATUS
, &acpi_desc
->bus_cmd_force_en
);
1379 set_bit(ND_CMD_CLEAR_ERROR
, &acpi_desc
->bus_cmd_force_en
);
1382 static int nfit_test_blk_do_io(struct nd_blk_region
*ndbr
, resource_size_t dpa
,
1383 void *iobuf
, u64 len
, int rw
)
1385 struct nfit_blk
*nfit_blk
= ndbr
->blk_provider_data
;
1386 struct nfit_blk_mmio
*mmio
= &nfit_blk
->mmio
[BDW
];
1387 struct nd_region
*nd_region
= &ndbr
->nd_region
;
1390 lane
= nd_region_acquire_lane(nd_region
);
1392 memcpy(mmio
->addr
.base
+ dpa
, iobuf
, len
);
1394 memcpy(iobuf
, mmio
->addr
.base
+ dpa
, len
);
1396 /* give us some some coverage of the mmio_flush_range() API */
1397 mmio_flush_range(mmio
->addr
.base
+ dpa
, len
);
1399 nd_region_release_lane(nd_region
, lane
);
1404 static int nfit_test_probe(struct platform_device
*pdev
)
1406 struct nvdimm_bus_descriptor
*nd_desc
;
1407 struct acpi_nfit_desc
*acpi_desc
;
1408 struct device
*dev
= &pdev
->dev
;
1409 struct nfit_test
*nfit_test
;
1412 nfit_test
= to_nfit_test(&pdev
->dev
);
1415 if (nfit_test
->num_dcr
) {
1416 int num
= nfit_test
->num_dcr
;
1418 nfit_test
->dimm
= devm_kcalloc(dev
, num
, sizeof(void *),
1420 nfit_test
->dimm_dma
= devm_kcalloc(dev
, num
, sizeof(dma_addr_t
),
1422 nfit_test
->flush
= devm_kcalloc(dev
, num
, sizeof(void *),
1424 nfit_test
->flush_dma
= devm_kcalloc(dev
, num
, sizeof(dma_addr_t
),
1426 nfit_test
->label
= devm_kcalloc(dev
, num
, sizeof(void *),
1428 nfit_test
->label_dma
= devm_kcalloc(dev
, num
,
1429 sizeof(dma_addr_t
), GFP_KERNEL
);
1430 nfit_test
->dcr
= devm_kcalloc(dev
, num
,
1431 sizeof(struct nfit_test_dcr
*), GFP_KERNEL
);
1432 nfit_test
->dcr_dma
= devm_kcalloc(dev
, num
,
1433 sizeof(dma_addr_t
), GFP_KERNEL
);
1434 if (nfit_test
->dimm
&& nfit_test
->dimm_dma
&& nfit_test
->label
1435 && nfit_test
->label_dma
&& nfit_test
->dcr
1436 && nfit_test
->dcr_dma
&& nfit_test
->flush
1437 && nfit_test
->flush_dma
)
1443 if (nfit_test
->num_pm
) {
1444 int num
= nfit_test
->num_pm
;
1446 nfit_test
->spa_set
= devm_kcalloc(dev
, num
, sizeof(void *),
1448 nfit_test
->spa_set_dma
= devm_kcalloc(dev
, num
,
1449 sizeof(dma_addr_t
), GFP_KERNEL
);
1450 if (nfit_test
->spa_set
&& nfit_test
->spa_set_dma
)
1456 /* per-nfit specific alloc */
1457 if (nfit_test
->alloc(nfit_test
))
1460 nfit_test
->setup(nfit_test
);
1461 acpi_desc
= &nfit_test
->acpi_desc
;
1462 acpi_nfit_desc_init(acpi_desc
, &pdev
->dev
);
1463 acpi_desc
->blk_do_io
= nfit_test_blk_do_io
;
1464 nd_desc
= &acpi_desc
->nd_desc
;
1465 nd_desc
->provider_name
= NULL
;
1466 nd_desc
->module
= THIS_MODULE
;
1467 nd_desc
->ndctl
= nfit_test_ctl
;
1469 rc
= acpi_nfit_init(acpi_desc
, nfit_test
->nfit_buf
,
1470 nfit_test
->nfit_size
);
1474 if (nfit_test
->setup
!= nfit_test0_setup
)
1477 nfit_test
->setup_hotplug
= 1;
1478 nfit_test
->setup(nfit_test
);
1480 rc
= acpi_nfit_init(acpi_desc
, nfit_test
->nfit_buf
,
1481 nfit_test
->nfit_size
);
1488 static int nfit_test_remove(struct platform_device
*pdev
)
1493 static void nfit_test_release(struct device
*dev
)
1495 struct nfit_test
*nfit_test
= to_nfit_test(dev
);
1500 static const struct platform_device_id nfit_test_id
[] = {
1505 static struct platform_driver nfit_test_driver
= {
1506 .probe
= nfit_test_probe
,
1507 .remove
= nfit_test_remove
,
1509 .name
= KBUILD_MODNAME
,
1511 .id_table
= nfit_test_id
,
1514 static __init
int nfit_test_init(void)
1518 nfit_test_setup(nfit_test_lookup
);
1520 for (i
= 0; i
< NUM_NFITS
; i
++) {
1521 struct nfit_test
*nfit_test
;
1522 struct platform_device
*pdev
;
1524 nfit_test
= kzalloc(sizeof(*nfit_test
), GFP_KERNEL
);
1529 INIT_LIST_HEAD(&nfit_test
->resources
);
1532 nfit_test
->num_pm
= NUM_PM
;
1533 nfit_test
->num_dcr
= NUM_DCR
;
1534 nfit_test
->alloc
= nfit_test0_alloc
;
1535 nfit_test
->setup
= nfit_test0_setup
;
1538 nfit_test
->num_pm
= 1;
1539 nfit_test
->alloc
= nfit_test1_alloc
;
1540 nfit_test
->setup
= nfit_test1_setup
;
1546 pdev
= &nfit_test
->pdev
;
1547 pdev
->name
= KBUILD_MODNAME
;
1549 pdev
->dev
.release
= nfit_test_release
;
1550 rc
= platform_device_register(pdev
);
1552 put_device(&pdev
->dev
);
1556 rc
= dma_coerce_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(64));
1560 instances
[i
] = nfit_test
;
1563 rc
= platform_driver_register(&nfit_test_driver
);
1569 for (i
= 0; i
< NUM_NFITS
; i
++)
1571 platform_device_unregister(&instances
[i
]->pdev
);
1572 nfit_test_teardown();
1576 static __exit
void nfit_test_exit(void)
1580 platform_driver_unregister(&nfit_test_driver
);
1581 for (i
= 0; i
< NUM_NFITS
; i
++)
1582 platform_device_unregister(&instances
[i
]->pdev
);
1583 nfit_test_teardown();
1586 module_init(nfit_test_init
);
1587 module_exit(nfit_test_exit
);
1588 MODULE_LICENSE("GPL v2");
1589 MODULE_AUTHOR("Intel Corporation");