blob: e53cb7c973fa1fc2f6aab168e16dd9aab9030db7 [file] [log] [blame]
Angel Pons32859fc2020-04-02 23:48:27 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Aaron Durbin04654a22015-03-17 11:43:44 -05002#ifndef PROGRAM_LOADING_H
3#define PROGRAM_LOADING_H
Aaron Durbinbdf913a2014-02-24 14:56:34 -06004
Ting Shen05532262019-01-28 17:22:22 +08005#include <bootmem.h>
Julius Werner965846f2021-01-11 16:07:02 -08006#include <commonlib/bsd/cbfs_serialized.h>
Aaron Durbin7e7a4df2015-12-08 14:34:35 -06007#include <commonlib/region.h>
Julius Werner797a1102022-03-07 18:54:47 -08008#include <types.h>
Aaron Durbinbdf913a2014-02-24 14:56:34 -06009
Aaron Durbin6e76fff2015-03-20 09:42:05 -050010enum {
11 /* Last segment of program. Can be used to take different actions for
12 * cache maintenance of a program load. */
13 SEG_FINAL = 1 << 0,
14};
Ionela Voinescu00903e52015-01-09 13:14:20 +000015
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060016enum prog_type {
Julius Werner55b30812018-05-21 18:30:17 +000017 PROG_UNKNOWN,
Julius Werner99f46832018-05-16 14:14:04 -070018 PROG_BOOTBLOCK,
Julius Werner55b30812018-05-21 18:30:17 +000019 PROG_VERSTAGE,
20 PROG_ROMSTAGE,
21 PROG_RAMSTAGE,
22 PROG_REFCODE,
23 PROG_PAYLOAD,
24 PROG_BL31,
25 PROG_BL32,
Philipp Deppenwiese01797b12018-11-08 10:39:39 +010026 PROG_POSTCAR,
Patrick Rudolph4c3da702019-07-07 13:10:56 +020027 PROG_OPENSBI,
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060028};
29
Aaron Durbin096f4572016-03-31 13:49:00 -050030/*
31 * prog_segment_loaded() is called for each segment of a program loaded. The
32 * SEG_FINAL flag will be set on the last segment loaded. The following two
33 * functions, platform_segment_loaded() and arch_segment_loaded(), are called
34 * in that order within prog_segment_loaded(). In short, rely on
35 * prog_segment_loaded() to perform the proper dispatch sequence.
36 */
37void prog_segment_loaded(uintptr_t start, size_t size, int flags);
38void platform_segment_loaded(uintptr_t start, size_t size, int flags);
Aaron Durbin6e76fff2015-03-20 09:42:05 -050039void arch_segment_loaded(uintptr_t start, size_t size, int flags);
Ionela Voinescu00903e52015-01-09 13:14:20 +000040
Aaron Durbin3948e532015-03-20 13:00:20 -050041/* Representation of a program. */
42struct prog {
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060043 enum prog_type type;
Julius Werner965846f2021-01-11 16:07:02 -080044 enum cbfs_type cbfs_type;
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060045 const char *name;
Julius Werner2e973942020-09-03 21:17:20 -070046 void *start; /* Program start in memory. */
47 size_t size; /* Program size in memory (including BSS). */
48 void (*entry)(void *); /* Function pointer to entry point. */
49 void *arg; /* Optional argument (only valid for some archs). */
Aaron Durbin3948e532015-03-20 13:00:20 -050050};
51
Aaron Durbinac12c66c2015-05-20 12:08:55 -050052#define PROG_INIT(type_, name_) \
53 { \
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060054 .type = (type_), \
55 .name = (name_), \
Aaron Durbinac12c66c2015-05-20 12:08:55 -050056 }
57
58static inline const char *prog_name(const struct prog *prog)
59{
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060060 return prog->name;
Aaron Durbinac12c66c2015-05-20 12:08:55 -050061}
62
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060063static inline enum prog_type prog_type(const struct prog *prog)
Aaron Durbinac12c66c2015-05-20 12:08:55 -050064{
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060065 return prog->type;
Aaron Durbinac12c66c2015-05-20 12:08:55 -050066}
67
Julius Werner965846f2021-01-11 16:07:02 -080068static inline enum cbfs_type prog_cbfs_type(const struct prog *prog)
Patrick Rudolph71327fb2018-05-03 10:35:26 +020069{
70 return prog->cbfs_type;
71}
72
Aaron Durbin3948e532015-03-20 13:00:20 -050073static inline size_t prog_size(const struct prog *prog)
74{
Julius Werner2e973942020-09-03 21:17:20 -070075 return prog->size;
Aaron Durbin3948e532015-03-20 13:00:20 -050076}
77
78static inline void *prog_start(const struct prog *prog)
79{
Julius Werner2e973942020-09-03 21:17:20 -070080 return prog->start;
Aaron Durbin3948e532015-03-20 13:00:20 -050081}
82
83static inline void *prog_entry(const struct prog *prog)
84{
85 return prog->entry;
86}
87
88static inline void *prog_entry_arg(const struct prog *prog)
89{
90 return prog->arg;
91}
92
Julius Werner2e973942020-09-03 21:17:20 -070093/* Can be used to get an rdev representation of program area in memory. */
94static inline void prog_chain_rdev(const struct prog *prog,
95 struct region_device *rdev_out)
Aaron Durbin6a452ef2015-05-19 16:25:20 -050096{
Julius Wernerc8931972021-04-16 16:48:32 -070097 rdev_chain_mem(rdev_out, prog->start, prog->size);
Aaron Durbin6a452ef2015-05-19 16:25:20 -050098}
99
Aaron Durbin3948e532015-03-20 13:00:20 -0500100static inline void prog_set_area(struct prog *prog, void *start, size_t size)
101{
Julius Werner2e973942020-09-03 21:17:20 -0700102 prog->start = start;
103 prog->size = size;
Aaron Durbin3948e532015-03-20 13:00:20 -0500104}
105
106static inline void prog_set_entry(struct prog *prog, void *e, void *arg)
107{
108 prog->entry = e;
109 prog->arg = arg;
110}
111
Arthur Heymans5331a7c2019-10-23 17:07:15 +0200112static inline void prog_set_arg(struct prog *prog, void *arg)
113{
114 prog->arg = arg;
115}
116
Frans Hendriksfc580342019-06-14 14:36:37 +0200117/* The prog_locate_hook() is called prior to CBFS traversal. The hook can be
Julius Werner53584672021-01-11 16:44:06 -0800118 * used to implement policy that allows or prohibits further program loading.
119 * The type and name field within struct prog are the only valid fields. A 0
120 * return value allows loading while a non-zero return value prohibits it. */
Frans Hendriksfc580342019-06-14 14:36:37 +0200121int prog_locate_hook(struct prog *prog);
Aaron Durbinac12c66c2015-05-20 12:08:55 -0500122
Aaron Durbinb3847e62015-03-20 15:55:08 -0500123/* Run the program described by prog. */
124void prog_run(struct prog *prog);
125/* Per architecture implementation running a program. */
126void arch_prog_run(struct prog *prog);
127/* Platform (SoC/chipset) specific overrides for running a program. This is
128 * called prior to calling the arch_prog_run. Thus, if there is anything
129 * special that needs to be done by the platform similar to the architecture
130 * code it needs to that as well. */
131void platform_prog_run(struct prog *prog);
132
Aaron Durbind1b0e872015-03-17 13:17:06 -0500133/************************
134 * ROMSTAGE LOADING *
135 ************************/
136
137/* Run romstage from bootblock. */
138void run_romstage(void);
Aaron Durbin04654a22015-03-17 11:43:44 -0500139
Kyösti Mälkkib8d575c2019-12-16 16:00:49 +0200140/* Runtime selector for CBFS_PREFIX of romstage. */
Julius Werner797a1102022-03-07 18:54:47 -0800141enum cb_err legacy_romstage_select_and_load(struct prog *romstage);
Kyösti Mälkkib8d575c2019-12-16 16:00:49 +0200142
Aaron Durbin04654a22015-03-17 11:43:44 -0500143/************************
144 * RAMSTAGE LOADING *
145 ************************/
146
Raul E Rangelb25576f2021-11-05 10:29:24 -0600147/*
148 * Asynchronously preloads ramstage.
149 *
150 * This should be called early on to allow ramstage to load before
151 * `run_ramstage` is called.
152 */
153void preload_ramstage(void);
Aaron Durbince9efe02015-03-20 16:37:12 -0500154/* Run ramstage from romstage. */
Arthur Heymans84b2f9f2022-06-23 11:53:34 +0200155void __noreturn run_ramstage(void);
Aaron Durbince9efe02015-03-20 16:37:12 -0500156
Aaron Durbin04654a22015-03-17 11:43:44 -0500157/***********************
158 * PAYLOAD LOADING *
159 ***********************/
160
Kyösti Mälkkia48433d2018-06-07 06:31:43 +0300161int payload_arch_usable_ram_quirk(uint64_t start, uint64_t size);
162
Raul E Rangel67798cf2021-07-02 17:07:05 -0600163/*
164 * Asynchronously preloads the payload.
165 *
166 * This should be called early on to allow the payload to load before
167 * `payload_load` is called.
168 */
169void payload_preload(void);
Aaron Durbinebf2ed42015-03-20 10:20:15 -0500170/* Load payload into memory in preparation to run. */
171void payload_load(void);
Aaron Durbinbdf913a2014-02-24 14:56:34 -0600172
173/* Run the loaded payload. */
Aaron Durbinebf2ed42015-03-20 10:20:15 -0500174void payload_run(void);
Aaron Durbinbdf913a2014-02-24 14:56:34 -0600175
Simon Glass7ae73fc2016-08-27 12:18:38 -0600176/*
Ronald G. Minnichc3085542018-10-24 15:46:51 -0700177 * selfload() and selfload_check() load payloads into memory.
178 * selfload() does not check the payload to see if it targets memory.
179 * Call selfload_check() to check that the payload targets usable memory.
180 * If it does not, the load will fail and this function
181 * will return false. On successful payload loading these functions return true.
Simon Glass7ae73fc2016-08-27 12:18:38 -0600182 *
183 * Defined in src/lib/selfboot.c
184 */
Ting Shen05532262019-01-28 17:22:22 +0800185bool selfload_check(struct prog *payload, enum bootmem_type dest_type);
Ronald G. Minnichc3085542018-10-24 15:46:51 -0700186bool selfload(struct prog *payload);
Julius Werner965846f2021-01-11 16:07:02 -0800187/* Like selfload_check() but with the payload data already mapped to memory. */
188bool selfload_mapped(struct prog *payload, void *mapping,
189 enum bootmem_type dest_type);
190
191/* Load a FIT payload. The payload data must already be mapped to memory. */
192void fit_payload(struct prog *payload, void *data);
Aaron Durbin04654a22015-03-17 11:43:44 -0500193
194#endif /* PROGRAM_LOADING_H */