[U-Boot] [PATCH v2 11/11] efi_selftest: check installation of the device tree
Simon Glass
sjg at chromium.org
Fri Mar 23 14:30:31 UTC 2018
Hi Heinrich,
On 15 February 2018 at 00:31, Heinrich Schuchardt <xypron.glpk at gmx.de> wrote:
> The unit test checks if a device tree is installed. It requires that the
> 'compatible' property of the root node exists. If available it prints the
> 'serial-number' property.
>
> The serial-number property is derived from the environment variable
> 'serial#'. This can be used to check if the image_setup_libfdt() function
> is executed.
>
> A Python test is supplied. It sets a value for serial# and checks that the
> selftest shows this as serial-number.
>
> Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
> ---
> v2
> new patch
> ---
> lib/efi_selftest/Makefile | 1 +
> lib/efi_selftest/efi_selftest_fdt.c | 188 ++++++++++++++++++++++++++++++++++++
> test/py/tests/test_efi_selftest.py | 14 +++
> 3 files changed, 203 insertions(+)
> create mode 100644 lib/efi_selftest/efi_selftest_fdt.c
>
> diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
> index c4bdbdf6c05..88c44840d52 100644
> --- a/lib/efi_selftest/Makefile
> +++ b/lib/efi_selftest/Makefile
> @@ -19,6 +19,7 @@ efi_selftest_console.o \
> efi_selftest_devicepath.o \
> efi_selftest_events.o \
> efi_selftest_exitbootservices.o \
> +efi_selftest_fdt.o \
> efi_selftest_gop.o \
> efi_selftest_manageprotocols.o \
> efi_selftest_snp.o \
> diff --git a/lib/efi_selftest/efi_selftest_fdt.c b/lib/efi_selftest/efi_selftest_fdt.c
> new file mode 100644
> index 00000000000..24db0dcf7d5
> --- /dev/null
> +++ b/lib/efi_selftest/efi_selftest_fdt.c
> @@ -0,0 +1,188 @@
> +/*
> + * efi_selftest_pos
> + *
> + * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk at gmx.de>
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + *
> + * Test the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
> + *
> + * The following services are tested:
> + * OutputString, TestString, SetAttribute.
> + */
> +
> +#include <efi_selftest.h>
> +#include <libfdt.h>
> +
> +static struct efi_boot_services *boottime;
> +static const char *fdt;
> +
> +/* This should be sufficent for */
> +#define BUFFERSIZE 0x100000
> +
> +static efi_guid_t fdt_guid = EFI_FDT_GUID;
> +
> +/*
> + * Convert FDT value to host endianness.
> + *
> + * @val FDT value
> + * @return converted value
> + */
> +static uint32_t f2h(fdt32_t val)
fdt32_to_cpu() ?
> +{
> + char *buf = (char *)&val;
> + char i;
> +
> +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
> + /* Swap the bytes */
> + i = buf[0]; buf[0] = buf[3]; buf[3] = i;
> + i = buf[1]; buf[1] = buf[2]; buf[2] = i;
> +#endif
> + return *(uint32_t *)buf;
> +}
> +
> +/*
> + * Return the value of a property of the FDT root node.
> + *
> + * @name name of the property
> + * @return value of the property
> + */
> +static char *get_property(const u16 *property)
We should use libfdt here as it already has this implementation.
[..]
> +/*
> + * Setup unit test.
> + *
> + * @handle: handle of the loaded image
> + * @systable: system table
> + * @return: EFI_ST_SUCCESS for success
> + */
> +static int setup(const efi_handle_t img_handle,
> + const struct efi_system_table *systable)
> +{
> + efi_uintn_t i;
> +
> + boottime = systable->boottime;
> +
> + /* Find configuration tables */
> + for (i = 0; i < systable->nr_tables; ++i) {
> + if (!efi_st_memcmp(&systable->tables[i].guid, &fdt_guid,
> + sizeof(efi_guid_t)))
> + fdt = systable->tables[i].table;
> + }
> + if (!fdt) {
> + efi_st_error("Missing device tree\n");
> + return EFI_ST_FAILURE;
> + }
> +
> + return EFI_ST_SUCCESS;
> +}
> +
> +/*
> + * Execute unit test.
> + *
> + * @return: EFI_ST_SUCCESS for success
> + */
> +static int execute(void)
> +{
> + char *str;
> + efi_status_t ret;
> +
> + str = get_property(L"compatible");
Why do we use unicode for the property name?
> + if (str) {
> + efi_st_printf("compatible: %s\n", str);
> + ret = boottime->free_pool(str);
> + if (ret != EFI_SUCCESS) {
> + efi_st_error("FreePool failed\n");
> + return EFI_ST_FAILURE;
> + }
> + } else {
> + efi_st_printf("Missing property 'compatible'\n");
> + return EFI_ST_FAILURE;
> + }
> + str = get_property(L"serial-number");
> + if (str) {
> + efi_st_printf("serial-number: %s\n", str);
> + ret = boottime->free_pool(str);
> + if (ret != EFI_SUCCESS) {
> + efi_st_error("FreePool failed\n");
> + return EFI_ST_FAILURE;
> + }
> + }
> +
> + return EFI_ST_SUCCESS;
> +}
> +
> +EFI_UNIT_TEST(fdt) = {
> + .name = "device tree",
> + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
> + .setup = setup,
> + .execute = execute,
> + .on_request = true,
> +};
> diff --git a/test/py/tests/test_efi_selftest.py b/test/py/tests/test_efi_selftest.py
> index 66b799bed66..b1ef6bd5811 100644
> --- a/test/py/tests/test_efi_selftest.py
> +++ b/test/py/tests/test_efi_selftest.py
> @@ -24,6 +24,20 @@ def test_efi_selftest(u_boot_console):
> raise Exception('Reset failed during the EFI selftest')
> u_boot_console.restart_uboot();
>
> + at pytest.mark.buildconfigspec('cmd_bootefi_selftest')
> + at pytest.mark.buildconfigspec('of_control')
> +def test_efi_selftest_device_tree(u_boot_console):
> + u_boot_console.run_command(cmd='setenv efi_selftest list')
> + output = u_boot_console.run_command('bootefi selftest')
> + assert '\'device tree\'' in output
> + u_boot_console.run_command(cmd='setenv efi_selftest device tree')
> + u_boot_console.run_command(cmd='setenv -f serial# Testing DT')
> + u_boot_console.run_command(cmd='bootefi selftest ${fdtcontroladdr}', wait_for_prompt=False)
> + m = u_boot_console.p.expect(['serial-number: Testing DT', 'U-Boot'])
Looks like a good test for this feature.
> + if m != 0:
> + raise Exception('Reset failed in \'device tree\' test')
> + u_boot_console.restart_uboot();
> +
> @pytest.mark.buildconfigspec('cmd_bootefi_selftest')
> def test_efi_selftest_watchdog_reboot(u_boot_console):
> u_boot_console.run_command(cmd='setenv efi_selftest list')
> --
> 2.15.1
>
Regards,
Simon
More information about the U-Boot
mailing list