1f739fcd8STom Rini /* SPDX-License-Identifier: GPL-2.0+ */
2cb149c66SAlexander Graf /*
3cb149c66SAlexander Graf * EFI application loader
4cb149c66SAlexander Graf *
5cb149c66SAlexander Graf * Copyright (c) 2016 Alexander Graf
6cb149c66SAlexander Graf */
7cb149c66SAlexander Graf
8cd9e18deSHeinrich Schuchardt #ifndef _EFI_LOADER_H
9cd9e18deSHeinrich Schuchardt #define _EFI_LOADER_H 1
10cd9e18deSHeinrich Schuchardt
11bee91169SAlexander Graf #include <common.h>
12cb149c66SAlexander Graf #include <part_efi.h>
13cb149c66SAlexander Graf #include <efi_api.h>
14bee91169SAlexander Graf
15bee91169SAlexander Graf /* No need for efi loader support in SPL */
169b5e6396SStephen Warren #if CONFIG_IS_ENABLED(EFI_LOADER)
17bee91169SAlexander Graf
18cb149c66SAlexander Graf #include <linux/list.h>
19cb149c66SAlexander Graf
204182a129SHeinrich Schuchardt /* Maximum number of configuration tables */
214182a129SHeinrich Schuchardt #define EFI_MAX_CONFIGURATION_TABLES 16
224182a129SHeinrich Schuchardt
234e6b5d65SHeinrich Schuchardt /* GUID used by the root node */
244e6b5d65SHeinrich Schuchardt #define U_BOOT_GUID \
254e6b5d65SHeinrich Schuchardt EFI_GUID(0xe61d73b9, 0xa384, 0x4acc, \
264e6b5d65SHeinrich Schuchardt 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, 0x62, 0x8b)
274e6b5d65SHeinrich Schuchardt
28c160d2f5SRob Clark int __efi_entry_check(void);
29c160d2f5SRob Clark int __efi_exit_check(void);
30ae0bd3a9SHeinrich Schuchardt const char *__efi_nesting(void);
31af65db85SRob Clark const char *__efi_nesting_inc(void);
32af65db85SRob Clark const char *__efi_nesting_dec(void);
33c160d2f5SRob Clark
34a095aadfSRob Clark /*
35a095aadfSRob Clark * Enter the u-boot world from UEFI:
36a095aadfSRob Clark */
37bee91169SAlexander Graf #define EFI_ENTRY(format, ...) do { \
38c160d2f5SRob Clark assert(__efi_entry_check()); \
39af65db85SRob Clark debug("%sEFI: Entry %s(" format ")\n", __efi_nesting_inc(), \
40af65db85SRob Clark __func__, ##__VA_ARGS__); \
41bee91169SAlexander Graf } while(0)
42bee91169SAlexander Graf
43a095aadfSRob Clark /*
44a095aadfSRob Clark * Exit the u-boot world back to UEFI:
45a095aadfSRob Clark */
46804b1d73SRob Clark #define EFI_EXIT(ret) ({ \
47c81883dfSxypron.glpk@gmx.de typeof(ret) _r = ret; \
48af65db85SRob Clark debug("%sEFI: Exit: %s: %u\n", __efi_nesting_dec(), \
49c81883dfSxypron.glpk@gmx.de __func__, (u32)((uintptr_t) _r & ~EFI_ERROR_MASK)); \
50c160d2f5SRob Clark assert(__efi_exit_check()); \
51c160d2f5SRob Clark _r; \
52804b1d73SRob Clark })
53bee91169SAlexander Graf
54a095aadfSRob Clark /*
55ea630ce9SHeinrich Schuchardt * Call non-void UEFI function from u-boot and retrieve return value:
56a095aadfSRob Clark */
57ea630ce9SHeinrich Schuchardt #define EFI_CALL(exp) ({ \
58ea630ce9SHeinrich Schuchardt debug("%sEFI: Call: %s\n", __efi_nesting_inc(), #exp); \
59ea630ce9SHeinrich Schuchardt assert(__efi_exit_check()); \
60ea630ce9SHeinrich Schuchardt typeof(exp) _r = exp; \
61ea630ce9SHeinrich Schuchardt assert(__efi_entry_check()); \
62ea630ce9SHeinrich Schuchardt debug("%sEFI: %lu returned by %s\n", __efi_nesting_dec(), \
63ea630ce9SHeinrich Schuchardt (unsigned long)((uintptr_t)_r & ~EFI_ERROR_MASK), #exp); \
64ea630ce9SHeinrich Schuchardt _r; \
65ea630ce9SHeinrich Schuchardt })
66ea630ce9SHeinrich Schuchardt
67ea630ce9SHeinrich Schuchardt /*
68ea630ce9SHeinrich Schuchardt * Call void UEFI function from u-boot:
69ea630ce9SHeinrich Schuchardt */
70ea630ce9SHeinrich Schuchardt #define EFI_CALL_VOID(exp) do { \
71af65db85SRob Clark debug("%sEFI: Call: %s\n", __efi_nesting_inc(), #exp); \
72c160d2f5SRob Clark assert(__efi_exit_check()); \
73a095aadfSRob Clark exp; \
74c160d2f5SRob Clark assert(__efi_entry_check()); \
75af65db85SRob Clark debug("%sEFI: Return From: %s\n", __efi_nesting_dec(), #exp); \
76a095aadfSRob Clark } while(0)
77a095aadfSRob Clark
78ae0bd3a9SHeinrich Schuchardt /*
79d5504144SHeinrich Schuchardt * Write an indented message with EFI prefix
80ae0bd3a9SHeinrich Schuchardt */
81d5504144SHeinrich Schuchardt #define EFI_PRINT(format, ...) ({ \
82d5504144SHeinrich Schuchardt debug("%sEFI: " format, __efi_nesting(), \
83d5504144SHeinrich Schuchardt ##__VA_ARGS__); \
84ae0bd3a9SHeinrich Schuchardt })
85ae0bd3a9SHeinrich Schuchardt
8689aea436SAlexander Graf #ifdef CONFIG_SYS_CACHELINE_SIZE
8789aea436SAlexander Graf #define EFI_CACHELINE_SIZE CONFIG_SYS_CACHELINE_SIZE
8889aea436SAlexander Graf #else
8989aea436SAlexander Graf /* Just use the greatest cache flush alignment requirement I'm aware of */
9089aea436SAlexander Graf #define EFI_CACHELINE_SIZE 128
9189aea436SAlexander Graf #endif
9289aea436SAlexander Graf
931fcb7ea2SHeinrich Schuchardt /* Key identifying current memory map */
941fcb7ea2SHeinrich Schuchardt extern efi_uintn_t efi_memory_map_key;
951fcb7ea2SHeinrich Schuchardt
9650149ea3SAlexander Graf extern struct efi_runtime_services efi_runtime_services;
97bee91169SAlexander Graf extern struct efi_system_table systab;
98bee91169SAlexander Graf
99ebb4dd5bSHeinrich Schuchardt extern struct efi_simple_text_output_protocol efi_con_out;
1003e603ec7SHeinrich Schuchardt extern struct efi_simple_text_input_protocol efi_con_in;
101ebb4dd5bSHeinrich Schuchardt extern struct efi_console_control_protocol efi_console_control;
102cc5b7081Sxypron.glpk@gmx.de extern const struct efi_device_path_to_text_protocol efi_device_path_to_text;
103e70f8dfaSLeif Lindholm /* implementation of the EFI_DEVICE_PATH_UTILITIES_PROTOCOL */
104e70f8dfaSLeif Lindholm extern const struct efi_device_path_utilities_protocol
105e70f8dfaSLeif Lindholm efi_device_path_utilities;
1060bc4b0daSHeinrich Schuchardt /* Implementation of the EFI_UNICODE_COLLATION_PROTOCOL */
1070bc4b0daSHeinrich Schuchardt extern const struct efi_unicode_collation_protocol
1080bc4b0daSHeinrich Schuchardt efi_unicode_collation_protocol;
109cb728e51SAKASHI Takahiro extern const struct efi_hii_config_routing_protocol efi_hii_config_routing;
110cb728e51SAKASHI Takahiro extern const struct efi_hii_config_access_protocol efi_hii_config_access;
111c9bfb222SLeif Lindholm extern const struct efi_hii_database_protocol efi_hii_database;
112c9bfb222SLeif Lindholm extern const struct efi_hii_string_protocol efi_hii_string;
113c1311ad4SAlexander Graf
114adae4313SRob Clark uint16_t *efi_dp_str(struct efi_device_path *dp);
115adae4313SRob Clark
1164e6b5d65SHeinrich Schuchardt /* GUID of the U-Boot root node */
1174e6b5d65SHeinrich Schuchardt extern const efi_guid_t efi_u_boot_guid;
118b3dd14b6SHeinrich Schuchardt /* GUID of the EFI_BLOCK_IO_PROTOCOL */
119b3dd14b6SHeinrich Schuchardt extern const efi_guid_t efi_block_io_guid;
1209975fe96SRob Clark extern const efi_guid_t efi_global_variable_guid;
121c1311ad4SAlexander Graf extern const efi_guid_t efi_guid_console_control;
122cb149c66SAlexander Graf extern const efi_guid_t efi_guid_device_path;
123f0959dbeSHeinrich Schuchardt /* GUID of the EFI_DRIVER_BINDING_PROTOCOL */
124f0959dbeSHeinrich Schuchardt extern const efi_guid_t efi_guid_driver_binding_protocol;
125a3a28f5fSHeinrich Schuchardt /* event group ExitBootServices() invoked */
126a3a28f5fSHeinrich Schuchardt extern const efi_guid_t efi_guid_event_group_exit_boot_services;
127a3a28f5fSHeinrich Schuchardt /* event group SetVirtualAddressMap() invoked */
128a3a28f5fSHeinrich Schuchardt extern const efi_guid_t efi_guid_event_group_virtual_address_change;
129a3a28f5fSHeinrich Schuchardt /* event group memory map changed */
130a3a28f5fSHeinrich Schuchardt extern const efi_guid_t efi_guid_event_group_memory_map_change;
131a3a28f5fSHeinrich Schuchardt /* event group boot manager about to boot */
132a3a28f5fSHeinrich Schuchardt extern const efi_guid_t efi_guid_event_group_ready_to_boot;
133a3a28f5fSHeinrich Schuchardt /* event group ResetSystem() invoked (before ExitBootServices) */
134a3a28f5fSHeinrich Schuchardt extern const efi_guid_t efi_guid_event_group_reset_system;
135bc4f9133SHeinrich Schuchardt /* GUID of the device tree table */
136bc4f9133SHeinrich Schuchardt extern const efi_guid_t efi_guid_fdt;
137cb149c66SAlexander Graf extern const efi_guid_t efi_guid_loaded_image;
138cc5b7081Sxypron.glpk@gmx.de extern const efi_guid_t efi_guid_device_path_to_text_protocol;
1392a92080dSRob Clark extern const efi_guid_t efi_simple_file_system_protocol_guid;
1402a92080dSRob Clark extern const efi_guid_t efi_file_info_guid;
1419e6835e6SHeinrich Schuchardt /* GUID for file system information */
1429e6835e6SHeinrich Schuchardt extern const efi_guid_t efi_file_system_info_guid;
143e70f8dfaSLeif Lindholm extern const efi_guid_t efi_guid_device_path_utilities_protocol;
1440bc4b0daSHeinrich Schuchardt /* GUID of the Unicode collation protocol */
1450bc4b0daSHeinrich Schuchardt extern const efi_guid_t efi_guid_unicode_collation_protocol;
146cb728e51SAKASHI Takahiro extern const efi_guid_t efi_guid_hii_config_routing_protocol;
147cb728e51SAKASHI Takahiro extern const efi_guid_t efi_guid_hii_config_access_protocol;
148c9bfb222SLeif Lindholm extern const efi_guid_t efi_guid_hii_database_protocol;
149c9bfb222SLeif Lindholm extern const efi_guid_t efi_guid_hii_string_protocol;
150cb149c66SAlexander Graf
15150149ea3SAlexander Graf extern unsigned int __efi_runtime_start, __efi_runtime_stop;
15250149ea3SAlexander Graf extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop;
15350149ea3SAlexander Graf
154bee91169SAlexander Graf /*
155fe1599daSHeinrich Schuchardt * When a protocol is opened a open protocol info entry is created.
156fe1599daSHeinrich Schuchardt * These are maintained in a list.
157fe1599daSHeinrich Schuchardt */
158fe1599daSHeinrich Schuchardt struct efi_open_protocol_info_item {
159fe1599daSHeinrich Schuchardt /* Link to the list of open protocol info entries of a protocol */
160fe1599daSHeinrich Schuchardt struct list_head link;
161fe1599daSHeinrich Schuchardt struct efi_open_protocol_info_entry info;
162fe1599daSHeinrich Schuchardt };
163fe1599daSHeinrich Schuchardt
164fe1599daSHeinrich Schuchardt /*
165bee91169SAlexander Graf * When the UEFI payload wants to open a protocol on an object to get its
166bee91169SAlexander Graf * interface (usually a struct with callback functions), this struct maps the
167fe1599daSHeinrich Schuchardt * protocol GUID to the respective protocol interface
168fe1599daSHeinrich Schuchardt */
169bee91169SAlexander Graf struct efi_handler {
17069fb6b1aSHeinrich Schuchardt /* Link to the list of protocols of a handle */
17169fb6b1aSHeinrich Schuchardt struct list_head link;
172bee91169SAlexander Graf const efi_guid_t *guid;
173b5349f74Sxypron.glpk@gmx.de void *protocol_interface;
174fe1599daSHeinrich Schuchardt /* Link to the list of open protocol info items */
175fe1599daSHeinrich Schuchardt struct list_head open_infos;
176bee91169SAlexander Graf };
177bee91169SAlexander Graf
178fae0118eSHeinrich Schuchardt /**
179fae0118eSHeinrich Schuchardt * struct efi_object - dereferenced EFI handle
180bee91169SAlexander Graf *
181fae0118eSHeinrich Schuchardt * @link: pointers to put the handle into a linked list
182fae0118eSHeinrich Schuchardt * @protocols: linked list with the protocol interfaces installed on this
183fae0118eSHeinrich Schuchardt * handle
184fae0118eSHeinrich Schuchardt *
185fae0118eSHeinrich Schuchardt * UEFI offers a flexible and expandable object model. The objects in the UEFI
186fae0118eSHeinrich Schuchardt * API are devices, drivers, and loaded images. struct efi_object is our storage
187fae0118eSHeinrich Schuchardt * structure for these objects.
188fae0118eSHeinrich Schuchardt *
189fae0118eSHeinrich Schuchardt * When including this structure into a larger structure always put it first so
190fae0118eSHeinrich Schuchardt * that when deleting a handle the whole encompassing structure can be freed.
191fae0118eSHeinrich Schuchardt *
192fae0118eSHeinrich Schuchardt * A pointer to this structure is referred to as a handle. Typedef efi_handle_t
193fae0118eSHeinrich Schuchardt * has been created for such pointers.
194bee91169SAlexander Graf */
195bee91169SAlexander Graf struct efi_object {
196bee91169SAlexander Graf /* Every UEFI object is part of a global object list */
197bee91169SAlexander Graf struct list_head link;
19869fb6b1aSHeinrich Schuchardt /* The list of protocols */
19969fb6b1aSHeinrich Schuchardt struct list_head protocols;
200bee91169SAlexander Graf };
201bee91169SAlexander Graf
202c6841592Sxypron.glpk@gmx.de /**
203c982874eSHeinrich Schuchardt * struct efi_loaded_image_obj - handle of a loaded image
204d39646a3SHeinrich Schuchardt *
205d39646a3SHeinrich Schuchardt * @header: EFI object header
206d39646a3SHeinrich Schuchardt * @reloc_base: base address for the relocated image
207d39646a3SHeinrich Schuchardt * @reloc_size: size of the relocated image
208d39646a3SHeinrich Schuchardt * @exit_jmp: long jump buffer for returning form started image
209d39646a3SHeinrich Schuchardt * @entry: entry address of the relocated image
210c982874eSHeinrich Schuchardt */
211c982874eSHeinrich Schuchardt struct efi_loaded_image_obj {
212d39646a3SHeinrich Schuchardt struct efi_object header;
213c982874eSHeinrich Schuchardt void *reloc_base;
214c982874eSHeinrich Schuchardt aligned_u64 reloc_size;
215c982874eSHeinrich Schuchardt efi_status_t exit_status;
216c982874eSHeinrich Schuchardt struct jmp_buf_data exit_jmp;
217c982874eSHeinrich Schuchardt EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
218c982874eSHeinrich Schuchardt struct efi_system_table *st);
219c982874eSHeinrich Schuchardt };
220c982874eSHeinrich Schuchardt
221c982874eSHeinrich Schuchardt /**
222c6841592Sxypron.glpk@gmx.de * struct efi_event
223c6841592Sxypron.glpk@gmx.de *
22443bce442SHeinrich Schuchardt * @link: Link to list of all events
225c6841592Sxypron.glpk@gmx.de * @type: Type of event, see efi_create_event
226c6841592Sxypron.glpk@gmx.de * @notify_tpl: Task priority level of notifications
227c6841592Sxypron.glpk@gmx.de * @nofify_function: Function to call when the event is triggered
228c6841592Sxypron.glpk@gmx.de * @notify_context: Data to be passed to the notify function
229b095f3c8SHeinrich Schuchardt * @group: Event group
23043bce442SHeinrich Schuchardt * @trigger_time: Period of the timer
23143bce442SHeinrich Schuchardt * @trigger_next: Next time to trigger the timer
232c6841592Sxypron.glpk@gmx.de * @trigger_type: Type of timer, see efi_set_timer
23343bce442SHeinrich Schuchardt * @is_queued: The notification function is queued
23443bce442SHeinrich Schuchardt * @is_signaled: The event occurred. The event is in the signaled state.
235c6841592Sxypron.glpk@gmx.de */
236c6841592Sxypron.glpk@gmx.de struct efi_event {
23743bce442SHeinrich Schuchardt struct list_head link;
238b521d29eSxypron.glpk@gmx.de uint32_t type;
239152cade3SHeinrich Schuchardt efi_uintn_t notify_tpl;
240c6841592Sxypron.glpk@gmx.de void (EFIAPI *notify_function)(struct efi_event *event, void *context);
241c6841592Sxypron.glpk@gmx.de void *notify_context;
242b095f3c8SHeinrich Schuchardt const efi_guid_t *group;
243c6841592Sxypron.glpk@gmx.de u64 trigger_next;
244c6841592Sxypron.glpk@gmx.de u64 trigger_time;
245b521d29eSxypron.glpk@gmx.de enum efi_timer_delay trigger_type;
246e190e897SHeinrich Schuchardt bool is_queued;
247e190e897SHeinrich Schuchardt bool is_signaled;
248c6841592Sxypron.glpk@gmx.de };
249c6841592Sxypron.glpk@gmx.de
250bee91169SAlexander Graf /* This list contains all UEFI objects we know of */
251bee91169SAlexander Graf extern struct list_head efi_obj_list;
252b095f3c8SHeinrich Schuchardt /* List of all events */
253b095f3c8SHeinrich Schuchardt extern struct list_head efi_events;
254bee91169SAlexander Graf
255056b45bcSAKASHI Takahiro /* Initialize efi execution environment */
256056b45bcSAKASHI Takahiro efi_status_t efi_init_obj_list(void);
2574e6b5d65SHeinrich Schuchardt /* Called by bootefi to initialize root node */
2584e6b5d65SHeinrich Schuchardt efi_status_t efi_root_node_register(void);
259640adadfSHeinrich Schuchardt /* Called by bootefi to initialize runtime */
260640adadfSHeinrich Schuchardt efi_status_t efi_initialize_system_table(void);
26191be9a77Sxypron.glpk@gmx.de /* Called by bootefi to make console interface available */
2626f566c23SHeinrich Schuchardt efi_status_t efi_console_register(void);
2632a22d05dSAlexander Graf /* Called by bootefi to make all disk storage accessible as EFI objects */
264df9cf561SHeinrich Schuchardt efi_status_t efi_disk_register(void);
26564e4db0fSHeinrich Schuchardt /* Create handles and protocols for the partitions of a block device */
26664e4db0fSHeinrich Schuchardt int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
26764e4db0fSHeinrich Schuchardt const char *if_typename, int diskid,
26864e4db0fSHeinrich Schuchardt const char *pdevname);
269be8d3241SAlexander Graf /* Called by bootefi to make GOP (graphical) interface available */
27080ea9b09SHeinrich Schuchardt efi_status_t efi_gop_register(void);
2710efe1bcfSAlexander Graf /* Called by bootefi to make the network interface available */
272075d425dSHeinrich Schuchardt efi_status_t efi_net_register(void);
273b3d60900SHeinrich Schuchardt /* Called by bootefi to make the watchdog available */
274d7b181d5SHeinrich Schuchardt efi_status_t efi_watchdog_register(void);
275e663b350SAlexander Graf /* Called by bootefi to make SMBIOS tables available */
2760864c565SSimon Glass /**
27786df34d4SBin Meng * efi_acpi_register() - write out ACPI tables
27886df34d4SBin Meng *
27986df34d4SBin Meng * Called by bootefi to make ACPI tables available
28086df34d4SBin Meng *
28186df34d4SBin Meng * @return 0 if OK, -ENOMEM if no memory is available for the tables
28286df34d4SBin Meng */
28386df34d4SBin Meng efi_status_t efi_acpi_register(void);
28486df34d4SBin Meng /**
2850864c565SSimon Glass * efi_smbios_register() - write out SMBIOS tables
2860864c565SSimon Glass *
2870864c565SSimon Glass * Called by bootefi to make SMBIOS tables available
2880864c565SSimon Glass *
2890864c565SSimon Glass * @return 0 if OK, -ENOMEM if no memory is available for the tables
2900864c565SSimon Glass */
2917657152bSHeinrich Schuchardt efi_status_t efi_smbios_register(void);
2920efe1bcfSAlexander Graf
2932a92080dSRob Clark struct efi_simple_file_system_protocol *
2942a92080dSRob Clark efi_fs_from_path(struct efi_device_path *fp);
2952a92080dSRob Clark
2960efe1bcfSAlexander Graf /* Called by networking code to memorize the dhcp ack package */
2970efe1bcfSAlexander Graf void efi_net_set_dhcp_ack(void *pkt, int len);
298b3d60900SHeinrich Schuchardt /* Called by efi_set_watchdog_timer to reset the timer */
299b3d60900SHeinrich Schuchardt efi_status_t efi_set_watchdog(unsigned long timeout);
3000efe1bcfSAlexander Graf
301bee91169SAlexander Graf /* Called from places to check whether a timer expired */
302bee91169SAlexander Graf void efi_timer_check(void);
303bee91169SAlexander Graf /* PE loader implementation */
3048f7e2b29SHeinrich Schuchardt efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
305c982874eSHeinrich Schuchardt struct efi_loaded_image *loaded_image_info);
306bee91169SAlexander Graf /* Called once to store the pristine gd pointer */
307bee91169SAlexander Graf void efi_save_gd(void);
308c160d2f5SRob Clark /* Special case handler for error/abort that just tries to dtrt to get
309c160d2f5SRob Clark * back to u-boot world */
310bee91169SAlexander Graf void efi_restore_gd(void);
31150149ea3SAlexander Graf /* Call this to relocate the runtime section to an address space */
31250149ea3SAlexander Graf void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map);
3130f4060ebSAlexander Graf /* Call this to set the current device name */
314c07ad7c0SAlexander Graf void efi_set_bootdev(const char *dev, const char *devnr, const char *path);
31544549d62SHeinrich Schuchardt /* Add a new object to the object list. */
316fae0118eSHeinrich Schuchardt void efi_add_handle(efi_handle_t obj);
3172edab5e2SHeinrich Schuchardt /* Create handle */
3182074f700SHeinrich Schuchardt efi_status_t efi_create_handle(efi_handle_t *handle);
319678e03a0SHeinrich Schuchardt /* Delete handle */
320fae0118eSHeinrich Schuchardt void efi_delete_handle(efi_handle_t obj);
3211b68153aSHeinrich Schuchardt /* Call this to validate a handle and find the EFI object for it */
3222074f700SHeinrich Schuchardt struct efi_object *efi_search_obj(const efi_handle_t handle);
323*f69d63faSHeinrich Schuchardt /* Start image */
324*f69d63faSHeinrich Schuchardt efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
325*f69d63faSHeinrich Schuchardt efi_uintn_t *exit_data_size,
326*f69d63faSHeinrich Schuchardt u16 **exit_data);
3273f79a2b5SHeinrich Schuchardt /* Find a protocol on a handle */
3282074f700SHeinrich Schuchardt efi_status_t efi_search_protocol(const efi_handle_t handle,
3293f79a2b5SHeinrich Schuchardt const efi_guid_t *protocol_guid,
3303f79a2b5SHeinrich Schuchardt struct efi_handler **handler);
3313f79a2b5SHeinrich Schuchardt /* Install new protocol on a handle */
3322074f700SHeinrich Schuchardt efi_status_t efi_add_protocol(const efi_handle_t handle,
3332074f700SHeinrich Schuchardt const efi_guid_t *protocol,
3343f79a2b5SHeinrich Schuchardt void *protocol_interface);
3353f79a2b5SHeinrich Schuchardt /* Delete protocol from a handle */
3362074f700SHeinrich Schuchardt efi_status_t efi_remove_protocol(const efi_handle_t handle,
3372074f700SHeinrich Schuchardt const efi_guid_t *protocol,
3383f79a2b5SHeinrich Schuchardt void *protocol_interface);
3393f79a2b5SHeinrich Schuchardt /* Delete all protocols from a handle */
3402074f700SHeinrich Schuchardt efi_status_t efi_remove_all_protocols(const efi_handle_t handle);
34149deb455Sxypron.glpk@gmx.de /* Call this to create an event */
342152cade3SHeinrich Schuchardt efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
34349deb455Sxypron.glpk@gmx.de void (EFIAPI *notify_function) (
34449deb455Sxypron.glpk@gmx.de struct efi_event *event,
34549deb455Sxypron.glpk@gmx.de void *context),
346b095f3c8SHeinrich Schuchardt void *notify_context, efi_guid_t *group,
347b095f3c8SHeinrich Schuchardt struct efi_event **event);
348bfc72462Sxypron.glpk@gmx.de /* Call this to set a timer */
349b521d29eSxypron.glpk@gmx.de efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type,
350bfc72462Sxypron.glpk@gmx.de uint64_t trigger_time);
35191be9a77Sxypron.glpk@gmx.de /* Call this to signal an event */
3529bc9664dSHeinrich Schuchardt void efi_signal_event(struct efi_event *event, bool check_tpl);
35350149ea3SAlexander Graf
3542a92080dSRob Clark /* open file system: */
3552a92080dSRob Clark struct efi_simple_file_system_protocol *efi_simple_file_system(
3562a92080dSRob Clark struct blk_desc *desc, int part, struct efi_device_path *dp);
3572a92080dSRob Clark
3582a92080dSRob Clark /* open file from device-path: */
3592a92080dSRob Clark struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp);
3602a92080dSRob Clark
361c3772ca1SHeinrich Schuchardt /**
362c3772ca1SHeinrich Schuchardt * efi_size_in_pages() - convert size in bytes to size in pages
363c3772ca1SHeinrich Schuchardt *
364c3772ca1SHeinrich Schuchardt * This macro returns the number of EFI memory pages required to hold 'size'
365c3772ca1SHeinrich Schuchardt * bytes.
366c3772ca1SHeinrich Schuchardt *
367c3772ca1SHeinrich Schuchardt * @size: size in bytes
368c3772ca1SHeinrich Schuchardt * Return: size in pages
369c3772ca1SHeinrich Schuchardt */
370c3772ca1SHeinrich Schuchardt #define efi_size_in_pages(size) ((size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT)
3715d00995cSAlexander Graf /* Generic EFI memory allocator, call this to get memory */
3725d00995cSAlexander Graf void *efi_alloc(uint64_t len, int memory_type);
3735d00995cSAlexander Graf /* More specific EFI memory allocator, called by EFI payloads */
374f5a2a938SHeinrich Schuchardt efi_status_t efi_allocate_pages(int type, int memory_type, efi_uintn_t pages,
3755d00995cSAlexander Graf uint64_t *memory);
376b61d857bSStefan Brüns /* EFI memory free function. */
377f5a2a938SHeinrich Schuchardt efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages);
378ead1274bSStefan Brüns /* EFI memory allocator for small allocations */
379f5a2a938SHeinrich Schuchardt efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size,
380ead1274bSStefan Brüns void **buffer);
38142417bc8SStefan Brüns /* EFI pool memory free function. */
38242417bc8SStefan Brüns efi_status_t efi_free_pool(void *buffer);
3835d00995cSAlexander Graf /* Returns the EFI memory map */
384f5a2a938SHeinrich Schuchardt efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
3855d00995cSAlexander Graf struct efi_mem_desc *memory_map,
386f5a2a938SHeinrich Schuchardt efi_uintn_t *map_key,
387f5a2a938SHeinrich Schuchardt efi_uintn_t *descriptor_size,
3885d00995cSAlexander Graf uint32_t *descriptor_version);
3895d00995cSAlexander Graf /* Adds a range into the EFI memory map */
3905d00995cSAlexander Graf uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
3915d00995cSAlexander Graf bool overlap_only_ram);
39205ef48a2SHeinrich Schuchardt /* Called by board init to initialize the EFI drivers */
393038782a2SHeinrich Schuchardt efi_status_t efi_driver_init(void);
3945d00995cSAlexander Graf /* Called by board init to initialize the EFI memory map */
3955d00995cSAlexander Graf int efi_memory_init(void);
396488bf12dSAlexander Graf /* Adds new or overrides configuration table entry to the system table */
397488bf12dSAlexander Graf efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table);
39856d92888SHeinrich Schuchardt /* Sets up a loaded image */
399c982874eSHeinrich Schuchardt efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path,
400c982874eSHeinrich Schuchardt struct efi_device_path *file_path,
401c982874eSHeinrich Schuchardt struct efi_loaded_image_obj **handle_ptr,
402c982874eSHeinrich Schuchardt struct efi_loaded_image **info_ptr);
4039975fe96SRob Clark efi_status_t efi_load_image_from_path(struct efi_device_path *file_path,
4040e18f584SHeinrich Schuchardt void **buffer, efi_uintn_t *size);
405c9a63f44SHeinrich Schuchardt /* Print information about all loaded images */
406c9a63f44SHeinrich Schuchardt void efi_print_image_infos(void *pc);
4075d00995cSAlexander Graf
40851735ae0SAlexander Graf #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
40951735ae0SAlexander Graf extern void *efi_bounce_buffer;
41051735ae0SAlexander Graf #define EFI_LOADER_BOUNCE_BUFFER_SIZE (64 * 1024 * 1024)
41151735ae0SAlexander Graf #endif
41251735ae0SAlexander Graf
413b66c60ddSRob Clark
414b66c60ddSRob Clark struct efi_device_path *efi_dp_next(const struct efi_device_path *dp);
415ff401d3fSHeinrich Schuchardt int efi_dp_match(const struct efi_device_path *a,
416ff401d3fSHeinrich Schuchardt const struct efi_device_path *b);
417b66c60ddSRob Clark struct efi_object *efi_dp_find_obj(struct efi_device_path *dp,
418b66c60ddSRob Clark struct efi_device_path **rem);
419f6dd3f35SHeinrich Schuchardt /* get size of the first device path instance excluding end node */
420f6dd3f35SHeinrich Schuchardt efi_uintn_t efi_dp_instance_size(const struct efi_device_path *dp);
421f6dd3f35SHeinrich Schuchardt /* size of multi-instance device path excluding end node */
422f6dd3f35SHeinrich Schuchardt efi_uintn_t efi_dp_size(const struct efi_device_path *dp);
423b66c60ddSRob Clark struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp);
424b66c60ddSRob Clark struct efi_device_path *efi_dp_append(const struct efi_device_path *dp1,
425b66c60ddSRob Clark const struct efi_device_path *dp2);
426b66c60ddSRob Clark struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp,
427b66c60ddSRob Clark const struct efi_device_path *node);
428211314c1SHeinrich Schuchardt /* Create a device path node of given type, sub-type, length */
429211314c1SHeinrich Schuchardt struct efi_device_path *efi_dp_create_device_node(const u8 type,
430211314c1SHeinrich Schuchardt const u8 sub_type,
431211314c1SHeinrich Schuchardt const u16 length);
4323acef5daSHeinrich Schuchardt /* Append device path instance */
4333acef5daSHeinrich Schuchardt struct efi_device_path *efi_dp_append_instance(
4343acef5daSHeinrich Schuchardt const struct efi_device_path *dp,
4353acef5daSHeinrich Schuchardt const struct efi_device_path *dpi);
4363acef5daSHeinrich Schuchardt /* Get next device path instance */
4373acef5daSHeinrich Schuchardt struct efi_device_path *efi_dp_get_next_instance(struct efi_device_path **dp,
4383acef5daSHeinrich Schuchardt efi_uintn_t *size);
4393acef5daSHeinrich Schuchardt /* Check if a device path contains muliple instances */
4403acef5daSHeinrich Schuchardt bool efi_dp_is_multi_instance(const struct efi_device_path *dp);
441b66c60ddSRob Clark
442b66c60ddSRob Clark struct efi_device_path *efi_dp_from_dev(struct udevice *dev);
443b66c60ddSRob Clark struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part);
44498d48bdfSHeinrich Schuchardt /* Create a device node for a block device partition. */
44598d48bdfSHeinrich Schuchardt struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part);
446b66c60ddSRob Clark struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part,
447b66c60ddSRob Clark const char *path);
448b66c60ddSRob Clark struct efi_device_path *efi_dp_from_eth(void);
449bf19273eSRob Clark struct efi_device_path *efi_dp_from_mem(uint32_t mem_type,
450bf19273eSRob Clark uint64_t start_address,
451bf19273eSRob Clark uint64_t end_address);
45265436f91SHeinrich Schuchardt /* Determine the last device path node that is not the end node. */
45365436f91SHeinrich Schuchardt const struct efi_device_path *efi_dp_last_node(
45465436f91SHeinrich Schuchardt const struct efi_device_path *dp);
45504298686SHeinrich Schuchardt efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path,
456b66c60ddSRob Clark struct efi_device_path **device_path,
457b66c60ddSRob Clark struct efi_device_path **file_path);
458f1589ffbSAKASHI Takahiro efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
459f1589ffbSAKASHI Takahiro const char *path,
460f1589ffbSAKASHI Takahiro struct efi_device_path **device,
461f1589ffbSAKASHI Takahiro struct efi_device_path **file);
462b66c60ddSRob Clark
463b66c60ddSRob Clark #define EFI_DP_TYPE(_dp, _type, _subtype) \
464b66c60ddSRob Clark (((_dp)->type == DEVICE_PATH_TYPE_##_type) && \
465b66c60ddSRob Clark ((_dp)->sub_type == DEVICE_PATH_SUB_TYPE_##_subtype))
466b66c60ddSRob Clark
4679d08f6dbSHeinrich Schuchardt /**
4689d08f6dbSHeinrich Schuchardt * ascii2unicode() - convert ASCII string to UTF-16 string
4699d08f6dbSHeinrich Schuchardt *
4709d08f6dbSHeinrich Schuchardt * A zero terminated ASCII string is converted to a zero terminated UTF-16
4719d08f6dbSHeinrich Schuchardt * string. The output buffer must be preassigned.
4729d08f6dbSHeinrich Schuchardt *
4739d08f6dbSHeinrich Schuchardt * @unicode: preassigned output buffer for UTF-16 string
4749d08f6dbSHeinrich Schuchardt * @ascii: ASCII string to be converted
4759d08f6dbSHeinrich Schuchardt */
ascii2unicode(u16 * unicode,const char * ascii)476487d756fSSimon Glass static inline void ascii2unicode(u16 *unicode, const char *ascii)
4770f4060ebSAlexander Graf {
4780f4060ebSAlexander Graf while (*ascii)
4790f4060ebSAlexander Graf *(unicode++) = *(ascii++);
480c412166dSHeinrich Schuchardt *unicode = 0;
4810f4060ebSAlexander Graf }
4820f4060ebSAlexander Graf
guidcmp(const efi_guid_t * g1,const efi_guid_t * g2)4833e094c59SRob Clark static inline int guidcmp(const efi_guid_t *g1, const efi_guid_t *g2)
4843e094c59SRob Clark {
4853e094c59SRob Clark return memcmp(g1, g2, sizeof(efi_guid_t));
4863e094c59SRob Clark }
4873e094c59SRob Clark
48850149ea3SAlexander Graf /*
48950149ea3SAlexander Graf * Use these to indicate that your code / data should go into the EFI runtime
49050149ea3SAlexander Graf * section and thus still be available when the OS is running
49150149ea3SAlexander Graf */
4927e21fbcaSAlexander Graf #define __efi_runtime_data __attribute__ ((section (".data.efi_runtime")))
4937e21fbcaSAlexander Graf #define __efi_runtime __attribute__ ((section (".text.efi_runtime")))
494bee91169SAlexander Graf
495a39f39cdSHeinrich Schuchardt /* Update CRC32 in table header */
496a39f39cdSHeinrich Schuchardt void __efi_runtime efi_update_table_header_crc32(struct efi_table_hdr *table);
497a39f39cdSHeinrich Schuchardt
49880a4800eSAlexander Graf /* Call this with mmio_ptr as the _pointer_ to a pointer to an MMIO region
49980a4800eSAlexander Graf * to make it available at runtime */
50022c793e6SHeinrich Schuchardt efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len);
50180a4800eSAlexander Graf
50280a4800eSAlexander Graf /* Boards may provide the functions below to implement RTS functionality */
50380a4800eSAlexander Graf
5043c63db9cSAlexander Graf void __efi_runtime EFIAPI efi_reset_system(
50580a4800eSAlexander Graf enum efi_reset_type reset_type,
50680a4800eSAlexander Graf efi_status_t reset_status,
50780a4800eSAlexander Graf unsigned long data_size, void *reset_data);
50822c793e6SHeinrich Schuchardt
50922c793e6SHeinrich Schuchardt /* Architecture specific initialization of the EFI subsystem */
51022c793e6SHeinrich Schuchardt efi_status_t efi_reset_system_init(void);
51180a4800eSAlexander Graf
5123c63db9cSAlexander Graf efi_status_t __efi_runtime EFIAPI efi_get_time(
51380a4800eSAlexander Graf struct efi_time *time,
51480a4800eSAlexander Graf struct efi_time_cap *capabilities);
51580a4800eSAlexander Graf
516623b3a57SHeinrich Schuchardt #ifdef CONFIG_CMD_BOOTEFI_SELFTEST
517623b3a57SHeinrich Schuchardt /*
518623b3a57SHeinrich Schuchardt * Entry point for the tests of the EFI API.
519623b3a57SHeinrich Schuchardt * It is called by 'bootefi selftest'
520623b3a57SHeinrich Schuchardt */
521623b3a57SHeinrich Schuchardt efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle,
522623b3a57SHeinrich Schuchardt struct efi_system_table *systab);
523623b3a57SHeinrich Schuchardt #endif
524623b3a57SHeinrich Schuchardt
5250bda81bfSHeinrich Schuchardt efi_status_t EFIAPI efi_get_variable(u16 *variable_name,
5260bda81bfSHeinrich Schuchardt const efi_guid_t *vendor, u32 *attributes,
5270bda81bfSHeinrich Schuchardt efi_uintn_t *data_size, void *data);
52845c66f9cSHeinrich Schuchardt efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size,
52945c66f9cSHeinrich Schuchardt u16 *variable_name,
5300bda81bfSHeinrich Schuchardt const efi_guid_t *vendor);
5310bda81bfSHeinrich Schuchardt efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
5320bda81bfSHeinrich Schuchardt const efi_guid_t *vendor, u32 attributes,
533452257a3SHeinrich Schuchardt efi_uintn_t data_size, const void *data);
534ad644e7cSRob Clark
5351a82b341SAKASHI Takahiro /*
5361a82b341SAKASHI Takahiro * See section 3.1.3 in the v2.7 UEFI spec for more details on
5371a82b341SAKASHI Takahiro * the layout of EFI_LOAD_OPTION. In short it is:
5381a82b341SAKASHI Takahiro *
5391a82b341SAKASHI Takahiro * typedef struct _EFI_LOAD_OPTION {
5401a82b341SAKASHI Takahiro * UINT32 Attributes;
5411a82b341SAKASHI Takahiro * UINT16 FilePathListLength;
5421a82b341SAKASHI Takahiro * // CHAR16 Description[]; <-- variable length, NULL terminated
5431a82b341SAKASHI Takahiro * // EFI_DEVICE_PATH_PROTOCOL FilePathList[];
5441a82b341SAKASHI Takahiro * <-- FilePathListLength bytes
5451a82b341SAKASHI Takahiro * // UINT8 OptionalData[];
5461a82b341SAKASHI Takahiro * } EFI_LOAD_OPTION;
5471a82b341SAKASHI Takahiro */
5481a82b341SAKASHI Takahiro struct efi_load_option {
5491a82b341SAKASHI Takahiro u32 attributes;
5501a82b341SAKASHI Takahiro u16 file_path_length;
5511a82b341SAKASHI Takahiro u16 *label;
5521a82b341SAKASHI Takahiro struct efi_device_path *file_path;
5531a82b341SAKASHI Takahiro u8 *optional_data;
5541a82b341SAKASHI Takahiro };
5551a82b341SAKASHI Takahiro
5561a82b341SAKASHI Takahiro void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data);
5571a82b341SAKASHI Takahiro unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data);
5589975fe96SRob Clark void *efi_bootmgr_load(struct efi_device_path **device_path,
5599975fe96SRob Clark struct efi_device_path **file_path);
5609975fe96SRob Clark
5619b5e6396SStephen Warren #else /* CONFIG_IS_ENABLED(EFI_LOADER) */
562bee91169SAlexander Graf
56350149ea3SAlexander Graf /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */
5643c63db9cSAlexander Graf #define __efi_runtime_data
5653c63db9cSAlexander Graf #define __efi_runtime
efi_add_runtime_mmio(void * mmio_ptr,u64 len)56622c793e6SHeinrich Schuchardt static inline efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len)
56722c793e6SHeinrich Schuchardt {
56822c793e6SHeinrich Schuchardt return EFI_SUCCESS;
56922c793e6SHeinrich Schuchardt }
57050149ea3SAlexander Graf
571bee91169SAlexander Graf /* No loader configured, stub out EFI_ENTRY */
efi_restore_gd(void)572bee91169SAlexander Graf static inline void efi_restore_gd(void) { }
efi_set_bootdev(const char * dev,const char * devnr,const char * path)573c07ad7c0SAlexander Graf static inline void efi_set_bootdev(const char *dev, const char *devnr,
574c07ad7c0SAlexander Graf const char *path) { }
efi_net_set_dhcp_ack(void * pkt,int len)5750efe1bcfSAlexander Graf static inline void efi_net_set_dhcp_ack(void *pkt, int len) { }
efi_print_image_infos(void * pc)576c9a63f44SHeinrich Schuchardt static inline void efi_print_image_infos(void *pc) { }
577bee91169SAlexander Graf
5789b5e6396SStephen Warren #endif /* CONFIG_IS_ENABLED(EFI_LOADER) */
579cd9e18deSHeinrich Schuchardt
580cd9e18deSHeinrich Schuchardt #endif /* _EFI_LOADER_H */
581