xref: /DragonStub/inc/dragonstub/dragonstub.h (revision 2604d7835e66d1fccc0973634b0121c7925e25f6)
1 #pragma once
2 
3 #include <efi.h>
4 #include <efilib.h>
5 #include "printk.h"
6 #include "linux-efi.h"
7 #include "compiler_attributes.h"
8 #include "linux/ctype.h"
9 #include <lib.h>
10 #include <dragonstub/linux/hex.h>
11 #include <dragonstub/minmax.h>
12 #include "types.h"
13 #include "linux/div64.h"
14 #include "limits.h"
15 #include "linux/sizes.h"
16 
17 /// @brief
18 /// @param image
19 /// @param cmdline_ptr
20 /// @return
21 EFI_STATUS efi_handle_cmdline(EFI_LOADED_IMAGE *image, char **cmdline_ptr);
22 
23 char *efi_convert_cmdline(EFI_LOADED_IMAGE *image, int *cmd_line_len);
24 
25 #define efi_table_attr(inst, attr) (inst->attr)
26 
27 typedef u32 efi_tcg2_event_log_format;
28 #define INITRD_EVENT_TAG_ID 0x8F3B22ECU
29 #define LOAD_OPTIONS_EVENT_TAG_ID 0x8F3B22EDU
30 #define EV_EVENT_TAG 0x00000006U
31 #define EFI_TCG2_EVENT_HEADER_VERSION 0x1
32 
33 struct efi_tcg2_event {
34 	u32 event_size;
35 	struct {
36 		u32 header_size;
37 		u16 header_version;
38 		u32 pcr_index;
39 		u32 event_type;
40 	} __packed event_header;
41 	/* u8[] event follows here */
42 } __packed;
43 
44 struct efi_tcg2_tagged_event {
45 	u32 tagged_event_id;
46 	u32 tagged_event_data_size;
47 	/* u8  tagged event data follows here */
48 } __packed;
49 
50 typedef struct efi_tcg2_event efi_tcg2_event_t;
51 typedef struct efi_tcg2_tagged_event efi_tcg2_tagged_event_t;
52 typedef union efi_tcg2_protocol efi_tcg2_protocol_t;
53 
54 union efi_tcg2_protocol {
55 	struct {
56 		void *get_capability;
57 		efi_status_t(__efiapi *get_event_log)(efi_tcg2_protocol_t *,
58 						      efi_tcg2_event_log_format,
59 						      efi_physical_addr_t *,
60 						      efi_physical_addr_t *,
61 						      efi_bool_t *);
62 		efi_status_t(__efiapi *hash_log_extend_event)(
63 			efi_tcg2_protocol_t *, u64, efi_physical_addr_t, u64,
64 			const efi_tcg2_event_t *);
65 		void *submit_command;
66 		void *get_active_pcr_banks;
67 		void *set_active_pcr_banks;
68 		void *get_result_of_set_active_pcr_banks;
69 	};
70 	struct {
71 		u32 get_capability;
72 		u32 get_event_log;
73 		u32 hash_log_extend_event;
74 		u32 submit_command;
75 		u32 get_active_pcr_banks;
76 		u32 set_active_pcr_banks;
77 		u32 get_result_of_set_active_pcr_banks;
78 	} mixed_mode;
79 };
80 
81 struct riscv_efi_boot_protocol {
82 	u64 revision;
83 
84 	efi_status_t(__efiapi *get_boot_hartid)(
85 		struct riscv_efi_boot_protocol *, unsigned long *boot_hartid);
86 };
87 
88 typedef struct {
89 	u32 attributes;
90 	u16 file_path_list_length;
91 	u8 variable_data[];
92 	// efi_char16_t description[];
93 	// efi_device_path_protocol_t file_path_list[];
94 	// u8 optional_data[];
95 } __packed efi_load_option_t;
96 
97 typedef struct efi_generic_dev_path efi_device_path_protocol_t;
98 
99 #define EFI_LOAD_OPTION_ACTIVE 0x0001U
100 #define EFI_LOAD_OPTION_FORCE_RECONNECT 0x0002U
101 #define EFI_LOAD_OPTION_HIDDEN 0x0008U
102 #define EFI_LOAD_OPTION_CATEGORY 0x1f00U
103 #define EFI_LOAD_OPTION_CATEGORY_BOOT 0x0000U
104 #define EFI_LOAD_OPTION_CATEGORY_APP 0x0100U
105 
106 #define EFI_LOAD_OPTION_BOOT_MASK                          \
107 	(EFI_LOAD_OPTION_ACTIVE | EFI_LOAD_OPTION_HIDDEN | \
108 	 EFI_LOAD_OPTION_CATEGORY)
109 #define EFI_LOAD_OPTION_MASK \
110 	(EFI_LOAD_OPTION_FORCE_RECONNECT | EFI_LOAD_OPTION_BOOT_MASK)
111 
112 typedef struct {
113 	u32 attributes;
114 	u16 file_path_list_length;
115 	const efi_char16_t *description;
116 	const efi_device_path_protocol_t *file_path_list;
117 	u32 optional_data_size;
118 	const void *optional_data;
119 } efi_load_option_unpacked_t;
120 
121 typedef EFI_LOADED_IMAGE efi_loaded_image_t;
122 
123 /* The macro below handles dispatching via the thunk if needed */
124 
125 #define efi_fn_call(inst, func, ...) ((inst)->func(__VA_ARGS__))
126 
127 #define efi_call_proto(inst, func, ...)                           \
128 	({                                                        \
129 		__typeof__(inst) __inst = (inst);                 \
130 		efi_fn_call(__inst, func, __inst, ##__VA_ARGS__); \
131 	})
132 
133 #define efi_rt_call(func, ...) \
134 	efi_fn_call(efi_table_attr(ST, RuntimeServices), func, ##__VA_ARGS__)
135 
136 #define get_efi_var(name, vendor, ...)                   \
137 	efi_rt_call(GetVariable, (efi_char16_t *)(name), \
138 		    (efi_guid_t *)(vendor), __VA_ARGS__)
139 
140 #define set_efi_var(name, vendor, ...)                   \
141 	efi_rt_call(SetVariable, (efi_char16_t *)(name), \
142 		    (efi_guid_t *)(vendor), __VA_ARGS__)
143 
144 char *skip_spaces(const char *str);
145 long simple_strtol(const char *cp, char **endp, unsigned int base);
146 unsigned int atou(const char *s);
147 /**
148  * simple_strtoull - convert a string to an unsigned long long
149  * @cp: The start of the string
150  * @endp: A pointer to the end of the parsed string will be placed here
151  * @base: The number base to use
152  */
153 unsigned long long simple_strtoull(const char *cp, char **endp,
154 				   unsigned int base);
155 long simple_strtol(const char *cp, char **endp, unsigned int base);
156 
157 #define strtoul(cp, endp, base) simple_strtoull(cp, endp, base)
158 
159 size_t strnlen(const char *s, size_t maxlen);
160 /**
161  * strlen - Find the length of a string
162  * @s: The string to be sized
163  */
164 size_t strlen(const char *s);
165 int strncmp(const char *cs, const char *ct, size_t count);
166 int strcmp(const char *str1, const char *str2);
167 char *strchr(const char *s, int c);
168 /**
169  * strstr - Find the first substring in a %NUL terminated string
170  * @s1: The string to be searched
171  * @s2: The string to search for
172  */
173 char *strstr(const char *s1, const char *s2);
174 
175 char *next_arg(char *args, char **param, char **val);
176 
177 /**
178  * strstarts - does @str start with @prefix?
179  * @str: string to examine
180  * @prefix: prefix to look for.
181  */
182 static inline bool strstarts(const char *str, const char *prefix)
183 {
184 	return strncmp(str, prefix, strlen(prefix)) == 0;
185 }
186 
187 efi_status_t efi_parse_options(char const *cmdline);
188 
189 /// @brief 要加载的内核负载信息
190 struct payload_info {
191 	/// @brief 负载起始地址
192 	u64 payload_addr;
193 	/// @brief 负载大小
194 	u64 payload_size;
195 	/// @brief 被加载到的物理地址
196 	u64 loaded_paddr;
197 	/// @brief 加载了多大
198 	u64 loaded_size;
199 	/// @brief 加载的内核的入口物理地址
200 	u64 kernel_entry;
201 };
202 
203 /// @brief 寻找要加载的内核负载
204 /// @param handle efi_handle
205 /// @param image efi_loaded_image_t
206 /// @param ret_info 返回的负载信息
207 /// @return
208 efi_status_t find_payload(efi_handle_t handle, efi_loaded_image_t *loaded_image,
209 			  struct payload_info *ret_info);
210 
211 /* shared entrypoint between the normal stub and the zboot stub */
212 efi_status_t efi_stub_common(efi_handle_t handle, efi_loaded_image_t *image,
213 			     struct payload_info *payload_info,
214 			     char *cmdline_ptr);
215 
216 efi_status_t efi_boot_kernel(efi_handle_t handle, efi_loaded_image_t *image,
217 			     struct payload_info *payload_info,
218 			     char *cmdline_ptr);
219 
220 efi_status_t check_platform_features(void);
221 void *get_efi_config_table(efi_guid_t guid);
222 typedef EFI_CONFIGURATION_TABLE efi_config_table_t;
223 
224 static inline int efi_guidcmp(efi_guid_t left, efi_guid_t right)
225 {
226 	return memcmp(&left, &right, sizeof(efi_guid_t));
227 }
228 
229 static inline char *efi_guid_to_str(efi_guid_t *guid, char *out)
230 {
231 	snprintf(out, 1024, "%pUl", &guid->Data1);
232 	return out;
233 }
234 
235 static inline void print_efi_guid(efi_guid_t *guid)
236 {
237 	efi_info("GUID: data1: %p data2: %p data3: %p data4: %p\n", guid->Data1,
238 		 guid->Data2, guid->Data3, guid->Data4);
239 }
240 
241 /*
242  * efi_allocate_virtmap() - create a pool allocation for the virtmap
243  *
244  * Create an allocation that is of sufficient size to hold all the memory
245  * descriptors that will be passed to SetVirtualAddressMap() to inform the
246  * firmware about the virtual mapping that will be used under the OS to call
247  * into the firmware.
248  */
249 efi_status_t efi_alloc_virtmap(efi_memory_desc_t **virtmap,
250 			       unsigned long *desc_size, u32 *desc_ver);
251 
252 /*
253  * efi_get_virtmap() - create a virtual mapping for the EFI memory map
254  *
255  * This function populates the virt_addr fields of all memory region descriptors
256  * in @memory_map whose EFI_MEMORY_RUNTIME attribute is set. Those descriptors
257  * are also copied to @runtime_map, and their total count is returned in @count.
258  */
259 void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
260 		     unsigned long desc_size, efi_memory_desc_t *runtime_map,
261 		     int *count);
262 
263 extern bool efi_nochunk;
264 extern bool efi_nokaslr;
265 extern bool efi_novamap;
266 
267 /*
268  * Determine whether we're in secure boot mode.
269  */
270 enum efi_secureboot_mode efi_get_secureboot(void);
271 void *get_fdt(unsigned long *fdt_size);
272 
273 /*
274  * Allow the platform to override the allocation granularity: this allows
275  * systems that have the capability to run with a larger page size to deal
276  * with the allocations for initrd and fdt more efficiently.
277  */
278 #ifndef EFI_ALLOC_ALIGN
279 #define EFI_ALLOC_ALIGN EFI_PAGE_SIZE
280 #endif
281 
282 #ifndef EFI_ALLOC_LIMIT
283 #define EFI_ALLOC_LIMIT ULONG_MAX
284 #endif
285 
286 /*
287  * Allocation types for calls to boottime->allocate_pages.
288  */
289 #define EFI_ALLOCATE_ANY_PAGES 0
290 #define EFI_ALLOCATE_MAX_ADDRESS 1
291 #define EFI_ALLOCATE_ADDRESS 2
292 #define EFI_MAX_ALLOCATE_TYPE 3
293 
294 /**
295  * efi_allocate_pages_aligned() - Allocate memory pages
296  * @size:	minimum number of bytes to allocate
297  * @addr:	On return the address of the first allocated page. The first
298  *		allocated page has alignment EFI_ALLOC_ALIGN which is an
299  *		architecture dependent multiple of the page size.
300  * @max:	the address that the last allocated memory page shall not
301  *		exceed
302  * @align:	minimum alignment of the base of the allocation
303  *
304  * Allocate pages as EFI_LOADER_DATA. The allocated pages are aligned according
305  * to @align, which should be >= EFI_ALLOC_ALIGN. The last allocated page will
306  * not exceed the address given by @max.
307  *
308  * Return:	status code
309  */
310 efi_status_t efi_allocate_pages_aligned(unsigned long size, unsigned long *addr,
311 					unsigned long max, unsigned long align,
312 					int memory_type);
313 
314 /**
315  * efi_allocate_pages() - Allocate memory pages
316  * @size:	minimum number of bytes to allocate
317  * @addr:	On return the address of the first allocated page. The first
318  *		allocated page has alignment EFI_ALLOC_ALIGN which is an
319  *		architecture dependent multiple of the page size.
320  * @max:	the address that the last allocated memory page shall not
321  *		exceed
322  *
323  * Allocate pages as EFI_LOADER_DATA. The allocated pages are aligned according
324  * to EFI_ALLOC_ALIGN. The last allocated page will not exceed the address
325  * given by @max.
326  *
327  * Return:	status code
328  */
329 efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr,
330 				unsigned long max);
331 
332 /**
333  * efi_allocate_pages_exact() - Allocate memory pages at a specific address
334  * @size:	minimum number of bytes to allocate
335  * @addr:	The address of the first allocated page.
336  *
337  * Allocate pages as EFI_LOADER_DATA. The allocated pages are aligned according
338  * to EFI_ALLOC_ALIGN.
339  *
340  * Return:	status code
341  */
342 efi_status_t efi_allocate_pages_exact(unsigned long size, unsigned long addr);
343 
344 /**
345  * efi_free() - free memory pages
346  * @size:	size of the memory area to free in bytes
347  * @addr:	start of the memory area to free (must be EFI_PAGE_SIZE
348  *		aligned)
349  *
350  * @size is rounded up to a multiple of EFI_ALLOC_ALIGN which is an
351  * architecture specific multiple of EFI_PAGE_SIZE. So this function should
352  * only be used to return pages allocated with efi_allocate_pages() or
353  * efi_low_alloc_above().
354  */
355 void efi_free(unsigned long size, unsigned long addr);
356 
357 /*
358  * An efi_boot_memmap is used by efi_get_memory_map() to return the
359  * EFI memory map in a dynamically allocated buffer.
360  *
361  * The buffer allocated for the EFI memory map includes extra room for
362  * a minimum of EFI_MMAP_NR_SLACK_SLOTS additional EFI memory descriptors.
363  * This facilitates the reuse of the EFI memory map buffer when a second
364  * call to ExitBootServices() is needed because of intervening changes to
365  * the EFI memory map. Other related structures, e.g. x86 e820ext, need
366  * to factor in this headroom requirement as well.
367  */
368 #define EFI_MMAP_NR_SLACK_SLOTS 8
369 
370 /**
371  * efi_get_memory_map() - get memory map
372  * @map:		pointer to memory map pointer to which to assign the
373  *			newly allocated memory map
374  * @install_cfg_tbl:	whether or not to install the boot memory map as a
375  *			configuration table
376  *
377  * Retrieve the UEFI memory map. The allocated memory leaves room for
378  * up to EFI_MMAP_NR_SLACK_SLOTS additional memory map entries.
379  *
380  * Return:	status code
381  */
382 efi_status_t efi_get_memory_map(struct efi_boot_memmap **map,
383 				bool install_cfg_tbl);
384 
385 #ifdef CONFIG_64BIT
386 #define MAX_FDT_SIZE (1UL << 21)
387 #else
388 #error "MAX_FDT_SIZE not yet defined for 32-bit"
389 #endif
390 
391 /* Helper macros for the usual case of using simple C variables: */
392 #ifndef fdt_setprop_inplace_var
393 #define fdt_setprop_inplace_var(fdt, node_offset, name, var) \
394 	fdt_setprop_inplace((fdt), (node_offset), (name), &(var), sizeof(var))
395 #endif
396 
397 #ifndef fdt_setprop_var
398 #define fdt_setprop_var(fdt, node_offset, name, var) \
399 	fdt_setprop((fdt), (node_offset), (name), &(var), sizeof(var))
400 #endif
401 
402 #define efi_get_handle_at(array, idx)     \
403 	(efi_is_native() ? (array)[idx] : \
404 			   (efi_handle_t)(unsigned long)((u32 *)(array))[idx])
405 
406 #define efi_get_handle_num(size) \
407 	((size) / (efi_is_native() ? sizeof(efi_handle_t) : sizeof(u32)))
408 
409 /**
410  * efi_get_random_bytes() - fill a buffer with random bytes
411  * @size:	size of the buffer
412  * @out:	caller allocated buffer to receive the random bytes
413  *
414  * The call will fail if either the firmware does not implement the
415  * EFI_RNG_PROTOCOL or there are not enough random bytes available to fill
416  * the buffer.
417  *
418  * Return:	status code
419  */
420 efi_status_t efi_get_random_bytes(unsigned long size, u8 *out);
421 
422 typedef efi_status_t (*efi_exit_boot_map_processing)(
423 	struct efi_boot_memmap *map, void *priv);
424 
425 /**
426  * efi_exit_boot_services() - Exit boot services
427  * @handle:	handle of the exiting image
428  * @priv:	argument to be passed to @priv_func
429  * @priv_func:	function to process the memory map before exiting boot services
430  *
431  * Handle calling ExitBootServices according to the requirements set out by the
432  * spec.  Obtains the current memory map, and returns that info after calling
433  * ExitBootServices.  The client must specify a function to perform any
434  * processing of the memory map data prior to ExitBootServices.  A client
435  * specific structure may be passed to the function via priv.  The client
436  * function may be called multiple times.
437  *
438  * Return:	status code
439  */
440 efi_status_t efi_exit_boot_services(void *handle, void *priv,
441 				    efi_exit_boot_map_processing priv_func);
442 
443 void __noreturn efi_enter_kernel(struct payload_info *payload_info,
444 				 unsigned long fdt, unsigned long fdt_size);
445 
446 typedef union efi_memory_attribute_protocol efi_memory_attribute_protocol_t;
447 
448 union efi_memory_attribute_protocol {
449 	struct {
450 		efi_status_t(__efiapi *get_memory_attributes)(
451 			efi_memory_attribute_protocol_t *, efi_physical_addr_t,
452 			u64, u64 *);
453 
454 		efi_status_t(__efiapi *set_memory_attributes)(
455 			efi_memory_attribute_protocol_t *, efi_physical_addr_t,
456 			u64, u64);
457 
458 		efi_status_t(__efiapi *clear_memory_attributes)(
459 			efi_memory_attribute_protocol_t *, efi_physical_addr_t,
460 			u64, u64);
461 	};
462 	struct {
463 		u32 get_memory_attributes;
464 		u32 set_memory_attributes;
465 		u32 clear_memory_attributes;
466 	} mixed_mode;
467 };