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/workqueue.h>
17 #include <linux/libnvdimm.h>
18 #include <linux/vmalloc.h>
19 #include <linux/device.h>
20 #include <linux/module.h>
21 #include <linux/mutex.h>
22 #include <linux/ndctl.h>
23 #include <linux/sizes.h>
24 #include <linux/list.h>
25 #include <linux/slab.h>
28 #include "nfit_test.h"
31 * Generate an NFIT table to describe the following topology:
33 * BUS0: Interleaved PMEM regions, and aliasing with BLK regions
35 * (a) (b) DIMM BLK-REGION
36 * +----------+--------------+----------+---------+
37 * +------+ | blk2.0 | pm0.0 | blk2.1 | pm1.0 | 0 region2
38 * | imc0 +--+- - - - - region0 - - - -+----------+ +
39 * +--+---+ | blk3.0 | pm0.0 | blk3.1 | pm1.0 | 1 region3
40 * | +----------+--------------v----------v v
44 * | +-------------------------^----------^ ^
45 * +--+---+ | blk4.0 | pm1.0 | 2 region4
46 * | imc1 +--+-------------------------+----------+ +
47 * +------+ | blk5.0 | pm1.0 | 3 region5
48 * +-------------------------+----------+-+-------+
52 * +--+---+ (Hotplug DIMM)
53 * | +----------------------------------------------+
54 * +--+---+ | blk6.0/pm7.0 | 4 region6/7
55 * | imc0 +--+----------------------------------------------+
59 * *) In this layout we have four dimms and two memory controllers in one
60 * socket. Each unique interface (BLK or PMEM) to DPA space
61 * is identified by a region device with a dynamically assigned id.
63 * *) The first portion of dimm0 and dimm1 are interleaved as REGION0.
64 * A single PMEM namespace "pm0.0" is created using half of the
65 * REGION0 SPA-range. REGION0 spans dimm0 and dimm1. PMEM namespace
66 * allocate from from the bottom of a region. The unallocated
67 * portion of REGION0 aliases with REGION2 and REGION3. That
68 * unallacted capacity is reclaimed as BLK namespaces ("blk2.0" and
69 * "blk3.0") starting at the base of each DIMM to offset (a) in those
70 * DIMMs. "pm0.0", "blk2.0" and "blk3.0" are free-form readable
71 * names that can be assigned to a namespace.
73 * *) In the last portion of dimm0 and dimm1 we have an interleaved
74 * SPA range, REGION1, that spans those two dimms as well as dimm2
75 * and dimm3. Some of REGION1 allocated to a PMEM namespace named
76 * "pm1.0" the rest is reclaimed in 4 BLK namespaces (for each
77 * dimm in the interleave set), "blk2.1", "blk3.1", "blk4.0", and
80 * *) The portion of dimm2 and dimm3 that do not participate in the
81 * REGION1 interleaved SPA range (i.e. the DPA address below offset
82 * (b) are also included in the "blk4.0" and "blk5.0" namespaces.
83 * Note, that BLK namespaces need not be contiguous in DPA-space, and
84 * can consume aliased capacity from multiple interleave sets.
86 * BUS1: Legacy NVDIMM (single contiguous range)
89 * +---------------------+
90 * |---------------------|
92 * |---------------------|
93 * +---------------------+
95 * *) A NFIT-table may describe a simple system-physical-address range
96 * with no BLK aliasing. This type of region may optionally
97 * reference an NVDIMM.
104 NUM_SPA
= NUM_PM
+ NUM_DCR
+ NUM_BDW
,
105 NUM_MEM
= NUM_DCR
+ NUM_BDW
+ 2 /* spa0 iset */ + 4 /* spa1 iset */,
107 LABEL_SIZE
= SZ_128K
,
108 SPA_VCD_SIZE
= SZ_4M
,
109 SPA0_SIZE
= DIMM_SIZE
,
110 SPA1_SIZE
= DIMM_SIZE
*2,
111 SPA2_SIZE
= DIMM_SIZE
,
114 NUM_NFITS
= 2, /* permit testing multiple NFITs per system */
117 struct nfit_test_dcr
{
120 __u8 aperature
[BDW_SIZE
];
123 #define NFIT_DIMM_HANDLE(node, socket, imc, chan, dimm) \
124 (((node & 0xfff) << 16) | ((socket & 0xf) << 12) \
125 | ((imc & 0xf) << 8) | ((chan & 0xf) << 4) | (dimm & 0xf))
127 static u32 handle
[NUM_DCR
] = {
128 [0] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 0),
129 [1] = NFIT_DIMM_HANDLE(0, 0, 0, 0, 1),
130 [2] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 0),
131 [3] = NFIT_DIMM_HANDLE(0, 0, 1, 0, 1),
132 [4] = NFIT_DIMM_HANDLE(0, 1, 0, 0, 0),
136 struct acpi_nfit_desc acpi_desc
;
137 struct platform_device pdev
;
138 struct list_head resources
;
145 dma_addr_t
*dimm_dma
;
147 dma_addr_t
*flush_dma
;
149 dma_addr_t
*label_dma
;
151 dma_addr_t
*spa_set_dma
;
152 struct nfit_test_dcr
**dcr
;
154 int (*alloc
)(struct nfit_test
*t
);
155 void (*setup
)(struct nfit_test
*t
);
158 struct nd_cmd_ars_status
*ars_status
;
159 unsigned long deadline
;
164 static struct nfit_test
*to_nfit_test(struct device
*dev
)
166 struct platform_device
*pdev
= to_platform_device(dev
);
168 return container_of(pdev
, struct nfit_test
, pdev
);
171 static int nfit_test_cmd_get_config_size(struct nd_cmd_get_config_size
*nd_cmd
,
172 unsigned int buf_len
)
174 if (buf_len
< sizeof(*nd_cmd
))
178 nd_cmd
->config_size
= LABEL_SIZE
;
179 nd_cmd
->max_xfer
= SZ_4K
;
184 static int nfit_test_cmd_get_config_data(struct nd_cmd_get_config_data_hdr
185 *nd_cmd
, unsigned int buf_len
, void *label
)
187 unsigned int len
, offset
= nd_cmd
->in_offset
;
190 if (buf_len
< sizeof(*nd_cmd
))
192 if (offset
>= LABEL_SIZE
)
194 if (nd_cmd
->in_length
+ sizeof(*nd_cmd
) > buf_len
)
198 len
= min(nd_cmd
->in_length
, LABEL_SIZE
- offset
);
199 memcpy(nd_cmd
->out_buf
, label
+ offset
, len
);
200 rc
= buf_len
- sizeof(*nd_cmd
) - len
;
205 static int nfit_test_cmd_set_config_data(struct nd_cmd_set_config_hdr
*nd_cmd
,
206 unsigned int buf_len
, void *label
)
208 unsigned int len
, offset
= nd_cmd
->in_offset
;
212 if (buf_len
< sizeof(*nd_cmd
))
214 if (offset
>= LABEL_SIZE
)
216 if (nd_cmd
->in_length
+ sizeof(*nd_cmd
) + 4 > buf_len
)
219 status
= (void *)nd_cmd
+ nd_cmd
->in_length
+ sizeof(*nd_cmd
);
221 len
= min(nd_cmd
->in_length
, LABEL_SIZE
- offset
);
222 memcpy(label
+ offset
, nd_cmd
->in_buf
, len
);
223 rc
= buf_len
- sizeof(*nd_cmd
) - (len
+ 4);
228 #define NFIT_TEST_ARS_RECORDS 4
229 #define NFIT_TEST_CLEAR_ERR_UNIT 256
231 static int nfit_test_cmd_ars_cap(struct nd_cmd_ars_cap
*nd_cmd
,
232 unsigned int buf_len
)
234 if (buf_len
< sizeof(*nd_cmd
))
237 nd_cmd
->max_ars_out
= sizeof(struct nd_cmd_ars_status
)
238 + NFIT_TEST_ARS_RECORDS
* sizeof(struct nd_ars_record
);
239 nd_cmd
->status
= (ND_ARS_PERSISTENT
| ND_ARS_VOLATILE
) << 16;
240 nd_cmd
->clear_err_unit
= NFIT_TEST_CLEAR_ERR_UNIT
;
246 * Initialize the ars_state to return an ars_result 1 second in the future with
247 * a 4K error range in the middle of the requested address range.
249 static void post_ars_status(struct ars_state
*ars_state
, u64 addr
, u64 len
)
251 struct nd_cmd_ars_status
*ars_status
;
252 struct nd_ars_record
*ars_record
;
254 ars_state
->deadline
= jiffies
+ 1*HZ
;
255 ars_status
= ars_state
->ars_status
;
256 ars_status
->status
= 0;
257 ars_status
->out_length
= sizeof(struct nd_cmd_ars_status
)
258 + sizeof(struct nd_ars_record
);
259 ars_status
->address
= addr
;
260 ars_status
->length
= len
;
261 ars_status
->type
= ND_ARS_PERSISTENT
;
262 ars_status
->num_records
= 1;
263 ars_record
= &ars_status
->records
[0];
264 ars_record
->handle
= 0;
265 ars_record
->err_address
= addr
+ len
/ 2;
266 ars_record
->length
= SZ_4K
;
269 static int nfit_test_cmd_ars_start(struct ars_state
*ars_state
,
270 struct nd_cmd_ars_start
*ars_start
, unsigned int buf_len
,
273 if (buf_len
< sizeof(*ars_start
))
276 spin_lock(&ars_state
->lock
);
277 if (time_before(jiffies
, ars_state
->deadline
)) {
278 ars_start
->status
= NFIT_ARS_START_BUSY
;
281 ars_start
->status
= 0;
282 ars_start
->scrub_time
= 1;
283 post_ars_status(ars_state
, ars_start
->address
,
287 spin_unlock(&ars_state
->lock
);
292 static int nfit_test_cmd_ars_status(struct ars_state
*ars_state
,
293 struct nd_cmd_ars_status
*ars_status
, unsigned int buf_len
,
296 if (buf_len
< ars_state
->ars_status
->out_length
)
299 spin_lock(&ars_state
->lock
);
300 if (time_before(jiffies
, ars_state
->deadline
)) {
301 memset(ars_status
, 0, buf_len
);
302 ars_status
->status
= NFIT_ARS_STATUS_BUSY
;
303 ars_status
->out_length
= sizeof(*ars_status
);
306 memcpy(ars_status
, ars_state
->ars_status
,
307 ars_state
->ars_status
->out_length
);
310 spin_unlock(&ars_state
->lock
);
314 static int nfit_test_cmd_clear_error(struct nd_cmd_clear_error
*clear_err
,
315 unsigned int buf_len
, int *cmd_rc
)
317 const u64 mask
= NFIT_TEST_CLEAR_ERR_UNIT
- 1;
318 if (buf_len
< sizeof(*clear_err
))
321 if ((clear_err
->address
& mask
) || (clear_err
->length
& mask
))
325 * Report 'all clear' success for all commands even though a new
326 * scrub will find errors again. This is enough to have the
327 * error removed from the 'badblocks' tracking in the pmem
330 clear_err
->status
= 0;
331 clear_err
->cleared
= clear_err
->length
;
336 static int nfit_test_cmd_smart(struct nd_cmd_smart
*smart
, unsigned int buf_len
)
338 static const struct nd_smart_payload smart_data
= {
339 .flags
= ND_SMART_HEALTH_VALID
| ND_SMART_TEMP_VALID
340 | ND_SMART_SPARES_VALID
| ND_SMART_ALARM_VALID
341 | ND_SMART_USED_VALID
| ND_SMART_SHUTDOWN_VALID
,
342 .health
= ND_SMART_NON_CRITICAL_HEALTH
,
343 .temperature
= 23 * 16,
345 .alarm_flags
= ND_SMART_SPARE_TRIP
| ND_SMART_TEMP_TRIP
,
351 if (buf_len
< sizeof(*smart
))
353 memcpy(smart
->data
, &smart_data
, sizeof(smart_data
));
357 static int nfit_test_cmd_smart_threshold(struct nd_cmd_smart_threshold
*smart_t
,
358 unsigned int buf_len
)
360 static const struct nd_smart_threshold_payload smart_t_data
= {
361 .alarm_control
= ND_SMART_SPARE_TRIP
| ND_SMART_TEMP_TRIP
,
362 .temperature
= 40 * 16,
366 if (buf_len
< sizeof(*smart_t
))
368 memcpy(smart_t
->data
, &smart_t_data
, sizeof(smart_t_data
));
372 static int nfit_test_ctl(struct nvdimm_bus_descriptor
*nd_desc
,
373 struct nvdimm
*nvdimm
, unsigned int cmd
, void *buf
,
374 unsigned int buf_len
, int *cmd_rc
)
376 struct acpi_nfit_desc
*acpi_desc
= to_acpi_desc(nd_desc
);
377 struct nfit_test
*t
= container_of(acpi_desc
, typeof(*t
), acpi_desc
);
378 unsigned int func
= cmd
;
379 int i
, rc
= 0, __cmd_rc
;
386 struct nfit_mem
*nfit_mem
= nvdimm_provider_data(nvdimm
);
387 unsigned long cmd_mask
= nvdimm_cmd_mask(nvdimm
);
392 if (cmd
== ND_CMD_CALL
) {
393 struct nd_cmd_pkg
*call_pkg
= buf
;
395 buf_len
= call_pkg
->nd_size_in
+ call_pkg
->nd_size_out
;
396 buf
= (void *) call_pkg
->nd_payload
;
397 func
= call_pkg
->nd_command
;
398 if (call_pkg
->nd_family
!= nfit_mem
->family
)
402 if (!test_bit(cmd
, &cmd_mask
)
403 || !test_bit(func
, &nfit_mem
->dsm_mask
))
406 /* lookup label space for the given dimm */
407 for (i
= 0; i
< ARRAY_SIZE(handle
); i
++)
408 if (__to_nfit_memdev(nfit_mem
)->device_handle
==
411 if (i
>= ARRAY_SIZE(handle
))
415 case ND_CMD_GET_CONFIG_SIZE
:
416 rc
= nfit_test_cmd_get_config_size(buf
, buf_len
);
418 case ND_CMD_GET_CONFIG_DATA
:
419 rc
= nfit_test_cmd_get_config_data(buf
, buf_len
,
422 case ND_CMD_SET_CONFIG_DATA
:
423 rc
= nfit_test_cmd_set_config_data(buf
, buf_len
,
427 rc
= nfit_test_cmd_smart(buf
, buf_len
);
429 case ND_CMD_SMART_THRESHOLD
:
430 rc
= nfit_test_cmd_smart_threshold(buf
, buf_len
);
436 struct ars_state
*ars_state
= &t
->ars_state
;
438 if (!nd_desc
|| !test_bit(cmd
, &nd_desc
->cmd_mask
))
443 rc
= nfit_test_cmd_ars_cap(buf
, buf_len
);
445 case ND_CMD_ARS_START
:
446 rc
= nfit_test_cmd_ars_start(ars_state
, buf
, buf_len
,
449 case ND_CMD_ARS_STATUS
:
450 rc
= nfit_test_cmd_ars_status(ars_state
, buf
, buf_len
,
453 case ND_CMD_CLEAR_ERROR
:
454 rc
= nfit_test_cmd_clear_error(buf
, buf_len
, cmd_rc
);
464 static DEFINE_SPINLOCK(nfit_test_lock
);
465 static struct nfit_test
*instances
[NUM_NFITS
];
467 static void release_nfit_res(void *data
)
469 struct nfit_test_resource
*nfit_res
= data
;
470 struct resource
*res
= nfit_res
->res
;
472 spin_lock(&nfit_test_lock
);
473 list_del(&nfit_res
->list
);
474 spin_unlock(&nfit_test_lock
);
476 vfree(nfit_res
->buf
);
481 static void *__test_alloc(struct nfit_test
*t
, size_t size
, dma_addr_t
*dma
,
484 struct device
*dev
= &t
->pdev
.dev
;
485 struct resource
*res
= kzalloc(sizeof(*res
) * 2, GFP_KERNEL
);
486 struct nfit_test_resource
*nfit_res
= kzalloc(sizeof(*nfit_res
),
490 if (!res
|| !buf
|| !nfit_res
)
492 rc
= devm_add_action(dev
, release_nfit_res
, nfit_res
);
495 INIT_LIST_HEAD(&nfit_res
->list
);
496 memset(buf
, 0, size
);
501 res
->end
= *dma
+ size
- 1;
503 spin_lock(&nfit_test_lock
);
504 list_add(&nfit_res
->list
, &t
->resources
);
505 spin_unlock(&nfit_test_lock
);
507 return nfit_res
->buf
;
516 static void *test_alloc(struct nfit_test
*t
, size_t size
, dma_addr_t
*dma
)
518 void *buf
= vmalloc(size
);
520 *dma
= (unsigned long) buf
;
521 return __test_alloc(t
, size
, dma
, buf
);
524 static struct nfit_test_resource
*nfit_test_lookup(resource_size_t addr
)
528 for (i
= 0; i
< ARRAY_SIZE(instances
); i
++) {
529 struct nfit_test_resource
*n
, *nfit_res
= NULL
;
530 struct nfit_test
*t
= instances
[i
];
534 spin_lock(&nfit_test_lock
);
535 list_for_each_entry(n
, &t
->resources
, list
) {
536 if (addr
>= n
->res
->start
&& (addr
< n
->res
->start
537 + resource_size(n
->res
))) {
540 } else if (addr
>= (unsigned long) n
->buf
541 && (addr
< (unsigned long) n
->buf
542 + resource_size(n
->res
))) {
547 spin_unlock(&nfit_test_lock
);
555 static int ars_state_init(struct device
*dev
, struct ars_state
*ars_state
)
557 ars_state
->ars_status
= devm_kzalloc(dev
,
558 sizeof(struct nd_cmd_ars_status
)
559 + sizeof(struct nd_ars_record
) * NFIT_TEST_ARS_RECORDS
,
561 if (!ars_state
->ars_status
)
563 spin_lock_init(&ars_state
->lock
);
567 static int nfit_test0_alloc(struct nfit_test
*t
)
569 size_t nfit_size
= sizeof(struct acpi_nfit_system_address
) * NUM_SPA
570 + sizeof(struct acpi_nfit_memory_map
) * NUM_MEM
571 + sizeof(struct acpi_nfit_control_region
) * NUM_DCR
572 + offsetof(struct acpi_nfit_control_region
,
573 window_size
) * NUM_DCR
574 + sizeof(struct acpi_nfit_data_region
) * NUM_BDW
575 + (sizeof(struct acpi_nfit_flush_address
)
576 + sizeof(u64
) * NUM_HINTS
) * NUM_DCR
;
579 t
->nfit_buf
= test_alloc(t
, nfit_size
, &t
->nfit_dma
);
582 t
->nfit_size
= nfit_size
;
584 t
->spa_set
[0] = test_alloc(t
, SPA0_SIZE
, &t
->spa_set_dma
[0]);
588 t
->spa_set
[1] = test_alloc(t
, SPA1_SIZE
, &t
->spa_set_dma
[1]);
592 t
->spa_set
[2] = test_alloc(t
, SPA0_SIZE
, &t
->spa_set_dma
[2]);
596 for (i
= 0; i
< NUM_DCR
; i
++) {
597 t
->dimm
[i
] = test_alloc(t
, DIMM_SIZE
, &t
->dimm_dma
[i
]);
601 t
->label
[i
] = test_alloc(t
, LABEL_SIZE
, &t
->label_dma
[i
]);
604 sprintf(t
->label
[i
], "label%d", i
);
606 t
->flush
[i
] = test_alloc(t
, sizeof(u64
) * NUM_HINTS
,
612 for (i
= 0; i
< NUM_DCR
; i
++) {
613 t
->dcr
[i
] = test_alloc(t
, LABEL_SIZE
, &t
->dcr_dma
[i
]);
618 return ars_state_init(&t
->pdev
.dev
, &t
->ars_state
);
621 static int nfit_test1_alloc(struct nfit_test
*t
)
623 size_t nfit_size
= sizeof(struct acpi_nfit_system_address
) * 2
624 + sizeof(struct acpi_nfit_memory_map
)
625 + offsetof(struct acpi_nfit_control_region
, window_size
);
627 t
->nfit_buf
= test_alloc(t
, nfit_size
, &t
->nfit_dma
);
630 t
->nfit_size
= nfit_size
;
632 t
->spa_set
[0] = test_alloc(t
, SPA2_SIZE
, &t
->spa_set_dma
[0]);
636 t
->spa_set
[1] = test_alloc(t
, SPA_VCD_SIZE
, &t
->spa_set_dma
[1]);
640 return ars_state_init(&t
->pdev
.dev
, &t
->ars_state
);
643 static void dcr_common_init(struct acpi_nfit_control_region
*dcr
)
645 dcr
->vendor_id
= 0xabcd;
647 dcr
->revision_id
= 1;
648 dcr
->valid_fields
= 1;
649 dcr
->manufacturing_location
= 0xa;
650 dcr
->manufacturing_date
= cpu_to_be16(2016);
653 static void nfit_test0_setup(struct nfit_test
*t
)
655 const int flush_hint_size
= sizeof(struct acpi_nfit_flush_address
)
656 + (sizeof(u64
) * NUM_HINTS
);
657 struct acpi_nfit_desc
*acpi_desc
;
658 struct acpi_nfit_memory_map
*memdev
;
659 void *nfit_buf
= t
->nfit_buf
;
660 struct acpi_nfit_system_address
*spa
;
661 struct acpi_nfit_control_region
*dcr
;
662 struct acpi_nfit_data_region
*bdw
;
663 struct acpi_nfit_flush_address
*flush
;
664 unsigned int offset
, i
;
667 * spa0 (interleave first half of dimm0 and dimm1, note storage
668 * does not actually alias the related block-data-window
672 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
673 spa
->header
.length
= sizeof(*spa
);
674 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
675 spa
->range_index
= 0+1;
676 spa
->address
= t
->spa_set_dma
[0];
677 spa
->length
= SPA0_SIZE
;
680 * spa1 (interleave last half of the 4 DIMMS, note storage
681 * does not actually alias the related block-data-window
684 spa
= nfit_buf
+ sizeof(*spa
);
685 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
686 spa
->header
.length
= sizeof(*spa
);
687 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
688 spa
->range_index
= 1+1;
689 spa
->address
= t
->spa_set_dma
[1];
690 spa
->length
= SPA1_SIZE
;
692 /* spa2 (dcr0) dimm0 */
693 spa
= nfit_buf
+ sizeof(*spa
) * 2;
694 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
695 spa
->header
.length
= sizeof(*spa
);
696 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
697 spa
->range_index
= 2+1;
698 spa
->address
= t
->dcr_dma
[0];
699 spa
->length
= DCR_SIZE
;
701 /* spa3 (dcr1) dimm1 */
702 spa
= nfit_buf
+ sizeof(*spa
) * 3;
703 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
704 spa
->header
.length
= sizeof(*spa
);
705 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
706 spa
->range_index
= 3+1;
707 spa
->address
= t
->dcr_dma
[1];
708 spa
->length
= DCR_SIZE
;
710 /* spa4 (dcr2) dimm2 */
711 spa
= nfit_buf
+ sizeof(*spa
) * 4;
712 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
713 spa
->header
.length
= sizeof(*spa
);
714 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
715 spa
->range_index
= 4+1;
716 spa
->address
= t
->dcr_dma
[2];
717 spa
->length
= DCR_SIZE
;
719 /* spa5 (dcr3) dimm3 */
720 spa
= nfit_buf
+ sizeof(*spa
) * 5;
721 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
722 spa
->header
.length
= sizeof(*spa
);
723 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
724 spa
->range_index
= 5+1;
725 spa
->address
= t
->dcr_dma
[3];
726 spa
->length
= DCR_SIZE
;
728 /* spa6 (bdw for dcr0) dimm0 */
729 spa
= nfit_buf
+ sizeof(*spa
) * 6;
730 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
731 spa
->header
.length
= sizeof(*spa
);
732 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
733 spa
->range_index
= 6+1;
734 spa
->address
= t
->dimm_dma
[0];
735 spa
->length
= DIMM_SIZE
;
737 /* spa7 (bdw for dcr1) dimm1 */
738 spa
= nfit_buf
+ sizeof(*spa
) * 7;
739 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
740 spa
->header
.length
= sizeof(*spa
);
741 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
742 spa
->range_index
= 7+1;
743 spa
->address
= t
->dimm_dma
[1];
744 spa
->length
= DIMM_SIZE
;
746 /* spa8 (bdw for dcr2) dimm2 */
747 spa
= nfit_buf
+ sizeof(*spa
) * 8;
748 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
749 spa
->header
.length
= sizeof(*spa
);
750 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
751 spa
->range_index
= 8+1;
752 spa
->address
= t
->dimm_dma
[2];
753 spa
->length
= DIMM_SIZE
;
755 /* spa9 (bdw for dcr3) dimm3 */
756 spa
= nfit_buf
+ sizeof(*spa
) * 9;
757 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
758 spa
->header
.length
= sizeof(*spa
);
759 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
760 spa
->range_index
= 9+1;
761 spa
->address
= t
->dimm_dma
[3];
762 spa
->length
= DIMM_SIZE
;
764 offset
= sizeof(*spa
) * 10;
765 /* mem-region0 (spa0, dimm0) */
766 memdev
= nfit_buf
+ offset
;
767 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
768 memdev
->header
.length
= sizeof(*memdev
);
769 memdev
->device_handle
= handle
[0];
770 memdev
->physical_id
= 0;
771 memdev
->region_id
= 0;
772 memdev
->range_index
= 0+1;
773 memdev
->region_index
= 4+1;
774 memdev
->region_size
= SPA0_SIZE
/2;
775 memdev
->region_offset
= t
->spa_set_dma
[0];
777 memdev
->interleave_index
= 0;
778 memdev
->interleave_ways
= 2;
780 /* mem-region1 (spa0, dimm1) */
781 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
);
782 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
783 memdev
->header
.length
= sizeof(*memdev
);
784 memdev
->device_handle
= handle
[1];
785 memdev
->physical_id
= 1;
786 memdev
->region_id
= 0;
787 memdev
->range_index
= 0+1;
788 memdev
->region_index
= 5+1;
789 memdev
->region_size
= SPA0_SIZE
/2;
790 memdev
->region_offset
= t
->spa_set_dma
[0] + SPA0_SIZE
/2;
792 memdev
->interleave_index
= 0;
793 memdev
->interleave_ways
= 2;
795 /* mem-region2 (spa1, dimm0) */
796 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 2;
797 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
798 memdev
->header
.length
= sizeof(*memdev
);
799 memdev
->device_handle
= handle
[0];
800 memdev
->physical_id
= 0;
801 memdev
->region_id
= 1;
802 memdev
->range_index
= 1+1;
803 memdev
->region_index
= 4+1;
804 memdev
->region_size
= SPA1_SIZE
/4;
805 memdev
->region_offset
= t
->spa_set_dma
[1];
806 memdev
->address
= SPA0_SIZE
/2;
807 memdev
->interleave_index
= 0;
808 memdev
->interleave_ways
= 4;
810 /* mem-region3 (spa1, dimm1) */
811 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 3;
812 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
813 memdev
->header
.length
= sizeof(*memdev
);
814 memdev
->device_handle
= handle
[1];
815 memdev
->physical_id
= 1;
816 memdev
->region_id
= 1;
817 memdev
->range_index
= 1+1;
818 memdev
->region_index
= 5+1;
819 memdev
->region_size
= SPA1_SIZE
/4;
820 memdev
->region_offset
= t
->spa_set_dma
[1] + SPA1_SIZE
/4;
821 memdev
->address
= SPA0_SIZE
/2;
822 memdev
->interleave_index
= 0;
823 memdev
->interleave_ways
= 4;
825 /* mem-region4 (spa1, dimm2) */
826 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 4;
827 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
828 memdev
->header
.length
= sizeof(*memdev
);
829 memdev
->device_handle
= handle
[2];
830 memdev
->physical_id
= 2;
831 memdev
->region_id
= 0;
832 memdev
->range_index
= 1+1;
833 memdev
->region_index
= 6+1;
834 memdev
->region_size
= SPA1_SIZE
/4;
835 memdev
->region_offset
= t
->spa_set_dma
[1] + 2*SPA1_SIZE
/4;
836 memdev
->address
= SPA0_SIZE
/2;
837 memdev
->interleave_index
= 0;
838 memdev
->interleave_ways
= 4;
840 /* mem-region5 (spa1, dimm3) */
841 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 5;
842 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
843 memdev
->header
.length
= sizeof(*memdev
);
844 memdev
->device_handle
= handle
[3];
845 memdev
->physical_id
= 3;
846 memdev
->region_id
= 0;
847 memdev
->range_index
= 1+1;
848 memdev
->region_index
= 7+1;
849 memdev
->region_size
= SPA1_SIZE
/4;
850 memdev
->region_offset
= t
->spa_set_dma
[1] + 3*SPA1_SIZE
/4;
851 memdev
->address
= SPA0_SIZE
/2;
852 memdev
->interleave_index
= 0;
853 memdev
->interleave_ways
= 4;
855 /* mem-region6 (spa/dcr0, dimm0) */
856 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 6;
857 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
858 memdev
->header
.length
= sizeof(*memdev
);
859 memdev
->device_handle
= handle
[0];
860 memdev
->physical_id
= 0;
861 memdev
->region_id
= 0;
862 memdev
->range_index
= 2+1;
863 memdev
->region_index
= 0+1;
864 memdev
->region_size
= 0;
865 memdev
->region_offset
= 0;
867 memdev
->interleave_index
= 0;
868 memdev
->interleave_ways
= 1;
870 /* mem-region7 (spa/dcr1, dimm1) */
871 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 7;
872 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
873 memdev
->header
.length
= sizeof(*memdev
);
874 memdev
->device_handle
= handle
[1];
875 memdev
->physical_id
= 1;
876 memdev
->region_id
= 0;
877 memdev
->range_index
= 3+1;
878 memdev
->region_index
= 1+1;
879 memdev
->region_size
= 0;
880 memdev
->region_offset
= 0;
882 memdev
->interleave_index
= 0;
883 memdev
->interleave_ways
= 1;
885 /* mem-region8 (spa/dcr2, dimm2) */
886 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 8;
887 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
888 memdev
->header
.length
= sizeof(*memdev
);
889 memdev
->device_handle
= handle
[2];
890 memdev
->physical_id
= 2;
891 memdev
->region_id
= 0;
892 memdev
->range_index
= 4+1;
893 memdev
->region_index
= 2+1;
894 memdev
->region_size
= 0;
895 memdev
->region_offset
= 0;
897 memdev
->interleave_index
= 0;
898 memdev
->interleave_ways
= 1;
900 /* mem-region9 (spa/dcr3, dimm3) */
901 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 9;
902 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
903 memdev
->header
.length
= sizeof(*memdev
);
904 memdev
->device_handle
= handle
[3];
905 memdev
->physical_id
= 3;
906 memdev
->region_id
= 0;
907 memdev
->range_index
= 5+1;
908 memdev
->region_index
= 3+1;
909 memdev
->region_size
= 0;
910 memdev
->region_offset
= 0;
912 memdev
->interleave_index
= 0;
913 memdev
->interleave_ways
= 1;
915 /* mem-region10 (spa/bdw0, dimm0) */
916 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 10;
917 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
918 memdev
->header
.length
= sizeof(*memdev
);
919 memdev
->device_handle
= handle
[0];
920 memdev
->physical_id
= 0;
921 memdev
->region_id
= 0;
922 memdev
->range_index
= 6+1;
923 memdev
->region_index
= 0+1;
924 memdev
->region_size
= 0;
925 memdev
->region_offset
= 0;
927 memdev
->interleave_index
= 0;
928 memdev
->interleave_ways
= 1;
930 /* mem-region11 (spa/bdw1, dimm1) */
931 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 11;
932 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
933 memdev
->header
.length
= sizeof(*memdev
);
934 memdev
->device_handle
= handle
[1];
935 memdev
->physical_id
= 1;
936 memdev
->region_id
= 0;
937 memdev
->range_index
= 7+1;
938 memdev
->region_index
= 1+1;
939 memdev
->region_size
= 0;
940 memdev
->region_offset
= 0;
942 memdev
->interleave_index
= 0;
943 memdev
->interleave_ways
= 1;
945 /* mem-region12 (spa/bdw2, dimm2) */
946 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 12;
947 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
948 memdev
->header
.length
= sizeof(*memdev
);
949 memdev
->device_handle
= handle
[2];
950 memdev
->physical_id
= 2;
951 memdev
->region_id
= 0;
952 memdev
->range_index
= 8+1;
953 memdev
->region_index
= 2+1;
954 memdev
->region_size
= 0;
955 memdev
->region_offset
= 0;
957 memdev
->interleave_index
= 0;
958 memdev
->interleave_ways
= 1;
960 /* mem-region13 (spa/dcr3, dimm3) */
961 memdev
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_memory_map
) * 13;
962 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
963 memdev
->header
.length
= sizeof(*memdev
);
964 memdev
->device_handle
= handle
[3];
965 memdev
->physical_id
= 3;
966 memdev
->region_id
= 0;
967 memdev
->range_index
= 9+1;
968 memdev
->region_index
= 3+1;
969 memdev
->region_size
= 0;
970 memdev
->region_offset
= 0;
972 memdev
->interleave_index
= 0;
973 memdev
->interleave_ways
= 1;
975 offset
= offset
+ sizeof(struct acpi_nfit_memory_map
) * 14;
976 /* dcr-descriptor0: blk */
977 dcr
= nfit_buf
+ offset
;
978 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
979 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
980 dcr
->region_index
= 0+1;
981 dcr_common_init(dcr
);
982 dcr
->serial_number
= ~handle
[0];
983 dcr
->code
= NFIT_FIC_BLK
;
985 dcr
->window_size
= DCR_SIZE
;
986 dcr
->command_offset
= 0;
987 dcr
->command_size
= 8;
988 dcr
->status_offset
= 8;
989 dcr
->status_size
= 4;
991 /* dcr-descriptor1: blk */
992 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
);
993 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
994 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
995 dcr
->region_index
= 1+1;
996 dcr_common_init(dcr
);
997 dcr
->serial_number
= ~handle
[1];
998 dcr
->code
= NFIT_FIC_BLK
;
1000 dcr
->window_size
= DCR_SIZE
;
1001 dcr
->command_offset
= 0;
1002 dcr
->command_size
= 8;
1003 dcr
->status_offset
= 8;
1004 dcr
->status_size
= 4;
1006 /* dcr-descriptor2: blk */
1007 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
) * 2;
1008 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1009 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
1010 dcr
->region_index
= 2+1;
1011 dcr_common_init(dcr
);
1012 dcr
->serial_number
= ~handle
[2];
1013 dcr
->code
= NFIT_FIC_BLK
;
1015 dcr
->window_size
= DCR_SIZE
;
1016 dcr
->command_offset
= 0;
1017 dcr
->command_size
= 8;
1018 dcr
->status_offset
= 8;
1019 dcr
->status_size
= 4;
1021 /* dcr-descriptor3: blk */
1022 dcr
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_control_region
) * 3;
1023 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1024 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
1025 dcr
->region_index
= 3+1;
1026 dcr_common_init(dcr
);
1027 dcr
->serial_number
= ~handle
[3];
1028 dcr
->code
= NFIT_FIC_BLK
;
1030 dcr
->window_size
= DCR_SIZE
;
1031 dcr
->command_offset
= 0;
1032 dcr
->command_size
= 8;
1033 dcr
->status_offset
= 8;
1034 dcr
->status_size
= 4;
1036 offset
= offset
+ sizeof(struct acpi_nfit_control_region
) * 4;
1037 /* dcr-descriptor0: pmem */
1038 dcr
= nfit_buf
+ offset
;
1039 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1040 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1042 dcr
->region_index
= 4+1;
1043 dcr_common_init(dcr
);
1044 dcr
->serial_number
= ~handle
[0];
1045 dcr
->code
= NFIT_FIC_BYTEN
;
1048 /* dcr-descriptor1: pmem */
1049 dcr
= nfit_buf
+ offset
+ offsetof(struct acpi_nfit_control_region
,
1051 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1052 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1054 dcr
->region_index
= 5+1;
1055 dcr_common_init(dcr
);
1056 dcr
->serial_number
= ~handle
[1];
1057 dcr
->code
= NFIT_FIC_BYTEN
;
1060 /* dcr-descriptor2: pmem */
1061 dcr
= nfit_buf
+ offset
+ offsetof(struct acpi_nfit_control_region
,
1063 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1064 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1066 dcr
->region_index
= 6+1;
1067 dcr_common_init(dcr
);
1068 dcr
->serial_number
= ~handle
[2];
1069 dcr
->code
= NFIT_FIC_BYTEN
;
1072 /* dcr-descriptor3: pmem */
1073 dcr
= nfit_buf
+ offset
+ offsetof(struct acpi_nfit_control_region
,
1075 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1076 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1078 dcr
->region_index
= 7+1;
1079 dcr_common_init(dcr
);
1080 dcr
->serial_number
= ~handle
[3];
1081 dcr
->code
= NFIT_FIC_BYTEN
;
1084 offset
= offset
+ offsetof(struct acpi_nfit_control_region
,
1086 /* bdw0 (spa/dcr0, dimm0) */
1087 bdw
= nfit_buf
+ offset
;
1088 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1089 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1090 bdw
->region_index
= 0+1;
1093 bdw
->size
= BDW_SIZE
;
1094 bdw
->capacity
= DIMM_SIZE
;
1095 bdw
->start_address
= 0;
1097 /* bdw1 (spa/dcr1, dimm1) */
1098 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
);
1099 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1100 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1101 bdw
->region_index
= 1+1;
1104 bdw
->size
= BDW_SIZE
;
1105 bdw
->capacity
= DIMM_SIZE
;
1106 bdw
->start_address
= 0;
1108 /* bdw2 (spa/dcr2, dimm2) */
1109 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
) * 2;
1110 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1111 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1112 bdw
->region_index
= 2+1;
1115 bdw
->size
= BDW_SIZE
;
1116 bdw
->capacity
= DIMM_SIZE
;
1117 bdw
->start_address
= 0;
1119 /* bdw3 (spa/dcr3, dimm3) */
1120 bdw
= nfit_buf
+ offset
+ sizeof(struct acpi_nfit_data_region
) * 3;
1121 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1122 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1123 bdw
->region_index
= 3+1;
1126 bdw
->size
= BDW_SIZE
;
1127 bdw
->capacity
= DIMM_SIZE
;
1128 bdw
->start_address
= 0;
1130 offset
= offset
+ sizeof(struct acpi_nfit_data_region
) * 4;
1131 /* flush0 (dimm0) */
1132 flush
= nfit_buf
+ offset
;
1133 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1134 flush
->header
.length
= flush_hint_size
;
1135 flush
->device_handle
= handle
[0];
1136 flush
->hint_count
= NUM_HINTS
;
1137 for (i
= 0; i
< NUM_HINTS
; i
++)
1138 flush
->hint_address
[i
] = t
->flush_dma
[0] + i
* sizeof(u64
);
1140 /* flush1 (dimm1) */
1141 flush
= nfit_buf
+ offset
+ flush_hint_size
* 1;
1142 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1143 flush
->header
.length
= flush_hint_size
;
1144 flush
->device_handle
= handle
[1];
1145 flush
->hint_count
= NUM_HINTS
;
1146 for (i
= 0; i
< NUM_HINTS
; i
++)
1147 flush
->hint_address
[i
] = t
->flush_dma
[1] + i
* sizeof(u64
);
1149 /* flush2 (dimm2) */
1150 flush
= nfit_buf
+ offset
+ flush_hint_size
* 2;
1151 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1152 flush
->header
.length
= flush_hint_size
;
1153 flush
->device_handle
= handle
[2];
1154 flush
->hint_count
= NUM_HINTS
;
1155 for (i
= 0; i
< NUM_HINTS
; i
++)
1156 flush
->hint_address
[i
] = t
->flush_dma
[2] + i
* sizeof(u64
);
1158 /* flush3 (dimm3) */
1159 flush
= nfit_buf
+ offset
+ flush_hint_size
* 3;
1160 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1161 flush
->header
.length
= flush_hint_size
;
1162 flush
->device_handle
= handle
[3];
1163 flush
->hint_count
= NUM_HINTS
;
1164 for (i
= 0; i
< NUM_HINTS
; i
++)
1165 flush
->hint_address
[i
] = t
->flush_dma
[3] + i
* sizeof(u64
);
1167 if (t
->setup_hotplug
) {
1168 offset
= offset
+ flush_hint_size
* 4;
1169 /* dcr-descriptor4: blk */
1170 dcr
= nfit_buf
+ offset
;
1171 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1172 dcr
->header
.length
= sizeof(struct acpi_nfit_control_region
);
1173 dcr
->region_index
= 8+1;
1174 dcr_common_init(dcr
);
1175 dcr
->serial_number
= ~handle
[4];
1176 dcr
->code
= NFIT_FIC_BLK
;
1178 dcr
->window_size
= DCR_SIZE
;
1179 dcr
->command_offset
= 0;
1180 dcr
->command_size
= 8;
1181 dcr
->status_offset
= 8;
1182 dcr
->status_size
= 4;
1184 offset
= offset
+ sizeof(struct acpi_nfit_control_region
);
1185 /* dcr-descriptor4: pmem */
1186 dcr
= nfit_buf
+ offset
;
1187 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1188 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1190 dcr
->region_index
= 9+1;
1191 dcr_common_init(dcr
);
1192 dcr
->serial_number
= ~handle
[4];
1193 dcr
->code
= NFIT_FIC_BYTEN
;
1196 offset
= offset
+ offsetof(struct acpi_nfit_control_region
,
1198 /* bdw4 (spa/dcr4, dimm4) */
1199 bdw
= nfit_buf
+ offset
;
1200 bdw
->header
.type
= ACPI_NFIT_TYPE_DATA_REGION
;
1201 bdw
->header
.length
= sizeof(struct acpi_nfit_data_region
);
1202 bdw
->region_index
= 8+1;
1205 bdw
->size
= BDW_SIZE
;
1206 bdw
->capacity
= DIMM_SIZE
;
1207 bdw
->start_address
= 0;
1209 offset
= offset
+ sizeof(struct acpi_nfit_data_region
);
1210 /* spa10 (dcr4) dimm4 */
1211 spa
= nfit_buf
+ offset
;
1212 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1213 spa
->header
.length
= sizeof(*spa
);
1214 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_DCR
), 16);
1215 spa
->range_index
= 10+1;
1216 spa
->address
= t
->dcr_dma
[4];
1217 spa
->length
= DCR_SIZE
;
1220 * spa11 (single-dimm interleave for hotplug, note storage
1221 * does not actually alias the related block-data-window
1224 spa
= nfit_buf
+ offset
+ sizeof(*spa
);
1225 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1226 spa
->header
.length
= sizeof(*spa
);
1227 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
1228 spa
->range_index
= 11+1;
1229 spa
->address
= t
->spa_set_dma
[2];
1230 spa
->length
= SPA0_SIZE
;
1232 /* spa12 (bdw for dcr4) dimm4 */
1233 spa
= nfit_buf
+ offset
+ sizeof(*spa
) * 2;
1234 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1235 spa
->header
.length
= sizeof(*spa
);
1236 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_BDW
), 16);
1237 spa
->range_index
= 12+1;
1238 spa
->address
= t
->dimm_dma
[4];
1239 spa
->length
= DIMM_SIZE
;
1241 offset
= offset
+ sizeof(*spa
) * 3;
1242 /* mem-region14 (spa/dcr4, dimm4) */
1243 memdev
= nfit_buf
+ offset
;
1244 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1245 memdev
->header
.length
= sizeof(*memdev
);
1246 memdev
->device_handle
= handle
[4];
1247 memdev
->physical_id
= 4;
1248 memdev
->region_id
= 0;
1249 memdev
->range_index
= 10+1;
1250 memdev
->region_index
= 8+1;
1251 memdev
->region_size
= 0;
1252 memdev
->region_offset
= 0;
1253 memdev
->address
= 0;
1254 memdev
->interleave_index
= 0;
1255 memdev
->interleave_ways
= 1;
1257 /* mem-region15 (spa0, dimm4) */
1258 memdev
= nfit_buf
+ offset
+
1259 sizeof(struct acpi_nfit_memory_map
);
1260 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1261 memdev
->header
.length
= sizeof(*memdev
);
1262 memdev
->device_handle
= handle
[4];
1263 memdev
->physical_id
= 4;
1264 memdev
->region_id
= 0;
1265 memdev
->range_index
= 11+1;
1266 memdev
->region_index
= 9+1;
1267 memdev
->region_size
= SPA0_SIZE
;
1268 memdev
->region_offset
= t
->spa_set_dma
[2];
1269 memdev
->address
= 0;
1270 memdev
->interleave_index
= 0;
1271 memdev
->interleave_ways
= 1;
1273 /* mem-region16 (spa/bdw4, dimm4) */
1274 memdev
= nfit_buf
+ offset
+
1275 sizeof(struct acpi_nfit_memory_map
) * 2;
1276 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1277 memdev
->header
.length
= sizeof(*memdev
);
1278 memdev
->device_handle
= handle
[4];
1279 memdev
->physical_id
= 4;
1280 memdev
->region_id
= 0;
1281 memdev
->range_index
= 12+1;
1282 memdev
->region_index
= 8+1;
1283 memdev
->region_size
= 0;
1284 memdev
->region_offset
= 0;
1285 memdev
->address
= 0;
1286 memdev
->interleave_index
= 0;
1287 memdev
->interleave_ways
= 1;
1289 offset
= offset
+ sizeof(struct acpi_nfit_memory_map
) * 3;
1290 /* flush3 (dimm4) */
1291 flush
= nfit_buf
+ offset
;
1292 flush
->header
.type
= ACPI_NFIT_TYPE_FLUSH_ADDRESS
;
1293 flush
->header
.length
= flush_hint_size
;
1294 flush
->device_handle
= handle
[4];
1295 flush
->hint_count
= NUM_HINTS
;
1296 for (i
= 0; i
< NUM_HINTS
; i
++)
1297 flush
->hint_address
[i
] = t
->flush_dma
[4]
1301 post_ars_status(&t
->ars_state
, t
->spa_set_dma
[0], SPA0_SIZE
);
1303 acpi_desc
= &t
->acpi_desc
;
1304 set_bit(ND_CMD_GET_CONFIG_SIZE
, &acpi_desc
->dimm_cmd_force_en
);
1305 set_bit(ND_CMD_GET_CONFIG_DATA
, &acpi_desc
->dimm_cmd_force_en
);
1306 set_bit(ND_CMD_SET_CONFIG_DATA
, &acpi_desc
->dimm_cmd_force_en
);
1307 set_bit(ND_CMD_SMART
, &acpi_desc
->dimm_cmd_force_en
);
1308 set_bit(ND_CMD_ARS_CAP
, &acpi_desc
->bus_cmd_force_en
);
1309 set_bit(ND_CMD_ARS_START
, &acpi_desc
->bus_cmd_force_en
);
1310 set_bit(ND_CMD_ARS_STATUS
, &acpi_desc
->bus_cmd_force_en
);
1311 set_bit(ND_CMD_CLEAR_ERROR
, &acpi_desc
->bus_cmd_force_en
);
1312 set_bit(ND_CMD_SMART_THRESHOLD
, &acpi_desc
->dimm_cmd_force_en
);
1315 static void nfit_test1_setup(struct nfit_test
*t
)
1318 void *nfit_buf
= t
->nfit_buf
;
1319 struct acpi_nfit_memory_map
*memdev
;
1320 struct acpi_nfit_control_region
*dcr
;
1321 struct acpi_nfit_system_address
*spa
;
1322 struct acpi_nfit_desc
*acpi_desc
;
1325 /* spa0 (flat range with no bdw aliasing) */
1326 spa
= nfit_buf
+ offset
;
1327 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1328 spa
->header
.length
= sizeof(*spa
);
1329 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_PM
), 16);
1330 spa
->range_index
= 0+1;
1331 spa
->address
= t
->spa_set_dma
[0];
1332 spa
->length
= SPA2_SIZE
;
1334 /* virtual cd region */
1335 spa
= nfit_buf
+ sizeof(*spa
);
1336 spa
->header
.type
= ACPI_NFIT_TYPE_SYSTEM_ADDRESS
;
1337 spa
->header
.length
= sizeof(*spa
);
1338 memcpy(spa
->range_guid
, to_nfit_uuid(NFIT_SPA_VCD
), 16);
1339 spa
->range_index
= 0;
1340 spa
->address
= t
->spa_set_dma
[1];
1341 spa
->length
= SPA_VCD_SIZE
;
1343 offset
+= sizeof(*spa
) * 2;
1344 /* mem-region0 (spa0, dimm0) */
1345 memdev
= nfit_buf
+ offset
;
1346 memdev
->header
.type
= ACPI_NFIT_TYPE_MEMORY_MAP
;
1347 memdev
->header
.length
= sizeof(*memdev
);
1348 memdev
->device_handle
= 0;
1349 memdev
->physical_id
= 0;
1350 memdev
->region_id
= 0;
1351 memdev
->range_index
= 0+1;
1352 memdev
->region_index
= 0+1;
1353 memdev
->region_size
= SPA2_SIZE
;
1354 memdev
->region_offset
= 0;
1355 memdev
->address
= 0;
1356 memdev
->interleave_index
= 0;
1357 memdev
->interleave_ways
= 1;
1358 memdev
->flags
= ACPI_NFIT_MEM_SAVE_FAILED
| ACPI_NFIT_MEM_RESTORE_FAILED
1359 | ACPI_NFIT_MEM_FLUSH_FAILED
| ACPI_NFIT_MEM_HEALTH_OBSERVED
1360 | ACPI_NFIT_MEM_NOT_ARMED
;
1362 offset
+= sizeof(*memdev
);
1363 /* dcr-descriptor0 */
1364 dcr
= nfit_buf
+ offset
;
1365 dcr
->header
.type
= ACPI_NFIT_TYPE_CONTROL_REGION
;
1366 dcr
->header
.length
= offsetof(struct acpi_nfit_control_region
,
1368 dcr
->region_index
= 0+1;
1369 dcr_common_init(dcr
);
1370 dcr
->serial_number
= ~0;
1371 dcr
->code
= NFIT_FIC_BYTE
;
1374 post_ars_status(&t
->ars_state
, t
->spa_set_dma
[0], SPA2_SIZE
);
1376 acpi_desc
= &t
->acpi_desc
;
1377 set_bit(ND_CMD_ARS_CAP
, &acpi_desc
->bus_cmd_force_en
);
1378 set_bit(ND_CMD_ARS_START
, &acpi_desc
->bus_cmd_force_en
);
1379 set_bit(ND_CMD_ARS_STATUS
, &acpi_desc
->bus_cmd_force_en
);
1380 set_bit(ND_CMD_CLEAR_ERROR
, &acpi_desc
->bus_cmd_force_en
);
1383 static int nfit_test_blk_do_io(struct nd_blk_region
*ndbr
, resource_size_t dpa
,
1384 void *iobuf
, u64 len
, int rw
)
1386 struct nfit_blk
*nfit_blk
= ndbr
->blk_provider_data
;
1387 struct nfit_blk_mmio
*mmio
= &nfit_blk
->mmio
[BDW
];
1388 struct nd_region
*nd_region
= &ndbr
->nd_region
;
1391 lane
= nd_region_acquire_lane(nd_region
);
1393 memcpy(mmio
->addr
.base
+ dpa
, iobuf
, len
);
1395 memcpy(iobuf
, mmio
->addr
.base
+ dpa
, len
);
1397 /* give us some some coverage of the mmio_flush_range() API */
1398 mmio_flush_range(mmio
->addr
.base
+ dpa
, len
);
1400 nd_region_release_lane(nd_region
, lane
);
1405 static int nfit_test_probe(struct platform_device
*pdev
)
1407 struct nvdimm_bus_descriptor
*nd_desc
;
1408 struct acpi_nfit_desc
*acpi_desc
;
1409 struct device
*dev
= &pdev
->dev
;
1410 struct nfit_test
*nfit_test
;
1413 nfit_test
= to_nfit_test(&pdev
->dev
);
1416 if (nfit_test
->num_dcr
) {
1417 int num
= nfit_test
->num_dcr
;
1419 nfit_test
->dimm
= devm_kcalloc(dev
, num
, sizeof(void *),
1421 nfit_test
->dimm_dma
= devm_kcalloc(dev
, num
, sizeof(dma_addr_t
),
1423 nfit_test
->flush
= devm_kcalloc(dev
, num
, sizeof(void *),
1425 nfit_test
->flush_dma
= devm_kcalloc(dev
, num
, sizeof(dma_addr_t
),
1427 nfit_test
->label
= devm_kcalloc(dev
, num
, sizeof(void *),
1429 nfit_test
->label_dma
= devm_kcalloc(dev
, num
,
1430 sizeof(dma_addr_t
), GFP_KERNEL
);
1431 nfit_test
->dcr
= devm_kcalloc(dev
, num
,
1432 sizeof(struct nfit_test_dcr
*), GFP_KERNEL
);
1433 nfit_test
->dcr_dma
= devm_kcalloc(dev
, num
,
1434 sizeof(dma_addr_t
), GFP_KERNEL
);
1435 if (nfit_test
->dimm
&& nfit_test
->dimm_dma
&& nfit_test
->label
1436 && nfit_test
->label_dma
&& nfit_test
->dcr
1437 && nfit_test
->dcr_dma
&& nfit_test
->flush
1438 && nfit_test
->flush_dma
)
1444 if (nfit_test
->num_pm
) {
1445 int num
= nfit_test
->num_pm
;
1447 nfit_test
->spa_set
= devm_kcalloc(dev
, num
, sizeof(void *),
1449 nfit_test
->spa_set_dma
= devm_kcalloc(dev
, num
,
1450 sizeof(dma_addr_t
), GFP_KERNEL
);
1451 if (nfit_test
->spa_set
&& nfit_test
->spa_set_dma
)
1457 /* per-nfit specific alloc */
1458 if (nfit_test
->alloc(nfit_test
))
1461 nfit_test
->setup(nfit_test
);
1462 acpi_desc
= &nfit_test
->acpi_desc
;
1463 acpi_nfit_desc_init(acpi_desc
, &pdev
->dev
);
1464 acpi_desc
->blk_do_io
= nfit_test_blk_do_io
;
1465 nd_desc
= &acpi_desc
->nd_desc
;
1466 nd_desc
->provider_name
= NULL
;
1467 nd_desc
->module
= THIS_MODULE
;
1468 nd_desc
->ndctl
= nfit_test_ctl
;
1470 rc
= acpi_nfit_init(acpi_desc
, nfit_test
->nfit_buf
,
1471 nfit_test
->nfit_size
);
1475 if (nfit_test
->setup
!= nfit_test0_setup
)
1478 flush_work(&acpi_desc
->work
);
1479 nfit_test
->setup_hotplug
= 1;
1480 nfit_test
->setup(nfit_test
);
1482 rc
= acpi_nfit_init(acpi_desc
, nfit_test
->nfit_buf
,
1483 nfit_test
->nfit_size
);
1490 static int nfit_test_remove(struct platform_device
*pdev
)
1495 static void nfit_test_release(struct device
*dev
)
1497 struct nfit_test
*nfit_test
= to_nfit_test(dev
);
1502 static const struct platform_device_id nfit_test_id
[] = {
1507 static struct platform_driver nfit_test_driver
= {
1508 .probe
= nfit_test_probe
,
1509 .remove
= nfit_test_remove
,
1511 .name
= KBUILD_MODNAME
,
1513 .id_table
= nfit_test_id
,
1516 static __init
int nfit_test_init(void)
1520 nfit_test_setup(nfit_test_lookup
);
1522 for (i
= 0; i
< NUM_NFITS
; i
++) {
1523 struct nfit_test
*nfit_test
;
1524 struct platform_device
*pdev
;
1526 nfit_test
= kzalloc(sizeof(*nfit_test
), GFP_KERNEL
);
1531 INIT_LIST_HEAD(&nfit_test
->resources
);
1534 nfit_test
->num_pm
= NUM_PM
;
1535 nfit_test
->num_dcr
= NUM_DCR
;
1536 nfit_test
->alloc
= nfit_test0_alloc
;
1537 nfit_test
->setup
= nfit_test0_setup
;
1540 nfit_test
->num_pm
= 1;
1541 nfit_test
->alloc
= nfit_test1_alloc
;
1542 nfit_test
->setup
= nfit_test1_setup
;
1548 pdev
= &nfit_test
->pdev
;
1549 pdev
->name
= KBUILD_MODNAME
;
1551 pdev
->dev
.release
= nfit_test_release
;
1552 rc
= platform_device_register(pdev
);
1554 put_device(&pdev
->dev
);
1558 rc
= dma_coerce_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(64));
1562 instances
[i
] = nfit_test
;
1565 rc
= platform_driver_register(&nfit_test_driver
);
1571 for (i
= 0; i
< NUM_NFITS
; i
++)
1573 platform_device_unregister(&instances
[i
]->pdev
);
1574 nfit_test_teardown();
1578 static __exit
void nfit_test_exit(void)
1582 platform_driver_unregister(&nfit_test_driver
);
1583 for (i
= 0; i
< NUM_NFITS
; i
++)
1584 platform_device_unregister(&instances
[i
]->pdev
);
1585 nfit_test_teardown();
1588 module_init(nfit_test_init
);
1589 module_exit(nfit_test_exit
);
1590 MODULE_LICENSE("GPL v2");
1591 MODULE_AUTHOR("Intel Corporation");