]> Git Repo - u-boot.git/blob - test/dm/nvmxip.c
537959a0930caf8d76f15075470910e7b3ffd23e
[u-boot.git] / test / dm / nvmxip.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Functional tests for UCLASS_FFA  class
4  *
5  * Copyright 2023 Arm Limited and/or its affiliates <[email protected]>
6  *
7  * Authors:
8  *   Abdellatif El Khlifi <[email protected]>
9  */
10
11 #include <blk.h>
12 #include <console.h>
13 #include <dm.h>
14 #include <mapmem.h>
15 #include <dm/test.h>
16 #include <linux/bitops.h>
17 #include <test/test.h>
18 #include <test/ut.h>
19 #include <nvmxip.h>
20
21 /* NVMXIP devices described in the device tree */
22 #define SANDBOX_NVMXIP_DEVICES 2
23
24 /* reference device tree data for the probed devices */
25 static struct nvmxip_plat nvmqspi_refdata[SANDBOX_NVMXIP_DEVICES] = {
26         {0x08000000, 9, 4096}, {0x08200000, 9, 2048}
27 };
28
29 #define NVMXIP_BLK_START_PATTERN 0x1122334455667788ULL
30 #define NVMXIP_BLK_END_PATTERN 0xa1a2a3a4a5a6a7a8ULL
31
32 /**
33  * dm_nvmxip_flash_sanity() - check flash data
34  * @uts: test state
35  * @device_idx: the NVMXIP device index
36  * @buffer:     the user buffer where the blocks data is copied to
37  *
38  * Mode 1: When buffer is NULL, initialize the flash with pattern data at the start
39  * and at the end of each block. This pattern data will be used to check data consistency
40  * when verifying the data read.
41  * Mode 2: When the user buffer is provided in the argument (not NULL), compare the data
42  * of the start and the end of each block in the user buffer with the expected pattern data.
43  * Return an error when the check fails.
44  *
45  * Return:
46  *
47  * 0 on success. Otherwise, failure
48  */
49 static int dm_nvmxip_flash_sanity(struct unit_test_state *uts, u8 device_idx, void *buffer)
50 {
51         int i;
52         u64 *ptr;
53         u8 *base;
54         unsigned long blksz;
55
56         blksz = BIT(nvmqspi_refdata[device_idx].lba_shift);
57
58         if (!buffer) {
59                 /* Mode 1: point at the flash start address. Pattern data will be written */
60                 base = map_sysmem(nvmqspi_refdata[device_idx].phys_base, 0);
61         } else {
62                 /* Mode 2: point at the user buffer containing the data read and to be verified */
63                 base = buffer;
64         }
65
66         for (i = 0; i < nvmqspi_refdata[device_idx].lba ; i++) {
67                 ptr = (u64 *)(base + i * blksz);
68
69                 /* write an 8 bytes pattern at the start of the current block */
70                 if (!buffer)
71                         *ptr = NVMXIP_BLK_START_PATTERN;
72                 else
73                         ut_asserteq_64(NVMXIP_BLK_START_PATTERN, *ptr);
74
75                 ptr = (u64 *)((u8 *)ptr + blksz - sizeof(u64));
76
77                 /* write an 8 bytes pattern at the end of the current block */
78                 if (!buffer)
79                         *ptr = NVMXIP_BLK_END_PATTERN;
80                 else
81                         ut_asserteq_64(NVMXIP_BLK_END_PATTERN, *ptr);
82         }
83
84         if (!buffer)
85                 unmap_sysmem(base);
86
87         return 0;
88 }
89
90 /**
91  * dm_test_nvmxip() - check flash data
92  * @uts: test state
93  * Return:
94  *
95  * CMD_RET_SUCCESS on success. Otherwise, failure
96  */
97 static int dm_test_nvmxip(struct unit_test_state *uts)
98 {
99         struct nvmxip_plat *plat_data = NULL;
100         struct udevice *dev = NULL, *bdev = NULL;
101         u8 device_idx;
102         void *buffer = NULL;
103         unsigned long flashsz;
104
105         sandbox_set_enable_memio(true);
106
107         /* set the flash content first for both devices */
108         dm_nvmxip_flash_sanity(uts, 0, NULL);
109         dm_nvmxip_flash_sanity(uts, 1, NULL);
110
111         /* probing all NVM XIP QSPI devices */
112         for (device_idx = 0, uclass_first_device(UCLASS_NVMXIP, &dev);
113              dev;
114              uclass_next_device(&dev), device_idx++) {
115                 plat_data = dev_get_plat(dev);
116
117                 /* device tree entries checks */
118                 ut_assertok(nvmqspi_refdata[device_idx].phys_base != plat_data->phys_base);
119                 ut_assertok(nvmqspi_refdata[device_idx].lba_shift != plat_data->lba_shift);
120                 ut_assertok(nvmqspi_refdata[device_idx].lba != plat_data->lba);
121
122                 /* before reading all the flash blocks, let's calculate the flash size */
123                 flashsz = plat_data->lba << plat_data->lba_shift;
124
125                 /* allocate the user buffer where to copy the blocks data to */
126                 buffer = calloc(flashsz, 1);
127                 ut_assertok(!buffer);
128
129                 /* the block device is the child of the parent device probed with DT */
130                 ut_assertok(device_find_first_child(dev, &bdev));
131
132                 /* reading all the flash blocks */
133                 ut_asserteq(plat_data->lba, blk_read(bdev, 0, plat_data->lba, buffer));
134
135                 /* compare the data read from flash with the expected data */
136                 dm_nvmxip_flash_sanity(uts, device_idx, buffer);
137
138                 free(buffer);
139         }
140
141         ut_assertok(device_idx != SANDBOX_NVMXIP_DEVICES);
142
143         return CMD_RET_SUCCESS;
144 }
145
146 DM_TEST(dm_test_nvmxip, UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC);
This page took 0.021987 seconds and 2 git commands to generate.