1f412fd2aSLoGin #pragma once 2f412fd2aSLoGin 3f412fd2aSLoGin #include <efi.h> 4f412fd2aSLoGin #include <efilib.h> 5f412fd2aSLoGin #include "printk.h" 6f412fd2aSLoGin #include "linux-efi.h" 7f412fd2aSLoGin #include "compiler_attributes.h" 8f412fd2aSLoGin #include "linux/ctype.h" 9f412fd2aSLoGin #include <lib.h> 10f412fd2aSLoGin #include <dragonstub/linux/hex.h> 11823f0493SLoGin #include <dragonstub/minmax.h> 12f412fd2aSLoGin #include "types.h" 13f412fd2aSLoGin #include "linux/div64.h" 143e6106c4SLoGin #include "limits.h" 15823f0493SLoGin #include "linux/sizes.h" 16f412fd2aSLoGin 17f412fd2aSLoGin /// @brief 18f412fd2aSLoGin /// @param image 19f412fd2aSLoGin /// @param cmdline_ptr 20f412fd2aSLoGin /// @return 21f412fd2aSLoGin EFI_STATUS efi_handle_cmdline(EFI_LOADED_IMAGE *image, char **cmdline_ptr); 22f412fd2aSLoGin 23f412fd2aSLoGin char *efi_convert_cmdline(EFI_LOADED_IMAGE *image, int *cmd_line_len); 24f412fd2aSLoGin 25f412fd2aSLoGin #define efi_table_attr(inst, attr) (inst->attr) 26f412fd2aSLoGin 27f412fd2aSLoGin typedef u32 efi_tcg2_event_log_format; 28f412fd2aSLoGin #define INITRD_EVENT_TAG_ID 0x8F3B22ECU 29f412fd2aSLoGin #define LOAD_OPTIONS_EVENT_TAG_ID 0x8F3B22EDU 30f412fd2aSLoGin #define EV_EVENT_TAG 0x00000006U 31f412fd2aSLoGin #define EFI_TCG2_EVENT_HEADER_VERSION 0x1 32f412fd2aSLoGin 33f412fd2aSLoGin struct efi_tcg2_event { 34f412fd2aSLoGin u32 event_size; 35f412fd2aSLoGin struct { 36f412fd2aSLoGin u32 header_size; 37f412fd2aSLoGin u16 header_version; 38f412fd2aSLoGin u32 pcr_index; 39f412fd2aSLoGin u32 event_type; 40f412fd2aSLoGin } __packed event_header; 41f412fd2aSLoGin /* u8[] event follows here */ 42f412fd2aSLoGin } __packed; 43f412fd2aSLoGin 44f412fd2aSLoGin struct efi_tcg2_tagged_event { 45f412fd2aSLoGin u32 tagged_event_id; 46f412fd2aSLoGin u32 tagged_event_data_size; 47f412fd2aSLoGin /* u8 tagged event data follows here */ 48f412fd2aSLoGin } __packed; 49f412fd2aSLoGin 50f412fd2aSLoGin typedef struct efi_tcg2_event efi_tcg2_event_t; 51f412fd2aSLoGin typedef struct efi_tcg2_tagged_event efi_tcg2_tagged_event_t; 52f412fd2aSLoGin typedef union efi_tcg2_protocol efi_tcg2_protocol_t; 53f412fd2aSLoGin 54f412fd2aSLoGin union efi_tcg2_protocol { 55f412fd2aSLoGin struct { 56f412fd2aSLoGin void *get_capability; 57f412fd2aSLoGin efi_status_t(__efiapi *get_event_log)(efi_tcg2_protocol_t *, 58f412fd2aSLoGin efi_tcg2_event_log_format, 59f412fd2aSLoGin efi_physical_addr_t *, 60f412fd2aSLoGin efi_physical_addr_t *, 61f412fd2aSLoGin efi_bool_t *); 62f412fd2aSLoGin efi_status_t(__efiapi *hash_log_extend_event)( 63f412fd2aSLoGin efi_tcg2_protocol_t *, u64, efi_physical_addr_t, u64, 64f412fd2aSLoGin const efi_tcg2_event_t *); 65f412fd2aSLoGin void *submit_command; 66f412fd2aSLoGin void *get_active_pcr_banks; 67f412fd2aSLoGin void *set_active_pcr_banks; 68f412fd2aSLoGin void *get_result_of_set_active_pcr_banks; 69f412fd2aSLoGin }; 70f412fd2aSLoGin struct { 71f412fd2aSLoGin u32 get_capability; 72f412fd2aSLoGin u32 get_event_log; 73f412fd2aSLoGin u32 hash_log_extend_event; 74f412fd2aSLoGin u32 submit_command; 75f412fd2aSLoGin u32 get_active_pcr_banks; 76f412fd2aSLoGin u32 set_active_pcr_banks; 77f412fd2aSLoGin u32 get_result_of_set_active_pcr_banks; 78f412fd2aSLoGin } mixed_mode; 79f412fd2aSLoGin }; 80f412fd2aSLoGin 81f412fd2aSLoGin struct riscv_efi_boot_protocol { 82f412fd2aSLoGin u64 revision; 83f412fd2aSLoGin 84f412fd2aSLoGin efi_status_t(__efiapi *get_boot_hartid)( 85f412fd2aSLoGin struct riscv_efi_boot_protocol *, unsigned long *boot_hartid); 86f412fd2aSLoGin }; 87f412fd2aSLoGin 88f412fd2aSLoGin typedef struct { 89f412fd2aSLoGin u32 attributes; 90f412fd2aSLoGin u16 file_path_list_length; 91f412fd2aSLoGin u8 variable_data[]; 92f412fd2aSLoGin // efi_char16_t description[]; 93f412fd2aSLoGin // efi_device_path_protocol_t file_path_list[]; 94f412fd2aSLoGin // u8 optional_data[]; 95f412fd2aSLoGin } __packed efi_load_option_t; 96f412fd2aSLoGin 97f412fd2aSLoGin typedef struct efi_generic_dev_path efi_device_path_protocol_t; 98f412fd2aSLoGin 99f412fd2aSLoGin #define EFI_LOAD_OPTION_ACTIVE 0x0001U 100f412fd2aSLoGin #define EFI_LOAD_OPTION_FORCE_RECONNECT 0x0002U 101f412fd2aSLoGin #define EFI_LOAD_OPTION_HIDDEN 0x0008U 102f412fd2aSLoGin #define EFI_LOAD_OPTION_CATEGORY 0x1f00U 103f412fd2aSLoGin #define EFI_LOAD_OPTION_CATEGORY_BOOT 0x0000U 104f412fd2aSLoGin #define EFI_LOAD_OPTION_CATEGORY_APP 0x0100U 105f412fd2aSLoGin 106f412fd2aSLoGin #define EFI_LOAD_OPTION_BOOT_MASK \ 107f412fd2aSLoGin (EFI_LOAD_OPTION_ACTIVE | EFI_LOAD_OPTION_HIDDEN | \ 108f412fd2aSLoGin EFI_LOAD_OPTION_CATEGORY) 109f412fd2aSLoGin #define EFI_LOAD_OPTION_MASK \ 110f412fd2aSLoGin (EFI_LOAD_OPTION_FORCE_RECONNECT | EFI_LOAD_OPTION_BOOT_MASK) 111f412fd2aSLoGin 112f412fd2aSLoGin typedef struct { 113f412fd2aSLoGin u32 attributes; 114f412fd2aSLoGin u16 file_path_list_length; 115f412fd2aSLoGin const efi_char16_t *description; 116f412fd2aSLoGin const efi_device_path_protocol_t *file_path_list; 117f412fd2aSLoGin u32 optional_data_size; 118f412fd2aSLoGin const void *optional_data; 119f412fd2aSLoGin } efi_load_option_unpacked_t; 120f412fd2aSLoGin 12178b790faSLoGin typedef EFI_LOADED_IMAGE efi_loaded_image_t; 12278b790faSLoGin 123f412fd2aSLoGin /* The macro below handles dispatching via the thunk if needed */ 124f412fd2aSLoGin 125f412fd2aSLoGin #define efi_fn_call(inst, func, ...) ((inst)->func(__VA_ARGS__)) 126f412fd2aSLoGin 127f412fd2aSLoGin #define efi_call_proto(inst, func, ...) \ 128f412fd2aSLoGin ({ \ 129f412fd2aSLoGin __typeof__(inst) __inst = (inst); \ 130f412fd2aSLoGin efi_fn_call(__inst, func, __inst, ##__VA_ARGS__); \ 131f412fd2aSLoGin }) 13278b790faSLoGin 133823f0493SLoGin #define efi_rt_call(func, ...) \ 134823f0493SLoGin efi_fn_call(efi_table_attr(ST, RuntimeServices), func, ##__VA_ARGS__) 135823f0493SLoGin 136823f0493SLoGin #define get_efi_var(name, vendor, ...) \ 137823f0493SLoGin efi_rt_call(GetVariable, (efi_char16_t *)(name), \ 138823f0493SLoGin (efi_guid_t *)(vendor), __VA_ARGS__) 139823f0493SLoGin 140823f0493SLoGin #define set_efi_var(name, vendor, ...) \ 141823f0493SLoGin efi_rt_call(SetVariable, (efi_char16_t *)(name), \ 142823f0493SLoGin (efi_guid_t *)(vendor), __VA_ARGS__) 14378b790faSLoGin 14478b790faSLoGin char *skip_spaces(const char *str); 14578b790faSLoGin long simple_strtol(const char *cp, char **endp, unsigned int base); 14678b790faSLoGin unsigned int atou(const char *s); 14778b790faSLoGin /** 14878b790faSLoGin * simple_strtoull - convert a string to an unsigned long long 14978b790faSLoGin * @cp: The start of the string 15078b790faSLoGin * @endp: A pointer to the end of the parsed string will be placed here 15178b790faSLoGin * @base: The number base to use 15278b790faSLoGin */ 15378b790faSLoGin unsigned long long simple_strtoull(const char *cp, char **endp, 15478b790faSLoGin unsigned int base); 15578b790faSLoGin long simple_strtol(const char *cp, char **endp, unsigned int base); 1563e6106c4SLoGin 1573e6106c4SLoGin #define strtoul(cp, endp, base) simple_strtoull(cp, endp, base) 1583e6106c4SLoGin 15978b790faSLoGin size_t strnlen(const char *s, size_t maxlen); 16078b790faSLoGin /** 16178b790faSLoGin * strlen - Find the length of a string 16278b790faSLoGin * @s: The string to be sized 16378b790faSLoGin */ 16478b790faSLoGin size_t strlen(const char *s); 16578b790faSLoGin int strncmp(const char *cs, const char *ct, size_t count); 16678b790faSLoGin int strcmp(const char *str1, const char *str2); 1673e6106c4SLoGin char *strchr(const char *s, int c); 168823f0493SLoGin /** 169823f0493SLoGin * strstr - Find the first substring in a %NUL terminated string 170823f0493SLoGin * @s1: The string to be searched 171823f0493SLoGin * @s2: The string to search for 172823f0493SLoGin */ 173823f0493SLoGin char *strstr(const char *s1, const char *s2); 174823f0493SLoGin 17578b790faSLoGin char *next_arg(char *args, char **param, char **val); 17678b790faSLoGin 17778b790faSLoGin /** 17878b790faSLoGin * strstarts - does @str start with @prefix? 17978b790faSLoGin * @str: string to examine 18078b790faSLoGin * @prefix: prefix to look for. 18178b790faSLoGin */ 18278b790faSLoGin static inline bool strstarts(const char *str, const char *prefix) 18378b790faSLoGin { 18478b790faSLoGin return strncmp(str, prefix, strlen(prefix)) == 0; 18578b790faSLoGin } 18678b790faSLoGin 18778b790faSLoGin efi_status_t efi_parse_options(char const *cmdline); 188fe0ee6eaSLoGin 189fe0ee6eaSLoGin /// @brief 要加载的内核负载信息 190fe0ee6eaSLoGin struct payload_info { 191fe0ee6eaSLoGin /// @brief 负载起始地址 192fe0ee6eaSLoGin u64 payload_addr; 193fe0ee6eaSLoGin /// @brief 负载大小 194fe0ee6eaSLoGin u64 payload_size; 195823f0493SLoGin /// @brief 被加载到的物理地址 196823f0493SLoGin u64 loaded_paddr; 197823f0493SLoGin /// @brief 加载了多大 198823f0493SLoGin u64 loaded_size; 199823f0493SLoGin /// @brief 加载的内核的入口物理地址 200823f0493SLoGin u64 kernel_entry; 201fe0ee6eaSLoGin }; 202fe0ee6eaSLoGin 203fe0ee6eaSLoGin /// @brief 寻找要加载的内核负载 204fe0ee6eaSLoGin /// @param handle efi_handle 205fe0ee6eaSLoGin /// @param image efi_loaded_image_t 206fe0ee6eaSLoGin /// @param ret_info 返回的负载信息 207fe0ee6eaSLoGin /// @return 208fe0ee6eaSLoGin efi_status_t find_payload(efi_handle_t handle, efi_loaded_image_t *loaded_image, 209fe0ee6eaSLoGin struct payload_info *ret_info); 2103e6106c4SLoGin 2113e6106c4SLoGin /* shared entrypoint between the normal stub and the zboot stub */ 212823f0493SLoGin efi_status_t efi_stub_common(efi_handle_t handle, efi_loaded_image_t *image, 213823f0493SLoGin struct payload_info *payload_info, 214823f0493SLoGin char *cmdline_ptr); 215823f0493SLoGin 216823f0493SLoGin efi_status_t efi_boot_kernel(efi_handle_t handle, efi_loaded_image_t *image, 2173e6106c4SLoGin struct payload_info *payload_info, 2183e6106c4SLoGin char *cmdline_ptr); 2193e6106c4SLoGin 2203e6106c4SLoGin efi_status_t check_platform_features(void); 2213e6106c4SLoGin void *get_efi_config_table(efi_guid_t guid); 2223e6106c4SLoGin typedef EFI_CONFIGURATION_TABLE efi_config_table_t; 2233e6106c4SLoGin 2243e6106c4SLoGin static inline int efi_guidcmp(efi_guid_t left, efi_guid_t right) 2253e6106c4SLoGin { 2263e6106c4SLoGin return memcmp(&left, &right, sizeof(efi_guid_t)); 2273e6106c4SLoGin } 2283e6106c4SLoGin 2293e6106c4SLoGin static inline char *efi_guid_to_str(efi_guid_t *guid, char *out) 2303e6106c4SLoGin { 2313e6106c4SLoGin snprintf(out, 1024, "%pUl", &guid->Data1); 2323e6106c4SLoGin return out; 2333e6106c4SLoGin } 2343e6106c4SLoGin 2353e6106c4SLoGin static inline void print_efi_guid(efi_guid_t *guid) 2363e6106c4SLoGin { 2373e6106c4SLoGin efi_info("GUID: data1: %p data2: %p data3: %p data4: %p\n", guid->Data1, 2383e6106c4SLoGin guid->Data2, guid->Data3, guid->Data4); 2393e6106c4SLoGin } 240823f0493SLoGin 241823f0493SLoGin /* 242823f0493SLoGin * efi_allocate_virtmap() - create a pool allocation for the virtmap 243823f0493SLoGin * 244823f0493SLoGin * Create an allocation that is of sufficient size to hold all the memory 245823f0493SLoGin * descriptors that will be passed to SetVirtualAddressMap() to inform the 246823f0493SLoGin * firmware about the virtual mapping that will be used under the OS to call 247823f0493SLoGin * into the firmware. 248823f0493SLoGin */ 249823f0493SLoGin efi_status_t efi_alloc_virtmap(efi_memory_desc_t **virtmap, 250823f0493SLoGin unsigned long *desc_size, u32 *desc_ver); 251823f0493SLoGin 252823f0493SLoGin /* 253823f0493SLoGin * efi_get_virtmap() - create a virtual mapping for the EFI memory map 254823f0493SLoGin * 255823f0493SLoGin * This function populates the virt_addr fields of all memory region descriptors 256823f0493SLoGin * in @memory_map whose EFI_MEMORY_RUNTIME attribute is set. Those descriptors 257823f0493SLoGin * are also copied to @runtime_map, and their total count is returned in @count. 258823f0493SLoGin */ 259823f0493SLoGin void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, 260823f0493SLoGin unsigned long desc_size, efi_memory_desc_t *runtime_map, 261823f0493SLoGin int *count); 262823f0493SLoGin 263823f0493SLoGin extern bool efi_nochunk; 264823f0493SLoGin extern bool efi_nokaslr; 265823f0493SLoGin extern bool efi_novamap; 266823f0493SLoGin 267823f0493SLoGin /* 268823f0493SLoGin * Determine whether we're in secure boot mode. 269823f0493SLoGin */ 270823f0493SLoGin enum efi_secureboot_mode efi_get_secureboot(void); 271823f0493SLoGin void *get_fdt(unsigned long *fdt_size); 272823f0493SLoGin 273823f0493SLoGin /* 274823f0493SLoGin * Allow the platform to override the allocation granularity: this allows 275823f0493SLoGin * systems that have the capability to run with a larger page size to deal 276823f0493SLoGin * with the allocations for initrd and fdt more efficiently. 277823f0493SLoGin */ 278823f0493SLoGin #ifndef EFI_ALLOC_ALIGN 279823f0493SLoGin #define EFI_ALLOC_ALIGN EFI_PAGE_SIZE 280823f0493SLoGin #endif 281823f0493SLoGin 282823f0493SLoGin #ifndef EFI_ALLOC_LIMIT 283823f0493SLoGin #define EFI_ALLOC_LIMIT ULONG_MAX 284823f0493SLoGin #endif 285823f0493SLoGin 286823f0493SLoGin /* 287823f0493SLoGin * Allocation types for calls to boottime->allocate_pages. 288823f0493SLoGin */ 289823f0493SLoGin #define EFI_ALLOCATE_ANY_PAGES 0 290823f0493SLoGin #define EFI_ALLOCATE_MAX_ADDRESS 1 291823f0493SLoGin #define EFI_ALLOCATE_ADDRESS 2 292823f0493SLoGin #define EFI_MAX_ALLOCATE_TYPE 3 293823f0493SLoGin 294823f0493SLoGin /** 295823f0493SLoGin * efi_allocate_pages_aligned() - Allocate memory pages 296823f0493SLoGin * @size: minimum number of bytes to allocate 297823f0493SLoGin * @addr: On return the address of the first allocated page. The first 298823f0493SLoGin * allocated page has alignment EFI_ALLOC_ALIGN which is an 299823f0493SLoGin * architecture dependent multiple of the page size. 300823f0493SLoGin * @max: the address that the last allocated memory page shall not 301823f0493SLoGin * exceed 302823f0493SLoGin * @align: minimum alignment of the base of the allocation 303823f0493SLoGin * 304823f0493SLoGin * Allocate pages as EFI_LOADER_DATA. The allocated pages are aligned according 305823f0493SLoGin * to @align, which should be >= EFI_ALLOC_ALIGN. The last allocated page will 306823f0493SLoGin * not exceed the address given by @max. 307823f0493SLoGin * 308823f0493SLoGin * Return: status code 309823f0493SLoGin */ 310823f0493SLoGin efi_status_t efi_allocate_pages_aligned(unsigned long size, unsigned long *addr, 311823f0493SLoGin unsigned long max, unsigned long align, 312823f0493SLoGin int memory_type); 313823f0493SLoGin 314823f0493SLoGin /** 315823f0493SLoGin * efi_allocate_pages() - Allocate memory pages 316823f0493SLoGin * @size: minimum number of bytes to allocate 317823f0493SLoGin * @addr: On return the address of the first allocated page. The first 318823f0493SLoGin * allocated page has alignment EFI_ALLOC_ALIGN which is an 319823f0493SLoGin * architecture dependent multiple of the page size. 320823f0493SLoGin * @max: the address that the last allocated memory page shall not 321823f0493SLoGin * exceed 322823f0493SLoGin * 323823f0493SLoGin * Allocate pages as EFI_LOADER_DATA. The allocated pages are aligned according 324823f0493SLoGin * to EFI_ALLOC_ALIGN. The last allocated page will not exceed the address 325823f0493SLoGin * given by @max. 326823f0493SLoGin * 327823f0493SLoGin * Return: status code 328823f0493SLoGin */ 329823f0493SLoGin efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr, 330823f0493SLoGin unsigned long max); 331823f0493SLoGin 332823f0493SLoGin /** 333823f0493SLoGin * efi_allocate_pages_exact() - Allocate memory pages at a specific address 334823f0493SLoGin * @size: minimum number of bytes to allocate 335823f0493SLoGin * @addr: The address of the first allocated page. 336823f0493SLoGin * 337823f0493SLoGin * Allocate pages as EFI_LOADER_DATA. The allocated pages are aligned according 338823f0493SLoGin * to EFI_ALLOC_ALIGN. 339823f0493SLoGin * 340823f0493SLoGin * Return: status code 341823f0493SLoGin */ 342823f0493SLoGin efi_status_t efi_allocate_pages_exact(unsigned long size, unsigned long addr); 343823f0493SLoGin 344823f0493SLoGin /** 345823f0493SLoGin * efi_free() - free memory pages 346823f0493SLoGin * @size: size of the memory area to free in bytes 347823f0493SLoGin * @addr: start of the memory area to free (must be EFI_PAGE_SIZE 348823f0493SLoGin * aligned) 349823f0493SLoGin * 350823f0493SLoGin * @size is rounded up to a multiple of EFI_ALLOC_ALIGN which is an 351823f0493SLoGin * architecture specific multiple of EFI_PAGE_SIZE. So this function should 352823f0493SLoGin * only be used to return pages allocated with efi_allocate_pages() or 353823f0493SLoGin * efi_low_alloc_above(). 354823f0493SLoGin */ 355823f0493SLoGin void efi_free(unsigned long size, unsigned long addr); 356823f0493SLoGin 357823f0493SLoGin /* 358823f0493SLoGin * An efi_boot_memmap is used by efi_get_memory_map() to return the 359823f0493SLoGin * EFI memory map in a dynamically allocated buffer. 360823f0493SLoGin * 361823f0493SLoGin * The buffer allocated for the EFI memory map includes extra room for 362823f0493SLoGin * a minimum of EFI_MMAP_NR_SLACK_SLOTS additional EFI memory descriptors. 363823f0493SLoGin * This facilitates the reuse of the EFI memory map buffer when a second 364823f0493SLoGin * call to ExitBootServices() is needed because of intervening changes to 365823f0493SLoGin * the EFI memory map. Other related structures, e.g. x86 e820ext, need 366823f0493SLoGin * to factor in this headroom requirement as well. 367823f0493SLoGin */ 368823f0493SLoGin #define EFI_MMAP_NR_SLACK_SLOTS 8 369823f0493SLoGin 370823f0493SLoGin /** 371823f0493SLoGin * efi_get_memory_map() - get memory map 372823f0493SLoGin * @map: pointer to memory map pointer to which to assign the 373823f0493SLoGin * newly allocated memory map 374823f0493SLoGin * @install_cfg_tbl: whether or not to install the boot memory map as a 375823f0493SLoGin * configuration table 376823f0493SLoGin * 377823f0493SLoGin * Retrieve the UEFI memory map. The allocated memory leaves room for 378823f0493SLoGin * up to EFI_MMAP_NR_SLACK_SLOTS additional memory map entries. 379823f0493SLoGin * 380823f0493SLoGin * Return: status code 381823f0493SLoGin */ 382823f0493SLoGin efi_status_t efi_get_memory_map(struct efi_boot_memmap **map, 383823f0493SLoGin bool install_cfg_tbl); 384823f0493SLoGin 385823f0493SLoGin #ifdef CONFIG_64BIT 386823f0493SLoGin #define MAX_FDT_SIZE (1UL << 21) 387823f0493SLoGin #else 388823f0493SLoGin #error "MAX_FDT_SIZE not yet defined for 32-bit" 389823f0493SLoGin #endif 390823f0493SLoGin 391823f0493SLoGin /* Helper macros for the usual case of using simple C variables: */ 392823f0493SLoGin #ifndef fdt_setprop_inplace_var 393823f0493SLoGin #define fdt_setprop_inplace_var(fdt, node_offset, name, var) \ 394823f0493SLoGin fdt_setprop_inplace((fdt), (node_offset), (name), &(var), sizeof(var)) 395823f0493SLoGin #endif 396823f0493SLoGin 397823f0493SLoGin #ifndef fdt_setprop_var 398823f0493SLoGin #define fdt_setprop_var(fdt, node_offset, name, var) \ 399823f0493SLoGin fdt_setprop((fdt), (node_offset), (name), &(var), sizeof(var)) 400823f0493SLoGin #endif 401823f0493SLoGin 402823f0493SLoGin #define efi_get_handle_at(array, idx) \ 403823f0493SLoGin (efi_is_native() ? (array)[idx] : \ 404823f0493SLoGin (efi_handle_t)(unsigned long)((u32 *)(array))[idx]) 405823f0493SLoGin 406823f0493SLoGin #define efi_get_handle_num(size) \ 407823f0493SLoGin ((size) / (efi_is_native() ? sizeof(efi_handle_t) : sizeof(u32))) 408823f0493SLoGin 409823f0493SLoGin /** 410823f0493SLoGin * efi_get_random_bytes() - fill a buffer with random bytes 411823f0493SLoGin * @size: size of the buffer 412823f0493SLoGin * @out: caller allocated buffer to receive the random bytes 413823f0493SLoGin * 414823f0493SLoGin * The call will fail if either the firmware does not implement the 415823f0493SLoGin * EFI_RNG_PROTOCOL or there are not enough random bytes available to fill 416823f0493SLoGin * the buffer. 417823f0493SLoGin * 418823f0493SLoGin * Return: status code 419823f0493SLoGin */ 420823f0493SLoGin efi_status_t efi_get_random_bytes(unsigned long size, u8 *out); 421823f0493SLoGin 422823f0493SLoGin typedef efi_status_t (*efi_exit_boot_map_processing)( 423823f0493SLoGin struct efi_boot_memmap *map, void *priv); 424823f0493SLoGin 425823f0493SLoGin /** 426823f0493SLoGin * efi_exit_boot_services() - Exit boot services 427823f0493SLoGin * @handle: handle of the exiting image 428823f0493SLoGin * @priv: argument to be passed to @priv_func 429823f0493SLoGin * @priv_func: function to process the memory map before exiting boot services 430823f0493SLoGin * 431823f0493SLoGin * Handle calling ExitBootServices according to the requirements set out by the 432823f0493SLoGin * spec. Obtains the current memory map, and returns that info after calling 433823f0493SLoGin * ExitBootServices. The client must specify a function to perform any 434823f0493SLoGin * processing of the memory map data prior to ExitBootServices. A client 435823f0493SLoGin * specific structure may be passed to the function via priv. The client 436823f0493SLoGin * function may be called multiple times. 437823f0493SLoGin * 438823f0493SLoGin * Return: status code 439823f0493SLoGin */ 440823f0493SLoGin efi_status_t efi_exit_boot_services(void *handle, void *priv, 441823f0493SLoGin efi_exit_boot_map_processing priv_func); 442823f0493SLoGin 443823f0493SLoGin void __noreturn efi_enter_kernel(struct payload_info *payload_info, 444823f0493SLoGin unsigned long fdt, unsigned long fdt_size); 445823f0493SLoGin 4462604d783SLoGin typedef union efi_memory_attribute_protocol efi_memory_attribute_protocol_t; 4472604d783SLoGin 4482604d783SLoGin union efi_memory_attribute_protocol { 4492604d783SLoGin struct { 4502604d783SLoGin efi_status_t(__efiapi *get_memory_attributes)( 4512604d783SLoGin efi_memory_attribute_protocol_t *, efi_physical_addr_t, 4522604d783SLoGin u64, u64 *); 4532604d783SLoGin 4542604d783SLoGin efi_status_t(__efiapi *set_memory_attributes)( 4552604d783SLoGin efi_memory_attribute_protocol_t *, efi_physical_addr_t, 4562604d783SLoGin u64, u64); 4572604d783SLoGin 4582604d783SLoGin efi_status_t(__efiapi *clear_memory_attributes)( 4592604d783SLoGin efi_memory_attribute_protocol_t *, efi_physical_addr_t, 4602604d783SLoGin u64, u64); 4612604d783SLoGin }; 4622604d783SLoGin struct { 4632604d783SLoGin u32 get_memory_attributes; 4642604d783SLoGin u32 set_memory_attributes; 4652604d783SLoGin u32 clear_memory_attributes; 4662604d783SLoGin } mixed_mode; 4672604d783SLoGin }; 4687fc3806dSLoGin 4697fc3806dSLoGin /** 4707fc3806dSLoGin * 安装到efi config table的信息 4717fc3806dSLoGin * 472*552e14d5SLoGin * 表示dragonstub把内核加载到的地址和大小 4737fc3806dSLoGin */ 4747fc3806dSLoGin struct dragonstub_payload_efi { 475*552e14d5SLoGin u64 loaded_addr; 476*552e14d5SLoGin u64 size; 4777fc3806dSLoGin }; 4787fc3806dSLoGin 4797fc3806dSLoGin #define DRAGONSTUB_EFI_PAYLOAD_EFI_GUID \ 4807fc3806dSLoGin MAKE_EFI_GUID(0xddf1d47c, 0x102c, 0xaaf9, 0xce, 0x34, 0xbc, 0xef, \ 4817fc3806dSLoGin 0x98, 0x12, 0x00, 0x31) 482