blob: 1012d97a0a25aeeee66102f6e8e0dffc15436f99 [file] [log] [blame]
Furquan Shaikh2af76f42014-04-28 16:39:40 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2013 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.
Furquan Shaikh2af76f42014-04-28 16:39:40 -070014 */
15
16#include <arch/cache.h>
Furquan Shaikh441df532014-09-11 16:06:01 -070017#include <arch/lib_helpers.h>
Furquan Shaikh2af76f42014-04-28 16:39:40 -070018#include <arch/stages.h>
Furquan Shaikh441df532014-09-11 16:06:01 -070019#include <arch/transition.h>
Julius Werner745a75f2015-05-11 16:45:56 -070020#include <arm_tf.h>
21#include <cbmem.h>
Furquan Shaikh2af76f42014-04-28 16:39:40 -070022#include <console/console.h>
Aaron Durbin04654a22015-03-17 11:43:44 -050023#include <program_loading.h>
Aaron Durbinb3847e62015-03-20 15:55:08 -050024#include <rules.h>
Furquan Shaikh441df532014-09-11 16:06:01 -070025#include <string.h>
Furquan Shaikh2af76f42014-04-28 16:39:40 -070026
Aaron Durbinb3847e62015-03-20 15:55:08 -050027static void run_payload(struct prog *prog)
Furquan Shaikh2af76f42014-04-28 16:39:40 -070028{
Aaron Durbin3948e532015-03-20 13:00:20 -050029 void (*doit)(void *);
30 void *arg;
Furquan Shaikhabde3b52014-08-26 15:39:51 -070031
Aaron Durbinb3847e62015-03-20 15:55:08 -050032 doit = prog_entry(prog);
33 arg = prog_entry_arg(prog);
Julius Wernerda3a1462015-05-13 11:19:33 -070034 u64 payload_spsr = SPSR_EXCEPTION_MASK | get_eret_el(EL2, SPSR_USE_L);
Aaron Durbin3948e532015-03-20 13:00:20 -050035
Julius Werner745a75f2015-05-11 16:45:56 -070036 if (IS_ENABLED(CONFIG_ARM64_USE_ARM_TRUSTED_FIRMWARE))
37 arm_tf_run_bl31((u64)doit, (u64)arg, payload_spsr);
Julius Werner786b1222015-05-07 16:59:31 -070038 else {
Julius Wernerf52602a2015-05-07 16:59:31 -070039 uint8_t current_el = get_current_el();
40
Julius Werner883ec982015-05-07 16:59:31 -070041 cache_sync_instructions();
42
Julius Wernerf52602a2015-05-07 16:59:31 -070043 printk(BIOS_SPEW, "entry = %p\n", doit);
44
Julius Werner786b1222015-05-07 16:59:31 -070045 /* If current EL is not EL3, jump to payload at same EL. */
Julius Wernerbbca3a92015-05-07 16:59:31 -070046 if (current_el != EL3)
Julius Werner786b1222015-05-07 16:59:31 -070047 doit(arg);
Julius Wernerbbca3a92015-05-07 16:59:31 -070048 else {
49 /* If current EL is EL3, we transition to payload in EL2. */
50 struct exc_state exc_state;
51 memset(&exc_state, 0, sizeof(exc_state));
Julius Werner745a75f2015-05-11 16:45:56 -070052 exc_state.elx.spsr = payload_spsr;
Julius Wernerbbca3a92015-05-07 16:59:31 -070053
54 transition_with_entry(doit, arg, &exc_state);
Julius Werner786b1222015-05-07 16:59:31 -070055 }
Furquan Shaikh441df532014-09-11 16:06:01 -070056 }
Furquan Shaikh2af76f42014-04-28 16:39:40 -070057}
Aaron Durbinb3847e62015-03-20 15:55:08 -050058
59void arch_prog_run(struct prog *prog)
60{
61 void (*doit)(void *);
62 void *arg;
63
Aaron Durbinac12c66c2015-05-20 12:08:55 -050064 if (ENV_RAMSTAGE && prog_type(prog) == ASSET_PAYLOAD) {
Aaron Durbinb3847e62015-03-20 15:55:08 -050065 run_payload(prog);
66 return;
Paul Menzel9484f552015-04-05 18:30:05 +020067 }
Aaron Durbinb3847e62015-03-20 15:55:08 -050068
69 doit = prog_entry(prog);
70 arg = prog_entry_arg(prog);
71
72 doit(prog_entry_arg(prog));
73}
Julius Werner66a476a2015-10-12 16:45:21 -070074
75#if !IS_ENABLED(CONFIG_SOC_NVIDIA_TEGRA132)
76/* Generic stage entry point. Can be overridden by board/SoC if needed. */
77__attribute__((weak)) void stage_entry(void)
78{
79 main();
80}
81#endif