blob: ee54f19cbfdc7b7c961a460d143a903dd62e93b8 [file] [log] [blame]
Angel Ponsf94ac9a2020-04-05 15:46:48 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Duncan Lauriec88c54c2014-04-30 16:36:13 -07002
3#include <string.h>
Furquan Shaikh76cedd22020-05-02 10:24:23 -07004#include <acpi/acpi.h>
Angel Ponse4c8dc82021-02-07 23:40:41 +01005#include <cbmem.h>
Duncan Lauriec88c54c2014-04-30 16:36:13 -07006#include <console/console.h>
Aaron Durbin83a8df52015-03-27 21:01:52 -05007#include <console/streams.h>
Aaron Durbin460703b2015-03-27 21:17:22 -05008#include <program_loading.h>
Duncan Lauriec88c54c2014-04-30 16:36:13 -07009#include <rmodule.h>
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060010#include <stage_cache.h>
Julius Werner4ee4bd52014-10-20 13:46:39 -070011#include <soc/pei_data.h>
12#include <soc/pei_wrapper.h>
Kyösti Mälkki1ec23c92015-05-29 06:18:18 +030013#include <soc/pm.h>
Angel Pons12fc21b2021-06-16 16:57:21 +020014#include <soc/refcode.h>
Duncan Lauriec88c54c2014-04-30 16:36:13 -070015
Patrick Georgie6e94932015-06-22 22:26:45 +020016static pei_wrapper_entry_t load_reference_code(void)
Duncan Lauriec88c54c2014-04-30 16:36:13 -070017{
Angel Pons67df3ff2021-01-29 18:20:11 +010018 if (resume_from_stage_cache()) {
19 struct prog prog;
20 stage_cache_load_stage(STAGE_REFCODE, &prog);
21 return prog_entry(&prog);
22 }
23
Aaron Durbinac12c66c2015-05-20 12:08:55 -050024 struct prog prog =
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060025 PROG_INIT(PROG_REFCODE, CONFIG_CBFS_PREFIX "/refcode");
Duncan Lauriec88c54c2014-04-30 16:36:13 -070026 struct rmod_stage_load refcode = {
27 .cbmem_id = CBMEM_ID_REFCODE,
Aaron Durbin460703b2015-03-27 21:17:22 -050028 .prog = &prog,
Duncan Lauriec88c54c2014-04-30 16:36:13 -070029 };
Duncan Lauriec88c54c2014-04-30 16:36:13 -070030
Aaron Durbin899d13d2015-05-15 23:39:23 -050031 if (rmodule_stage_load(&refcode)) {
32 printk(BIOS_DEBUG, "Error loading reference code.\n");
33 return NULL;
34 }
Duncan Lauriec88c54c2014-04-30 16:36:13 -070035
36 /* Cache loaded reference code. */
Aaron Durbin899d13d2015-05-15 23:39:23 -050037 stage_cache_add(STAGE_REFCODE, &prog);
Duncan Lauriec88c54c2014-04-30 16:36:13 -070038
Patrick Georgie6e94932015-06-22 22:26:45 +020039 return (pei_wrapper_entry_t)prog_entry(&prog);
Duncan Lauriec88c54c2014-04-30 16:36:13 -070040}
41
42void broadwell_run_reference_code(void)
43{
Kenji Chen89f63882014-11-13 14:44:46 -080044 int ret, dummy;
Duncan Lauriec88c54c2014-04-30 16:36:13 -070045 struct pei_data pei_data;
46 pei_wrapper_entry_t entry;
47
48 memset(&pei_data, 0, sizeof(pei_data));
49 mainboard_fill_pei_data(&pei_data);
50 broadwell_fill_pei_data(&pei_data);
51
Aaron Durbin9e6d1432016-07-13 23:21:41 -050052 pei_data.boot_mode = acpi_is_wakeup_s3() ? ACPI_S3 : 0;
Elyes Haouas9018dee2022-11-18 15:07:33 +010053 pei_data.saved_data = (void *)&dummy;
Kenji Chen89f63882014-11-13 14:44:46 -080054
Duncan Lauriec88c54c2014-04-30 16:36:13 -070055 entry = load_reference_code();
56 if (entry == NULL) {
57 printk(BIOS_ERR, "Reference code not found\n");
58 return;
59 }
60
61 /* Call into reference code. */
62 ret = entry(&pei_data);
63 if (ret != 0) {
64 printk(BIOS_ERR, "Reference code returned %d\n", ret);
65 return;
66 }
67}