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 }; 468 469 /** 470 * 安装到efi config table的信息 471 * 472 * 表示dragonstub加载的内核的地址和大小 473 */ 474 struct dragonstub_payload_efi { 475 u64 payload_addr; 476 u64 payload_size; 477 }; 478 479 #define DRAGONSTUB_EFI_PAYLOAD_EFI_GUID \ 480 MAKE_EFI_GUID(0xddf1d47c, 0x102c, 0xaaf9, 0xce, 0x34, 0xbc, 0xef, \ 481 0x98, 0x12, 0x00, 0x31) 482