From 45c66f9cdfe40aee78c01ea3f4cdc9573b2c60ed Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 17 May 2018 07:57:05 +0200 Subject: efi_loader: adjust definitions of variable services The definitons of the variable services are adjusted: - use efi_uintn_t instead of unsigned long - use u16 * instead of s16 * for Unicode strings - correct definition of QueryVariableInfo - rename efi_get_next_variable to efi_get_next_variable_name Signed-off-by: Heinrich Schuchardt Signed-off-by: Alexander Graf --- include/efi_api.h | 24 ++++++++++++------------ include/efi_loader.h | 18 +++++++++--------- 2 files changed, 21 insertions(+), 21 deletions(-) (limited to 'include') diff --git a/include/efi_api.h b/include/efi_api.h index 64c27e494bc..094be6edf9b 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -214,15 +214,15 @@ struct efi_runtime_services { uint32_t descriptor_version, struct efi_mem_desc *virtmap); efi_status_t (*convert_pointer)(unsigned long dbg, void **address); - efi_status_t (EFIAPI *get_variable)(s16 *variable_name, - efi_guid_t *vendor, u32 *attributes, - unsigned long *data_size, void *data); - efi_status_t (EFIAPI *get_next_variable)( - unsigned long *variable_name_size, - s16 *variable_name, efi_guid_t *vendor); - efi_status_t (EFIAPI *set_variable)(s16 *variable_name, - efi_guid_t *vendor, u32 attributes, - unsigned long data_size, void *data); + efi_status_t (EFIAPI *get_variable)(u16 *variable_name, + efi_guid_t *vendor, u32 *attributes, + efi_uintn_t *data_size, void *data); + efi_status_t (EFIAPI *get_next_variable_name)( + efi_uintn_t *variable_name_size, + u16 *variable_name, efi_guid_t *vendor); + efi_status_t (EFIAPI *set_variable)(u16 *variable_name, + efi_guid_t *vendor, u32 attributes, + efi_uintn_t data_size, void *data); efi_status_t (EFIAPI *get_next_high_mono_count)( uint32_t *high_count); void (EFIAPI *reset_system)(enum efi_reset_type reset_type, @@ -239,9 +239,9 @@ struct efi_runtime_services { u32 reset_type); efi_status_t (EFIAPI *query_variable_info)( u32 attributes, - u64 maximum_variable_storage_size, - u64 remaining_variable_storage_size, - u64 maximum_variable_size); + u64 *maximum_variable_storage_size, + u64 *remaining_variable_storage_size, + u64 *maximum_variable_size); }; /* EFI event group GUID definitions */ diff --git a/include/efi_loader.h b/include/efi_loader.h index ec000658f6d..0c286bf6bed 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -422,15 +422,15 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle, struct efi_system_table *systab); #endif -efi_status_t EFIAPI efi_get_variable(s16 *variable_name, - efi_guid_t *vendor, u32 *attributes, - unsigned long *data_size, void *data); -efi_status_t EFIAPI efi_get_next_variable( - unsigned long *variable_name_size, - s16 *variable_name, efi_guid_t *vendor); -efi_status_t EFIAPI efi_set_variable(s16 *variable_name, - efi_guid_t *vendor, u32 attributes, - unsigned long data_size, void *data); +efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor, + u32 *attributes, efi_uintn_t *data_size, + void *data); +efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, + u16 *variable_name, + efi_guid_t *vendor); +efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor, + u32 attributes, efi_uintn_t data_size, + void *data); void *efi_bootmgr_load(struct efi_device_path **device_path, struct efi_device_path **file_path); -- cgit v1.3.1 From c3b11dea7c9f9bb009cb7358170c47abd1c4a298 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 3 Apr 2018 21:59:32 +0200 Subject: efi_loader: allow unaligned memory access The UEFI spec mandates that unaligned memory access should be enabled if supported by the CPU architecture. This patch adds an empty weak function unaligned_access() that can be overridden by an architecture specific routine. Signed-off-by: Heinrich Schuchardt Signed-off-by: Alexander Graf --- cmd/bootefi.c | 13 +++++++++++++ include/asm-generic/unaligned.h | 3 +++ 2 files changed, 16 insertions(+) (limited to 'include') diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 80491c77fd1..806339823ff 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -17,6 +17,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -82,6 +83,15 @@ out: return ret; } +/* + * Allow unaligned memory access. + * + * This routine is overridden by architectures providing this feature. + */ +void __weak allow_unaligned(void) +{ +} + /* * Set the load options of an image from an environment variable. * @@ -370,6 +380,9 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) efi_status_t r; void *fdt_addr; + /* Allow unaligned memory access */ + allow_unaligned(); + /* Initialize EFI drivers */ r = efi_init_obj_list(); if (r != EFI_SUCCESS) { diff --git a/include/asm-generic/unaligned.h b/include/asm-generic/unaligned.h index fd0255099aa..3d33a5a063e 100644 --- a/include/asm-generic/unaligned.h +++ b/include/asm-generic/unaligned.h @@ -20,4 +20,7 @@ #error invalid endian #endif +/* Allow unaligned memory access */ +void allow_unaligned(void); + #endif -- cgit v1.3.1 From 0864c565a274ddbc23dda667d71524e7efbbef8f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 16 May 2018 09:42:19 -0600 Subject: efi: Update some comments related to smbios tables Clarify the operation of this code with some additional comments. Signed-off-by: Simon Glass Reviewed-by: Heinrich Schuchardt Signed-off-by: Alexander Graf --- include/efi_loader.h | 7 +++++++ include/smbios.h | 5 +++-- lib/efi_loader/efi_smbios.c | 7 ++++++- 3 files changed, 16 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/efi_loader.h b/include/efi_loader.h index 0c286bf6bed..c66252a7dd2 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -214,6 +214,13 @@ efi_status_t efi_net_register(void); /* Called by bootefi to make the watchdog available */ efi_status_t efi_watchdog_register(void); /* Called by bootefi to make SMBIOS tables available */ +/** + * efi_smbios_register() - write out SMBIOS tables + * + * Called by bootefi to make SMBIOS tables available + * + * @return 0 if OK, -ENOMEM if no memory is available for the tables + */ efi_status_t efi_smbios_register(void); struct efi_simple_file_system_protocol * diff --git a/include/smbios.h b/include/smbios.h index 79880ef5b5c..97b9ddce237 100644 --- a/include/smbios.h +++ b/include/smbios.h @@ -231,8 +231,9 @@ typedef int (*smbios_write_type)(ulong *addr, int handle); * * This writes SMBIOS table at a given address. * - * @addr: start address to write SMBIOS table - * @return: end address of SMBIOS table + * @addr: start address to write SMBIOS table. If this is not + * 16-byte-aligned then it will be aligned before the table is written + * @return: end address of SMBIOS table (and start address for next entry) */ ulong write_smbios_table(ulong addr); diff --git a/lib/efi_loader/efi_smbios.c b/lib/efi_loader/efi_smbios.c index 482436e2adb..7c3fc8af0b2 100644 --- a/lib/efi_loader/efi_smbios.c +++ b/lib/efi_loader/efi_smbios.c @@ -29,7 +29,12 @@ efi_status_t efi_smbios_register(void) if (ret != EFI_SUCCESS) return ret; - /* Generate SMBIOS tables */ + /* + * Generate SMBIOS tables - we know that efi_allocate_pages() returns + * a 4k-aligned address, so it is safe to assume that + * write_smbios_table() will write the table at that address. + */ + assert(!(dmi & 0xf)); write_smbios_table(dmi); /* And expose them to our EFI payload */ -- cgit v1.3.1 From 30eef21fa041635fb8327ef9001d78cb187c359f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 16 May 2018 09:42:22 -0600 Subject: sandbox: Add a setjmp() implementation Add an implementation of setjmp() and longjmp() which rely on the underlying host C library. Since we cannot know how large the jump buffer needs to be, pick something that should be suitable and check it at runtime. At present we need access to the underlying struct as well. Signed-off-by: Simon Glass Signed-off-by: Alexander Graf --- arch/sandbox/cpu/cpu.c | 13 +++++++++++++ arch/sandbox/cpu/os.c | 23 +++++++++++++++++++++++ arch/sandbox/include/asm/setjmp.h | 30 ++++++++++++++++++++++++++++++ include/os.h | 21 +++++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 arch/sandbox/include/asm/setjmp.h (limited to 'include') diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index d4ad020012e..cde0b055a67 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -164,3 +165,15 @@ ulong timer_get_boot_us(void) return (count - base_count) / 1000; } + +int setjmp(jmp_buf jmp) +{ + return os_setjmp((ulong *)jmp, sizeof(*jmp)); +} + +void longjmp(jmp_buf jmp, int ret) +{ + os_longjmp((ulong *)jmp, ret); + while (1) + ; +} diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index d76d0211a2d..5839932b005 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -628,3 +629,25 @@ void os_localtime(struct rtc_time *rt) rt->tm_yday = tm->tm_yday; rt->tm_isdst = tm->tm_isdst; } + +int os_setjmp(ulong *jmp, int size) +{ + jmp_buf dummy; + + /* + * We cannot rely on the struct name that jmp_buf uses, so use a + * local variable here + */ + if (size < sizeof(dummy)) { + printf("setjmp: jmpbuf is too small (%d bytes, need %d)\n", + size, sizeof(jmp_buf)); + return -ENOSPC; + } + + return setjmp((struct __jmp_buf_tag *)jmp); +} + +void os_longjmp(ulong *jmp, int ret) +{ + longjmp((struct __jmp_buf_tag *)jmp, ret); +} diff --git a/arch/sandbox/include/asm/setjmp.h b/arch/sandbox/include/asm/setjmp.h new file mode 100644 index 00000000000..0fb1a11f234 --- /dev/null +++ b/arch/sandbox/include/asm/setjmp.h @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) 2018 Google, Inc + * Written by Simon Glass + */ + +#ifndef _SETJMP_H_ +#define _SETJMP_H_ + +struct jmp_buf_data { + /* + * We're not sure how long this should be: + * + * amd64: 200 bytes + * arm64: 392 bytes + * armhf: 392 bytes + * + * So allow space for all of those, plus some extra. + * We don't need to worry about 16-byte alignment, since this does not + * run on Windows. + */ + ulong data[128]; +}; + +typedef struct jmp_buf_data jmp_buf[1]; + +int setjmp(jmp_buf jmp); +__noreturn void longjmp(jmp_buf jmp, int ret); + +#endif /* _SETJMP_H_ */ diff --git a/include/os.h b/include/os.h index 64e89a06c94..c8e0f52d306 100644 --- a/include/os.h +++ b/include/os.h @@ -330,4 +330,25 @@ int os_spl_to_uboot(const char *fname); */ void os_localtime(struct rtc_time *rt); +/** + * os_setjmp() - Call setjmp() + * + * Call the host system's setjmp() function. + * + * @jmp: Buffer to store current execution state + * @size: Size of buffer + * @return normal setjmp() value if OK, -ENOSPC if @size is too small + */ +int os_setjmp(ulong *jmp, int size); + +/** + * os_longjmp() - Call longjmp() + * + * Call the host system's longjmp() function. + * + * @jmp: Buffer where previous execution state was stored + * @ret: Value to pass to longjmp() + */ +void os_longjmp(ulong *jmp, int ret); + #endif -- cgit v1.3.1 From 329da4850c61994b83c025da68e1966a1259fd00 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 16 May 2018 09:42:25 -0600 Subject: Define board_quiesce_devices() in a shared location This undocumented function relies on arch-specific code to declare a nop weak version. Add the weak function in common code instead to avoid having to duplicate the same function in each arch. Signed-off-by: Simon Glass Signed-off-by: Alexander Graf --- arch/arm/include/asm/u-boot-arm.h | 1 - arch/x86/include/asm/u-boot-x86.h | 1 - arch/x86/lib/bootm.c | 4 ---- common/bootm.c | 4 ++++ include/bootm.h | 2 ++ 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/arch/arm/include/asm/u-boot-arm.h b/arch/arm/include/asm/u-boot-arm.h index 01c3ba87c3f..cc828c45045 100644 --- a/arch/arm/include/asm/u-boot-arm.h +++ b/arch/arm/include/asm/u-boot-arm.h @@ -37,7 +37,6 @@ int arch_early_init_r(void); /* board/.../... */ int board_init(void); -void board_quiesce_devices(void); /* cpu/.../interrupt.c */ int arch_interrupt_init (void); diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 9be45846a53..2340ef83323 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -84,7 +84,6 @@ static inline __attribute__((no_instrument_function)) uint64_t rdtsc(void) /* board/... */ void timer_set_tsc_base(uint64_t new_base); uint64_t timer_get_tsc(void); -void board_quiesce_devices(void); void quick_ram_check(void); diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c index 533ba075bb1..54c22fe6de3 100644 --- a/arch/x86/lib/bootm.c +++ b/arch/x86/lib/bootm.c @@ -27,10 +27,6 @@ DECLARE_GLOBAL_DATA_PTR; #define COMMAND_LINE_OFFSET 0x9000 -__weak void board_quiesce_devices(void) -{ -} - void bootm_announce_and_cleanup(void) { printf("\nStarting kernel ...\n\n"); diff --git a/common/bootm.c b/common/bootm.c index a0ffc1cd679..e789f6818aa 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -46,6 +46,10 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], bootm_headers_t *images, ulong *os_data, ulong *os_len); +__weak void board_quiesce_devices(void) +{ +} + #ifdef CONFIG_LMB static void boot_start_lmb(bootm_headers_t *images) { diff --git a/include/bootm.h b/include/bootm.h index 9e42e179878..9f7956d2e35 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -72,4 +72,6 @@ int bootm_decomp_image(int comp, ulong load, ulong image_start, int type, void *load_buf, void *image_buf, ulong image_len, uint unc_len, ulong *load_end); +void board_quiesce_devices(void); + #endif -- cgit v1.3.1 From 896019b18b0a6f9392fa234c082ef492e1630cc3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 16 May 2018 09:42:26 -0600 Subject: Add a comment for board_quiesce_devices() This exported function should have a comment describing what it does. Also it should really be removed in favour of device_remove(), which handles this sort of thing now. Add a comment with a TODO. Signed-off-by: Simon Glass Signed-off-by: Alexander Graf --- include/bootm.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/bootm.h b/include/bootm.h index 9f7956d2e35..0501414e0dc 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -72,6 +72,12 @@ int bootm_decomp_image(int comp, ulong load, ulong image_start, int type, void *load_buf, void *image_buf, ulong image_len, uint unc_len, ulong *load_end); +/* + * boards should define this to disable devices when EFI exits from boot + * services. + * + * TODO(sjg@chromium.org>): Update this to use driver model's device_remove(). + */ void board_quiesce_devices(void); #endif -- cgit v1.3.1