mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-22 20:58:22 +00:00
efi_loader: need either ACPI table or device tree
The EBBR specification prescribes that we should have either an ACPI table or a device tree but not both. Let us enforce this condition in the `bootefi` command. If the bootefi command is called without a device tree parameter use a previously device tree or fall back to the internal device tree. The fdt unit test should not be run on boards with an ACPI table. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
This commit is contained in:
parent
68066d5bcd
commit
6182495e10
2 changed files with 74 additions and 29 deletions
102
cmd/bootefi.c
102
cmd/bootefi.c
|
@ -84,6 +84,8 @@ out:
|
||||||
efi_root, NULL));
|
efi_root, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* copy_fdt() - Copy the device tree to a new location available to EFI
|
* copy_fdt() - Copy the device tree to a new location available to EFI
|
||||||
*
|
*
|
||||||
|
@ -185,6 +187,25 @@ static void efi_carve_out_dt_rsv(void *fdt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_config_table() - get configuration table
|
||||||
|
*
|
||||||
|
* @guid: GUID of the configuration table
|
||||||
|
* Return: pointer to configuration table or NULL
|
||||||
|
*/
|
||||||
|
static void *get_config_table(const efi_guid_t *guid)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < systab.nr_tables; i++) {
|
||||||
|
if (!guidcmp(guid, &systab.tables[i].guid))
|
||||||
|
return systab.tables[i].table;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* efi_install_fdt() - install fdt passed by a command argument
|
* efi_install_fdt() - install fdt passed by a command argument
|
||||||
* @fdt_opt: pointer to argument
|
* @fdt_opt: pointer to argument
|
||||||
|
@ -195,47 +216,72 @@ static void efi_carve_out_dt_rsv(void *fdt)
|
||||||
*/
|
*/
|
||||||
static efi_status_t efi_install_fdt(const char *fdt_opt)
|
static efi_status_t efi_install_fdt(const char *fdt_opt)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* The EBBR spec requires that we have either an FDT or an ACPI table
|
||||||
|
* but not both.
|
||||||
|
*/
|
||||||
|
#if CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE)
|
||||||
|
if (fdt_opt) {
|
||||||
|
printf("ERROR: can't have ACPI table and device tree.\n");
|
||||||
|
return EFI_LOAD_ERROR;
|
||||||
|
}
|
||||||
|
#else
|
||||||
unsigned long fdt_addr;
|
unsigned long fdt_addr;
|
||||||
void *fdt;
|
void *fdt;
|
||||||
bootm_headers_t img = { 0 };
|
bootm_headers_t img = { 0 };
|
||||||
efi_status_t ret;
|
efi_status_t ret;
|
||||||
|
|
||||||
if (fdt_opt) {
|
if (fdt_opt) {
|
||||||
/* Install device tree */
|
|
||||||
fdt_addr = simple_strtoul(fdt_opt, NULL, 16);
|
fdt_addr = simple_strtoul(fdt_opt, NULL, 16);
|
||||||
if (!fdt_addr && *fdt_opt != '0')
|
if (!fdt_addr)
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
fdt = map_sysmem(fdt_addr, 0);
|
|
||||||
if (fdt_check_header(fdt)) {
|
|
||||||
printf("ERROR: invalid device tree\n");
|
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
|
} else {
|
||||||
|
/* Look for device tree that is already installed */
|
||||||
|
if (get_config_table(&efi_guid_fdt))
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
/* Use our own device tree as default */
|
||||||
|
fdt_opt = env_get("fdtcontroladdr");
|
||||||
|
if (!fdt_opt) {
|
||||||
|
printf("ERROR: need device tree\n");
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
fdt_addr = simple_strtoul(fdt_opt, NULL, 16);
|
||||||
/* Create memory reservation as indicated by the device tree */
|
if (!fdt_addr) {
|
||||||
efi_carve_out_dt_rsv(fdt);
|
printf("ERROR: invalid $fdtcontroladdr\n");
|
||||||
|
|
||||||
/* Prepare fdt for payload */
|
|
||||||
ret = copy_fdt(&fdt);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (image_setup_libfdt(&img, fdt, 0, NULL)) {
|
|
||||||
printf("ERROR: failed to process device tree\n");
|
|
||||||
return EFI_LOAD_ERROR;
|
return EFI_LOAD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Link to it in the efi tables */
|
|
||||||
ret = efi_install_configuration_table(&efi_guid_fdt, fdt);
|
|
||||||
if (ret != EFI_SUCCESS) {
|
|
||||||
printf("ERROR: failed to install device tree\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Remove device tree. EFI_NOT_FOUND can be ignored here */
|
|
||||||
efi_install_configuration_table(&efi_guid_fdt, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Install device tree */
|
||||||
|
fdt = map_sysmem(fdt_addr, 0);
|
||||||
|
if (fdt_check_header(fdt)) {
|
||||||
|
printf("ERROR: invalid device tree\n");
|
||||||
|
return EFI_LOAD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create memory reservations as indicated by the device tree */
|
||||||
|
efi_carve_out_dt_rsv(fdt);
|
||||||
|
|
||||||
|
/* Prepare device tree for payload */
|
||||||
|
ret = copy_fdt(&fdt);
|
||||||
|
if (ret) {
|
||||||
|
printf("ERROR: out of memory\n");
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image_setup_libfdt(&img, fdt, 0, NULL)) {
|
||||||
|
printf("ERROR: failed to process device tree\n");
|
||||||
|
return EFI_LOAD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Install device tree as UEFI table */
|
||||||
|
ret = efi_install_configuration_table(&efi_guid_fdt, fdt);
|
||||||
|
if (ret != EFI_SUCCESS) {
|
||||||
|
printf("ERROR: failed to install device tree\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* GENERATE_ACPI_TABLE */
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ efi_selftest_events.o \
|
||||||
efi_selftest_event_groups.o \
|
efi_selftest_event_groups.o \
|
||||||
efi_selftest_exception.o \
|
efi_selftest_exception.o \
|
||||||
efi_selftest_exitbootservices.o \
|
efi_selftest_exitbootservices.o \
|
||||||
efi_selftest_fdt.o \
|
|
||||||
efi_selftest_gop.o \
|
efi_selftest_gop.o \
|
||||||
efi_selftest_loaded_image.o \
|
efi_selftest_loaded_image.o \
|
||||||
efi_selftest_manageprotocols.o \
|
efi_selftest_manageprotocols.o \
|
||||||
|
|
Loading…
Add table
Reference in a new issue