[PATCH] qfw: Allocate ACPI memory using efi logic

Simon Glass sjg at chromium.org
Sat Mar 12 03:25:11 CET 2022


Hi Alex,

On Sun, 27 Feb 2022 at 07:23, Alexander Graf <agraf at csgraf.de> wrote:
>
> When we allocate ACPI tables dynamically as part of the qfw ACPI loading
> code and then later want to boot a UEFI target using them, we need to make
> sure that the UEFI logic is aware that these memory regions are ACPI, so
> that the loading kernel can mark them as reserved.
>
> Since we'll never see alignment requirements more than a page, let's just
> use efi_allocate_pages when we see high memory allocation requests in a
> UEFI enabled environment. Even if we then boot using the native zImage
> later, the memory allocation will still be valid.
>
> Without this patch, Linux will refuse to consume the DSDT when passed from
> qfw's ACPI framework. With this patch, it happily uses it.
>
> Signed-off-by: Alexander Graf <agraf at csgraf.de>
> ---
>  drivers/misc/qfw.c | 17 ++++++++++++++++-
>  1 file changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c
> index 754bc6a603..7c6ed41f48 100644
> --- a/drivers/misc/qfw.c
> +++ b/drivers/misc/qfw.c
> @@ -18,6 +18,9 @@
>  #if defined(CONFIG_GENERATE_ACPI_TABLE) && !defined(CONFIG_ARM)
>  #include <asm/tables.h>
>  #endif
> +#ifdef CONFIG_EFI_LOADER
> +#include <efi_loader.h>
> +#endif
>
>  #if defined(CONFIG_GENERATE_ACPI_TABLE) && !defined(CONFIG_SANDBOX)
>  /*
> @@ -35,7 +38,7 @@ static int bios_linker_allocate(struct udevice *dev,
>  {
>         uint32_t size, align;
>         struct fw_file *file;
> -       unsigned long aligned_addr;
> +       unsigned long aligned_addr = 0;
>
>         align = le32_to_cpu(entry->alloc.align);
>         /* align must be power of 2 */
> @@ -59,7 +62,19 @@ static int bios_linker_allocate(struct udevice *dev,
>          * in which is low memory
>          */
>         if (entry->alloc.zone == BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH) {
> +#ifdef CONFIG_EFI_LOADER
> +               efi_status_t ret;
> +               u64 efi_addr = 1ULL << 32;
> +
> +               ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
> +                                        EFI_ACPI_RECLAIM_MEMORY,
> +                                        efi_size_in_pages(size),
> +                                        &efi_addr);
> +               if (ret == EFI_SUCCESS)
> +                       aligned_addr = efi_addr;
> +#else
>                 aligned_addr = (unsigned long)memalign(align, size);
> +#endif
>                 if (!aligned_addr) {
>                         printf("error: allocating resource\n");
>                         return -ENOMEM;
> --
> 2.32.0
>

The tables are normally created on start-up, before the command line
starts, so we can examine them in U-Boot.

It is a terrible idea fo call efi_allocate_pages() in code like this.
and the #ifdef as well. Ick!!

You can put ACPI tables in a bloblist so they are continguous and then
the EFI code can present the bloblist as reserved to Linux.

See coral, which does this.

Regards,
Simon


More information about the U-Boot mailing list