blob: ba42465046b49979e3324b5dd82da41ad835e9ca [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>
Aaron Durbinbdf913a2014-02-24 14:56:34 -06008#include <stdint.h>
9#include <stddef.h>
10
Aaron Durbin6e76fff2015-03-20 09:42:05 -050011enum {
12 /* Last segment of program. Can be used to take different actions for
13 * cache maintenance of a program load. */
14 SEG_FINAL = 1 << 0,
15};
Ionela Voinescu00903e52015-01-09 13:14:20 +000016
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060017enum prog_type {
Julius Werner55b30812018-05-21 18:30:17 +000018 PROG_UNKNOWN,
Julius Werner99f46832018-05-16 14:14:04 -070019 PROG_BOOTBLOCK,
Julius Werner55b30812018-05-21 18:30:17 +000020 PROG_VERSTAGE,
21 PROG_ROMSTAGE,
22 PROG_RAMSTAGE,
23 PROG_REFCODE,
24 PROG_PAYLOAD,
25 PROG_BL31,
26 PROG_BL32,
Philipp Deppenwiese01797b12018-11-08 10:39:39 +010027 PROG_POSTCAR,
Patrick Rudolph4c3da702019-07-07 13:10:56 +020028 PROG_OPENSBI,
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060029};
30
Aaron Durbin096f4572016-03-31 13:49:00 -050031/*
32 * prog_segment_loaded() is called for each segment of a program loaded. The
33 * SEG_FINAL flag will be set on the last segment loaded. The following two
34 * functions, platform_segment_loaded() and arch_segment_loaded(), are called
35 * in that order within prog_segment_loaded(). In short, rely on
36 * prog_segment_loaded() to perform the proper dispatch sequence.
37 */
38void prog_segment_loaded(uintptr_t start, size_t size, int flags);
39void platform_segment_loaded(uintptr_t start, size_t size, int flags);
Aaron Durbin6e76fff2015-03-20 09:42:05 -050040void arch_segment_loaded(uintptr_t start, size_t size, int flags);
Ionela Voinescu00903e52015-01-09 13:14:20 +000041
Aaron Durbin3948e532015-03-20 13:00:20 -050042/* Representation of a program. */
43struct prog {
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060044 enum prog_type type;
Julius Werner965846f2021-01-11 16:07:02 -080045 enum cbfs_type cbfs_type;
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060046 const char *name;
Julius Werner2e973942020-09-03 21:17:20 -070047 void *start; /* Program start in memory. */
48 size_t size; /* Program size in memory (including BSS). */
49 void (*entry)(void *); /* Function pointer to entry point. */
50 void *arg; /* Optional argument (only valid for some archs). */
Aaron Durbin3948e532015-03-20 13:00:20 -050051};
52
Aaron Durbinac12c66c2015-05-20 12:08:55 -050053#define PROG_INIT(type_, name_) \
54 { \
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060055 .type = (type_), \
56 .name = (name_), \
Aaron Durbinac12c66c2015-05-20 12:08:55 -050057 }
58
59static inline const char *prog_name(const struct prog *prog)
60{
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060061 return prog->name;
Aaron Durbinac12c66c2015-05-20 12:08:55 -050062}
63
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060064static inline enum prog_type prog_type(const struct prog *prog)
Aaron Durbinac12c66c2015-05-20 12:08:55 -050065{
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060066 return prog->type;
Aaron Durbinac12c66c2015-05-20 12:08:55 -050067}
68
Julius Werner965846f2021-01-11 16:07:02 -080069static inline enum cbfs_type prog_cbfs_type(const struct prog *prog)
Patrick Rudolph71327fb2018-05-03 10:35:26 +020070{
71 return prog->cbfs_type;
72}
73
Aaron Durbin3948e532015-03-20 13:00:20 -050074static inline size_t prog_size(const struct prog *prog)
75{
Julius Werner2e973942020-09-03 21:17:20 -070076 return prog->size;
Aaron Durbin3948e532015-03-20 13:00:20 -050077}
78
79static inline void *prog_start(const struct prog *prog)
80{
Julius Werner2e973942020-09-03 21:17:20 -070081 return prog->start;
Aaron Durbin3948e532015-03-20 13:00:20 -050082}
83
84static inline void *prog_entry(const struct prog *prog)
85{
86 return prog->entry;
87}
88
89static inline void *prog_entry_arg(const struct prog *prog)
90{
91 return prog->arg;
92}
93
Julius Werner2e973942020-09-03 21:17:20 -070094/* Can be used to get an rdev representation of program area in memory. */
95static inline void prog_chain_rdev(const struct prog *prog,
96 struct region_device *rdev_out)
Aaron Durbin6a452ef2015-05-19 16:25:20 -050097{
Julius Wernerc8931972021-04-16 16:48:32 -070098 rdev_chain_mem(rdev_out, prog->start, prog->size);
Aaron Durbin6a452ef2015-05-19 16:25:20 -050099}
100
Aaron Durbin3948e532015-03-20 13:00:20 -0500101static inline void prog_set_area(struct prog *prog, void *start, size_t size)
102{
Julius Werner2e973942020-09-03 21:17:20 -0700103 prog->start = start;
104 prog->size = size;
Aaron Durbin3948e532015-03-20 13:00:20 -0500105}
106
107static inline void prog_set_entry(struct prog *prog, void *e, void *arg)
108{
109 prog->entry = e;
110 prog->arg = arg;
111}
112
Arthur Heymans5331a7c2019-10-23 17:07:15 +0200113static inline void prog_set_arg(struct prog *prog, void *arg)
114{
115 prog->arg = arg;
116}
117
Frans Hendriksfc580342019-06-14 14:36:37 +0200118/* The prog_locate_hook() is called prior to CBFS traversal. The hook can be
Julius Werner53584672021-01-11 16:44:06 -0800119 * used to implement policy that allows or prohibits further program loading.
120 * The type and name field within struct prog are the only valid fields. A 0
121 * return value allows loading while a non-zero return value prohibits it. */
Frans Hendriksfc580342019-06-14 14:36:37 +0200122int prog_locate_hook(struct prog *prog);
Aaron Durbinac12c66c2015-05-20 12:08:55 -0500123
Aaron Durbinb3847e62015-03-20 15:55:08 -0500124/* Run the program described by prog. */
125void prog_run(struct prog *prog);
126/* Per architecture implementation running a program. */
127void arch_prog_run(struct prog *prog);
128/* Platform (SoC/chipset) specific overrides for running a program. This is
129 * called prior to calling the arch_prog_run. Thus, if there is anything
130 * special that needs to be done by the platform similar to the architecture
131 * code it needs to that as well. */
132void platform_prog_run(struct prog *prog);
133
Aaron Durbind1b0e872015-03-17 13:17:06 -0500134/************************
135 * ROMSTAGE LOADING *
136 ************************/
137
138/* Run romstage from bootblock. */
139void run_romstage(void);
Aaron Durbin04654a22015-03-17 11:43:44 -0500140
Kyösti Mälkkib8d575c2019-12-16 16:00:49 +0200141/* Runtime selector for CBFS_PREFIX of romstage. */
Julius Werner1de87082020-12-23 17:38:11 -0800142int legacy_romstage_select_and_load(struct prog *romstage);
Kyösti Mälkkib8d575c2019-12-16 16:00:49 +0200143
Aaron Durbin04654a22015-03-17 11:43:44 -0500144/************************
145 * RAMSTAGE LOADING *
146 ************************/
147
Raul E Rangelb25576f2021-11-05 10:29:24 -0600148/*
149 * Asynchronously preloads ramstage.
150 *
151 * This should be called early on to allow ramstage to load before
152 * `run_ramstage` is called.
153 */
154void preload_ramstage(void);
Aaron Durbince9efe02015-03-20 16:37:12 -0500155/* Run ramstage from romstage. */
156void run_ramstage(void);
157
Aaron Durbin04654a22015-03-17 11:43:44 -0500158/***********************
159 * PAYLOAD LOADING *
160 ***********************/
161
Kyösti Mälkkia48433d2018-06-07 06:31:43 +0300162int payload_arch_usable_ram_quirk(uint64_t start, uint64_t size);
163
Raul E Rangel67798cf2021-07-02 17:07:05 -0600164/*
165 * Asynchronously preloads the payload.
166 *
167 * This should be called early on to allow the payload to load before
168 * `payload_load` is called.
169 */
170void payload_preload(void);
Aaron Durbinebf2ed42015-03-20 10:20:15 -0500171/* Load payload into memory in preparation to run. */
172void payload_load(void);
Aaron Durbinbdf913a2014-02-24 14:56:34 -0600173
174/* Run the loaded payload. */
Aaron Durbinebf2ed42015-03-20 10:20:15 -0500175void payload_run(void);
Aaron Durbinbdf913a2014-02-24 14:56:34 -0600176
Simon Glass7ae73fc2016-08-27 12:18:38 -0600177/*
Ronald G. Minnichc3085542018-10-24 15:46:51 -0700178 * selfload() and selfload_check() load payloads into memory.
179 * selfload() does not check the payload to see if it targets memory.
180 * Call selfload_check() to check that the payload targets usable memory.
181 * If it does not, the load will fail and this function
182 * will return false. On successful payload loading these functions return true.
Simon Glass7ae73fc2016-08-27 12:18:38 -0600183 *
184 * Defined in src/lib/selfboot.c
185 */
Ting Shen05532262019-01-28 17:22:22 +0800186bool selfload_check(struct prog *payload, enum bootmem_type dest_type);
Ronald G. Minnichc3085542018-10-24 15:46:51 -0700187bool selfload(struct prog *payload);
Julius Werner965846f2021-01-11 16:07:02 -0800188/* Like selfload_check() but with the payload data already mapped to memory. */
189bool selfload_mapped(struct prog *payload, void *mapping,
190 enum bootmem_type dest_type);
191
192/* Load a FIT payload. The payload data must already be mapped to memory. */
193void fit_payload(struct prog *payload, void *data);
Aaron Durbin04654a22015-03-17 11:43:44 -0500194
195#endif /* PROGRAM_LOADING_H */