1 /* This file is part of the coreboot project. */
2 /* SPDX-License-Identifier: GPL-2.0-or-later */
6 #include <commonlib/fsp.h>
7 #include <commonlib/stdlib.h>
8 #include <console/console.h>
11 #include <program_loading.h>
12 #include <soc/intel/common/vbt.h>
13 #include <stage_cache.h>
15 #include <timestamp.h>
18 struct fsp_header fsps_hdr
;
20 static void do_silicon_init(struct fsp_header
*hdr
)
23 fsp_silicon_init_fn silicon_init
;
26 const struct cbmem_entry
*logo_entry
= NULL
;
28 supd
= (FSPS_UPD
*) (hdr
->cfg_region_offset
+ hdr
->image_base
);
30 if (supd
->FspUpdHeader
.Signature
!= FSPS_UPD_SIGNATURE
)
31 die_with_post_code(POST_INVALID_VENDOR_BINARY
,
32 "Invalid FSPS signature\n");
34 /* Disallow invalid config regions. Default settings are likely bad
35 * choices for coreboot, and different sized UPD from what the region
36 * allows is potentially a build problem.
38 if (!hdr
->cfg_region_size
|| hdr
->cfg_region_size
!= sizeof(FSPS_UPD
))
39 die_with_post_code(POST_INVALID_VENDOR_BINARY
,
40 "Invalid FSPS UPD region\n");
42 upd
= xmalloc(hdr
->cfg_region_size
);
44 memcpy(upd
, supd
, hdr
->cfg_region_size
);
46 /* Give SoC/mainboard a chance to populate entries */
47 platform_fsp_silicon_init_params_cb(upd
);
49 /* Populate logo related entries */
50 if (CONFIG(FSP2_0_DISPLAY_LOGO
))
51 logo_entry
= soc_load_logo(upd
);
53 /* Call SiliconInit */
54 silicon_init
= (void *) (hdr
->image_base
+
55 hdr
->silicon_init_entry_offset
);
56 fsp_debug_before_silicon_init(silicon_init
, supd
, upd
);
58 timestamp_add_now(TS_FSP_SILICON_INIT_START
);
59 post_code(POST_FSP_SILICON_INIT
);
60 status
= silicon_init(upd
);
61 timestamp_add_now(TS_FSP_SILICON_INIT_END
);
62 post_code(POST_FSP_SILICON_EXIT
);
65 cbmem_entry_remove(logo_entry
);
67 fsp_debug_after_silicon_init(status
);
69 /* Handle any errors returned by FspSiliconInit */
70 fsp_handle_reset(status
);
71 if (status
!= FSP_SUCCESS
) {
72 /* Assume video failure if attempted to initialize graphics */
73 if (CONFIG(RUN_FSP_GOP
) && vbt_get())
74 postcode
= POST_VIDEO_FAILURE
;
76 postcode
= POST_HW_INIT_FAILURE
; /* else generic */
78 printk(BIOS_SPEW
, "FspSiliconInit returned 0x%08x\n", status
);
79 die_with_post_code(postcode
,
80 "FspSiliconInit returned an error!\n");
84 void fsps_load(bool s3wake
)
86 struct fsp_header
*hdr
= &fsps_hdr
;
87 struct cbfsf file_desc
;
88 struct region_device rdev
;
89 const char *name
= CONFIG_FSP_S_CBFS
;
92 struct prog fsps
= PROG_INIT(PROG_REFCODE
, name
);
98 if (s3wake
&& !CONFIG(NO_STAGE_CACHE
)) {
99 printk(BIOS_DEBUG
, "Loading FSPS from stage_cache\n");
100 stage_cache_load_stage(STAGE_REFCODE
, &fsps
);
101 if (fsp_validate_component(hdr
, prog_rdev(&fsps
)) != CB_SUCCESS
)
102 die("On resume fsps header is invalid\n");
107 if (cbfs_boot_locate(&file_desc
, name
, NULL
)) {
108 printk(BIOS_ERR
, "Could not locate %s in CBFS\n", name
);
109 die("FSPS not available!\n");
112 cbfs_file_data(&rdev
, &file_desc
);
114 /* Load and relocate into CBMEM. */
115 size
= region_device_sz(&rdev
);
116 dest
= cbmem_add(CBMEM_ID_REFCODE
, size
);
119 die("Could not add FSPS to CBMEM!\n");
121 if (rdev_readat(&rdev
, dest
, 0, size
) < 0)
122 die("Failed to read FSPS!\n");
124 if (fsp_component_relocate((uintptr_t)dest
, dest
, size
) < 0)
125 die("Unable to relocate FSPS!\n");
127 /* Create new region device in memory after relocation. */
128 rdev_chain(&rdev
, &addrspace_32bit
.rdev
, (uintptr_t)dest
, size
);
130 if (fsp_validate_component(hdr
, &rdev
) != CB_SUCCESS
)
131 die("Invalid FSPS header!\n");
133 prog_set_area(&fsps
, dest
, size
);
135 stage_cache_add(STAGE_REFCODE
, &fsps
);
137 /* Signal that FSP component has been loaded. */
138 prog_segment_loaded(hdr
->image_base
, hdr
->image_size
, SEG_FINAL
);
142 void fsp_silicon_init(bool s3wake
)
145 do_silicon_init(&fsps_hdr
);
148 /* Load bmp and set FSP parameters, fsp_load_logo can be used */
149 __weak
const struct cbmem_entry
*soc_load_logo(FSPS_UPD
*supd
)