| From 0ecb61da60febc66e589d6fbf439478af1c88283 Mon Sep 17 00:00:00 2001 |
| From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> |
| Date: Mon, 12 Jun 2023 17:33:54 +0100 |
| Subject: [PATCH 32/42] sandbox64: add a test case for UCLASS_NVMXIP |
| |
| provide a test for NVM XIP devices |
| |
| The test case allows to make sure of the following: |
| |
| - The NVM XIP QSPI devices are probed |
| - The DT entries are read correctly |
| - the data read from the flash by the NVMXIP block driver is correct |
| |
| Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> |
| Upstream-Status: Backport [https://github.com/u-boot/u-boot/commit/c9c2c95d4cd27fe0cd41fe13a863899d268f973c] |
| |
| Changelog: |
| =============== |
| |
| v2: |
| |
| * address nits |
| --- |
| MAINTAINERS | 1 + |
| test/dm/Makefile | 6 +- |
| test/dm/nvmxip.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++ |
| 3 files changed, 151 insertions(+), 1 deletion(-) |
| create mode 100644 test/dm/nvmxip.c |
| |
| diff --git a/MAINTAINERS b/MAINTAINERS |
| index f81654346e..6692ce9974 100644 |
| --- a/MAINTAINERS |
| +++ b/MAINTAINERS |
| @@ -1208,6 +1208,7 @@ S: Maintained |
| F: doc/develop/driver-model/nvmxip.rst |
| F: doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt |
| F: drivers/mtd/nvmxip/ |
| +F: test/dm/nvmxip.c |
| |
| NVMEM |
| M: Sean Anderson <seanga2@gmail.com> |
| diff --git a/test/dm/Makefile b/test/dm/Makefile |
| index 85e99e1c12..963fa927f7 100644 |
| --- a/test/dm/Makefile |
| +++ b/test/dm/Makefile |
| @@ -1,7 +1,7 @@ |
| # SPDX-License-Identifier: GPL-2.0+ |
| # |
| # Copyright (c) 2013 Google, Inc |
| -# (C) Copyright 2022 ARM Limited |
| +# Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> |
| |
| obj-$(CONFIG_UT_DM) += test-dm.o |
| |
| @@ -18,6 +18,10 @@ obj-$(CONFIG_UT_DM) += test-uclass.o |
| obj-$(CONFIG_UT_DM) += core.o |
| obj-$(CONFIG_UT_DM) += read.o |
| obj-$(CONFIG_UT_DM) += phys2bus.o |
| +ifeq ($(CONFIG_NVMXIP_QSPI)$(CONFIG_SANDBOX64),yy) |
| +obj-y += nvmxip.o |
| +endif |
| + |
| ifneq ($(CONFIG_SANDBOX),) |
| ifeq ($(CONFIG_ACPIGEN),y) |
| obj-y += acpi.o |
| diff --git a/test/dm/nvmxip.c b/test/dm/nvmxip.c |
| new file mode 100644 |
| index 0000000000..e934748eb5 |
| --- /dev/null |
| +++ b/test/dm/nvmxip.c |
| @@ -0,0 +1,145 @@ |
| +// SPDX-License-Identifier: GPL-2.0+ |
| +/* |
| + * Functional tests for UCLASS_FFA class |
| + * |
| + * Copyright 2023 Arm Limited and/or its affiliates <open-source-office@arm.com> |
| + * |
| + * Authors: |
| + * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> |
| + */ |
| + |
| +#include <common.h> |
| +#include <blk.h> |
| +#include <console.h> |
| +#include <dm.h> |
| +#include <mapmem.h> |
| +#include <dm/test.h> |
| +#include <linux/bitops.h> |
| +#include <test/test.h> |
| +#include <test/ut.h> |
| +#include "../../drivers/mtd/nvmxip/nvmxip.h" |
| + |
| +/* NVMXIP devices described in the device tree */ |
| +#define SANDBOX_NVMXIP_DEVICES 2 |
| + |
| +/* reference device tree data for the probed devices */ |
| +static struct nvmxip_plat nvmqspi_refdata[SANDBOX_NVMXIP_DEVICES] = { |
| + {0x08000000, 9, 4096}, {0x08200000, 9, 2048} |
| +}; |
| + |
| +#define NVMXIP_BLK_START_PATTERN 0x1122334455667788ULL |
| +#define NVMXIP_BLK_END_PATTERN 0xa1a2a3a4a5a6a7a8ULL |
| + |
| +/** |
| + * dm_nvmxip_flash_sanity() - check flash data |
| + * @uts: test state |
| + * @device_idx: the NVMXIP device index |
| + * @buffer: the user buffer where the blocks data is copied to |
| + * |
| + * Mode 1: When buffer is NULL, initialize the flash with pattern data at the start |
| + * and at the end of each block. This pattern data will be used to check data consistency |
| + * when verifying the data read. |
| + * Mode 2: When the user buffer is provided in the argument (not NULL), compare the data |
| + * of the start and the end of each block in the user buffer with the expected pattern data. |
| + * Return an error when the check fails. |
| + * |
| + * Return: |
| + * |
| + * 0 on success. Otherwise, failure |
| + */ |
| +static int dm_nvmxip_flash_sanity(struct unit_test_state *uts, u8 device_idx, void *buffer) |
| +{ |
| + int i; |
| + u64 *ptr; |
| + u8 *base; |
| + unsigned long blksz; |
| + |
| + blksz = BIT(nvmqspi_refdata[device_idx].lba_shift); |
| + |
| + if (!buffer) { |
| + /* Mode 1: point at the flash start address. Pattern data will be written */ |
| + base = map_sysmem(nvmqspi_refdata[device_idx].phys_base, 0); |
| + } else { |
| + /* Mode 2: point at the user buffer containing the data read and to be verified */ |
| + base = buffer; |
| + } |
| + |
| + for (i = 0; i < nvmqspi_refdata[device_idx].lba ; i++) { |
| + ptr = (u64 *)(base + i * blksz); |
| + |
| + /* write an 8 bytes pattern at the start of the current block */ |
| + if (!buffer) |
| + *ptr = NVMXIP_BLK_START_PATTERN; |
| + else |
| + ut_asserteq_64(NVMXIP_BLK_START_PATTERN, *ptr); |
| + |
| + ptr = (u64 *)((u8 *)ptr + blksz - sizeof(u64)); |
| + |
| + /* write an 8 bytes pattern at the end of the current block */ |
| + if (!buffer) |
| + *ptr = NVMXIP_BLK_END_PATTERN; |
| + else |
| + ut_asserteq_64(NVMXIP_BLK_END_PATTERN, *ptr); |
| + } |
| + |
| + if (!buffer) |
| + unmap_sysmem(base); |
| + |
| + return 0; |
| +} |
| + |
| +/** |
| + * dm_test_nvmxip() - check flash data |
| + * @uts: test state |
| + * Return: |
| + * |
| + * CMD_RET_SUCCESS on success. Otherwise, failure |
| + */ |
| +static int dm_test_nvmxip(struct unit_test_state *uts) |
| +{ |
| + struct nvmxip_plat *plat_data = NULL; |
| + struct udevice *dev = NULL, *bdev = NULL; |
| + u8 device_idx; |
| + void *buffer = NULL; |
| + unsigned long flashsz; |
| + |
| + /* set the flash content first for both devices */ |
| + dm_nvmxip_flash_sanity(uts, 0, NULL); |
| + dm_nvmxip_flash_sanity(uts, 1, NULL); |
| + |
| + /* probing all NVM XIP QSPI devices */ |
| + for (device_idx = 0, uclass_first_device(UCLASS_NVMXIP, &dev); |
| + dev; |
| + uclass_next_device(&dev), device_idx++) { |
| + plat_data = dev_get_plat(dev); |
| + |
| + /* device tree entries checks */ |
| + ut_assertok(nvmqspi_refdata[device_idx].phys_base != plat_data->phys_base); |
| + ut_assertok(nvmqspi_refdata[device_idx].lba_shift != plat_data->lba_shift); |
| + ut_assertok(nvmqspi_refdata[device_idx].lba != plat_data->lba); |
| + |
| + /* before reading all the flash blocks, let's calculate the flash size */ |
| + flashsz = plat_data->lba << plat_data->lba_shift; |
| + |
| + /* allocate the user buffer where to copy the blocks data to */ |
| + buffer = calloc(flashsz, 1); |
| + ut_assertok(!buffer); |
| + |
| + /* the block device is the child of the parent device probed with DT */ |
| + ut_assertok(device_find_first_child(dev, &bdev)); |
| + |
| + /* reading all the flash blocks */ |
| + ut_asserteq(plat_data->lba, blk_read(bdev, 0, plat_data->lba, buffer)); |
| + |
| + /* compare the data read from flash with the expected data */ |
| + dm_nvmxip_flash_sanity(uts, device_idx, buffer); |
| + |
| + free(buffer); |
| + } |
| + |
| + ut_assertok(device_idx != SANDBOX_NVMXIP_DEVICES); |
| + |
| + return CMD_RET_SUCCESS; |
| +} |
| + |
| +DM_TEST(dm_test_nvmxip, UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC); |
| -- |
| 2.25.1 |
| |