From 38671d4f1cd44c22e5485606034ed5f3be9f1211 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 11 Jul 2019 06:07:40 +0200 Subject: efi_loader: duplicate IMAGE_SUBSYSTEM_EFI_APPLICATION IMAGE_SUBSYSTEM_EFI_APPLICATION is already defined in include/asm-generic/pe.h which is included in include/pe.h. We should not define it twice. Signed-off-by: Heinrich Schuchardt --- include/pe.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/pe.h b/include/pe.h index 36e1908b7ea..c7aeb2dcb6f 100644 --- a/include/pe.h +++ b/include/pe.h @@ -48,7 +48,6 @@ typedef struct _IMAGE_DOS_HEADER { #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b #define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b -#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 typedef struct _IMAGE_FILE_HEADER { uint16_t Machine; -- cgit v1.3.1 From a35c33c0dc9ef9d2ab44cf677ac17a359c79b019 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 11 Jul 2019 06:39:32 +0200 Subject: efi_loader: use predefined constants in crt0_*_efi.S We should use predefined constants instead of magic numbers. Move some constant definitions from include/pe.h to include/asm-generic/pe.h. Use these constants in crt0_*_efi.S. Signed-off-by: Heinrich Schuchardt --- arch/arm/lib/crt0_aarch64_efi.S | 9 ++++----- arch/arm/lib/crt0_arm_efi.S | 9 ++++----- arch/riscv/lib/crt0_riscv_efi.S | 11 +++++------ include/asm-generic/pe.h | 16 ++++++++++++++++ include/pe.h | 15 --------------- 5 files changed, 29 insertions(+), 31 deletions(-) (limited to 'include') diff --git a/arch/arm/lib/crt0_aarch64_efi.S b/arch/arm/lib/crt0_aarch64_efi.S index cb205fa30a5..368933ecf2d 100644 --- a/arch/arm/lib/crt0_aarch64_efi.S +++ b/arch/arm/lib/crt0_aarch64_efi.S @@ -17,14 +17,13 @@ */ .globl ImageBase ImageBase: - .ascii "MZ" + .short IMAGE_DOS_SIGNATURE /* 'MZ' */ .skip 58 /* 'MZ' + pad + offset == 64 */ .long pe_header - ImageBase /* Offset to the PE header */ pe_header: - .ascii "PE" - .short 0 + .long IMAGE_NT_SIGNATURE /* 'PE' */ coff_header: - .short 0xaa64 /* AArch64 */ + .short IMAGE_FILE_MACHINE_ARM64 /* AArch64 */ .short 2 /* nr_sections */ .long 0 /* TimeDateStamp */ .long 0 /* PointerToSymbolTable */ @@ -36,7 +35,7 @@ coff_header: IMAGE_FILE_LOCAL_SYMS_STRIPPED | \ IMAGE_FILE_DEBUG_STRIPPED) optional_header: - .short 0x20b /* PE32+ format */ + .short IMAGE_NT_OPTIONAL_HDR64_MAGIC /* PE32+ format */ .byte 0x02 /* MajorLinkerVersion */ .byte 0x14 /* MinorLinkerVersion */ .long _edata - _start /* SizeOfCode */ diff --git a/arch/arm/lib/crt0_arm_efi.S b/arch/arm/lib/crt0_arm_efi.S index 5470e2ff0e6..cc8a115f319 100644 --- a/arch/arm/lib/crt0_arm_efi.S +++ b/arch/arm/lib/crt0_arm_efi.S @@ -16,14 +16,13 @@ */ .globl image_base image_base: - .ascii "MZ" + .short IMAGE_DOS_SIGNATURE /* 'MZ' */ .skip 58 /* 'MZ' + pad + offset == 64 */ .long pe_header - image_base /* Offset to the PE header */ pe_header: - .ascii "PE" - .short 0 + .long IMAGE_NT_SIGNATURE /* 'PE' */ coff_header: - .short 0x1c2 /* Mixed ARM/Thumb */ + .short IMAGE_FILE_MACHINE_THUMB /* Mixed ARM/Thumb */ .short 2 /* nr_sections */ .long 0 /* TimeDateStamp */ .long 0 /* PointerToSymbolTable */ @@ -36,7 +35,7 @@ coff_header: IMAGE_FILE_32BIT_MACHINE | \ IMAGE_FILE_DEBUG_STRIPPED) optional_header: - .short 0x10b /* PE32 format */ + .short IMAGE_NT_OPTIONAL_HDR32_MAGIC /* PE32 format */ .byte 0x02 /* MajorLinkerVersion */ .byte 0x14 /* MinorLinkerVersion */ .long _edata - _start /* SizeOfCode */ diff --git a/arch/riscv/lib/crt0_riscv_efi.S b/arch/riscv/lib/crt0_riscv_efi.S index b7b5329e1f7..87fe1e56f90 100644 --- a/arch/riscv/lib/crt0_riscv_efi.S +++ b/arch/riscv/lib/crt0_riscv_efi.S @@ -14,12 +14,12 @@ #define SIZE_LONG 8 #define SAVE_LONG(reg, idx) sd reg, (idx*SIZE_LONG)(sp) #define LOAD_LONG(reg, idx) ld reg, (idx*SIZE_LONG)(sp) -#define PE_MACHINE 0x5064 +#define PE_MACHINE IMAGE_FILE_MACHINE_RISCV64 #else #define SIZE_LONG 4 #define SAVE_LONG(reg, idx) sw reg, (idx*SIZE_LONG)(sp) #define LOAD_LONG(reg, idx) lw reg, (idx*SIZE_LONG)(sp) -#define PE_MACHINE 0x5032 +#define PE_MACHINE IMAGE_FILE_MACHINE_RISCV32 #endif @@ -30,12 +30,11 @@ */ .globl ImageBase ImageBase: - .ascii "MZ" + .short IMAGE_DOS_SIGNATURE /* 'MZ' */ .skip 58 /* 'MZ' + pad + offset == 64 */ .long pe_header - ImageBase /* Offset to the PE header */ pe_header: - .ascii "PE" - .short 0 + .long IMAGE_NT_SIGNATURE /* 'PE' */ coff_header: .short PE_MACHINE /* RISC-V 64/32-bit */ .short 2 /* nr_sections */ @@ -49,7 +48,7 @@ coff_header: IMAGE_FILE_LOCAL_SYMS_STRIPPED | \ IMAGE_FILE_DEBUG_STRIPPED) optional_header: - .short 0x20b /* PE32+ format */ + .short IMAGE_NT_OPTIONAL_HDR64_MAGIC /* PE32+ format */ .byte 0x02 /* MajorLinkerVersion */ .byte 0x14 /* MinorLinkerVersion */ .long _edata - _start /* SizeOfCode */ diff --git a/include/asm-generic/pe.h b/include/asm-generic/pe.h index faae534e371..b247519a3d5 100644 --- a/include/asm-generic/pe.h +++ b/include/asm-generic/pe.h @@ -29,6 +29,22 @@ #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 +/* Machine types */ +#define IMAGE_FILE_MACHINE_I386 0x014c +#define IMAGE_FILE_MACHINE_ARM 0x01c0 +#define IMAGE_FILE_MACHINE_THUMB 0x01c2 +#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 +#define IMAGE_FILE_MACHINE_AMD64 0x8664 +#define IMAGE_FILE_MACHINE_ARM64 0xaa64 +#define IMAGE_FILE_MACHINE_RISCV32 0x5032 +#define IMAGE_FILE_MACHINE_RISCV64 0x5064 + +/* Header magic constants */ +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x010b +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x020b +#define IMAGE_DOS_SIGNATURE 0x5a4d /* MZ */ +#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ + /* Subsystem type */ #define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 #define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 diff --git a/include/pe.h b/include/pe.h index c7aeb2dcb6f..bff3b0aa7a6 100644 --- a/include/pe.h +++ b/include/pe.h @@ -34,21 +34,6 @@ typedef struct _IMAGE_DOS_HEADER { uint32_t e_lfanew; /* 3c: Offset to extended header */ } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; -#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */ -#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ - -#define IMAGE_FILE_MACHINE_I386 0x014c -#define IMAGE_FILE_MACHINE_ARM 0x01c0 -#define IMAGE_FILE_MACHINE_THUMB 0x01c2 -#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 -#define IMAGE_FILE_MACHINE_AMD64 0x8664 -#define IMAGE_FILE_MACHINE_ARM64 0xaa64 -#define IMAGE_FILE_MACHINE_RISCV32 0x5032 -#define IMAGE_FILE_MACHINE_RISCV64 0x5064 - -#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b -#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b - typedef struct _IMAGE_FILE_HEADER { uint16_t Machine; uint16_t NumberOfSections; -- cgit v1.3.1 From b225c92fd0c0b09b99e2290c5e42708f9046a7a2 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Mon, 15 Jul 2019 12:00:39 +0100 Subject: efi_loader: Change return type of efi_add_memory_map() We currently have some inconsistent use of efi_add_memory_map() throughout the code. In particular the return value of efi_add_memory_map() is not interpreted the same way by various users in the codebase. This patch does the following: - Changes efi_add_memory_map() to return efi_status_t. - Adds a method description to efi_add_memory_map(). - Changes efi_add_memory_map() to return EFI_SUCCESS - Returns non-zero for error in efi_add_memory_map() - Updates efi_allocate_pages() to new efi_add_memory_map() - Updates efi_free_pages() to new efi_add_memory_map() - Updates efi_carve_out_dt_rsv() to new efi_add_memory_map() - Updates efi_add_runtime_mmio() to new efi_add_memory_map() Fixes: 5d00995c361c ("efi_loader: Implement memory allocation and map") Fixes: 74c16acce30b ("efi_loader: Don't allocate from memory holes") Suggested-by: Heinrich Schuchardt Cc: Alexander Graf Signed-off-by: Bryan O'Donoghue Reviewed-by: Heinrich Schuchardt --- cmd/bootefi.c | 4 ++-- include/efi_loader.h | 4 ++-- lib/efi_loader/efi_memory.c | 32 ++++++++++++++++++++------------ lib/efi_loader/efi_runtime.c | 6 +++--- 4 files changed, 27 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/cmd/bootefi.c b/cmd/bootefi.c index c19256e00dc..04d3e3e4a72 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -169,8 +169,8 @@ static void efi_carve_out_dt_rsv(void *fdt) pages = efi_size_in_pages(size + (addr & EFI_PAGE_MASK)); addr &= ~EFI_PAGE_MASK; - if (!efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE, - false)) + if (efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE, + false) != EFI_SUCCESS) printf("FDT memrsv map %d: Failed to add to map\n", i); } } diff --git a/include/efi_loader.h b/include/efi_loader.h index db4763fc9b7..6cc6a3835c9 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -476,8 +476,8 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size, efi_uintn_t *descriptor_size, uint32_t *descriptor_version); /* Adds a range into the EFI memory map */ -uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, - bool overlap_only_ram); +efi_status_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, + bool overlap_only_ram); /* Called by board init to initialize the EFI drivers */ efi_status_t efi_driver_init(void); /* Called by board init to initialize the EFI memory map */ diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 27379381e87..4c0216b1d24 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -223,8 +223,17 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, return EFI_CARVE_LOOP_AGAIN; } -uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, - bool overlap_only_ram) +/** + * efi_add_memory_map() - add memory area to the memory map + * + * @start: start address, must be a multiple of EFI_PAGE_SIZE + * @pages: number of pages to add + * @memory_type: type of memory added + * @overlap_only_ram: the memory area must overlap existing + * Return: status code + */ +efi_status_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, + bool overlap_only_ram) { struct list_head *lhandle; struct efi_mem_list *newlist; @@ -239,7 +248,7 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, return EFI_INVALID_PARAMETER; if (!pages) - return start; + return EFI_SUCCESS; ++efi_memory_map_key; newlist = calloc(1, sizeof(*newlist)); @@ -277,7 +286,7 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, * The user requested to only have RAM overlaps, * but we hit a non-RAM region. Error out. */ - return 0; + return EFI_NO_MAPPING; case EFI_CARVE_NO_OVERLAP: /* Just ignore this list entry */ break; @@ -307,7 +316,7 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, * The payload wanted to have RAM overlaps, but we overlapped * with an unallocated region. Error out. */ - return 0; + return EFI_NO_MAPPING; } /* Add our new map */ @@ -326,7 +335,7 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, } } - return start; + return EFI_SUCCESS; } /** @@ -455,7 +464,7 @@ efi_status_t efi_allocate_pages(int type, int memory_type, } /* Reserve that map in our memory maps */ - if (efi_add_memory_map(addr, pages, memory_type, true) != addr) + if (efi_add_memory_map(addr, pages, memory_type, true) != EFI_SUCCESS) /* Map would overlap, bail out */ return EFI_OUT_OF_RESOURCES; @@ -487,7 +496,6 @@ void *efi_alloc(uint64_t len, int memory_type) */ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) { - uint64_t r = 0; efi_status_t ret; ret = efi_check_allocated(memory, true); @@ -501,13 +509,13 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) return EFI_INVALID_PARAMETER; } - r = efi_add_memory_map(memory, pages, EFI_CONVENTIONAL_MEMORY, false); + ret = efi_add_memory_map(memory, pages, EFI_CONVENTIONAL_MEMORY, false); /* Merging of adjacent free regions is missing */ - if (r == memory) - return EFI_SUCCESS; + if (ret != EFI_SUCCESS) + return EFI_NOT_FOUND; - return EFI_NOT_FOUND; + return ret; } /** diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c index 9f4ba2f9772..8b56ab0207c 100644 --- a/lib/efi_loader/efi_runtime.c +++ b/lib/efi_loader/efi_runtime.c @@ -694,10 +694,10 @@ efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len) struct efi_runtime_mmio_list *newmmio; u64 pages = (len + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT; uint64_t addr = *(uintptr_t *)mmio_ptr; - uint64_t retaddr; + efi_status_t ret; - retaddr = efi_add_memory_map(addr, pages, EFI_MMAP_IO, false); - if (retaddr != addr) + ret = efi_add_memory_map(addr, pages, EFI_MMAP_IO, false); + if (ret != EFI_SUCCESS) return EFI_OUT_OF_RESOURCES; newmmio = calloc(1, sizeof(*newmmio)); -- cgit v1.3.1 From ade317a281652354cb3d86d40a8c012b32f28497 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 14 Jul 2019 18:51:00 +0200 Subject: efi_loader: avoid alignment error In packed structures GUIDs are not aligned. Avoid a build error with GCC 9.1 by using const void * as argument for guidcmp(). Reported-by: Ramon Fried Signed-off-by: Heinrich Schuchardt --- include/efi_loader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/efi_loader.h b/include/efi_loader.h index 6cc6a3835c9..5298ea7997f 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -567,7 +567,7 @@ static inline void ascii2unicode(u16 *unicode, const char *ascii) *unicode = 0; } -static inline int guidcmp(const efi_guid_t *g1, const efi_guid_t *g2) +static inline int guidcmp(const void *g1, const void *g2) { return memcmp(g1, g2, sizeof(efi_guid_t)); } -- cgit v1.3.1 From 317068b8b6b15ad38f7aa1019310e41764c80e5b Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 14 Jul 2019 17:28:49 +0200 Subject: efi_loader: support unaligned u16 strings Allow unaligned u16 strings as arguments to u16_strdup() and u16_strlen(). Signed-off-by: Heinrich Schuchardt --- include/charset.h | 4 ++-- lib/charset.c | 23 ++++++++++++++--------- 2 files changed, 16 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/charset.h b/include/charset.h index 4f7ae8fafdf..020f8a90df0 100644 --- a/include/charset.h +++ b/include/charset.h @@ -178,7 +178,7 @@ s32 utf_to_upper(const s32 code); * ReturnValue: number of non-zero words. * This is not the number of utf-16 letters! */ -size_t u16_strlen(const u16 *in); +size_t u16_strlen(const void *in); /** * u16_strlen - count non-zero words @@ -214,7 +214,7 @@ u16 *u16_strcpy(u16 *dest, const u16 *src); * @src: source buffer (null terminated) * Return: allocated new buffer on success, NULL on failure */ -u16 *u16_strdup(const u16 *src); +u16 *u16_strdup(const void *src); /** * utf16_to_utf8() - Convert an utf16 string to utf8 diff --git a/lib/charset.c b/lib/charset.c index 5e349ed5ee4..72d745da4f4 100644 --- a/lib/charset.c +++ b/lib/charset.c @@ -335,11 +335,16 @@ s32 utf_to_upper(const s32 code) return ret; } -size_t u16_strlen(const u16 *in) +size_t u16_strlen(const void *in) { - size_t i; - for (i = 0; in[i]; i++); - return i; + const char *pos = in; + size_t ret; + + for (; pos[0] || pos[1]; pos += 2) + ; + ret = pos - (char *)in; + ret >>= 1; + return ret; } size_t u16_strnlen(const u16 *in, size_t count) @@ -362,18 +367,18 @@ u16 *u16_strcpy(u16 *dest, const u16 *src) return tmp; } -u16 *u16_strdup(const u16 *src) +u16 *u16_strdup(const void *src) { u16 *new; + size_t len; if (!src) return NULL; - - new = malloc((u16_strlen(src) + 1) * sizeof(u16)); + len = (u16_strlen(src) + 1) * sizeof(u16); + new = malloc(len); if (!new) return NULL; - - u16_strcpy(new, src); + memcpy(new, src, len); return new; } -- cgit v1.3.1