program_loading.h
1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 #ifndef PROGRAM_LOADING_H 3 #define PROGRAM_LOADING_H 4 5 #include <bootmem.h> 6 #include <commonlib/bsd/cbfs_serialized.h> 7 #include <commonlib/region.h> 8 #include <types.h> 9 10 enum { 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 }; 15 16 enum prog_type { 17 PROG_UNKNOWN, 18 PROG_BOOTBLOCK, 19 PROG_VERSTAGE, 20 PROG_ROMSTAGE, 21 PROG_RAMSTAGE, 22 PROG_REFCODE, 23 PROG_PAYLOAD, 24 PROG_BL31, 25 PROG_BL32, 26 PROG_POSTCAR, 27 PROG_OPENSBI, 28 }; 29 30 /* 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 */ 37 void prog_segment_loaded(uintptr_t start, size_t size, int flags); 38 void platform_segment_loaded(uintptr_t start, size_t size, int flags); 39 void arch_segment_loaded(uintptr_t start, size_t size, int flags); 40 41 /* Representation of a program. */ 42 struct prog { 43 enum prog_type type; 44 enum cbfs_type cbfs_type; 45 const char *name; 46 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). */ 50 }; 51 52 #define PROG_INIT(type_, name_) \ 53 { \ 54 .type = (type_), \ 55 .name = (name_), \ 56 } 57 58 static inline const char *prog_name(const struct prog *prog) 59 { 60 return prog->name; 61 } 62 63 static inline enum prog_type prog_type(const struct prog *prog) 64 { 65 return prog->type; 66 } 67 68 static inline enum cbfs_type prog_cbfs_type(const struct prog *prog) 69 { 70 return prog->cbfs_type; 71 } 72 73 static inline size_t prog_size(const struct prog *prog) 74 { 75 return prog->size; 76 } 77 78 static inline void *prog_start(const struct prog *prog) 79 { 80 return prog->start; 81 } 82 83 static inline void *prog_entry(const struct prog *prog) 84 { 85 return prog->entry; 86 } 87 88 static inline void *prog_entry_arg(const struct prog *prog) 89 { 90 return prog->arg; 91 } 92 93 /* Can be used to get an rdev representation of program area in memory. */ 94 static inline void prog_chain_rdev(const struct prog *prog, 95 struct region_device *rdev_out) 96 { 97 rdev_chain_mem(rdev_out, prog->start, prog->size); 98 } 99 100 static inline void prog_set_area(struct prog *prog, void *start, size_t size) 101 { 102 prog->start = start; 103 prog->size = size; 104 } 105 106 static inline void prog_set_entry(struct prog *prog, void *e, void *arg) 107 { 108 prog->entry = e; 109 prog->arg = arg; 110 } 111 112 static inline void prog_set_arg(struct prog *prog, void *arg) 113 { 114 prog->arg = arg; 115 } 116 117 /* The prog_locate_hook() is called prior to CBFS traversal. The hook can be 118 * 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. */ 121 int prog_locate_hook(struct prog *prog); 122 123 /* Run the program described by prog. */ 124 void prog_run(struct prog *prog); 125 /* Per architecture implementation running a program. */ 126 void 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. */ 131 void platform_prog_run(struct prog *prog); 132 133 /************************ 134 * ROMSTAGE LOADING * 135 ************************/ 136 137 /* Run romstage from bootblock. */ 138 void run_romstage(void); 139 140 /* Runtime selector for CBFS_PREFIX of romstage. */ 141 enum cb_err legacy_romstage_select_and_load(struct prog *romstage); 142 143 /************************ 144 * RAMSTAGE LOADING * 145 ************************/ 146 147 /* 148 * Asynchronously preloads ramstage. 149 * 150 * This should be called early on to allow ramstage to load before 151 * `run_ramstage` is called. 152 */ 153 void preload_ramstage(void); 154 /* Run ramstage from romstage. */ 155 void __noreturn run_ramstage(void); 156 157 /*********************** 158 * PAYLOAD LOADING * 159 ***********************/ 160 161 int payload_arch_usable_ram_quirk(uint64_t start, uint64_t size); 162 163 /* 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 */ 169 void payload_preload(void); 170 /* Load payload into memory in preparation to run. */ 171 void payload_load(void); 172 173 /* Run the loaded payload. */ 174 void payload_run(void); 175 176 /* 177 * 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. 182 * 183 * Defined in src/lib/selfboot.c 184 */ 185 bool selfload_check(struct prog *payload, enum bootmem_type dest_type); 186 bool selfload(struct prog *payload); 187 /* Like selfload_check() but with the payload data already mapped to memory. */ 188 bool 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. */ 192 void fit_payload(struct prog *payload, void *data); 193 194 #endif /* PROGRAM_LOADING_H */