blob: 537959a0930caf8d76f15075470910e7b3ffd23e [file] [log] [blame]
Abdellatif El Khlifie1ab9902023-04-17 10:11:58 +01001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Functional tests for UCLASS_FFA class
4 *
5 * Copyright 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
6 *
7 * Authors:
8 * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
9 */
10
Abdellatif El Khlifie1ab9902023-04-17 10:11:58 +010011#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>
Rui Miguel Silvad5cf7a02023-06-12 09:09:16 +010019#include <nvmxip.h>
Abdellatif El Khlifie1ab9902023-04-17 10:11:58 +010020
21/* NVMXIP devices described in the device tree */
22#define SANDBOX_NVMXIP_DEVICES 2
23
24/* reference device tree data for the probed devices */
25static 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 */
49static 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 */
97static 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
Marek Vasuta78f3b42023-08-23 02:18:20 +0200105 sandbox_set_enable_memio(true);
106
Abdellatif El Khlifie1ab9902023-04-17 10:11:58 +0100107 /* 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
146DM_TEST(dm_test_nvmxip, UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC);