]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
7a3c343c | 2 | #pragma once |
0fa2cac4 KS |
3 | |
4 | #include <efi.h> | |
5 | #include <efilib.h> | |
6 | ||
e5bc5f1f YW |
7 | #include "string-util-fundamental.h" |
8 | ||
7700e9ba | 9 | #define offsetof(type, member) __builtin_offsetof(type, member) |
0fa2cac4 | 10 | |
88657f75 LP |
11 | #define UINTN_MAX (~(UINTN)0) |
12 | #define INTN_MAX ((INTN)(UINTN_MAX>>1)) | |
13 | #ifndef UINT32_MAX | |
14 | #define UINT32_MAX ((UINT32) -1) | |
15 | #endif | |
16 | #ifndef UINT64_MAX | |
17 | #define UINT64_MAX ((UINT64) -1) | |
18 | #endif | |
19 | ||
ec4106af JJ |
20 | /* gnu-efi format specifiers for integers are fixed to either 64bit with 'l' and 32bit without a size prefix. |
21 | * We rely on %u/%d/%x to format regular ints, so ensure the size is what we expect. At the same time, we also | |
22 | * need specifiers for (U)INTN which are native (pointer) sized. */ | |
23 | assert_cc(sizeof(int) == sizeof(UINT32)); | |
24 | #if __SIZEOF_POINTER__ == 4 | |
25 | # define PRIuN L"u" | |
26 | # define PRIiN L"d" | |
27 | #elif __SIZEOF_POINTER__ == 8 | |
28 | # define PRIuN L"lu" | |
29 | # define PRIiN L"ld" | |
30 | #else | |
31 | # error "Unexpected pointer size" | |
32 | #endif | |
33 | ||
484ddd29 JJ |
34 | #define xnew_alloc(type, n, alloc) \ |
35 | ({ \ | |
36 | UINTN _alloc_size; \ | |
1462d245 | 37 | assert_se(!__builtin_mul_overflow(sizeof(type), (n), &_alloc_size)); \ |
484ddd29 JJ |
38 | (type *) alloc(_alloc_size); \ |
39 | }) | |
40 | ||
1462d245 LP |
41 | #define xallocate_pool(size) ASSERT_SE_PTR(AllocatePool(size)) |
42 | #define xallocate_zero_pool(size) ASSERT_SE_PTR(AllocateZeroPool(size)) | |
43 | #define xreallocate_pool(p, old_size, new_size) ASSERT_SE_PTR(ReallocatePool((p), (old_size), (new_size))) | |
44 | #define xpool_print(fmt, ...) ((CHAR16 *) ASSERT_SE_PTR(PoolPrint((fmt), ##__VA_ARGS__))) | |
45 | #define xstrdup(str) ((CHAR16 *) ASSERT_SE_PTR(StrDuplicate(str))) | |
484ddd29 JJ |
46 | #define xnew(type, n) xnew_alloc(type, (n), xallocate_pool) |
47 | #define xnew0(type, n) xnew_alloc(type, (n), xallocate_zero_pool) | |
48 | ||
427ee7ec | 49 | EFI_STATUS parse_boolean(const CHAR8 *v, BOOLEAN *b); |
4db7e6d7 | 50 | |
bcea9332 | 51 | EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *value, UINT32 flags); |
70cd15e9 | 52 | EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const void *buf, UINTN size, UINT32 flags); |
edad24c6 YW |
53 | EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN i, UINT32 flags); |
54 | EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const CHAR16 *NAME, UINT32 value, UINT32 flags); | |
55 | EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 value, UINT32 flags); | |
70cd15e9 | 56 | void efivar_set_time_usec(const EFI_GUID *vendor, const CHAR16 *name, UINT64 usec); |
0fa2cac4 | 57 | |
5e1f0e6f | 58 | EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value); |
427ee7ec | 59 | EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size); |
a7308a26 | 60 | EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i); |
987d0a12 DDM |
61 | EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT32 *ret); |
62 | EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 *ret); | |
2a7c1675 | 63 | EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOOLEAN *ret); |
0fa2cac4 | 64 | |
ef53d52b | 65 | CHAR8 *strchra(const CHAR8 *s, CHAR8 c); |
4f943415 JJ |
66 | CHAR16 *xstra_to_path(const CHAR8 *stra); |
67 | CHAR16 *xstra_to_str(const CHAR8 *stra); | |
0fa2cac4 | 68 | |
85eb489e | 69 | EFI_STATUS file_read(EFI_FILE *dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **content, UINTN *content_size); |
a42d7cf1 | 70 | |
0b2281a2 | 71 | static inline void free_poolp(void *p) { |
2880e665 LP |
72 | void *q = *(void**) p; |
73 | ||
74 | if (!q) | |
75 | return; | |
76 | ||
2d1ac308 | 77 | (void) BS->FreePool(q); |
a42d7cf1 ZJS |
78 | } |
79 | ||
0b2281a2 | 80 | #define _cleanup_freepool_ _cleanup_(free_poolp) |
3aaa95e0 | 81 | |
85eb489e | 82 | static inline void file_closep(EFI_FILE **handle) { |
3aaa95e0 LP |
83 | if (!*handle) |
84 | return; | |
85 | ||
12f32748 | 86 | (*handle)->Close(*handle); |
3aaa95e0 | 87 | } |
0e2bc732 | 88 | |
7d2ebb6f DDM |
89 | /* |
90 | * Allocated random UUID, intended to be shared across tools that implement | |
91 | * the (ESP)\loader\entries\<vendor>-<revision>.conf convention and the | |
92 | * associated EFI variables. | |
93 | */ | |
94 | #define LOADER_GUID \ | |
95 | &(const EFI_GUID) { 0x4a67b082, 0x0a4c, 0x41cf, { 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } } | |
96 | #define EFI_GLOBAL_GUID &(const EFI_GUID) EFI_GLOBAL_VARIABLE | |
b49dd00f | 97 | |
70cd15e9 | 98 | void log_error_stall(const CHAR16 *fmt, ...); |
b19fa812 | 99 | EFI_STATUS log_oom(void); |
8aba0eec JJ |
100 | |
101 | /* This works just like log_error_errno() from userspace, but requires you | |
102 | * to provide err a second time if you want to use %r in the message! */ | |
103 | #define log_error_status_stall(err, fmt, ...) \ | |
104 | ({ \ | |
105 | log_error_stall(fmt, ##__VA_ARGS__); \ | |
106 | err; \ | |
107 | }) | |
43ee1fe0 | 108 | |
70cd15e9 JJ |
109 | void print_at(UINTN x, UINTN y, UINTN attr, const CHAR16 *str); |
110 | void clear_screen(UINTN attr); | |
c6dfe360 | 111 | |
70cd15e9 JJ |
112 | typedef INTN (*compare_pointer_func_t)(const void *a, const void *b); |
113 | void sort_pointer_array(void **array, UINTN n_members, compare_pointer_func_t compare); | |
80b2f4d9 | 114 | |
85eb489e | 115 | EFI_STATUS get_file_info_harder(EFI_FILE *handle, EFI_FILE_INFO **ret, UINTN *ret_size); |
c6dfe360 | 116 | |
85eb489e | 117 | EFI_STATUS readdir_harder(EFI_FILE *handle, EFI_FILE_INFO **buffer, UINTN *buffer_size); |
c6dfe360 LP |
118 | |
119 | UINTN strnlena(const CHAR8 *p, UINTN maxlen); | |
0a15a824 | 120 | CHAR8 *xstrndup8(const CHAR8 *p, UINTN sz); |
245e9d55 JJ |
121 | INTN strncasecmpa(const CHAR8 *a, const CHAR8 *b, UINTN maxlen); |
122 | static inline BOOLEAN strncaseeqa(const CHAR8 *a, const CHAR8 *b, UINTN maxlen) { | |
123 | return strncasecmpa(a, b, maxlen) == 0; | |
124 | } | |
c6dfe360 LP |
125 | |
126 | BOOLEAN is_ascii(const CHAR16 *f); | |
127 | ||
128 | CHAR16 **strv_free(CHAR16 **l); | |
129 | ||
130 | static inline void strv_freep(CHAR16 ***p) { | |
131 | strv_free(*p); | |
132 | } | |
133 | ||
85eb489e | 134 | EFI_STATUS open_directory(EFI_FILE *root_dir, const CHAR16 *path, EFI_FILE **ret); |
a0a644be LP |
135 | |
136 | /* Conversion between EFI_PHYSICAL_ADDRESS and pointers is not obvious. The former is always 64bit, even on | |
137 | * 32bit archs. And gcc complains if we cast a pointer to an integer of a different size. Hence let's do the | |
138 | * conversion indirectly: first into UINTN (which is defined by UEFI to have the same size as a pointer), and | |
139 | * then extended to EFI_PHYSICAL_ADDRESS. */ | |
140 | static inline EFI_PHYSICAL_ADDRESS POINTER_TO_PHYSICAL_ADDRESS(const void *p) { | |
141 | return (EFI_PHYSICAL_ADDRESS) (UINTN) p; | |
142 | } | |
143 | ||
144 | static inline void *PHYSICAL_ADDRESS_TO_POINTER(EFI_PHYSICAL_ADDRESS addr) { | |
145 | #if __SIZEOF_POINTER__ == 4 | |
146 | /* On 32bit systems the address might not be convertible (as pointers are 32bit but | |
147 | * EFI_PHYSICAL_ADDRESS 64bit) */ | |
148 | assert(addr <= UINT32_MAX); | |
149 | #elif __SIZEOF_POINTER__ != 8 | |
150 | #error "Unexpected pointer size" | |
151 | #endif | |
152 | ||
153 | return (void*) (UINTN) addr; | |
154 | } | |
3a624912 | 155 | |
70cd15e9 | 156 | UINT64 get_os_indications_supported(void); |
948d085e JJ |
157 | |
158 | #ifdef EFI_DEBUG | |
159 | void debug_break(void); | |
160 | extern UINT8 _text, _data; | |
161 | /* Report the relocated position of text and data sections so that a debugger | |
162 | * can attach to us. See debug-sd-boot.sh for how this can be done. */ | |
ec4106af | 163 | # define debug_hook(identity) Print(identity L"@0x%lx,0x%lx\n", POINTER_TO_PHYSICAL_ADDRESS(&_text), POINTER_TO_PHYSICAL_ADDRESS(&_data)) |
948d085e JJ |
164 | #else |
165 | # define debug_hook(identity) | |
166 | #endif | |
85d2f13b JJ |
167 | |
168 | #if defined(__i386__) || defined(__x86_64__) | |
cc25bedb | 169 | void beep(UINTN beep_count); |
85d2f13b | 170 | #else |
cc25bedb | 171 | static inline void beep(UINTN beep_count) {} |
85d2f13b | 172 | #endif |