diff options
author | Tom Rini <trini@konsulko.com> | 2019-10-08 18:45:26 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2019-10-08 18:45:26 -0400 |
commit | efea5a34bb5be542630ce7161bd3b9cc26a0bcf3 (patch) | |
tree | fb747d83d81f9c3400a561782114e4c6ecd61a07 /arch/x86/lib | |
parent | 9d536fe8ae7672bdee091f9100389b6f3e53cfc6 (diff) | |
parent | cc2d27dcdc3e1c76d09d54015e3992380bd7e0fa (diff) |
Merge https://gitlab.denx.de/u-boot/custodians/u-boot-x86
- Rename existing FSP code to fsp1
- Add fsp2 directory in preparation to support FSP 2.0
- Various x86 platform codes update
- Various bug fixes and updates in dm core, sandbox and spl
Diffstat (limited to 'arch/x86/lib')
-rw-r--r-- | arch/x86/lib/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/lib/acpi_s3.c | 2 | ||||
-rw-r--r-- | arch/x86/lib/coreboot_table.c | 2 | ||||
-rw-r--r-- | arch/x86/lib/fsp/Makefile | 4 | ||||
-rw-r--r-- | arch/x86/lib/fsp/fsp_common.c | 65 | ||||
-rw-r--r-- | arch/x86/lib/fsp/fsp_dram.c | 38 | ||||
-rw-r--r-- | arch/x86/lib/fsp/fsp_support.c | 203 | ||||
-rw-r--r-- | arch/x86/lib/fsp1/Makefile | 9 | ||||
-rw-r--r-- | arch/x86/lib/fsp1/fsp_car.S (renamed from arch/x86/lib/fsp/fsp_car.S) | 10 | ||||
-rw-r--r-- | arch/x86/lib/fsp1/fsp_common.c | 77 | ||||
-rw-r--r-- | arch/x86/lib/fsp1/fsp_dram.c | 36 | ||||
-rw-r--r-- | arch/x86/lib/fsp1/fsp_graphics.c (renamed from arch/x86/lib/fsp/fsp_graphics.c) | 2 | ||||
-rw-r--r-- | arch/x86/lib/fsp1/fsp_support.c | 199 | ||||
-rw-r--r-- | arch/x86/lib/hob.c | 8 | ||||
-rw-r--r-- | arch/x86/lib/init_helpers.c | 22 | ||||
-rw-r--r-- | arch/x86/lib/lpc-uclass.c | 2 | ||||
-rw-r--r-- | arch/x86/lib/spl.c | 13 | ||||
-rw-r--r-- | arch/x86/lib/tpl.c | 7 |
18 files changed, 387 insertions, 314 deletions
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 906be5eab9..ca0ca1066b 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -44,6 +44,8 @@ obj-$(CONFIG_CMD_ZBOOT) += zimage.o endif obj-$(CONFIG_USE_HOB) += hob.o obj-$(CONFIG_HAVE_FSP) += fsp/ +obj-$(CONFIG_FSP_VERSION1) += fsp1/ +obj-$(CONFIG_FSP_VERSION2) += fsp2/ ifdef CONFIG_SPL_BUILD ifdef CONFIG_TPL_BUILD diff --git a/arch/x86/lib/acpi_s3.c b/arch/x86/lib/acpi_s3.c index 03917188a9..197636c4b5 100644 --- a/arch/x86/lib/acpi_s3.c +++ b/arch/x86/lib/acpi_s3.c @@ -4,8 +4,8 @@ */ #include <common.h> +#include <acpi_s3.h> #include <asm/acpi.h> -#include <asm/acpi_s3.h> #include <asm/acpi_table.h> #include <asm/post.h> #include <linux/linkage.h> diff --git a/arch/x86/lib/coreboot_table.c b/arch/x86/lib/coreboot_table.c index 2d08a2db0d..8685aa3046 100644 --- a/arch/x86/lib/coreboot_table.c +++ b/arch/x86/lib/coreboot_table.c @@ -4,8 +4,8 @@ */ #include <common.h> +#include <acpi_s3.h> #include <vbe.h> -#include <asm/acpi_s3.h> #include <asm/coreboot_tables.h> #include <asm/e820.h> diff --git a/arch/x86/lib/fsp/Makefile b/arch/x86/lib/fsp/Makefile index 870de71bd7..9e34856473 100644 --- a/arch/x86/lib/fsp/Makefile +++ b/arch/x86/lib/fsp/Makefile @@ -1,9 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ # -# Copyright (C) 2015 Google, Inc +# Copyright 2019 Google LLC -obj-y += fsp_car.o obj-y += fsp_common.o obj-y += fsp_dram.o -obj-$(CONFIG_VIDEO_FSP) += fsp_graphics.o obj-y += fsp_support.o diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c index ed0827c6e9..40ba866d77 100644 --- a/arch/x86/lib/fsp/fsp_common.c +++ b/arch/x86/lib/fsp/fsp_common.c @@ -4,10 +4,10 @@ */ #include <common.h> +#include <acpi_s3.h> #include <dm.h> #include <errno.h> #include <rtc.h> -#include <asm/acpi_s3.h> #include <asm/cmos_layout.h> #include <asm/early_cmos.h> #include <asm/io.h> @@ -55,11 +55,9 @@ void board_final_cleanup(void) debug("fail, error code %x\n", status); else debug("OK\n"); - - return; } -static __maybe_unused void *fsp_prepare_mrc_cache(void) +void *fsp_prepare_mrc_cache(void) { struct mrc_data_container *cache; struct mrc_region entry; @@ -104,62 +102,3 @@ int fsp_save_s3_stack(void) return 0; } #endif - -int arch_fsp_init(void) -{ - void *nvs; - int stack = CONFIG_FSP_TEMP_RAM_ADDR; - int boot_mode = BOOT_FULL_CONFIG; -#ifdef CONFIG_HAVE_ACPI_RESUME - int prev_sleep_state = chipset_prev_sleep_state(); - gd->arch.prev_sleep_state = prev_sleep_state; -#endif - - if (!gd->arch.hob_list) { -#ifdef CONFIG_ENABLE_MRC_CACHE - nvs = fsp_prepare_mrc_cache(); -#else - nvs = NULL; -#endif - -#ifdef CONFIG_HAVE_ACPI_RESUME - if (prev_sleep_state == ACPI_S3) { - if (nvs == NULL) { - /* If waking from S3 and no cache then */ - debug("No MRC cache found in S3 resume path\n"); - post_code(POST_RESUME_FAILURE); - /* Clear Sleep Type */ - chipset_clear_sleep_state(); - /* Reboot */ - debug("Rebooting..\n"); - outb(SYS_RST | RST_CPU, IO_PORT_RESET); - /* Should not reach here.. */ - panic("Reboot System"); - } - - /* - * DM is not available yet at this point, hence call - * CMOS access library which does not depend on DM. - */ - stack = cmos_read32(CMOS_FSP_STACK_ADDR); - boot_mode = BOOT_ON_S3_RESUME; - } -#endif - /* - * The first time we enter here, call fsp_init(). - * Note the execution does not return to this function, - * instead it jumps to fsp_continue(). - */ - fsp_init(stack, boot_mode, nvs); - } else { - /* - * The second time we enter here, adjust the size of malloc() - * pool before relocation. Given gd->malloc_base was adjusted - * after the call to board_init_f_init_reserve() in arch/x86/ - * cpu/start.S, we should fix up gd->malloc_limit here. - */ - gd->malloc_limit += CONFIG_FSP_SYS_MALLOC_F_LEN; - } - - return 0; -} diff --git a/arch/x86/lib/fsp/fsp_dram.c b/arch/x86/lib/fsp/fsp_dram.c index 3a23b70410..2d1023068f 100644 --- a/arch/x86/lib/fsp/fsp_dram.c +++ b/arch/x86/lib/fsp/fsp_dram.c @@ -4,6 +4,7 @@ */ #include <common.h> +#include <handoff.h> #include <asm/fsp/fsp_support.h> #include <asm/e820.h> #include <asm/mrccache.h> @@ -11,7 +12,7 @@ DECLARE_GLOBAL_DATA_PTR; -int dram_init(void) +int fsp_scan_for_ram_size(void) { phys_size_t ram_size = 0; const struct hob_header *hdr; @@ -22,9 +23,8 @@ int dram_init(void) if (hdr->type == HOB_TYPE_RES_DESC) { res_desc = (struct hob_res_desc *)hdr; if (res_desc->type == RES_SYS_MEM || - res_desc->type == RES_MEM_RESERVED) { + res_desc->type == RES_MEM_RESERVED) ram_size += res_desc->len; - } } hdr = get_next_hob(hdr); } @@ -32,13 +32,8 @@ int dram_init(void) gd->ram_size = ram_size; post_code(POST_DRAM); -#ifdef CONFIG_ENABLE_MRC_CACHE - gd->arch.mrc_output = fsp_get_nvs_data(gd->arch.hob_list, - &gd->arch.mrc_output_len); -#endif - return 0; -} +}; int dram_init_banksize(void) { @@ -48,19 +43,6 @@ int dram_init_banksize(void) return 0; } -/* - * This function looks for the highest region of memory lower than 4GB which - * has enough space for U-Boot where U-Boot is aligned on a page boundary. - * It overrides the default implementation found elsewhere which simply - * picks the end of ram, wherever that may be. The location of the stack, - * the relocation address, and how far U-Boot is moved by relocation are - * set in the global data structure. - */ -ulong board_get_usable_ram_top(ulong total_size) -{ - return fsp_get_usable_lowmem_top(gd->arch.hob_list); -} - unsigned int install_e820_map(unsigned int max_entries, struct e820_entry *entries) { @@ -98,7 +80,7 @@ unsigned int install_e820_map(unsigned int max_entries, * reserved in order for ACPI S3 resume to work. */ entries[num_entries].addr = gd->start_addr_sp - CONFIG_STACK_SIZE; - entries[num_entries].size = gd->ram_top - gd->start_addr_sp + \ + entries[num_entries].size = gd->ram_top - gd->start_addr_sp + CONFIG_STACK_SIZE; entries[num_entries].type = E820_RESERVED; num_entries++; @@ -106,3 +88,13 @@ unsigned int install_e820_map(unsigned int max_entries, return num_entries; } + +#if CONFIG_IS_ENABLED(HANDOFF) && IS_ENABLED(CONFIG_USE_HOB) +int handoff_arch_save(struct spl_handoff *ho) +{ + ho->arch.usable_ram_top = fsp_get_usable_lowmem_top(gd->arch.hob_list); + ho->arch.hob_list = gd->arch.hob_list; + + return 0; +} +#endif diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c index 0eaa9b232b..983888fd74 100644 --- a/arch/x86/lib/fsp/fsp_support.c +++ b/arch/x86/lib/fsp/fsp_support.c @@ -5,199 +5,9 @@ */ #include <common.h> -#include <asm/fsp/fsp_support.h> +#include <asm/fsp1/fsp_support.h> #include <asm/post.h> -struct fsp_header *__attribute__((optimize("O0"))) find_fsp_header(void) -{ - /* - * This function may be called before the a stack is established, - * so special care must be taken. First, it cannot declare any local - * variable using stack. Only register variable can be used here. - * Secondly, some compiler version will add prolog or epilog code - * for the C function. If so the function call may not work before - * stack is ready. - * - * GCC 4.8.1 has been verified to be working for the following codes. - */ - volatile register u8 *fsp asm("eax"); - - /* Initalize the FSP base */ - fsp = (u8 *)CONFIG_FSP_ADDR; - - /* Check the FV signature, _FVH */ - if (((struct fv_header *)fsp)->sign == EFI_FVH_SIGNATURE) { - /* Go to the end of the FV header and align the address */ - fsp += ((struct fv_header *)fsp)->ext_hdr_off; - fsp += ((struct fv_ext_header *)fsp)->ext_hdr_size; - fsp = (u8 *)(((u32)fsp + 7) & 0xFFFFFFF8); - } else { - fsp = 0; - } - - /* Check the FFS GUID */ - if (fsp && - ((struct ffs_file_header *)fsp)->name.b[0] == FSP_GUID_BYTE0 && - ((struct ffs_file_header *)fsp)->name.b[1] == FSP_GUID_BYTE1 && - ((struct ffs_file_header *)fsp)->name.b[2] == FSP_GUID_BYTE2 && - ((struct ffs_file_header *)fsp)->name.b[3] == FSP_GUID_BYTE3 && - ((struct ffs_file_header *)fsp)->name.b[4] == FSP_GUID_BYTE4 && - ((struct ffs_file_header *)fsp)->name.b[5] == FSP_GUID_BYTE5 && - ((struct ffs_file_header *)fsp)->name.b[6] == FSP_GUID_BYTE6 && - ((struct ffs_file_header *)fsp)->name.b[7] == FSP_GUID_BYTE7 && - ((struct ffs_file_header *)fsp)->name.b[8] == FSP_GUID_BYTE8 && - ((struct ffs_file_header *)fsp)->name.b[9] == FSP_GUID_BYTE9 && - ((struct ffs_file_header *)fsp)->name.b[10] == FSP_GUID_BYTE10 && - ((struct ffs_file_header *)fsp)->name.b[11] == FSP_GUID_BYTE11 && - ((struct ffs_file_header *)fsp)->name.b[12] == FSP_GUID_BYTE12 && - ((struct ffs_file_header *)fsp)->name.b[13] == FSP_GUID_BYTE13 && - ((struct ffs_file_header *)fsp)->name.b[14] == FSP_GUID_BYTE14 && - ((struct ffs_file_header *)fsp)->name.b[15] == FSP_GUID_BYTE15) { - /* Add the FFS header size to find the raw section header */ - fsp += sizeof(struct ffs_file_header); - } else { - fsp = 0; - } - - if (fsp && - ((struct raw_section *)fsp)->type == EFI_SECTION_RAW) { - /* Add the raw section header size to find the FSP header */ - fsp += sizeof(struct raw_section); - } else { - fsp = 0; - } - - return (struct fsp_header *)fsp; -} - -void fsp_continue(u32 status, void *hob_list) -{ - post_code(POST_MRC); - - assert(status == 0); - - /* The boot loader main function entry */ - fsp_init_done(hob_list); -} - -void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) -{ - struct fsp_config_data config_data; - fsp_init_f init; - struct fsp_init_params params; - struct fspinit_rtbuf rt_buf; - struct fsp_header *fsp_hdr; - struct fsp_init_params *params_ptr; -#ifdef CONFIG_FSP_USE_UPD - struct vpd_region *fsp_vpd; - struct upd_region *fsp_upd; -#endif - - fsp_hdr = find_fsp_header(); - if (fsp_hdr == NULL) { - /* No valid FSP info header was found */ - panic("Invalid FSP header"); - } - - config_data.common.fsp_hdr = fsp_hdr; - config_data.common.stack_top = stack_top; - config_data.common.boot_mode = boot_mode; - -#ifdef CONFIG_FSP_USE_UPD - /* Get VPD region start */ - fsp_vpd = (struct vpd_region *)(fsp_hdr->img_base + - fsp_hdr->cfg_region_off); - - /* Verify the VPD data region is valid */ - assert(fsp_vpd->sign == VPD_IMAGE_ID); - - fsp_upd = &config_data.fsp_upd; - - /* Copy default data from Flash */ - memcpy(fsp_upd, (void *)(fsp_hdr->img_base + fsp_vpd->upd_offset), - sizeof(struct upd_region)); - - /* Verify the UPD data region is valid */ - assert(fsp_upd->terminator == UPD_TERMINATOR); -#endif - - memset(&rt_buf, 0, sizeof(struct fspinit_rtbuf)); - - /* Override any configuration if required */ - update_fsp_configs(&config_data, &rt_buf); - - memset(¶ms, 0, sizeof(struct fsp_init_params)); - params.nvs_buf = nvs_buf; - params.rt_buf = (struct fspinit_rtbuf *)&rt_buf; - params.continuation = (fsp_continuation_f)asm_continuation; - - init = (fsp_init_f)(fsp_hdr->img_base + fsp_hdr->fsp_init); - params_ptr = ¶ms; - - post_code(POST_PRE_MRC); - - /* Load GDT for FSP */ - setup_fsp_gdt(); - - /* - * Use ASM code to ensure the register value in EAX & EDX - * will be passed into fsp_continue - */ - asm volatile ( - "pushl %0;" - "call *%%eax;" - ".global asm_continuation;" - "asm_continuation:;" - "movl 4(%%esp), %%eax;" /* status */ - "movl 8(%%esp), %%edx;" /* hob_list */ - "jmp fsp_continue;" - : : "m"(params_ptr), "a"(init) - ); - - /* - * Should never get here. - * Control will continue from fsp_continue. - * This line below is to prevent the compiler from optimizing - * structure intialization. - * - * DO NOT REMOVE! - */ - init(¶ms); -} - -u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase) -{ - fsp_notify_f notify; - struct fsp_notify_params params; - struct fsp_notify_params *params_ptr; - u32 status; - - if (!fsp_hdr) - fsp_hdr = (struct fsp_header *)find_fsp_header(); - - if (fsp_hdr == NULL) { - /* No valid FSP info header */ - panic("Invalid FSP header"); - } - - notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify); - params.phase = phase; - params_ptr = ¶ms; - - /* - * Use ASM code to ensure correct parameter is on the stack for - * FspNotify as U-Boot is using different ABI from FSP - */ - asm volatile ( - "pushl %1;" /* push notify phase */ - "call *%%eax;" /* call FspNotify */ - "addl $4, %%esp;" /* clean up the stack */ - : "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr) - ); - - return status; -} - u32 fsp_get_usable_lowmem_top(const void *hob_list) { const struct hob_header *hdr; @@ -324,7 +134,7 @@ u32 fsp_get_fsp_reserved_mem(const void *hob_list, u32 *len) base = (u32)fsp_get_reserved_mem_from_guid(hob_list, &length, &guid); - if ((len != 0) && (base != 0)) + if (len && base) *len = (u32)length; return base; @@ -338,7 +148,7 @@ u32 fsp_get_tseg_reserved_mem(const void *hob_list, u32 *len) base = (u32)fsp_get_reserved_mem_from_guid(hob_list, &length, &guid); - if ((len != 0) && (base != 0)) + if (len && base) *len = (u32)length; return base; @@ -351,6 +161,13 @@ void *fsp_get_nvs_data(const void *hob_list, u32 *len) return hob_get_guid_hob_data(hob_list, len, &guid); } +void *fsp_get_var_nvs_data(const void *hob_list, u32 *len) +{ + const efi_guid_t guid = FSP_VARIABLE_NV_DATA_HOB_GUID; + + return hob_get_guid_hob_data(hob_list, len, &guid); +} + void *fsp_get_bootloader_tmp_mem(const void *hob_list, u32 *len) { const efi_guid_t guid = FSP_BOOTLOADER_TEMP_MEM_HOB_GUID; diff --git a/arch/x86/lib/fsp1/Makefile b/arch/x86/lib/fsp1/Makefile new file mode 100644 index 0000000000..870de71bd7 --- /dev/null +++ b/arch/x86/lib/fsp1/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2015 Google, Inc + +obj-y += fsp_car.o +obj-y += fsp_common.o +obj-y += fsp_dram.o +obj-$(CONFIG_VIDEO_FSP) += fsp_graphics.o +obj-y += fsp_support.o diff --git a/arch/x86/lib/fsp/fsp_car.S b/arch/x86/lib/fsp1/fsp_car.S index 8c54cea3db..a64a653435 100644 --- a/arch/x86/lib/fsp/fsp_car.S +++ b/arch/x86/lib/fsp1/fsp_car.S @@ -20,10 +20,10 @@ car_init: car_init_start: post_code(POST_CAR_START) - lea find_fsp_header_romstack, %esp - jmp find_fsp_header + lea fsp_find_header_romstack, %esp + jmp fsp_find_header -find_fsp_header_ret: +fsp_find_header_ret: /* EAX points to FSP_INFO_HEADER */ mov %eax, %ebp @@ -91,8 +91,8 @@ die: * contain the function return address as well as the parameters. */ .balign 4 -find_fsp_header_romstack: - .long find_fsp_header_ret +fsp_find_header_romstack: + .long fsp_find_header_ret .balign 4 temp_ram_init_romstack: diff --git a/arch/x86/lib/fsp1/fsp_common.c b/arch/x86/lib/fsp1/fsp_common.c new file mode 100644 index 0000000000..e8066d8de3 --- /dev/null +++ b/arch/x86/lib/fsp1/fsp_common.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#include <common.h> +#include <acpi_s3.h> +#include <dm.h> +#include <errno.h> +#include <rtc.h> +#include <asm/cmos_layout.h> +#include <asm/early_cmos.h> +#include <asm/io.h> +#include <asm/mrccache.h> +#include <asm/post.h> +#include <asm/processor.h> +#include <asm/fsp1/fsp_support.h> + +DECLARE_GLOBAL_DATA_PTR; + +int arch_fsp_init(void) +{ + void *nvs; + int stack = CONFIG_FSP_TEMP_RAM_ADDR; + int boot_mode = BOOT_FULL_CONFIG; +#ifdef CONFIG_HAVE_ACPI_RESUME + int prev_sleep_state = chipset_prev_sleep_state(); + gd->arch.prev_sleep_state = prev_sleep_state; +#endif + + if (!gd->arch.hob_list) { + if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) + nvs = fsp_prepare_mrc_cache(); + else + nvs = NULL; + +#ifdef CONFIG_HAVE_ACPI_RESUME + if (prev_sleep_state == ACPI_S3) { + if (nvs == NULL) { + /* If waking from S3 and no cache then */ + debug("No MRC cache found in S3 resume path\n"); + post_code(POST_RESUME_FAILURE); + /* Clear Sleep Type */ + chipset_clear_sleep_state(); + /* Reboot */ + debug("Rebooting..\n"); + outb(SYS_RST | RST_CPU, IO_PORT_RESET); + /* Should not reach here.. */ + panic("Reboot System"); + } + + /* + * DM is not available yet at this point, hence call + * CMOS access library which does not depend on DM. + */ + stack = cmos_read32(CMOS_FSP_STACK_ADDR); + boot_mode = BOOT_ON_S3_RESUME; + } +#endif + /* + * The first time we enter here, call fsp_init(). + * Note the execution does not return to this function, + * instead it jumps to fsp_continue(). + */ + fsp_init(stack, boot_mode, nvs); + } else { + /* + * The second time we enter here, adjust the size of malloc() + * pool before relocation. Given gd->malloc_base was adjusted + * after the call to board_init_f_init_reserve() in arch/x86/ + * cpu/start.S, we should fix up gd->malloc_limit here. + */ + gd->malloc_limit += CONFIG_FSP_SYS_MALLOC_F_LEN; + } + + return 0; +} diff --git a/arch/x86/lib/fsp1/fsp_dram.c b/arch/x86/lib/fsp1/fsp_dram.c new file mode 100644 index 0000000000..6a3349b42a --- /dev/null +++ b/arch/x86/lib/fsp1/fsp_dram.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#include <common.h> +#include <asm/fsp/fsp_support.h> + +int dram_init(void) +{ + int ret; + + /* The FSP has already set up DRAM, so grab the info we need */ + ret = fsp_scan_for_ram_size(); + if (ret) + return ret; + + if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) + gd->arch.mrc_output = fsp_get_nvs_data(gd->arch.hob_list, + &gd->arch.mrc_output_len); + + return 0; +} + +/* + * This function looks for the highest region of memory lower than 4GB which + * has enough space for U-Boot where U-Boot is aligned on a page boundary. + * It overrides the default implementation found elsewhere which simply + * picks the end of ram, wherever that may be. The location of the stack, + * the relocation address, and how far U-Boot is moved by relocation are + * set in the global data structure. + */ +ulong board_get_usable_ram_top(ulong total_size) +{ + return fsp_get_usable_lowmem_top(gd->arch.hob_list); +} diff --git a/arch/x86/lib/fsp/fsp_graphics.c b/arch/x86/lib/fsp1/fsp_graphics.c index 91d2d08557..52e71334f9 100644 --- a/arch/x86/lib/fsp/fsp_graphics.c +++ b/arch/x86/lib/fsp1/fsp_graphics.c @@ -7,7 +7,7 @@ #include <dm.h> #include <vbe.h> #include <video.h> -#include <asm/fsp/fsp_support.h> +#include <asm/fsp1/fsp_support.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/x86/lib/fsp1/fsp_support.c b/arch/x86/lib/fsp1/fsp_support.c new file mode 100644 index 0000000000..c7a2c73846 --- /dev/null +++ b/arch/x86/lib/fsp1/fsp_support.c @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: Intel +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#include <common.h> +#include <asm/fsp1/fsp_support.h> +#include <asm/post.h> + +struct fsp_header *__attribute__((optimize("O0"))) fsp_find_header(void) +{ + /* + * This function may be called before the a stack is established, + * so special care must be taken. First, it cannot declare any local + * variable using stack. Only register variable can be used here. + * Secondly, some compiler version will add prolog or epilog code + * for the C function. If so the function call may not work before + * stack is ready. + * + * GCC 4.8.1 has been verified to be working for the following codes. + */ + volatile register u8 *fsp asm("eax"); + + /* Initalize the FSP base */ + fsp = (u8 *)CONFIG_FSP_ADDR; + + /* Check the FV signature, _FVH */ + if (((struct fv_header *)fsp)->sign == EFI_FVH_SIGNATURE) { + /* Go to the end of the FV header and align the address */ + fsp += ((struct fv_header *)fsp)->ext_hdr_off; + fsp += ((struct fv_ext_header *)fsp)->ext_hdr_size; + fsp = (u8 *)(((u32)fsp + 7) & 0xFFFFFFF8); + } else { + fsp = 0; + } + + /* Check the FFS GUID */ + if (fsp && + ((struct ffs_file_header *)fsp)->name.b[0] == FSP_GUID_BYTE0 && + ((struct ffs_file_header *)fsp)->name.b[1] == FSP_GUID_BYTE1 && + ((struct ffs_file_header *)fsp)->name.b[2] == FSP_GUID_BYTE2 && + ((struct ffs_file_header *)fsp)->name.b[3] == FSP_GUID_BYTE3 && + ((struct ffs_file_header *)fsp)->name.b[4] == FSP_GUID_BYTE4 && + ((struct ffs_file_header *)fsp)->name.b[5] == FSP_GUID_BYTE5 && + ((struct ffs_file_header *)fsp)->name.b[6] == FSP_GUID_BYTE6 && + ((struct ffs_file_header *)fsp)->name.b[7] == FSP_GUID_BYTE7 && + ((struct ffs_file_header *)fsp)->name.b[8] == FSP_GUID_BYTE8 && + ((struct ffs_file_header *)fsp)->name.b[9] == FSP_GUID_BYTE9 && + ((struct ffs_file_header *)fsp)->name.b[10] == FSP_GUID_BYTE10 && + ((struct ffs_file_header *)fsp)->name.b[11] == FSP_GUID_BYTE11 && + ((struct ffs_file_header *)fsp)->name.b[12] == FSP_GUID_BYTE12 && + ((struct ffs_file_header *)fsp)->name.b[13] == FSP_GUID_BYTE13 && + ((struct ffs_file_header *)fsp)->name.b[14] == FSP_GUID_BYTE14 && + ((struct ffs_file_header *)fsp)->name.b[15] == FSP_GUID_BYTE15) { + /* Add the FFS header size to find the raw section header */ + fsp += sizeof(struct ffs_file_header); + } else { + fsp = 0; + } + + if (fsp && + ((struct raw_section *)fsp)->type == EFI_SECTION_RAW) { + /* Add the raw section header size to find the FSP header */ + fsp += sizeof(struct raw_section); + } else { + fsp = 0; + } + + return (struct fsp_header *)fsp; +} + +void fsp_continue(u32 status, void *hob_list) +{ + post_code(POST_MRC); + + assert(status == 0); + + /* The boot loader main function entry */ + fsp_init_done(hob_list); +} + +void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) +{ + struct fsp_config_data config_data; + fsp_init_f init; + struct fsp_init_params params; + struct fspinit_rtbuf rt_buf; + struct fsp_header *fsp_hdr; + struct fsp_init_params *params_ptr; +#ifdef CONFIG_FSP_USE_UPD + struct vpd_region *fsp_vpd; + struct upd_region *fsp_upd; +#endif + + fsp_hdr = fsp_find_header(); + if (fsp_hdr == NULL) { + /* No valid FSP info header was found */ + panic("Invalid FSP header"); + } + + config_data.common.fsp_hdr = fsp_hdr; + config_data.common.stack_top = stack_top; + config_data.common.boot_mode = boot_mode; + +#ifdef CONFIG_FSP_USE_UPD + /* Get VPD region start */ + fsp_vpd = (struct vpd_region *)(fsp_hdr->img_base + + fsp_hdr->cfg_region_off); + + /* Verify the VPD data region is valid */ + assert(fsp_vpd->sign == VPD_IMAGE_ID); + + fsp_upd = &config_data.fsp_upd; + + /* Copy default data from Flash */ + memcpy(fsp_upd, (void *)(fsp_hdr->img_base + fsp_vpd->upd_offset), + sizeof(struct upd_region)); + + /* Verify the UPD data region is valid */ + assert(fsp_upd->terminator == UPD_TERMINATOR); +#endif + + memset(&rt_buf, 0, sizeof(struct fspinit_rtbuf)); + + /* Override any configuration if required */ + fsp_update_configs(&config_data, &rt_buf); + + memset(¶ms, 0, sizeof(struct fsp_init_params)); + params.nvs_buf = nvs_buf; + params.rt_buf = (struct fspinit_rtbuf *)&rt_buf; + params.continuation = (fsp_continuation_f)fsp_asm_continuation; + + init = (fsp_init_f)(fsp_hdr->img_base + fsp_hdr->fsp_init); + params_ptr = ¶ms; + + post_code(POST_PRE_MRC); + + /* Load GDT for FSP */ + setup_fsp_gdt(); + + /* + * Use ASM code to ensure the register value in EAX & EDX + * will be passed into fsp_continue + */ + asm volatile ( + "pushl %0;" + "call *%%eax;" + ".global fsp_asm_continuation;" + "fsp_asm_continuation:;" + "movl 4(%%esp), %%eax;" /* status */ + "movl 8(%%esp), %%edx;" /* hob_list */ + "jmp fsp_continue;" + : : "m"(params_ptr), "a"(init) + ); + + /* + * Should never get here. + * Control will continue from fsp_continue. + * This line below is to prevent the compiler from optimizing + * structure intialization. + * + * DO NOT REMOVE! + */ + init(¶ms); +} + +u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase) +{ + fsp_notify_f notify; + struct fsp_notify_params params; + struct fsp_notify_params *params_ptr; + u32 status; + + if (!fsp_hdr) + fsp_hdr = (struct fsp_header *)fsp_find_header(); + + if (fsp_hdr == NULL) { + /* No valid FSP info header */ + panic("Invalid FSP header"); + } + + notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify); + params.phase = phase; + params_ptr = ¶ms; + + /* + * Use ASM code to ensure correct parameter is on the stack for + * FspNotify as U-Boot is using different ABI from FSP + */ + asm volatile ( + "pushl %1;" /* push notify phase */ + "call *%%eax;" /* call FspNotify */ + "addl $4, %%esp;" /* clean up the stack */ + : "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr) + ); + + return status; +} diff --git a/arch/x86/lib/hob.c b/arch/x86/lib/hob.c index dcee29b04c..f2c47240ee 100644 --- a/arch/x86/lib/hob.c +++ b/arch/x86/lib/hob.c @@ -13,7 +13,7 @@ * @type: HOB type to search * @hob_list: A pointer to the HOB list * - * @retval: A HOB object with matching type; Otherwise NULL. + * @return A HOB object with matching type; Otherwise NULL. */ const struct hob_header *hob_get_next_hob(uint type, const void *hob_list) { @@ -38,7 +38,7 @@ const struct hob_header *hob_get_next_hob(uint type, const void *hob_list) * @guid: GUID to search * @hob_list: A pointer to the HOB list * - * @retval: A HOB object with matching GUID; Otherwise NULL. + * @return A HOB object with matching GUID; Otherwise NULL. */ const struct hob_header *hob_get_next_guid_hob(const efi_guid_t *guid, const void *hob_list) @@ -65,8 +65,8 @@ const struct hob_header *hob_get_next_guid_hob(const efi_guid_t *guid, * If the GUID HOB is located, the length will be updated. * @guid A pointer to HOB GUID. * - * @retval NULL: Failed to find the GUID HOB. - * @retval others: GUID HOB data buffer pointer. + * @return NULL: Failed to find the GUID HOB. + * @return others: GUID HOB data buffer pointer. */ void *hob_get_guid_hob_data(const void *hob_list, u32 *len, const efi_guid_t *guid) diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index 4774a9bdb7..3e3a11ac2f 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -12,15 +12,23 @@ DECLARE_GLOBAL_DATA_PTR; int init_cache_f_r(void) { -#if CONFIG_IS_ENABLED(X86_32BIT_INIT) && !defined(CONFIG_HAVE_FSP) && \ - !defined(CONFIG_SYS_SLIMBOOTLOADER) + bool do_mtrr = CONFIG_IS_ENABLED(X86_32BIT_INIT) || + IS_ENABLED(CONFIG_FSP_VERSION2); int ret; - ret = mtrr_commit(false); - /* If MTRR MSR is not implemented by the processor, just ignore it */ - if (ret && ret != -ENOSYS) - return ret; -#endif + do_mtrr &= !IS_ENABLED(CONFIG_FSP_VERSION1) && + !IS_ENABLED(CONFIG_SYS_SLIMBOOTLOADER); + + if (do_mtrr) { + ret = mtrr_commit(false); + /* + * If MTRR MSR is not implemented by the processor, just ignore + * it + */ + if (ret && ret != -ENOSYS) + return ret; + } + /* Initialise the CPU cache(s) */ return init_cache(); } diff --git a/arch/x86/lib/lpc-uclass.c b/arch/x86/lib/lpc-uclass.c index 505d7a943d..1302a6e34a 100644 --- a/arch/x86/lib/lpc-uclass.c +++ b/arch/x86/lib/lpc-uclass.c @@ -10,5 +10,7 @@ UCLASS_DRIVER(lpc) = { .id = UCLASS_LPC, .name = "lpc", +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) .post_bind = dm_scan_fdt_dev, +#endif }; diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c index 5d5d1a9ca7..2baac91383 100644 --- a/arch/x86/lib/spl.c +++ b/arch/x86/lib/spl.c @@ -11,6 +11,7 @@ #include <asm/mrccache.h> #include <asm/mtrr.h> #include <asm/processor.h> +#include <asm/spl.h> #include <asm-generic/sections.h> DECLARE_GLOBAL_DATA_PTR; @@ -39,12 +40,7 @@ static int x86_spl_init(void) debug("%s: spl_init() failed\n", __func__); return ret; } -#ifdef CONFIG_TPL - /* Do a mini-init if TPL has already done the full init */ - ret = x86_cpu_reinit_f(); -#else ret = arch_cpu_init(); -#endif if (ret) { debug("%s: arch_cpu_init() failed\n", __func__); return ret; @@ -142,7 +138,7 @@ void board_init_f_r(void) u32 spl_boot_device(void) { - return BOOT_DEVICE_BOARD; + return BOOT_DEVICE_SPI_MMAP; } int spl_start_uboot(void) @@ -168,7 +164,7 @@ static int spl_board_load_image(struct spl_image_info *spl_image, return 0; } -SPL_LOAD_IMAGE_METHOD("SPI", 0, BOOT_DEVICE_BOARD, spl_board_load_image); +SPL_LOAD_IMAGE_METHOD("SPI", 5, BOOT_DEVICE_SPI_MMAP, spl_board_load_image); int spl_spi_load_image(void) { @@ -183,8 +179,7 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) printf("Jumping to 64-bit U-Boot: Note many features are missing\n"); ret = cpu_jump_to_64bit_uboot(spl_image->entry_point); debug("ret=%d\n", ret); - while (1) - ; + hang(); } #endif diff --git a/arch/x86/lib/tpl.c b/arch/x86/lib/tpl.c index 492a2d6521..cfefa78045 100644 --- a/arch/x86/lib/tpl.c +++ b/arch/x86/lib/tpl.c @@ -71,7 +71,7 @@ void board_init_f_r(void) u32 spl_boot_device(void) { return IS_ENABLED(CONFIG_CHROMEOS) ? BOOT_DEVICE_CROS_VBOOT : - BOOT_DEVICE_BOARD; + BOOT_DEVICE_SPI_MMAP; } int spl_start_uboot(void) @@ -97,7 +97,7 @@ static int spl_board_load_image(struct spl_image_info *spl_image, return 0; } -SPL_LOAD_IMAGE_METHOD("SPI", 0, BOOT_DEVICE_BOARD, spl_board_load_image); +SPL_LOAD_IMAGE_METHOD("SPI", 5, BOOT_DEVICE_SPI_MMAP, spl_board_load_image); int spl_spi_load_image(void) { @@ -108,8 +108,7 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { printf("Jumping to U-Boot SPL at %lx\n", (ulong)spl_image->entry_point); jump_to_spl(spl_image->entry_point); - while (1) - ; + hang(); } void spl_board_init(void) |