/* SPDX-License-Identifier: GPL-2.0-only */ #include #include #include #include #include #include #include #include #include #include #include /* SOC initialization after FSP silicon init */ __weak void soc_after_silicon_init(void) { } static void display_hob_info(FSP_INFO_HEADER *fsp_info_header) { const EFI_GUID graphics_info_guid = EFI_PEI_GRAPHICS_INFO_HOB_GUID; void *hob_list_ptr = get_hob_list(); /* Verify the HOBs */ if (hob_list_ptr == NULL) { printk(BIOS_ERR, "ERROR - HOB pointer is NULL!\n"); return; } if (CONFIG(DISPLAY_HOBS)) print_hob_type_structure(0, hob_list_ptr); /* * Verify that FSP is generating the required HOBs: * 7.1: FSP_BOOTLOADER_TEMP_MEMORY_HOB only produced for FSP 1.0 * 7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB verified by raminit * 7.3: FSP_NON_VOLATILE_STORAGE_HOB verified by raminit * 7.4: FSP_BOOTLOADER_TOLUM_HOB verified by raminit * 7.5: EFI_PEI_GRAPHICS_INFO_HOB verified below, * if the ImageAttribute bit is set * FSP_SMBIOS_MEMORY_INFO HOB verified by raminit */ if ((fsp_info_header->ImageAttribute & GRAPHICS_SUPPORT_BIT) && !get_next_guid_hob(&graphics_info_guid, hob_list_ptr) && CONFIG(DISPLAY_HOBS)) { printk(BIOS_ERR, "7.5: EFI_PEI_GRAPHICS_INFO_HOB missing!\n"); printk(BIOS_ERR, "ERROR - Missing one or more required FSP HOBs!\n"); } } void fsp_run_silicon_init(FSP_INFO_HEADER *fsp_info_header, int is_s3_wakeup) { FSP_SILICON_INIT fsp_silicon_init; SILICON_INIT_UPD *original_params; SILICON_INIT_UPD silicon_init_params; EFI_STATUS status; UPD_DATA_REGION *upd_ptr; VPD_DATA_REGION *vpd_ptr; const struct cbmem_entry *logo_entry = NULL; /* Display the FSP header */ if (fsp_info_header == NULL) { printk(BIOS_ERR, "FSP_INFO_HEADER not set!\n"); return; } print_fsp_info(fsp_info_header); /* Initialize the UPD values */ vpd_ptr = (VPD_DATA_REGION *)(fsp_info_header->CfgRegionOffset + fsp_info_header->ImageBase); printk(BIOS_DEBUG, "%p: VPD Data\n", vpd_ptr); upd_ptr = (UPD_DATA_REGION *)(vpd_ptr->PcdUpdRegionOffset + fsp_info_header->ImageBase); printk(BIOS_DEBUG, "%p: UPD Data\n", upd_ptr); original_params = (void *)((u8 *)upd_ptr + upd_ptr->SiliconInitUpdOffset); memcpy(&silicon_init_params, original_params, sizeof(silicon_init_params)); soc_silicon_init_params(&silicon_init_params); /* Locate VBT and pass to FSP GOP */ if (CONFIG(RUN_FSP_GOP)) load_vbt(&silicon_init_params); mainboard_silicon_init_params(&silicon_init_params); if (CONFIG(FSP1_1_DISPLAY_LOGO) && !is_s3_wakeup) logo_entry = soc_load_logo(&silicon_init_params); /* Display the UPD data */ if (CONFIG(DISPLAY_UPD_DATA)) soc_display_silicon_init_params(original_params, &silicon_init_params); /* Perform silicon initialization after RAM is configured */ printk(BIOS_DEBUG, "Calling FspSiliconInit\n"); fsp_silicon_init = (FSP_SILICON_INIT)(fsp_info_header->ImageBase + fsp_info_header->FspSiliconInitEntryOffset); timestamp_add_now(TS_FSP_SILICON_INIT_START); printk(BIOS_DEBUG, "Calling FspSiliconInit(%p) at %p\n", &silicon_init_params, fsp_silicon_init); post_code(POST_FSP_SILICON_INIT); status = fsp_silicon_init(&silicon_init_params); timestamp_add_now(TS_FSP_SILICON_INIT_END); printk(BIOS_DEBUG, "FspSiliconInit returned 0x%08x\n", status); /* The logo_entry can be freed up now as it is not required any longer */ if (logo_entry && !is_s3_wakeup) cbmem_entry_remove(logo_entry); /* Mark graphics init done after SiliconInit if VBT was provided */ #if CONFIG(RUN_FSP_GOP) /* GraphicsConfigPtr doesn't exist in Quark X1000's FSP, so this needs * to be #if'd out instead of using if (). */ if (silicon_init_params.GraphicsConfigPtr) gfx_set_init_done(1); #endif if (CONFIG(RUN_FSP_GOP)) { const EFI_GUID vbt_guid = EFI_PEI_GRAPHICS_INFO_HOB_GUID; u32 *vbt_hob; void *hob_list_ptr = get_hob_list(); vbt_hob = get_next_guid_hob(&vbt_guid, hob_list_ptr); if (vbt_hob == NULL) { printk(BIOS_ERR, "FSP_ERR: Graphics Data HOB is not present\n"); } else { EFI_PEI_GRAPHICS_INFO_HOB *gop; printk(BIOS_DEBUG, "FSP_DEBUG: Graphics Data HOB present\n"); gop = GET_GUID_HOB_DATA(vbt_hob); fb_add_framebuffer_info(gop->FrameBufferBase, gop->GraphicsMode.HorizontalResolution, gop->GraphicsMode.VerticalResolution, gop->GraphicsMode.PixelsPerScanLine * 4, 32); } } display_hob_info(fsp_info_header); soc_after_silicon_init(); } static int fsp_find_and_relocate(struct prog *fsp) { if (prog_locate(fsp)) { printk(BIOS_ERR, "ERROR: Couldn't find %s\n", prog_name(fsp)); return -1; } if (fsp_relocate(fsp, prog_rdev(fsp))) { printk(BIOS_ERR, "ERROR: FSP relocation failed.\n"); return -1; } return 0; } static void fsp_load(void) { struct prog fsp = PROG_INIT(PROG_REFCODE, "fsp.bin"); if (resume_from_stage_cache()) { stage_cache_load_stage(STAGE_REFCODE, &fsp); } else { fsp_find_and_relocate(&fsp); if (prog_entry(&fsp)) stage_cache_add(STAGE_REFCODE, &fsp); } /* FSP_INFO_HEADER is set as the program entry. */ fsp_update_fih(prog_entry(&fsp)); } void intel_silicon_init(void) { fsp_load(); fsp_run_silicon_init(fsp_get_fih(), acpi_is_wakeup_s3()); } /* Initialize the UPD parameters for SiliconInit */ __weak void mainboard_silicon_init_params( SILICON_INIT_UPD *params) { }; /* Display the UPD parameters for SiliconInit */ __weak void soc_display_silicon_init_params( const SILICON_INIT_UPD *old, SILICON_INIT_UPD *new) { printk(BIOS_SPEW, "UPD values for SiliconInit:\n"); hexdump32(BIOS_SPEW, new, sizeof(*new)); } /* Initialize the UPD parameters for SiliconInit */ __weak void soc_silicon_init_params(SILICON_INIT_UPD *params) { }