Re: [PATCH] qfw: Allocate ACPI memory using efi logic

2022-03-11 Thread Simon Glass
Hi Alex,

On Sun, 27 Feb 2022 at 07:23, Alexander Graf  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 
> ---
>  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 
>  #endif
> +#ifdef CONFIG_EFI_LOADER
> +#include 
> +#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),
> +_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


[PATCH] qfw: Allocate ACPI memory using efi logic

2022-02-27 Thread Alexander Graf
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 
---
 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 
 #endif
+#ifdef CONFIG_EFI_LOADER
+#include 
+#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),
+_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