[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