blob: c4179f159cc0703872c7e4ccaeead1ece56abd66 [file] [log] [blame]
Duncan Lauriec88c54c2014-04-30 16:36:13 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Google Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Duncan Lauriec88c54c2014-04-30 16:36:13 -070014 */
15
16#include <string.h>
17#include <arch/acpi.h>
18#include <cbmem.h>
19#include <console/console.h>
Aaron Durbin83a8df52015-03-27 21:01:52 -050020#include <console/streams.h>
Duncan Lauriec88c54c2014-04-30 16:36:13 -070021#include <cpu/x86/tsc.h>
Aaron Durbin460703b2015-03-27 21:17:22 -050022#include <program_loading.h>
Duncan Lauriec88c54c2014-04-30 16:36:13 -070023#include <rmodule.h>
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060024#include <stage_cache.h>
Duncan Lauriec88c54c2014-04-30 16:36:13 -070025#include <string.h>
Julius Werner4ee4bd52014-10-20 13:46:39 -070026#include <soc/pei_data.h>
27#include <soc/pei_wrapper.h>
Kyösti Mälkki1ec23c92015-05-29 06:18:18 +030028#include <soc/pm.h>
Julius Werner4ee4bd52014-10-20 13:46:39 -070029#include <soc/ramstage.h>
Duncan Lauriec88c54c2014-04-30 16:36:13 -070030
Duncan Lauriec88c54c2014-04-30 16:36:13 -070031static pei_wrapper_entry_t load_refcode_from_cache(void)
32{
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060033 struct prog refcode;
Duncan Lauriec88c54c2014-04-30 16:36:13 -070034
35 printk(BIOS_DEBUG, "refcode loading from cache.\n");
36
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060037 stage_cache_load_stage(STAGE_REFCODE, &refcode);
Duncan Lauriec88c54c2014-04-30 16:36:13 -070038
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060039 return (pei_wrapper_entry_t)prog_entry(&refcode);
Duncan Lauriec88c54c2014-04-30 16:36:13 -070040}
41
Patrick Georgie6e94932015-06-22 22:26:45 +020042static pei_wrapper_entry_t load_reference_code(void)
Duncan Lauriec88c54c2014-04-30 16:36:13 -070043{
Aaron Durbinac12c66c2015-05-20 12:08:55 -050044 struct prog prog =
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060045 PROG_INIT(PROG_REFCODE, CONFIG_CBFS_PREFIX "/refcode");
Duncan Lauriec88c54c2014-04-30 16:36:13 -070046 struct rmod_stage_load refcode = {
47 .cbmem_id = CBMEM_ID_REFCODE,
Aaron Durbin460703b2015-03-27 21:17:22 -050048 .prog = &prog,
Duncan Lauriec88c54c2014-04-30 16:36:13 -070049 };
Duncan Lauriec88c54c2014-04-30 16:36:13 -070050
Kyösti Mälkki9e94dbf2015-01-08 20:03:18 +020051 if (acpi_is_wakeup_s3()) {
Duncan Lauriec88c54c2014-04-30 16:36:13 -070052 return load_refcode_from_cache();
53 }
54
Aaron Durbin899d13d2015-05-15 23:39:23 -050055 if (prog_locate(&prog)) {
56 printk(BIOS_DEBUG, "Couldn't locate reference code.\n");
57 return NULL;
58 }
59
60 if (rmodule_stage_load(&refcode)) {
61 printk(BIOS_DEBUG, "Error loading reference code.\n");
62 return NULL;
63 }
Duncan Lauriec88c54c2014-04-30 16:36:13 -070064
65 /* Cache loaded reference code. */
Aaron Durbin899d13d2015-05-15 23:39:23 -050066 stage_cache_add(STAGE_REFCODE, &prog);
Duncan Lauriec88c54c2014-04-30 16:36:13 -070067
Patrick Georgie6e94932015-06-22 22:26:45 +020068 return (pei_wrapper_entry_t)prog_entry(&prog);
Duncan Lauriec88c54c2014-04-30 16:36:13 -070069}
70
71void broadwell_run_reference_code(void)
72{
Kenji Chen89f63882014-11-13 14:44:46 -080073 int ret, dummy;
Duncan Lauriec88c54c2014-04-30 16:36:13 -070074 struct pei_data pei_data;
75 pei_wrapper_entry_t entry;
76
77 memset(&pei_data, 0, sizeof(pei_data));
78 mainboard_fill_pei_data(&pei_data);
79 broadwell_fill_pei_data(&pei_data);
80
Aaron Durbin9e6d1432016-07-13 23:21:41 -050081 pei_data.boot_mode = acpi_is_wakeup_s3() ? ACPI_S3 : 0;
Kenji Chen89f63882014-11-13 14:44:46 -080082 pei_data.saved_data = (void *) &dummy;
83
Duncan Lauriec88c54c2014-04-30 16:36:13 -070084 entry = load_reference_code();
85 if (entry == NULL) {
86 printk(BIOS_ERR, "Reference code not found\n");
87 return;
88 }
89
90 /* Call into reference code. */
91 ret = entry(&pei_data);
92 if (ret != 0) {
93 printk(BIOS_ERR, "Reference code returned %d\n", ret);
94 return;
95 }
96}