2 * EFI application boot time services
4 * Copyright (c) 2016 Alexander Graf
6 * SPDX-License-Identifier: GPL-2.0+
10 #include <efi_loader.h>
12 #include <asm/global_data.h>
13 #include <libfdt_env.h>
14 #include <u-boot/crc.h>
19 DECLARE_GLOBAL_DATA_PTR
;
21 /* This list contains all the EFI objects our payload has access to */
22 LIST_HEAD(efi_obj_list
);
25 * If we're running on nasty systems (32bit ARM booting into non-EFI Linux)
26 * we need to do trickery with caches. Since we don't want to break the EFI
27 * aware boot path, only apply hacks when loading exiting directly (breaking
28 * direct Linux EFI booting along the way - oh well).
30 static bool efi_is_direct_boot
= true;
33 * EFI can pass arbitrary additional "tables" containing vendor specific
34 * information to the payload. One such table is the FDT table which contains
35 * a pointer to a flattened device tree blob.
37 * In most cases we want to pass an FDT to the payload, so reserve one slot of
38 * config table space for it. The pointer gets populated by do_bootefi_exec().
40 static struct efi_configuration_table __efi_runtime_data efi_conf_table
[2];
44 * The "gd" pointer lives in a register on ARM and AArch64 that we declare
45 * fixed when compiling U-Boot. However, the payload does not know about that
46 * restriction so we need to manually swap its and our view of that register on
47 * EFI callback entry/exit.
49 static volatile void *efi_gd
, *app_gd
;
52 /* Called from do_bootefi_exec() */
53 void efi_save_gd(void)
60 /* Called on every callback entry */
61 void efi_restore_gd(void)
64 /* Only restore if we're already in EFI context */
74 /* Called on every callback exit */
75 efi_status_t
efi_exit_func(efi_status_t ret
)
84 static efi_status_t
efi_unsupported(const char *funcname
)
86 debug("EFI: App called into unimplemented function %s\n", funcname
);
87 return EFI_EXIT(EFI_UNSUPPORTED
);
90 static int guidcmp(const efi_guid_t
*g1
, const efi_guid_t
*g2
)
92 return memcmp(g1
, g2
, sizeof(efi_guid_t
));
95 static unsigned long EFIAPI
efi_raise_tpl(unsigned long new_tpl
)
97 EFI_ENTRY("0x%lx", new_tpl
);
101 static void EFIAPI
efi_restore_tpl(unsigned long old_tpl
)
103 EFI_ENTRY("0x%lx", old_tpl
);
104 EFI_EXIT(efi_unsupported(__func__
));
107 static efi_status_t EFIAPI
efi_allocate_pages_ext(int type
, int memory_type
,
113 EFI_ENTRY("%d, %d, 0x%lx, %p", type
, memory_type
, pages
, memory
);
114 r
= efi_allocate_pages(type
, memory_type
, pages
, memory
);
118 static efi_status_t EFIAPI
efi_free_pages_ext(uint64_t memory
,
123 EFI_ENTRY("%"PRIx64
", 0x%lx", memory
, pages
);
124 r
= efi_free_pages(memory
, pages
);
128 static efi_status_t EFIAPI
efi_get_memory_map_ext(
129 unsigned long *memory_map_size
,
130 struct efi_mem_desc
*memory_map
,
131 unsigned long *map_key
,
132 unsigned long *descriptor_size
,
133 uint32_t *descriptor_version
)
137 EFI_ENTRY("%p, %p, %p, %p, %p", memory_map_size
, memory_map
,
138 map_key
, descriptor_size
, descriptor_version
);
139 r
= efi_get_memory_map(memory_map_size
, memory_map
, map_key
,
140 descriptor_size
, descriptor_version
);
144 static efi_status_t EFIAPI
efi_allocate_pool_ext(int pool_type
,
150 EFI_ENTRY("%d, %ld, %p", pool_type
, size
, buffer
);
151 r
= efi_allocate_pool(pool_type
, size
, buffer
);
155 static efi_status_t EFIAPI
efi_free_pool_ext(void *buffer
)
159 EFI_ENTRY("%p", buffer
);
160 r
= efi_free_pool(buffer
);
165 * Our event capabilities are very limited. Only support a single
166 * event to exist, so we don't need to maintain lists.
169 enum efi_event_type type
;
173 unsigned long notify_tpl
;
174 void (EFIAPI
*notify_function
) (void *event
, void *context
);
175 void *notify_context
;
177 /* Disable timers on bootup */
178 .trigger_next
= -1ULL,
181 static efi_status_t EFIAPI
efi_create_event(
182 enum efi_event_type type
, ulong notify_tpl
,
183 void (EFIAPI
*notify_function
) (void *event
,
185 void *notify_context
, void **event
)
187 EFI_ENTRY("%d, 0x%lx, %p, %p", type
, notify_tpl
, notify_function
,
189 if (efi_event
.notify_function
) {
190 /* We only support one event at a time */
191 return EFI_EXIT(EFI_OUT_OF_RESOURCES
);
195 return EFI_EXIT(EFI_INVALID_PARAMETER
);
197 if ((type
& EVT_NOTIFY_SIGNAL
) && (type
& EVT_NOTIFY_WAIT
))
198 return EFI_EXIT(EFI_INVALID_PARAMETER
);
200 if ((type
& (EVT_NOTIFY_SIGNAL
|EVT_NOTIFY_WAIT
)) &&
201 notify_function
== NULL
)
202 return EFI_EXIT(EFI_INVALID_PARAMETER
);
204 efi_event
.type
= type
;
205 efi_event
.notify_tpl
= notify_tpl
;
206 efi_event
.notify_function
= notify_function
;
207 efi_event
.notify_context
= notify_context
;
210 return EFI_EXIT(EFI_SUCCESS
);
214 * Our timers have to work without interrupts, so we check whenever keyboard
215 * input or disk accesses happen if enough time elapsed for it to fire.
217 void efi_timer_check(void)
219 u64 now
= timer_get_us();
221 if (now
>= efi_event
.trigger_next
) {
223 if (efi_event
.trigger_type
== EFI_TIMER_PERIODIC
)
224 efi_event
.trigger_next
+= efi_event
.trigger_time
/ 10;
225 if (efi_event
.type
& (EVT_NOTIFY_WAIT
| EVT_NOTIFY_SIGNAL
))
226 efi_event
.notify_function(&efi_event
,
227 efi_event
.notify_context
);
233 static efi_status_t EFIAPI
efi_set_timer(void *event
, int type
,
234 uint64_t trigger_time
)
236 /* We don't have 64bit division available everywhere, so limit timer
237 * distances to 32bit bits. */
238 u32 trigger32
= trigger_time
;
240 EFI_ENTRY("%p, %d, %"PRIx64
, event
, type
, trigger_time
);
242 if (trigger32
< trigger_time
) {
243 printf("WARNING: Truncating timer from %"PRIx64
" to %x\n",
244 trigger_time
, trigger32
);
247 if (event
!= &efi_event
) {
248 /* We only support one event at a time */
249 return EFI_EXIT(EFI_INVALID_PARAMETER
);
254 efi_event
.trigger_next
= -1ULL;
256 case EFI_TIMER_PERIODIC
:
257 case EFI_TIMER_RELATIVE
:
258 efi_event
.trigger_next
= timer_get_us() + (trigger32
/ 10);
261 return EFI_EXIT(EFI_INVALID_PARAMETER
);
263 efi_event
.trigger_type
= type
;
264 efi_event
.trigger_time
= trigger_time
;
266 return EFI_EXIT(EFI_SUCCESS
);
269 static efi_status_t EFIAPI
efi_wait_for_event(unsigned long num_events
,
270 void *event
, unsigned long *index
)
274 EFI_ENTRY("%ld, %p, %p", num_events
, event
, index
);
276 now
= timer_get_us();
277 while (now
< efi_event
.trigger_next
) { }
280 return EFI_EXIT(EFI_SUCCESS
);
283 static efi_status_t EFIAPI
efi_signal_event(void *event
)
285 EFI_ENTRY("%p", event
);
286 return EFI_EXIT(EFI_SUCCESS
);
289 static efi_status_t EFIAPI
efi_close_event(void *event
)
291 EFI_ENTRY("%p", event
);
292 efi_event
.trigger_next
= -1ULL;
293 return EFI_EXIT(EFI_SUCCESS
);
296 static efi_status_t EFIAPI
efi_check_event(void *event
)
298 EFI_ENTRY("%p", event
);
299 return EFI_EXIT(EFI_NOT_READY
);
302 static efi_status_t EFIAPI
efi_install_protocol_interface(void **handle
,
303 efi_guid_t
*protocol
, int protocol_interface_type
,
304 void *protocol_interface
)
306 struct list_head
*lhandle
;
310 EFI_ENTRY("%p, %p, %d, %p", handle
, protocol
, protocol_interface_type
,
313 if (!handle
|| !protocol
||
314 protocol_interface_type
!= EFI_NATIVE_INTERFACE
) {
315 r
= EFI_INVALID_PARAMETER
;
319 /* Create new handle if requested. */
321 r
= EFI_OUT_OF_RESOURCES
;
325 list_for_each(lhandle
, &efi_obj_list
) {
326 struct efi_object
*efiobj
;
327 efiobj
= list_entry(lhandle
, struct efi_object
, link
);
329 if (efiobj
->handle
!= *handle
)
331 /* Check if protocol is already installed on the handle. */
332 for (i
= 0; i
< ARRAY_SIZE(efiobj
->protocols
); i
++) {
333 struct efi_handler
*handler
= &efiobj
->protocols
[i
];
337 if (!guidcmp(handler
->guid
, protocol
)) {
338 r
= EFI_INVALID_PARAMETER
;
342 /* Install protocol in first empty slot. */
343 for (i
= 0; i
< ARRAY_SIZE(efiobj
->protocols
); i
++) {
344 struct efi_handler
*handler
= &efiobj
->protocols
[i
];
349 handler
->guid
= protocol
;
350 handler
->protocol_interface
= protocol_interface
;
354 r
= EFI_OUT_OF_RESOURCES
;
357 r
= EFI_INVALID_PARAMETER
;
362 static efi_status_t EFIAPI
efi_reinstall_protocol_interface(void *handle
,
363 efi_guid_t
*protocol
, void *old_interface
,
366 EFI_ENTRY("%p, %p, %p, %p", handle
, protocol
, old_interface
,
368 return EFI_EXIT(EFI_ACCESS_DENIED
);
371 static efi_status_t EFIAPI
efi_uninstall_protocol_interface(void *handle
,
372 efi_guid_t
*protocol
, void *protocol_interface
)
374 struct list_head
*lhandle
;
376 efi_status_t r
= EFI_NOT_FOUND
;
378 EFI_ENTRY("%p, %p, %p", handle
, protocol
, protocol_interface
);
380 if (!handle
|| !protocol
) {
381 r
= EFI_INVALID_PARAMETER
;
385 list_for_each(lhandle
, &efi_obj_list
) {
386 struct efi_object
*efiobj
;
387 efiobj
= list_entry(lhandle
, struct efi_object
, link
);
389 if (efiobj
->handle
!= handle
)
392 for (i
= 0; i
< ARRAY_SIZE(efiobj
->protocols
); i
++) {
393 struct efi_handler
*handler
= &efiobj
->protocols
[i
];
394 const efi_guid_t
*hprotocol
= handler
->guid
;
398 if (!guidcmp(hprotocol
, protocol
)) {
399 if (handler
->protocol_interface
) {
400 r
= EFI_ACCESS_DENIED
;
414 static efi_status_t EFIAPI
efi_register_protocol_notify(efi_guid_t
*protocol
,
418 EFI_ENTRY("%p, %p, %p", protocol
, event
, registration
);
419 return EFI_EXIT(EFI_OUT_OF_RESOURCES
);
422 static int efi_search(enum efi_locate_search_type search_type
,
423 efi_guid_t
*protocol
, void *search_key
,
424 struct efi_object
*efiobj
)
428 switch (search_type
) {
431 case by_register_notify
:
434 for (i
= 0; i
< ARRAY_SIZE(efiobj
->protocols
); i
++) {
435 const efi_guid_t
*guid
= efiobj
->protocols
[i
].guid
;
436 if (guid
&& !guidcmp(guid
, protocol
))
445 static efi_status_t EFIAPI
efi_locate_handle(
446 enum efi_locate_search_type search_type
,
447 efi_guid_t
*protocol
, void *search_key
,
448 unsigned long *buffer_size
, efi_handle_t
*buffer
)
450 struct list_head
*lhandle
;
451 unsigned long size
= 0;
453 EFI_ENTRY("%d, %p, %p, %p, %p", search_type
, protocol
, search_key
,
454 buffer_size
, buffer
);
456 /* Count how much space we need */
457 list_for_each(lhandle
, &efi_obj_list
) {
458 struct efi_object
*efiobj
;
459 efiobj
= list_entry(lhandle
, struct efi_object
, link
);
460 if (!efi_search(search_type
, protocol
, search_key
, efiobj
)) {
461 size
+= sizeof(void*);
465 if (*buffer_size
< size
) {
467 return EFI_EXIT(EFI_BUFFER_TOO_SMALL
);
470 /* Then fill the array */
471 list_for_each(lhandle
, &efi_obj_list
) {
472 struct efi_object
*efiobj
;
473 efiobj
= list_entry(lhandle
, struct efi_object
, link
);
474 if (!efi_search(search_type
, protocol
, search_key
, efiobj
)) {
475 *(buffer
++) = efiobj
->handle
;
480 return EFI_EXIT(EFI_SUCCESS
);
483 static efi_status_t EFIAPI
efi_locate_device_path(efi_guid_t
*protocol
,
484 struct efi_device_path
**device_path
,
485 efi_handle_t
*device
)
487 EFI_ENTRY("%p, %p, %p", protocol
, device_path
, device
);
488 return EFI_EXIT(EFI_NOT_FOUND
);
491 efi_status_t
efi_install_configuration_table(const efi_guid_t
*guid
, void *table
)
495 /* Check for guid override */
496 for (i
= 0; i
< systab
.nr_tables
; i
++) {
497 if (!guidcmp(guid
, &efi_conf_table
[i
].guid
)) {
498 efi_conf_table
[i
].table
= table
;
503 /* No override, check for overflow */
504 if (i
>= ARRAY_SIZE(efi_conf_table
))
505 return EFI_OUT_OF_RESOURCES
;
507 /* Add a new entry */
508 memcpy(&efi_conf_table
[i
].guid
, guid
, sizeof(*guid
));
509 efi_conf_table
[i
].table
= table
;
510 systab
.nr_tables
= i
+ 1;
515 static efi_status_t EFIAPI
efi_install_configuration_table_ext(efi_guid_t
*guid
,
518 EFI_ENTRY("%p, %p", guid
, table
);
519 return EFI_EXIT(efi_install_configuration_table(guid
, table
));
522 static efi_status_t EFIAPI
efi_load_image(bool boot_policy
,
523 efi_handle_t parent_image
,
524 struct efi_device_path
*file_path
,
526 unsigned long source_size
,
527 efi_handle_t
*image_handle
)
529 static struct efi_object loaded_image_info_obj
= {
532 .guid
= &efi_guid_loaded_image
,
536 struct efi_loaded_image
*info
;
537 struct efi_object
*obj
;
539 EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy
, parent_image
,
540 file_path
, source_buffer
, source_size
, image_handle
);
541 info
= malloc(sizeof(*info
));
542 loaded_image_info_obj
.protocols
[0].protocol_interface
= info
;
543 obj
= malloc(sizeof(loaded_image_info_obj
));
544 memset(info
, 0, sizeof(*info
));
545 memcpy(obj
, &loaded_image_info_obj
, sizeof(loaded_image_info_obj
));
547 info
->file_path
= file_path
;
548 info
->reserved
= efi_load_pe(source_buffer
, info
);
549 if (!info
->reserved
) {
552 return EFI_EXIT(EFI_UNSUPPORTED
);
555 *image_handle
= info
;
556 list_add_tail(&obj
->link
, &efi_obj_list
);
558 return EFI_EXIT(EFI_SUCCESS
);
561 static efi_status_t EFIAPI
efi_start_image(efi_handle_t image_handle
,
562 unsigned long *exit_data_size
,
565 ulong (*entry
)(void *image_handle
, struct efi_system_table
*st
);
566 struct efi_loaded_image
*info
= image_handle
;
568 EFI_ENTRY("%p, %p, %p", image_handle
, exit_data_size
, exit_data
);
569 entry
= info
->reserved
;
571 efi_is_direct_boot
= false;
573 /* call the image! */
574 if (setjmp(&info
->exit_jmp
)) {
575 /* We returned from the child image */
576 return EFI_EXIT(info
->exit_status
);
579 entry(image_handle
, &systab
);
581 /* Should usually never get here */
582 return EFI_EXIT(EFI_SUCCESS
);
585 static efi_status_t EFIAPI
efi_exit(efi_handle_t image_handle
,
586 efi_status_t exit_status
, unsigned long exit_data_size
,
589 struct efi_loaded_image
*loaded_image_info
= (void*)image_handle
;
591 EFI_ENTRY("%p, %ld, %ld, %p", image_handle
, exit_status
,
592 exit_data_size
, exit_data
);
594 loaded_image_info
->exit_status
= exit_status
;
595 longjmp(&loaded_image_info
->exit_jmp
, 1);
597 panic("EFI application exited");
600 static struct efi_object
*efi_search_obj(void *handle
)
602 struct list_head
*lhandle
;
604 list_for_each(lhandle
, &efi_obj_list
) {
605 struct efi_object
*efiobj
;
606 efiobj
= list_entry(lhandle
, struct efi_object
, link
);
607 if (efiobj
->handle
== handle
)
614 static efi_status_t EFIAPI
efi_unload_image(void *image_handle
)
616 struct efi_object
*efiobj
;
618 EFI_ENTRY("%p", image_handle
);
619 efiobj
= efi_search_obj(image_handle
);
621 list_del(&efiobj
->link
);
623 return EFI_EXIT(EFI_SUCCESS
);
626 static void efi_exit_caches(void)
628 #if defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
630 * Grub on 32bit ARM needs to have caches disabled before jumping into
631 * a zImage, but does not know of all cache layers. Give it a hand.
633 if (efi_is_direct_boot
)
634 cleanup_before_linux();
638 static efi_status_t EFIAPI
efi_exit_boot_services(void *image_handle
,
639 unsigned long map_key
)
641 EFI_ENTRY("%p, %ld", image_handle
, map_key
);
643 board_quiesce_devices();
645 /* Fix up caches for EFI payloads if necessary */
648 /* This stops all lingering devices */
649 bootm_disable_interrupts();
651 /* Give the payload some time to boot */
654 return EFI_EXIT(EFI_SUCCESS
);
657 static efi_status_t EFIAPI
efi_get_next_monotonic_count(uint64_t *count
)
659 static uint64_t mono
= 0;
660 EFI_ENTRY("%p", count
);
662 return EFI_EXIT(EFI_SUCCESS
);
665 static efi_status_t EFIAPI
efi_stall(unsigned long microseconds
)
667 EFI_ENTRY("%ld", microseconds
);
668 udelay(microseconds
);
669 return EFI_EXIT(EFI_SUCCESS
);
672 static efi_status_t EFIAPI
efi_set_watchdog_timer(unsigned long timeout
,
673 uint64_t watchdog_code
,
674 unsigned long data_size
,
675 uint16_t *watchdog_data
)
677 EFI_ENTRY("%ld, 0x%"PRIx64
", %ld, %p", timeout
, watchdog_code
,
678 data_size
, watchdog_data
);
679 return EFI_EXIT(efi_unsupported(__func__
));
682 static efi_status_t EFIAPI
efi_connect_controller(
683 efi_handle_t controller_handle
,
684 efi_handle_t
*driver_image_handle
,
685 struct efi_device_path
*remain_device_path
,
688 EFI_ENTRY("%p, %p, %p, %d", controller_handle
, driver_image_handle
,
689 remain_device_path
, recursive
);
690 return EFI_EXIT(EFI_NOT_FOUND
);
693 static efi_status_t EFIAPI
efi_disconnect_controller(void *controller_handle
,
694 void *driver_image_handle
,
697 EFI_ENTRY("%p, %p, %p", controller_handle
, driver_image_handle
,
699 return EFI_EXIT(EFI_INVALID_PARAMETER
);
702 static efi_status_t EFIAPI
efi_close_protocol(void *handle
,
703 efi_guid_t
*protocol
,
705 void *controller_handle
)
707 EFI_ENTRY("%p, %p, %p, %p", handle
, protocol
, agent_handle
,
709 return EFI_EXIT(EFI_NOT_FOUND
);
712 static efi_status_t EFIAPI
efi_open_protocol_information(efi_handle_t handle
,
713 efi_guid_t
*protocol
,
714 struct efi_open_protocol_info_entry
**entry_buffer
,
715 unsigned long *entry_count
)
717 EFI_ENTRY("%p, %p, %p, %p", handle
, protocol
, entry_buffer
,
719 return EFI_EXIT(EFI_NOT_FOUND
);
722 static efi_status_t EFIAPI
efi_protocols_per_handle(void *handle
,
723 efi_guid_t
***protocol_buffer
,
724 unsigned long *protocol_buffer_count
)
726 EFI_ENTRY("%p, %p, %p", handle
, protocol_buffer
,
727 protocol_buffer_count
);
728 return EFI_EXIT(EFI_OUT_OF_RESOURCES
);
731 static efi_status_t EFIAPI
efi_locate_handle_buffer(
732 enum efi_locate_search_type search_type
,
733 efi_guid_t
*protocol
, void *search_key
,
734 unsigned long *no_handles
, efi_handle_t
**buffer
)
736 EFI_ENTRY("%d, %p, %p, %p, %p", search_type
, protocol
, search_key
,
738 return EFI_EXIT(EFI_NOT_FOUND
);
741 static struct efi_class_map efi_class_maps
[] = {
743 .guid
= &efi_guid_console_control
,
744 .interface
= &efi_console_control
748 static efi_status_t EFIAPI
efi_locate_protocol(efi_guid_t
*protocol
,
750 void **protocol_interface
)
754 EFI_ENTRY("%p, %p, %p", protocol
, registration
, protocol_interface
);
755 for (i
= 0; i
< ARRAY_SIZE(efi_class_maps
); i
++) {
756 struct efi_class_map
*curmap
= &efi_class_maps
[i
];
757 if (!guidcmp(protocol
, curmap
->guid
)) {
758 *protocol_interface
= (void*)curmap
->interface
;
759 return EFI_EXIT(EFI_SUCCESS
);
763 return EFI_EXIT(EFI_NOT_FOUND
);
766 static efi_status_t EFIAPI
efi_install_multiple_protocol_interfaces(
769 EFI_ENTRY("%p", handle
);
770 return EFI_EXIT(EFI_OUT_OF_RESOURCES
);
773 static efi_status_t EFIAPI
efi_uninstall_multiple_protocol_interfaces(
776 EFI_ENTRY("%p", handle
);
777 return EFI_EXIT(EFI_INVALID_PARAMETER
);
780 static efi_status_t EFIAPI
efi_calculate_crc32(void *data
,
781 unsigned long data_size
,
784 EFI_ENTRY("%p, %ld", data
, data_size
);
785 *crc32_p
= crc32(0, data
, data_size
);
786 return EFI_EXIT(EFI_SUCCESS
);
789 static void EFIAPI
efi_copy_mem(void *destination
, void *source
,
790 unsigned long length
)
792 EFI_ENTRY("%p, %p, %ld", destination
, source
, length
);
793 memcpy(destination
, source
, length
);
796 static void EFIAPI
efi_set_mem(void *buffer
, unsigned long size
, uint8_t value
)
798 EFI_ENTRY("%p, %ld, 0x%x", buffer
, size
, value
);
799 memset(buffer
, value
, size
);
802 static efi_status_t EFIAPI
efi_open_protocol(
803 void *handle
, efi_guid_t
*protocol
,
804 void **protocol_interface
, void *agent_handle
,
805 void *controller_handle
, uint32_t attributes
)
807 struct list_head
*lhandle
;
809 efi_status_t r
= EFI_INVALID_PARAMETER
;
811 EFI_ENTRY("%p, %p, %p, %p, %p, 0x%x", handle
, protocol
,
812 protocol_interface
, agent_handle
, controller_handle
,
815 if (!handle
|| !protocol
||
816 (!protocol_interface
&& attributes
!=
817 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
)) {
821 switch (attributes
) {
822 case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
:
823 case EFI_OPEN_PROTOCOL_GET_PROTOCOL
:
824 case EFI_OPEN_PROTOCOL_TEST_PROTOCOL
:
826 case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
:
827 if (controller_handle
== handle
)
829 case EFI_OPEN_PROTOCOL_BY_DRIVER
:
830 case EFI_OPEN_PROTOCOL_BY_DRIVER
| EFI_OPEN_PROTOCOL_EXCLUSIVE
:
831 if (controller_handle
== NULL
)
833 case EFI_OPEN_PROTOCOL_EXCLUSIVE
:
834 if (agent_handle
== NULL
)
841 list_for_each(lhandle
, &efi_obj_list
) {
842 struct efi_object
*efiobj
;
843 efiobj
= list_entry(lhandle
, struct efi_object
, link
);
845 if (efiobj
->handle
!= handle
)
848 for (i
= 0; i
< ARRAY_SIZE(efiobj
->protocols
); i
++) {
849 struct efi_handler
*handler
= &efiobj
->protocols
[i
];
850 const efi_guid_t
*hprotocol
= handler
->guid
;
853 if (!guidcmp(hprotocol
, protocol
)) {
855 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
) {
856 *protocol_interface
=
857 handler
->protocol_interface
;
872 static efi_status_t EFIAPI
efi_handle_protocol(void *handle
,
873 efi_guid_t
*protocol
,
874 void **protocol_interface
)
876 return efi_open_protocol(handle
, protocol
, protocol_interface
, NULL
,
877 NULL
, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
);
880 static const struct efi_boot_services efi_boot_services
= {
882 .headersize
= sizeof(struct efi_table_hdr
),
884 .raise_tpl
= efi_raise_tpl
,
885 .restore_tpl
= efi_restore_tpl
,
886 .allocate_pages
= efi_allocate_pages_ext
,
887 .free_pages
= efi_free_pages_ext
,
888 .get_memory_map
= efi_get_memory_map_ext
,
889 .allocate_pool
= efi_allocate_pool_ext
,
890 .free_pool
= efi_free_pool_ext
,
891 .create_event
= efi_create_event
,
892 .set_timer
= efi_set_timer
,
893 .wait_for_event
= efi_wait_for_event
,
894 .signal_event
= efi_signal_event
,
895 .close_event
= efi_close_event
,
896 .check_event
= efi_check_event
,
897 .install_protocol_interface
= efi_install_protocol_interface
,
898 .reinstall_protocol_interface
= efi_reinstall_protocol_interface
,
899 .uninstall_protocol_interface
= efi_uninstall_protocol_interface
,
900 .handle_protocol
= efi_handle_protocol
,
902 .register_protocol_notify
= efi_register_protocol_notify
,
903 .locate_handle
= efi_locate_handle
,
904 .locate_device_path
= efi_locate_device_path
,
905 .install_configuration_table
= efi_install_configuration_table_ext
,
906 .load_image
= efi_load_image
,
907 .start_image
= efi_start_image
,
909 .unload_image
= efi_unload_image
,
910 .exit_boot_services
= efi_exit_boot_services
,
911 .get_next_monotonic_count
= efi_get_next_monotonic_count
,
913 .set_watchdog_timer
= efi_set_watchdog_timer
,
914 .connect_controller
= efi_connect_controller
,
915 .disconnect_controller
= efi_disconnect_controller
,
916 .open_protocol
= efi_open_protocol
,
917 .close_protocol
= efi_close_protocol
,
918 .open_protocol_information
= efi_open_protocol_information
,
919 .protocols_per_handle
= efi_protocols_per_handle
,
920 .locate_handle_buffer
= efi_locate_handle_buffer
,
921 .locate_protocol
= efi_locate_protocol
,
922 .install_multiple_protocol_interfaces
= efi_install_multiple_protocol_interfaces
,
923 .uninstall_multiple_protocol_interfaces
= efi_uninstall_multiple_protocol_interfaces
,
924 .calculate_crc32
= efi_calculate_crc32
,
925 .copy_mem
= efi_copy_mem
,
926 .set_mem
= efi_set_mem
,
930 static uint16_t __efi_runtime_data firmware_vendor
[] =
931 { 'D','a','s',' ','U','-','b','o','o','t',0 };
933 struct efi_system_table __efi_runtime_data systab
= {
935 .signature
= EFI_SYSTEM_TABLE_SIGNATURE
,
936 .revision
= 0x20005, /* 2.5 */
937 .headersize
= sizeof(struct efi_table_hdr
),
939 .fw_vendor
= (long)firmware_vendor
,
940 .con_in
= (void*)&efi_con_in
,
941 .con_out
= (void*)&efi_con_out
,
942 .std_err
= (void*)&efi_con_out
,
943 .runtime
= (void*)&efi_runtime_services
,
944 .boottime
= (void*)&efi_boot_services
,
946 .tables
= (void*)efi_conf_table
,