/ src / include / program_loading.h
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 */