From: Abdellatif El Khlifi Date: Mon, 17 Apr 2023 09:11:58 +0000 (+0100) Subject: sandbox64: add a test case for UCLASS_NVMXIP X-Git-Url: http://git.dujemihanovic.xyz/%22/img/sics.gif/%22/static/git-favicon.png?a=commitdiff_plain;h=56722fafd9b2a017930030e9b50c5784f64545db;p=u-boot.git 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 --- diff --git a/MAINTAINERS b/MAINTAINERS index fd155ca878..0257526bc8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1210,6 +1210,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 diff --git a/test/dm/Makefile b/test/dm/Makefile index e15bdbf04b..c8534b5cfa 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ # # Copyright (c) 2013 Google, Inc +# Copyright 2023 Arm Limited and/or its affiliates obj-$(CONFIG_UT_DM) += test-dm.o @@ -17,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 + * + * Authors: + * Abdellatif El Khlifi + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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);