1 /*
2  * Copyright (c) 2011 - 2022, Intel Corporation.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  *    * Redistributions of source code must retain the above copyright
9  *      notice, this list of conditions and the following disclaimer.
10  *    * Redistributions in binary form must reproduce the above copyright
11  *      notice, this list of conditions and the following disclaimer
12  *      in the documentation and/or other materials provided with the
13  *      distribution.
14  *    * Neither the name of Intel Corporation nor the names of its
15  *      contributors may be used to endorse or promote products
16  *      derived from this software without specific prior written
17  *      permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30  * OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * This file contains some wrappers around the gnu-efi functions. As
33  * we're not going through uefi_call_wrapper() directly, this allows
34  * us to get some type-safety for function call arguments and for the
35  * compiler to check that the number of function call arguments is
36  * correct.
37  *
38  * It's also a good place to document the EFI interface.
39  */
40 
41 #ifndef __EFILINUX_H__
42 #define __EFILINUX_H__
43 
44 #define EFILINUX_VERSION_MAJOR 1
45 #define EFILINUX_VERSION_MINOR 0
46 
47 #define MEM_ADDR_1MB (1U << 20U)
48 #define MEM_ADDR_4GB (0xFFFFFFFFU)
49 
50 
51 extern EFI_SYSTEM_TABLE *sys_table;
52 extern EFI_BOOT_SERVICES *boot;
53 extern EFI_RUNTIME_SERVICES *runtime;
54 
55 extern EFI_STATUS
56 emalloc_reserved_aligned(EFI_PHYSICAL_ADDRESS *addr, UINTN size, UINTN align,
57 		EFI_PHYSICAL_ADDRESS minaddr, EFI_PHYSICAL_ADDRESS maxaddr);
58 
59 /**
60  * allocate_pages - Allocate memory pages from the system
61  * @atype: type of allocation to perform
62  * @mtype: type of memory to allocate
63  * @num_pages: number of contiguous 4KB pages to allocate
64  * @memory: used to return the address of allocated pages
65  *
66  * Allocate @num_pages physically contiguous pages from the system
67  * memory and return a pointer to the base of the allocation in
68  * @memory if the allocation succeeds. On success, the firmware memory
69  * map is updated accordingly.
70  *
71  * If @atype is AllocateAddress then, on input, @memory specifies the
72  * address at which to attempt to allocate the memory pages.
73  */
74 static inline EFI_STATUS
allocate_pages(EFI_ALLOCATE_TYPE atype,EFI_MEMORY_TYPE mtype,UINTN num_pages,EFI_PHYSICAL_ADDRESS * memory)75 allocate_pages(EFI_ALLOCATE_TYPE atype, EFI_MEMORY_TYPE mtype,
76 	       UINTN num_pages, EFI_PHYSICAL_ADDRESS *memory)
77 {
78 	return uefi_call_wrapper(boot->AllocatePages, 4, atype,
79 				 mtype, num_pages, memory);
80 }
81 
82 /**
83  * free_pages - Return memory allocated by allocate_pages() to the firmware
84  * @memory: physical base address of the page range to be freed
85  * @num_pages: number of contiguous 4KB pages to free
86  *
87  * On success, the firmware memory map is updated accordingly.
88  */
89 static inline EFI_STATUS
free_pages(EFI_PHYSICAL_ADDRESS memory,UINTN num_pages)90 free_pages(EFI_PHYSICAL_ADDRESS memory, UINTN num_pages)
91 {
92 	return uefi_call_wrapper(boot->FreePages, 2, memory, num_pages);
93 }
94 
95 /**
96  * allocate_pool - Allocate pool memory
97  * @type: the type of pool to allocate
98  * @size: number of bytes to allocate from pool of @type
99  * @buffer: used to return the address of allocated memory
100  *
101  * Allocate memory from pool of @type. If the pool needs more memory
102  * pages are allocated from EfiConventionalMemory in order to grow the
103  * pool.
104  *
105  * All allocations are eight-byte aligned.
106  */
107 static inline EFI_STATUS
allocate_pool(EFI_MEMORY_TYPE type,UINTN size,void ** buffer)108 allocate_pool(EFI_MEMORY_TYPE type, UINTN size, void **buffer)
109 {
110 	return uefi_call_wrapper(boot->AllocatePool, 3, type, size, buffer);
111 }
112 
113 /**
114  * free_pool - Return pool memory to the system
115  * @buffer: the buffer to free
116  *
117  * Return @buffer to the system. The returned memory is marked as
118  * EfiConventionalMemory.
119  */
free_pool(void * buffer)120 static inline EFI_STATUS free_pool(void *buffer)
121 {
122 	return uefi_call_wrapper(boot->FreePool, 1, buffer);
123 }
124 
125 /**
126  * get_memory_map - Return the current memory map
127  * @size: the size in bytes of @map
128  * @map: buffer to hold the current memory map
129  * @key: used to return the key for the current memory map
130  * @descr_size: used to return the size in bytes of EFI_MEMORY_DESCRIPTOR
131  * @descr_version: used to return the version of EFI_MEMORY_DESCRIPTOR
132  *
133  * Get a copy of the current memory map. The memory map is an array of
134  * EFI_MEMORY_DESCRIPTORs. An EFI_MEMORY_DESCRIPTOR describes a
135  * contiguous block of memory.
136  *
137  * On success, @key is updated to contain an identifer for the current
138  * memory map. The firmware's key is changed every time something in
139  * the memory map changes. @size is updated to indicate the size of
140  * the memory map pointed to by @map.
141  *
142  * @descr_size and @descr_version are used to ensure backwards
143  * compatibility with future changes made to the EFI_MEMORY_DESCRIPTOR
144  * structure. @descr_size MUST be used when the size of an
145  * EFI_MEMORY_DESCRIPTOR is used in a calculation, e.g when iterating
146  * over an array of EFI_MEMORY_DESCRIPTORs.
147  *
148  * On failure, and if the buffer pointed to by @map is too small to
149  * hold the memory map, EFI_BUFFER_TOO_SMALL is returned and @size is
150  * updated to reflect the size of a buffer required to hold the memory
151  * map.
152  */
153 static inline EFI_STATUS
get_memory_map(UINTN * size,EFI_MEMORY_DESCRIPTOR * map,UINTN * key,UINTN * descr_size,UINT32 * descr_version)154 get_memory_map(UINTN *size, EFI_MEMORY_DESCRIPTOR *map, UINTN *key,
155 	       UINTN *descr_size, UINT32 *descr_version)
156 {
157 	return uefi_call_wrapper(boot->GetMemoryMap, 5, size, map,
158 				 key, descr_size, descr_version);
159 }
160 
161 /**
162  * exit_boot_serivces - Terminate all boot services
163  * @image: firmware-allocated handle that identifies the image
164  * @key: key to the latest memory map
165  *
166  * This function is called when efilinux wants to take complete
167  * control of the system. efilinux should not make calls to boot time
168  * services after this function is called.
169  */
170 static inline EFI_STATUS
exit_boot_services(EFI_HANDLE image,UINTN key)171 exit_boot_services(EFI_HANDLE image, UINTN key)
172 {
173 	return uefi_call_wrapper(boot->ExitBootServices, 2, image, key);
174 }
175 
176 
177 /**
178  * handle_protocol - Query @handle to see if it supports @protocol
179  * @handle: the handle being queried
180  * @protocol: the GUID of the protocol
181  * @interface: used to return the protocol interface
182  *
183  * Query @handle to see if @protocol is supported. If it is supported,
184  * @interface contains the protocol interface.
185  */
186 static inline EFI_STATUS
handle_protocol(EFI_HANDLE handle,EFI_GUID * protocol,void ** interface)187 handle_protocol(EFI_HANDLE handle, EFI_GUID *protocol, void **interface)
188 {
189         return uefi_call_wrapper(boot->HandleProtocol, 3,
190                                  handle, protocol, interface);
191 }
192 
193 
194 /*
195  * emalloc_reserved_mem - it is called to allocate memory hypervisor itself
196  * and trampoline code, and mark the allocate memory as EfiReserved memory
197  * type so that Service VM won't touch it during boot.
198  * @addr: a pointer to the allocated address on success
199  * @size: size in bytes of the requested allocation
200  * @max_addr: the allocated memory must be no more than this threshold
201  */
emalloc_reserved_mem(EFI_PHYSICAL_ADDRESS * addr,UINTN size,EFI_PHYSICAL_ADDRESS max_addr)202 static inline EFI_STATUS emalloc_reserved_mem(EFI_PHYSICAL_ADDRESS *addr,
203 	UINTN size, EFI_PHYSICAL_ADDRESS max_addr)
204 {
205 	*addr = max_addr;
206 	return allocate_pages(AllocateMaxAddress, EfiReservedMemoryType,
207 		EFI_SIZE_TO_PAGES(size), addr);
208 }
209 
210 
211 /*
212  * emalloc_fixed_addr - it is called to allocate memory hypervisor itself
213  * when CONFIG_RELOC config is NOT enable.And mark the allocated memory as
214  * EfiReserved memory type so that Service VM won't touch it during boot.
215  * @addr: a pointer to the allocated address on success
216  * @size: size in bytes of the requested allocation
217  */
emalloc_fixed_addr(EFI_PHYSICAL_ADDRESS * addr,UINTN size,EFI_PHYSICAL_ADDRESS fixed_addr)218 static inline EFI_STATUS emalloc_fixed_addr(EFI_PHYSICAL_ADDRESS *addr,
219 	UINTN size, EFI_PHYSICAL_ADDRESS fixed_addr)
220 {
221 	*addr = fixed_addr;
222 	return allocate_pages(AllocateAddress, EfiReservedMemoryType,
223 		EFI_SIZE_TO_PAGES(size), addr);
224 }
225 
get_variable(const CHAR16 * name,EFI_GUID * guid,UINT32 * attrs,UINTN * size,void * data)226 static inline EFI_STATUS get_variable(const CHAR16 *name, EFI_GUID *guid, UINT32 *attrs, UINTN *size, void *data)
227 {
228 	return uefi_call_wrapper(runtime->GetVariable, 5, name, guid, attrs, size, data);
229 }
230 
set_variable(const CHAR16 * name,EFI_GUID * guid,UINT32 attrs,UINTN size,void * data)231 static inline EFI_STATUS set_variable(const CHAR16 *name, EFI_GUID *guid, UINT32 attrs, UINTN size, void *data)
232 {
233 	return uefi_call_wrapper(runtime->SetVariable, 5, name, guid, attrs, size, data);
234 }
235 
236 /**
237  * exit - Terminate a loaded EFI image
238  * @image: firmware-allocated handle that identifies the image
239  * @status: the image's exit code
240  * @size: size in bytes of @reason. Ignored if @status is EFI_SUCCESS
241  * @reason: a NUL-terminated status string, optionally followed by binary data
242  *
243  * This function terminates @image and returns control to the boot
244  * services. This function MUST NOT be called until all loaded child
245  * images have exited. All memory allocated by the image must be freed
246  * before calling this function, apart from the buffer @reason, which
247  * will be freed by the firmware.
248  */
249 static inline EFI_STATUS
exit(EFI_HANDLE image,EFI_STATUS status,UINTN size,CHAR16 * reason)250 exit(EFI_HANDLE image, EFI_STATUS status, UINTN size, CHAR16 *reason)
251 {
252 	return uefi_call_wrapper(boot->Exit, 4, image, status, size, reason);
253 }
254 
255 #define PAGE_SIZE	4096
256 
257 static const CHAR16 *memory_types[] = {
258 	L"EfiReservedMemoryType",
259 	L"EfiLoaderCode",
260 	L"EfiLoaderData",
261 	L"EfiBootServicesCode",
262 	L"EfiBootServicesData",
263 	L"EfiRuntimeServicesCode",
264 	L"EfiRuntimeServicesData",
265 	L"EfiConventionalMemory",
266 	L"EfiUnusableMemory",
267 	L"EfiACPIReclaimMemory",
268 	L"EfiACPIMemoryNVS",
269 	L"EfiMemoryMappedIO",
270 	L"EfiMemoryMappedIOPortSpace",
271 	L"EfiPalCode",
272 };
273 
memory_type_to_str(UINT32 type)274 static inline const CHAR16 *memory_type_to_str(UINT32 type)
275 {
276 	if (type > sizeof(memory_types)/sizeof(CHAR16 *))
277 		return L"Unknown";
278 
279 	return memory_types[type];
280 }
281 
282 extern EFI_STATUS memory_map(EFI_MEMORY_DESCRIPTOR **map_buf,
283 			     UINTN *map_size, UINTN *map_key,
284 			     UINTN *desc_size, UINT32 *desc_version);
285 
286 #endif /* __EFILINUX_H__ */
287