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 "types.h" 12 #include "linux/div64.h" 13 #include "limits.h" 14 15 /// @brief 16 /// @param image 17 /// @param cmdline_ptr 18 /// @return 19 EFI_STATUS efi_handle_cmdline(EFI_LOADED_IMAGE *image, char **cmdline_ptr); 20 21 char *efi_convert_cmdline(EFI_LOADED_IMAGE *image, int *cmd_line_len); 22 23 #define efi_table_attr(inst, attr) (inst->attr) 24 25 typedef u32 efi_tcg2_event_log_format; 26 #define INITRD_EVENT_TAG_ID 0x8F3B22ECU 27 #define LOAD_OPTIONS_EVENT_TAG_ID 0x8F3B22EDU 28 #define EV_EVENT_TAG 0x00000006U 29 #define EFI_TCG2_EVENT_HEADER_VERSION 0x1 30 31 struct efi_tcg2_event { 32 u32 event_size; 33 struct { 34 u32 header_size; 35 u16 header_version; 36 u32 pcr_index; 37 u32 event_type; 38 } __packed event_header; 39 /* u8[] event follows here */ 40 } __packed; 41 42 struct efi_tcg2_tagged_event { 43 u32 tagged_event_id; 44 u32 tagged_event_data_size; 45 /* u8 tagged event data follows here */ 46 } __packed; 47 48 typedef struct efi_tcg2_event efi_tcg2_event_t; 49 typedef struct efi_tcg2_tagged_event efi_tcg2_tagged_event_t; 50 typedef union efi_tcg2_protocol efi_tcg2_protocol_t; 51 52 union efi_tcg2_protocol { 53 struct { 54 void *get_capability; 55 efi_status_t(__efiapi *get_event_log)(efi_tcg2_protocol_t *, 56 efi_tcg2_event_log_format, 57 efi_physical_addr_t *, 58 efi_physical_addr_t *, 59 efi_bool_t *); 60 efi_status_t(__efiapi *hash_log_extend_event)( 61 efi_tcg2_protocol_t *, u64, efi_physical_addr_t, u64, 62 const efi_tcg2_event_t *); 63 void *submit_command; 64 void *get_active_pcr_banks; 65 void *set_active_pcr_banks; 66 void *get_result_of_set_active_pcr_banks; 67 }; 68 struct { 69 u32 get_capability; 70 u32 get_event_log; 71 u32 hash_log_extend_event; 72 u32 submit_command; 73 u32 get_active_pcr_banks; 74 u32 set_active_pcr_banks; 75 u32 get_result_of_set_active_pcr_banks; 76 } mixed_mode; 77 }; 78 79 struct riscv_efi_boot_protocol { 80 u64 revision; 81 82 efi_status_t(__efiapi *get_boot_hartid)( 83 struct riscv_efi_boot_protocol *, unsigned long *boot_hartid); 84 }; 85 86 typedef struct { 87 u32 attributes; 88 u16 file_path_list_length; 89 u8 variable_data[]; 90 // efi_char16_t description[]; 91 // efi_device_path_protocol_t file_path_list[]; 92 // u8 optional_data[]; 93 } __packed efi_load_option_t; 94 95 typedef struct efi_generic_dev_path efi_device_path_protocol_t; 96 97 #define EFI_LOAD_OPTION_ACTIVE 0x0001U 98 #define EFI_LOAD_OPTION_FORCE_RECONNECT 0x0002U 99 #define EFI_LOAD_OPTION_HIDDEN 0x0008U 100 #define EFI_LOAD_OPTION_CATEGORY 0x1f00U 101 #define EFI_LOAD_OPTION_CATEGORY_BOOT 0x0000U 102 #define EFI_LOAD_OPTION_CATEGORY_APP 0x0100U 103 104 #define EFI_LOAD_OPTION_BOOT_MASK \ 105 (EFI_LOAD_OPTION_ACTIVE | EFI_LOAD_OPTION_HIDDEN | \ 106 EFI_LOAD_OPTION_CATEGORY) 107 #define EFI_LOAD_OPTION_MASK \ 108 (EFI_LOAD_OPTION_FORCE_RECONNECT | EFI_LOAD_OPTION_BOOT_MASK) 109 110 typedef struct { 111 u32 attributes; 112 u16 file_path_list_length; 113 const efi_char16_t *description; 114 const efi_device_path_protocol_t *file_path_list; 115 u32 optional_data_size; 116 const void *optional_data; 117 } efi_load_option_unpacked_t; 118 119 typedef EFI_LOADED_IMAGE efi_loaded_image_t; 120 121 /* The macro below handles dispatching via the thunk if needed */ 122 123 #define efi_fn_call(inst, func, ...) ((inst)->func(__VA_ARGS__)) 124 125 #define efi_call_proto(inst, func, ...) \ 126 ({ \ 127 __typeof__(inst) __inst = (inst); \ 128 efi_fn_call(__inst, func, __inst, ##__VA_ARGS__); \ 129 }) 130 131 /* 132 * This function handles the architcture specific differences between arm and 133 * arm64 regarding where the kernel image must be loaded and any memory that 134 * must be reserved. On failure it is required to free all 135 * all allocations it has made. 136 */ 137 efi_status_t 138 handle_kernel_image(unsigned long *image_addr, unsigned long *image_size, 139 unsigned long *reserve_addr, unsigned long *reserve_size, 140 efi_loaded_image_t *image, efi_handle_t image_handle); 141 142 char *skip_spaces(const char *str); 143 long simple_strtol(const char *cp, char **endp, unsigned int base); 144 unsigned int atou(const char *s); 145 /** 146 * simple_strtoull - convert a string to an unsigned long long 147 * @cp: The start of the string 148 * @endp: A pointer to the end of the parsed string will be placed here 149 * @base: The number base to use 150 */ 151 unsigned long long simple_strtoull(const char *cp, char **endp, 152 unsigned int base); 153 long simple_strtol(const char *cp, char **endp, unsigned int base); 154 155 #define strtoul(cp, endp, base) simple_strtoull(cp, endp, base) 156 157 size_t strnlen(const char *s, size_t maxlen); 158 /** 159 * strlen - Find the length of a string 160 * @s: The string to be sized 161 */ 162 size_t strlen(const char *s); 163 int strncmp(const char *cs, const char *ct, size_t count); 164 int strcmp(const char *str1, const char *str2); 165 char *strchr(const char *s, int c); 166 char *next_arg(char *args, char **param, char **val); 167 168 /** 169 * strstarts - does @str start with @prefix? 170 * @str: string to examine 171 * @prefix: prefix to look for. 172 */ 173 static inline bool strstarts(const char *str, const char *prefix) 174 { 175 return strncmp(str, prefix, strlen(prefix)) == 0; 176 } 177 178 efi_status_t efi_parse_options(char const *cmdline); 179 180 /// @brief 要加载的内核负载信息 181 struct payload_info { 182 /// @brief 负载起始地址 183 u64 payload_addr; 184 /// @brief 负载大小 185 u64 payload_size; 186 }; 187 188 /// @brief 寻找要加载的内核负载 189 /// @param handle efi_handle 190 /// @param image efi_loaded_image_t 191 /// @param ret_info 返回的负载信息 192 /// @return 193 efi_status_t find_payload(efi_handle_t handle, efi_loaded_image_t *loaded_image, 194 struct payload_info *ret_info); 195 196 /* shared entrypoint between the normal stub and the zboot stub */ 197 efi_status_t efi_stub_common(efi_handle_t handle, 198 struct payload_info *payload_info, 199 char *cmdline_ptr); 200 201 efi_status_t check_platform_features(void); 202 void *get_efi_config_table(efi_guid_t guid); 203 typedef EFI_CONFIGURATION_TABLE efi_config_table_t; 204 205 static inline int efi_guidcmp(efi_guid_t left, efi_guid_t right) 206 { 207 return memcmp(&left, &right, sizeof(efi_guid_t)); 208 } 209 210 static inline char *efi_guid_to_str(efi_guid_t *guid, char *out) 211 { 212 snprintf(out, 1024, "%pUl", &guid->Data1); 213 return out; 214 } 215 216 static inline void print_efi_guid(efi_guid_t *guid) 217 { 218 efi_info("GUID: data1: %p data2: %p data3: %p data4: %p\n", guid->Data1, 219 guid->Data2, guid->Data3, guid->Data4); 220 }