On Sat, Apr 10, 2021 at 01:03:55PM +0200, Ahmad Fatoum wrote:
> iomem was so far unimplemented for EFI, because barebox didn't know what
> to put there as the UEFI implementation does the heavy lifting.
> 
> Add an initcall that uses the EFI get_memory_map entry point to
> remedy this.
> 
> Signed-off-by: Ahmad Fatoum <[email protected]>
> ---
>  arch/x86/mach-efi/elf_x86_64_efi.lds.S |   3 +
>  common/efi/Makefile                    |   1 +
>  common/efi/efi-iomem.c                 | 175 +++++++++++++++++++++++++
>  common/memory.c                        |   2 +-
>  include/efi.h                          |   9 ++
>  5 files changed, 189 insertions(+), 1 deletion(-)
>  create mode 100644 common/efi/efi-iomem.c

Applied, thanks

Sascha

> 
> diff --git a/arch/x86/mach-efi/elf_x86_64_efi.lds.S 
> b/arch/x86/mach-efi/elf_x86_64_efi.lds.S
> index ed79118a3615..ab4a9e815c00 100644
> --- a/arch/x86/mach-efi/elf_x86_64_efi.lds.S
> +++ b/arch/x86/mach-efi/elf_x86_64_efi.lds.S
> @@ -42,6 +42,7 @@ SECTIONS
>               *(.got.plt)
>               *(.got)
>               *(.data*)
> +             __bss_start = .;
>               *(.sdata)
>               /* the EFI loader doesn't seem to like a .bss section, so we 
> stick
>                * it all into .data: */
> @@ -51,7 +52,9 @@ SECTIONS
>               *(.bss)
>               *(COMMON)
>               *(.rel.local)
> +             __bss_stop = .;
>       }
> +     _edata = .;
>  
>       . = ALIGN(4096);
>       .dynamic : { *(.dynamic) }
> diff --git a/common/efi/Makefile b/common/efi/Makefile
> index ef19969f93d5..d746fabe2109 100644
> --- a/common/efi/Makefile
> +++ b/common/efi/Makefile
> @@ -1,3 +1,4 @@
>  obj-y += efi.o
>  obj-y += efi-image.o
>  bbenv-y += env-efi
> +obj-$(CONFIG_CMD_IOMEM) += efi-iomem.o
> diff --git a/common/efi/efi-iomem.c b/common/efi/efi-iomem.c
> new file mode 100644
> index 000000000000..e223c595c478
> --- /dev/null
> +++ b/common/efi/efi-iomem.c
> @@ -0,0 +1,175 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2019 Ahmad Fatoum, Pengutronix
> +
> +#define pr_fmt(fmt) "efi-iomem: " fmt
> +
> +#include <common.h>
> +#include <init.h>
> +#include <efi.h>
> +#include <efi/efi.h>
> +#include <memory.h>
> +#include <linux/sizes.h>
> +
> +static int efi_parse_mmap(struct efi_memory_desc *desc)
> +{
> +     struct resource *res;
> +     u32 flags;
> +     const char *name;
> +     char *fullname;
> +     resource_size_t va_base, va_size;
> +     int ret = 0;
> +
> +     va_size = desc->npages * SZ_4K;
> +     if (!va_size)
> +             return 0;
> +
> +     /* XXX At least OVMF doesn't populate ->virt_start and leaves it at zero
> +      * for all mapping. Thus assume a 1:1 mapping and ignore virt_start
> +      */
> +     va_base = desc->phys_start;
> +
> +     switch (desc->type) {
> +     case EFI_RESERVED_TYPE:
> +             if (!IS_ENABLED(DEBUG))
> +                     return 0;
> +             name = "reserved";
> +             flags = IORESOURCE_MEM | IORESOURCE_DISABLED;
> +             break;
> +     case EFI_LOADER_CODE:
> +             return barebox_add_memory_bank("loader code", va_base, va_size);
> +     case EFI_LOADER_DATA:
> +             return barebox_add_memory_bank("loader data", va_base, va_size);
> +     case EFI_BOOT_SERVICES_CODE:
> +             if (!IS_ENABLED(DEBUG))
> +                     return 0;
> +             name = "boot services code";
> +             flags = IORESOURCE_MEM | IORESOURCE_READONLY;
> +             break;
> +     case EFI_BOOT_SERVICES_DATA:
> +             if (!IS_ENABLED(DEBUG))
> +                     return 0;
> +             name = "boot services data";
> +             flags = IORESOURCE_MEM;
> +             break;
> +     case EFI_RUNTIME_SERVICES_CODE:
> +             if (!IS_ENABLED(DEBUG))
> +                     return 0;
> +             name = "runtime services code";
> +             flags = IORESOURCE_MEM | IORESOURCE_READONLY;
> +             break;
> +     case EFI_RUNTIME_SERVICES_DATA:
> +             if (!IS_ENABLED(DEBUG))
> +                     return 0;
> +             name = "runtime services data";
> +             flags = IORESOURCE_MEM;
> +             break;
> +     case EFI_CONVENTIONAL_MEMORY:
> +             if (!IS_ENABLED(DEBUG))
> +                     return 0;
> +             name = "conventional memory";
> +             flags = IORESOURCE_MEM | IORESOURCE_PREFETCH | 
> IORESOURCE_CACHEABLE;
> +             break;
> +     case EFI_UNUSABLE_MEMORY:
> +             if (!IS_ENABLED(DEBUG))
> +                     return 0;
> +             name = "unusable";
> +             flags = IORESOURCE_MEM | IORESOURCE_DISABLED;
> +             break;
> +     case EFI_ACPI_RECLAIM_MEMORY:
> +             if (!IS_ENABLED(DEBUG))
> +                     return 0;
> +             name = "ACPI reclaim memory";
> +             flags = IORESOURCE_MEM | IORESOURCE_READONLY;
> +             break;
> +     case EFI_ACPI_MEMORY_NVS:
> +             if (!IS_ENABLED(DEBUG))
> +                     return 0;
> +             name = "ACPI NVS memory";
> +             flags = IORESOURCE_MEM | IORESOURCE_READONLY;
> +             break;
> +     case EFI_MEMORY_MAPPED_IO:
> +             if (!IS_ENABLED(DEBUG))
> +                     return 0;
> +             name = "MMIO";
> +             flags = IORESOURCE_MEM;
> +             break;
> +     case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
> +             if (!IS_ENABLED(DEBUG))
> +                     return 0;
> +             name = "MMIOPORT";
> +             flags = IORESOURCE_IO;
> +             break;
> +     case EFI_PAL_CODE:
> +             if (!IS_ENABLED(DEBUG))
> +                     return 0;
> +             name = "PAL code";
> +             flags = IORESOURCE_MEM | IORESOURCE_ROM_BIOS_COPY;
> +             break;
> +     default:
> +             if (!(desc->type & (1U << 31))) {
> +                     pr_warn("illegal memory type = %u >= %u\n",
> +                             desc->type, EFI_MAX_MEMORY_TYPE);
> +                     return -EINVAL;
> +             }
> +
> +             if (!IS_ENABLED(DEBUG))
> +                     return 0;
> +
> +             name = "vendor reserved";
> +             flags = IORESOURCE_MEM | IORESOURCE_ROM_BIOS_COPY;
> +     }
> +
> +     fullname = xasprintf("%s@%llx", name, desc->phys_start);
> +
> +     pr_debug("%s: (0x%llx+0x%llx)\n", fullname, va_base, va_size);
> +
> +     res = request_iomem_region(fullname, va_base, va_base + va_size - 1);
> +     if (IS_ERR(res)) {
> +             ret = PTR_ERR(res);
> +             goto out;
> +     }
> +
> +     res->flags |= flags;
> +
> +out:
> +     free(fullname);
> +     return ret;
> +}
> +
> +static int efi_barebox_populate_mmap(void)
> +{
> +     void *desc;
> +     u8 *mmap_buf = NULL;
> +     efi_status_t efiret;
> +     size_t mmap_size;
> +     size_t mapkey;
> +     size_t descsz;
> +     u32 descver;
> +     int ret = 0;
> +
> +     mmap_size = sizeof(struct efi_memory_desc);
> +
> +     do {
> +             mmap_buf = xrealloc(mmap_buf, mmap_size);
> +             efiret = BS->get_memory_map(&mmap_size, mmap_buf,
> +                                         &mapkey, &descsz, &descver);
> +     } while (efiret == EFI_BUFFER_TOO_SMALL);
> +
> +     if (EFI_ERROR(efiret)) {
> +             ret = -efi_errno(efiret);
> +             goto out;
> +     }
> +
> +     if (descver != 1) {
> +             ret = -ENOSYS;
> +             goto out;
> +     }
> +
> +     for (desc = mmap_buf; (u8 *)desc < &mmap_buf[mmap_size]; desc += descsz)
> +             efi_parse_mmap(desc);
> +
> +out:
> +     free(mmap_buf);
> +     return ret;
> +}
> +mem_initcall(efi_barebox_populate_mmap);
> diff --git a/common/memory.c b/common/memory.c
> index a56eaf949411..392522bfc3db 100644
> --- a/common/memory.c
> +++ b/common/memory.c
> @@ -53,7 +53,7 @@ void mem_malloc_init(void *start, void *end)
>       mem_malloc_initialized = 1;
>  }
>  
> -#if !defined __SANDBOX__ && !defined CONFIG_EFI_BOOTUP
> +#if !defined __SANDBOX__
>  static int mem_malloc_resource(void)
>  {
>       /*
> diff --git a/include/efi.h b/include/efi.h
> index b9f3428dc550..439803c29437 100644
> --- a/include/efi.h
> +++ b/include/efi.h
> @@ -91,6 +91,15 @@ typedef    struct {
>   * Memory map descriptor:
>   */
>  
> +struct efi_memory_desc {
> +    u32 type; /* enum efi_memory_type */
> +    u32 _padding;
> +    efi_physical_addr_t phys_start;
> +    void *virt_start;
> +    u64 npages;
> +    u64 attrs;
> +};
> +
>  /* Memory types: */
>  enum efi_memory_type {
>       EFI_RESERVED_TYPE,
> -- 
> 2.30.0
> 
> 
> _______________________________________________
> barebox mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

Reply via email to