efi_selftest: merge FDT and RISC-V tests

The test for the RISCV_EFI_BOOT_PROTOCOL retrieves the boot hart id via the
protocol and compares it to the value of the boot hart id in the device
tree. The boot hart id is already retrieved from the device tree in the FDT
test.

Merge the two tests to avoid code duplication.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
This commit is contained in:
Heinrich Schuchardt 2022-02-05 08:45:55 +01:00
parent 8efefcec00
commit b9b4cecf9b
3 changed files with 57 additions and 135 deletions

View file

@ -64,7 +64,6 @@ obj-$(CONFIG_EFI_LOADER_HII) += efi_selftest_hii.o
obj-$(CONFIG_EFI_RNG_PROTOCOL) += efi_selftest_rng.o
obj-$(CONFIG_EFI_GET_TIME) += efi_selftest_rtc.o
obj-$(CONFIG_EFI_TCG2_PROTOCOL) += efi_selftest_tcg2.o
obj-$(CONFIG_EFI_RISCV_BOOT_PROTOCOL) += efi_selftest_riscv.o
ifeq ($(CONFIG_GENERATE_ACPI_TABLE),)
obj-y += efi_selftest_fdt.o

View file

@ -1,15 +1,14 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* efi_selftest_pos
* efi_selftest_fdt
*
* Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
* Copyright (c) 2022 Ventana Micro Systems Inc
*
* Test the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
*
* The following services are tested:
* OutputString, TestString, SetAttribute.
* Check the device tree, test the RISCV_EFI_BOOT_PROTOCOL.
*/
#include <efi_riscv.h>
#include <efi_selftest.h>
#include <linux/libfdt.h>
@ -22,6 +21,8 @@ static const char *fdt;
static const efi_guid_t fdt_guid = EFI_FDT_GUID;
static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID;
static const efi_guid_t riscv_efi_boot_protocol_guid =
RISCV_EFI_BOOT_PROTOCOL_GUID;
/**
* f2h() - convert FDT value to host endianness.
@ -189,6 +190,29 @@ static int setup(const efi_handle_t img_handle,
return EFI_ST_SUCCESS;
}
__maybe_unused static efi_status_t get_boot_hartid(efi_uintn_t *efi_hartid)
{
efi_status_t ret;
struct riscv_efi_boot_protocol *prot;
/* Get RISC-V boot protocol */
ret = boottime->locate_protocol(&riscv_efi_boot_protocol_guid, NULL,
(void **)&prot);
if (ret != EFI_SUCCESS) {
efi_st_error("RISC-V Boot Protocol not available\n");
return EFI_ST_FAILURE;
}
/* Get boot hart ID from EFI protocol */
ret = prot->get_boot_hartid(prot, efi_hartid);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not retrieve boot hart ID\n");
return EFI_ST_FAILURE;
}
return EFI_ST_SUCCESS;
}
/*
* Execute unit test.
*
@ -220,19 +244,37 @@ static int execute(void)
return EFI_ST_FAILURE;
}
}
str = get_property(u"boot-hartid", u"chosen");
if (IS_ENABLED(CONFIG_RISCV)) {
if (str) {
efi_st_printf("boot-hartid: %u\n",
f2h(*(fdt32_t *)str));
ret = boottime->free_pool(str);
if (ret != EFI_SUCCESS) {
efi_st_error("FreePool failed\n");
u32 fdt_hartid;
str = get_property(u"boot-hartid", u"chosen");
if (!str) {
efi_st_error("boot-hartid missing in devicetree\n");
return EFI_ST_FAILURE;
}
fdt_hartid = f2h(*(fdt32_t *)str);
efi_st_printf("boot-hartid: %u\n", fdt_hartid);
ret = boottime->free_pool(str);
if (ret != EFI_SUCCESS) {
efi_st_error("FreePool failed\n");
return EFI_ST_FAILURE;
}
if (IS_ENABLED(CONFIG_EFI_RISCV_BOOT_PROTOCOL)) {
efi_uintn_t efi_hartid;
int r;
r = get_boot_hartid(&efi_hartid);
if (r != EFI_ST_SUCCESS)
return r;
/* Boot hart ID should be same */
if (efi_hartid != fdt_hartid) {
efi_st_error("boot-hartid differs: prot 0x%p, DT 0x%.8x\n",
(void *)(uintptr_t)efi_hartid,
fdt_hartid);
return EFI_ST_FAILURE;
}
} else {
efi_st_error("boot-hartid not found\n");
return EFI_ST_FAILURE;
}
}

View file

@ -1,119 +0,0 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* efi_selftest_riscv
*
* Copyright (c) 2022 Ventana Micro Systems Inc
*
* Test the RISCV_EFI_BOOT_PROTOCOL.
*
* The following services are tested:
* get_boot_hartid
*/
#include <efi_selftest.h>
#include <efi_riscv.h>
#include <linux/libfdt.h>
static const struct efi_system_table *systemtab;
static const struct efi_boot_services *boottime;
static const char *fdt;
static const efi_guid_t riscv_efi_boot_protocol_guid = RISCV_EFI_BOOT_PROTOCOL_GUID;
static const efi_guid_t fdt_guid = EFI_FDT_GUID;
/**
* efi_st_get_config_table() - get configuration table
*
* @guid: GUID of the configuration table
* Return: pointer to configuration table or NULL
*/
static void *efi_st_get_config_table(const efi_guid_t *guid)
{
size_t i;
for (i = 0; i < systab.nr_tables; i++) {
if (!guidcmp(guid, &systemtab->tables[i].guid))
return systemtab->tables[i].table;
}
return NULL;
}
/*
* 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)
{
systemtab = systable;
boottime = systable->boottime;
fdt = efi_st_get_config_table(&fdt_guid);
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)
{
efi_status_t ret;
struct riscv_efi_boot_protocol *prot;
efi_uintn_t efi_hartid, fdt_hartid;
int chosen_node, len;
const fdt32_t *prop;
/* Get riscv boot protocol */
ret = boottime->locate_protocol(&riscv_efi_boot_protocol_guid, NULL,
(void **)&prot);
if (ret != EFI_SUCCESS) {
efi_st_error("RISC-V Boot Protocol not available\n");
return EFI_ST_FAILURE;
}
/* Get Boot Hart ID from EFI protocol */
ret = prot->get_boot_hartid(prot, &efi_hartid);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not retrieve boot hart ID\n");
return EFI_ST_FAILURE;
}
/* Get Boot Hart ID from FDT */
chosen_node = fdt_path_offset(fdt, "/chosen");
if (chosen_node < 0) {
efi_st_error("/chosen node not found\n");
return EFI_ST_FAILURE;
}
prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid", &len);
if (!prop || len != sizeof(u32)) {
efi_st_error("boot-hartid not found\n");
return EFI_ST_FAILURE;
}
fdt_hartid = fdt32_to_cpu(*prop);
/* Boot Hart ID should be same */
if (efi_hartid != fdt_hartid) {
efi_st_error("boot-hartid is not same in EFI and FDT\n");
return EFI_ST_FAILURE;
}
return EFI_ST_SUCCESS;
}
EFI_UNIT_TEST(riscv) = {
.name = "riscv",
.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
.setup = setup,
.execute = execute,
};