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 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 efi_status_t EFIAPI
efi_free_pages_ext(uint64_t memory
, unsigned long pages
)
122 EFI_ENTRY("%"PRIx64
", 0x%lx", memory
, pages
);
123 r
= efi_free_pages(memory
, pages
);
127 efi_status_t EFIAPI
efi_get_memory_map_ext(unsigned long *memory_map_size
,
128 struct efi_mem_desc
*memory_map
,
129 unsigned long *map_key
,
130 unsigned long *descriptor_size
,
131 uint32_t *descriptor_version
)
135 EFI_ENTRY("%p, %p, %p, %p, %p", memory_map_size
, memory_map
,
136 map_key
, descriptor_size
, descriptor_version
);
137 r
= efi_get_memory_map(memory_map_size
, memory_map
, map_key
,
138 descriptor_size
, descriptor_version
);
142 static efi_status_t EFIAPI
efi_allocate_pool_ext(int pool_type
,
148 EFI_ENTRY("%d, %ld, %p", pool_type
, size
, buffer
);
149 r
= efi_allocate_pool(pool_type
, size
, buffer
);
153 static efi_status_t EFIAPI
efi_free_pool_ext(void *buffer
)
157 EFI_ENTRY("%p", buffer
);
158 r
= efi_free_pool(buffer
);
163 * Our event capabilities are very limited. Only support a single
164 * event to exist, so we don't need to maintain lists.
167 enum efi_event_type type
;
171 unsigned long notify_tpl
;
172 void (EFIAPI
*notify_function
) (void *event
, void *context
);
173 void *notify_context
;
175 /* Disable timers on bootup */
176 .trigger_next
= -1ULL,
179 static efi_status_t EFIAPI
efi_create_event(
180 enum efi_event_type type
, ulong notify_tpl
,
181 void (EFIAPI
*notify_function
) (void *event
,
183 void *notify_context
, void **event
)
185 EFI_ENTRY("%d, 0x%lx, %p, %p", type
, notify_tpl
, notify_function
,
187 if (efi_event
.notify_function
) {
188 /* We only support one event at a time */
189 return EFI_EXIT(EFI_OUT_OF_RESOURCES
);
193 return EFI_EXIT(EFI_INVALID_PARAMETER
);
195 if ((type
& EVT_NOTIFY_SIGNAL
) && (type
& EVT_NOTIFY_WAIT
))
196 return EFI_EXIT(EFI_INVALID_PARAMETER
);
198 if ((type
& (EVT_NOTIFY_SIGNAL
|EVT_NOTIFY_WAIT
)) &&
199 notify_function
== NULL
)
200 return EFI_EXIT(EFI_INVALID_PARAMETER
);
202 efi_event
.type
= type
;
203 efi_event
.notify_tpl
= notify_tpl
;
204 efi_event
.notify_function
= notify_function
;
205 efi_event
.notify_context
= notify_context
;
208 return EFI_EXIT(EFI_SUCCESS
);
212 * Our timers have to work without interrupts, so we check whenever keyboard
213 * input or disk accesses happen if enough time elapsed for it to fire.
215 void efi_timer_check(void)
217 u64 now
= timer_get_us();
219 if (now
>= efi_event
.trigger_next
) {
221 if (efi_event
.trigger_type
== EFI_TIMER_PERIODIC
)
222 efi_event
.trigger_next
+= efi_event
.trigger_time
/ 10;
223 if (efi_event
.type
& (EVT_NOTIFY_WAIT
| EVT_NOTIFY_SIGNAL
))
224 efi_event
.notify_function(&efi_event
,
225 efi_event
.notify_context
);
231 static efi_status_t EFIAPI
efi_set_timer(void *event
, int type
,
232 uint64_t trigger_time
)
234 /* We don't have 64bit division available everywhere, so limit timer
235 * distances to 32bit bits. */
236 u32 trigger32
= trigger_time
;
238 EFI_ENTRY("%p, %d, %"PRIx64
, event
, type
, trigger_time
);
240 if (trigger32
< trigger_time
) {
241 printf("WARNING: Truncating timer from %"PRIx64
" to %x\n",
242 trigger_time
, trigger32
);
245 if (event
!= &efi_event
) {
246 /* We only support one event at a time */
247 return EFI_EXIT(EFI_INVALID_PARAMETER
);
252 efi_event
.trigger_next
= -1ULL;
254 case EFI_TIMER_PERIODIC
:
255 case EFI_TIMER_RELATIVE
:
256 efi_event
.trigger_next
= timer_get_us() + (trigger32
/ 10);
259 return EFI_EXIT(EFI_INVALID_PARAMETER
);
261 efi_event
.trigger_type
= type
;
262 efi_event
.trigger_time
= trigger_time
;
264 return EFI_EXIT(EFI_SUCCESS
);
267 static efi_status_t EFIAPI
efi_wait_for_event(unsigned long num_events
,
268 void *event
, unsigned long *index
)
272 EFI_ENTRY("%ld, %p, %p", num_events
, event
, index
);
274 now
= timer_get_us();
275 while (now
< efi_event
.trigger_next
) { }
278 return EFI_EXIT(EFI_SUCCESS
);
281 static efi_status_t EFIAPI
efi_signal_event(void *event
)
283 EFI_ENTRY("%p", event
);
284 return EFI_EXIT(EFI_SUCCESS
);
287 static efi_status_t EFIAPI
efi_close_event(void *event
)
289 EFI_ENTRY("%p", event
);
290 efi_event
.trigger_next
= -1ULL;
291 return EFI_EXIT(EFI_SUCCESS
);
294 static efi_status_t EFIAPI
efi_check_event(void *event
)
296 EFI_ENTRY("%p", event
);
297 return EFI_EXIT(EFI_NOT_READY
);
300 static efi_status_t EFIAPI
efi_install_protocol_interface(void **handle
,
301 efi_guid_t
*protocol
, int protocol_interface_type
,
302 void *protocol_interface
)
304 EFI_ENTRY("%p, %p, %d, %p", handle
, protocol
, protocol_interface_type
,
306 return EFI_EXIT(EFI_OUT_OF_RESOURCES
);
308 static efi_status_t EFIAPI
efi_reinstall_protocol_interface(void *handle
,
309 efi_guid_t
*protocol
, void *old_interface
,
312 EFI_ENTRY("%p, %p, %p, %p", handle
, protocol
, old_interface
,
314 return EFI_EXIT(EFI_ACCESS_DENIED
);
317 static efi_status_t EFIAPI
efi_uninstall_protocol_interface(void *handle
,
318 efi_guid_t
*protocol
, void *protocol_interface
)
320 EFI_ENTRY("%p, %p, %p", handle
, protocol
, protocol_interface
);
321 return EFI_EXIT(EFI_NOT_FOUND
);
324 static efi_status_t EFIAPI
efi_register_protocol_notify(efi_guid_t
*protocol
,
328 EFI_ENTRY("%p, %p, %p", protocol
, event
, registration
);
329 return EFI_EXIT(EFI_OUT_OF_RESOURCES
);
332 static int efi_search(enum efi_locate_search_type search_type
,
333 efi_guid_t
*protocol
, void *search_key
,
334 struct efi_object
*efiobj
)
338 switch (search_type
) {
341 case by_register_notify
:
344 for (i
= 0; i
< ARRAY_SIZE(efiobj
->protocols
); i
++) {
345 const efi_guid_t
*guid
= efiobj
->protocols
[i
].guid
;
346 if (guid
&& !guidcmp(guid
, protocol
))
355 static efi_status_t EFIAPI
efi_locate_handle(
356 enum efi_locate_search_type search_type
,
357 efi_guid_t
*protocol
, void *search_key
,
358 unsigned long *buffer_size
, efi_handle_t
*buffer
)
360 struct list_head
*lhandle
;
361 unsigned long size
= 0;
363 EFI_ENTRY("%d, %p, %p, %p, %p", search_type
, protocol
, search_key
,
364 buffer_size
, buffer
);
366 /* Count how much space we need */
367 list_for_each(lhandle
, &efi_obj_list
) {
368 struct efi_object
*efiobj
;
369 efiobj
= list_entry(lhandle
, struct efi_object
, link
);
370 if (!efi_search(search_type
, protocol
, search_key
, efiobj
)) {
371 size
+= sizeof(void*);
375 if (*buffer_size
< size
) {
377 return EFI_EXIT(EFI_BUFFER_TOO_SMALL
);
380 /* Then fill the array */
381 list_for_each(lhandle
, &efi_obj_list
) {
382 struct efi_object
*efiobj
;
383 efiobj
= list_entry(lhandle
, struct efi_object
, link
);
384 if (!efi_search(search_type
, protocol
, search_key
, efiobj
)) {
385 *(buffer
++) = efiobj
->handle
;
390 return EFI_EXIT(EFI_SUCCESS
);
393 static efi_status_t EFIAPI
efi_locate_device_path(efi_guid_t
*protocol
,
394 struct efi_device_path
**device_path
,
395 efi_handle_t
*device
)
397 EFI_ENTRY("%p, %p, %p", protocol
, device_path
, device
);
398 return EFI_EXIT(EFI_NOT_FOUND
);
401 efi_status_t
efi_install_configuration_table(const efi_guid_t
*guid
, void *table
)
405 /* Check for guid override */
406 for (i
= 0; i
< systab
.nr_tables
; i
++) {
407 if (!guidcmp(guid
, &efi_conf_table
[i
].guid
)) {
408 efi_conf_table
[i
].table
= table
;
413 /* No override, check for overflow */
414 if (i
>= ARRAY_SIZE(efi_conf_table
))
415 return EFI_OUT_OF_RESOURCES
;
417 /* Add a new entry */
418 memcpy(&efi_conf_table
[i
].guid
, guid
, sizeof(*guid
));
419 efi_conf_table
[i
].table
= table
;
420 systab
.nr_tables
= i
+ 1;
425 static efi_status_t EFIAPI
efi_install_configuration_table_ext(efi_guid_t
*guid
,
428 EFI_ENTRY("%p, %p", guid
, table
);
429 return EFI_EXIT(efi_install_configuration_table(guid
, table
));
432 static efi_status_t EFIAPI
efi_load_image(bool boot_policy
,
433 efi_handle_t parent_image
,
434 struct efi_device_path
*file_path
,
436 unsigned long source_size
,
437 efi_handle_t
*image_handle
)
439 static struct efi_object loaded_image_info_obj
= {
442 .guid
= &efi_guid_loaded_image
,
443 .open
= &efi_return_handle
,
447 struct efi_loaded_image
*info
;
448 struct efi_object
*obj
;
450 EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy
, parent_image
,
451 file_path
, source_buffer
, source_size
, image_handle
);
452 info
= malloc(sizeof(*info
));
453 obj
= malloc(sizeof(loaded_image_info_obj
));
454 memset(info
, 0, sizeof(*info
));
455 memcpy(obj
, &loaded_image_info_obj
, sizeof(loaded_image_info_obj
));
457 info
->file_path
= file_path
;
458 info
->reserved
= efi_load_pe(source_buffer
, info
);
459 if (!info
->reserved
) {
462 return EFI_EXIT(EFI_UNSUPPORTED
);
465 *image_handle
= info
;
466 list_add_tail(&obj
->link
, &efi_obj_list
);
468 return EFI_EXIT(EFI_SUCCESS
);
471 static efi_status_t EFIAPI
efi_start_image(efi_handle_t image_handle
,
472 unsigned long *exit_data_size
,
475 ulong (*entry
)(void *image_handle
, struct efi_system_table
*st
);
476 struct efi_loaded_image
*info
= image_handle
;
478 EFI_ENTRY("%p, %p, %p", image_handle
, exit_data_size
, exit_data
);
479 entry
= info
->reserved
;
481 efi_is_direct_boot
= false;
483 /* call the image! */
484 if (setjmp(&info
->exit_jmp
)) {
485 /* We returned from the child image */
486 return EFI_EXIT(info
->exit_status
);
489 entry(image_handle
, &systab
);
491 /* Should usually never get here */
492 return EFI_EXIT(EFI_SUCCESS
);
495 static efi_status_t EFIAPI
efi_exit(efi_handle_t image_handle
,
496 efi_status_t exit_status
, unsigned long exit_data_size
,
499 struct efi_loaded_image
*loaded_image_info
= (void*)image_handle
;
501 EFI_ENTRY("%p, %ld, %ld, %p", image_handle
, exit_status
,
502 exit_data_size
, exit_data
);
504 loaded_image_info
->exit_status
= exit_status
;
505 longjmp(&loaded_image_info
->exit_jmp
, 1);
507 panic("EFI application exited");
510 static struct efi_object
*efi_search_obj(void *handle
)
512 struct list_head
*lhandle
;
514 list_for_each(lhandle
, &efi_obj_list
) {
515 struct efi_object
*efiobj
;
516 efiobj
= list_entry(lhandle
, struct efi_object
, link
);
517 if (efiobj
->handle
== handle
)
524 static efi_status_t EFIAPI
efi_unload_image(void *image_handle
)
526 struct efi_object
*efiobj
;
528 EFI_ENTRY("%p", image_handle
);
529 efiobj
= efi_search_obj(image_handle
);
531 list_del(&efiobj
->link
);
533 return EFI_EXIT(EFI_SUCCESS
);
536 static void efi_exit_caches(void)
538 #if defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
540 * Grub on 32bit ARM needs to have caches disabled before jumping into
541 * a zImage, but does not know of all cache layers. Give it a hand.
543 if (efi_is_direct_boot
)
544 cleanup_before_linux();
548 static efi_status_t EFIAPI
efi_exit_boot_services(void *image_handle
,
549 unsigned long map_key
)
551 EFI_ENTRY("%p, %ld", image_handle
, map_key
);
553 board_quiesce_devices();
555 /* Fix up caches for EFI payloads if necessary */
558 /* This stops all lingering devices */
559 bootm_disable_interrupts();
561 /* Give the payload some time to boot */
564 return EFI_EXIT(EFI_SUCCESS
);
567 static efi_status_t EFIAPI
efi_get_next_monotonic_count(uint64_t *count
)
569 static uint64_t mono
= 0;
570 EFI_ENTRY("%p", count
);
572 return EFI_EXIT(EFI_SUCCESS
);
575 static efi_status_t EFIAPI
efi_stall(unsigned long microseconds
)
577 EFI_ENTRY("%ld", microseconds
);
578 udelay(microseconds
);
579 return EFI_EXIT(EFI_SUCCESS
);
582 static efi_status_t EFIAPI
efi_set_watchdog_timer(unsigned long timeout
,
583 uint64_t watchdog_code
,
584 unsigned long data_size
,
585 uint16_t *watchdog_data
)
587 EFI_ENTRY("%ld, 0x%"PRIx64
", %ld, %p", timeout
, watchdog_code
,
588 data_size
, watchdog_data
);
589 return EFI_EXIT(efi_unsupported(__func__
));
592 static efi_status_t EFIAPI
efi_connect_controller(
593 efi_handle_t controller_handle
,
594 efi_handle_t
*driver_image_handle
,
595 struct efi_device_path
*remain_device_path
,
598 EFI_ENTRY("%p, %p, %p, %d", controller_handle
, driver_image_handle
,
599 remain_device_path
, recursive
);
600 return EFI_EXIT(EFI_NOT_FOUND
);
603 static efi_status_t EFIAPI
efi_disconnect_controller(void *controller_handle
,
604 void *driver_image_handle
,
607 EFI_ENTRY("%p, %p, %p", controller_handle
, driver_image_handle
,
609 return EFI_EXIT(EFI_INVALID_PARAMETER
);
612 static efi_status_t EFIAPI
efi_close_protocol(void *handle
,
613 efi_guid_t
*protocol
,
615 void *controller_handle
)
617 EFI_ENTRY("%p, %p, %p, %p", handle
, protocol
, agent_handle
,
619 return EFI_EXIT(EFI_NOT_FOUND
);
622 static efi_status_t EFIAPI
efi_open_protocol_information(efi_handle_t handle
,
623 efi_guid_t
*protocol
,
624 struct efi_open_protocol_info_entry
**entry_buffer
,
625 unsigned long *entry_count
)
627 EFI_ENTRY("%p, %p, %p, %p", handle
, protocol
, entry_buffer
,
629 return EFI_EXIT(EFI_NOT_FOUND
);
632 static efi_status_t EFIAPI
efi_protocols_per_handle(void *handle
,
633 efi_guid_t
***protocol_buffer
,
634 unsigned long *protocol_buffer_count
)
636 EFI_ENTRY("%p, %p, %p", handle
, protocol_buffer
,
637 protocol_buffer_count
);
638 return EFI_EXIT(EFI_OUT_OF_RESOURCES
);
641 static efi_status_t EFIAPI
efi_locate_handle_buffer(
642 enum efi_locate_search_type search_type
,
643 efi_guid_t
*protocol
, void *search_key
,
644 unsigned long *no_handles
, efi_handle_t
**buffer
)
646 EFI_ENTRY("%d, %p, %p, %p, %p", search_type
, protocol
, search_key
,
648 return EFI_EXIT(EFI_NOT_FOUND
);
651 static struct efi_class_map efi_class_maps
[] = {
653 .guid
= &efi_guid_console_control
,
654 .interface
= &efi_console_control
658 static efi_status_t EFIAPI
efi_locate_protocol(efi_guid_t
*protocol
,
660 void **protocol_interface
)
664 EFI_ENTRY("%p, %p, %p", protocol
, registration
, protocol_interface
);
665 for (i
= 0; i
< ARRAY_SIZE(efi_class_maps
); i
++) {
666 struct efi_class_map
*curmap
= &efi_class_maps
[i
];
667 if (!guidcmp(protocol
, curmap
->guid
)) {
668 *protocol_interface
= (void*)curmap
->interface
;
669 return EFI_EXIT(EFI_SUCCESS
);
673 return EFI_EXIT(EFI_NOT_FOUND
);
676 static efi_status_t EFIAPI
efi_install_multiple_protocol_interfaces(
679 EFI_ENTRY("%p", handle
);
680 return EFI_EXIT(EFI_OUT_OF_RESOURCES
);
683 static efi_status_t EFIAPI
efi_uninstall_multiple_protocol_interfaces(
686 EFI_ENTRY("%p", handle
);
687 return EFI_EXIT(EFI_INVALID_PARAMETER
);
690 static efi_status_t EFIAPI
efi_calculate_crc32(void *data
,
691 unsigned long data_size
,
694 EFI_ENTRY("%p, %ld", data
, data_size
);
695 *crc32_p
= crc32(0, data
, data_size
);
696 return EFI_EXIT(EFI_SUCCESS
);
699 static void EFIAPI
efi_copy_mem(void *destination
, void *source
,
700 unsigned long length
)
702 EFI_ENTRY("%p, %p, %ld", destination
, source
, length
);
703 memcpy(destination
, source
, length
);
706 static void EFIAPI
efi_set_mem(void *buffer
, unsigned long size
, uint8_t value
)
708 EFI_ENTRY("%p, %ld, 0x%x", buffer
, size
, value
);
709 memset(buffer
, value
, size
);
712 static efi_status_t EFIAPI
efi_open_protocol(
713 void *handle
, efi_guid_t
*protocol
,
714 void **protocol_interface
, void *agent_handle
,
715 void *controller_handle
, uint32_t attributes
)
717 struct list_head
*lhandle
;
719 efi_status_t r
= EFI_UNSUPPORTED
;
721 EFI_ENTRY("%p, %p, %p, %p, %p, 0x%x", handle
, protocol
,
722 protocol_interface
, agent_handle
, controller_handle
,
724 list_for_each(lhandle
, &efi_obj_list
) {
725 struct efi_object
*efiobj
;
726 efiobj
= list_entry(lhandle
, struct efi_object
, link
);
728 if (efiobj
->handle
!= handle
)
731 for (i
= 0; i
< ARRAY_SIZE(efiobj
->protocols
); i
++) {
732 struct efi_handler
*handler
= &efiobj
->protocols
[i
];
733 const efi_guid_t
*hprotocol
= handler
->guid
;
736 if (!guidcmp(hprotocol
, protocol
)) {
737 r
= handler
->open(handle
, protocol
,
738 protocol_interface
, agent_handle
,
739 controller_handle
, attributes
);
749 static efi_status_t EFIAPI
efi_handle_protocol(void *handle
,
750 efi_guid_t
*protocol
,
751 void **protocol_interface
)
753 return efi_open_protocol(handle
, protocol
, protocol_interface
,
757 static const struct efi_boot_services efi_boot_services
= {
759 .headersize
= sizeof(struct efi_table_hdr
),
761 .raise_tpl
= efi_raise_tpl
,
762 .restore_tpl
= efi_restore_tpl
,
763 .allocate_pages
= efi_allocate_pages_ext
,
764 .free_pages
= efi_free_pages_ext
,
765 .get_memory_map
= efi_get_memory_map_ext
,
766 .allocate_pool
= efi_allocate_pool_ext
,
767 .free_pool
= efi_free_pool_ext
,
768 .create_event
= efi_create_event
,
769 .set_timer
= efi_set_timer
,
770 .wait_for_event
= efi_wait_for_event
,
771 .signal_event
= efi_signal_event
,
772 .close_event
= efi_close_event
,
773 .check_event
= efi_check_event
,
774 .install_protocol_interface
= efi_install_protocol_interface
,
775 .reinstall_protocol_interface
= efi_reinstall_protocol_interface
,
776 .uninstall_protocol_interface
= efi_uninstall_protocol_interface
,
777 .handle_protocol
= efi_handle_protocol
,
779 .register_protocol_notify
= efi_register_protocol_notify
,
780 .locate_handle
= efi_locate_handle
,
781 .locate_device_path
= efi_locate_device_path
,
782 .install_configuration_table
= efi_install_configuration_table_ext
,
783 .load_image
= efi_load_image
,
784 .start_image
= efi_start_image
,
786 .unload_image
= efi_unload_image
,
787 .exit_boot_services
= efi_exit_boot_services
,
788 .get_next_monotonic_count
= efi_get_next_monotonic_count
,
790 .set_watchdog_timer
= efi_set_watchdog_timer
,
791 .connect_controller
= efi_connect_controller
,
792 .disconnect_controller
= efi_disconnect_controller
,
793 .open_protocol
= efi_open_protocol
,
794 .close_protocol
= efi_close_protocol
,
795 .open_protocol_information
= efi_open_protocol_information
,
796 .protocols_per_handle
= efi_protocols_per_handle
,
797 .locate_handle_buffer
= efi_locate_handle_buffer
,
798 .locate_protocol
= efi_locate_protocol
,
799 .install_multiple_protocol_interfaces
= efi_install_multiple_protocol_interfaces
,
800 .uninstall_multiple_protocol_interfaces
= efi_uninstall_multiple_protocol_interfaces
,
801 .calculate_crc32
= efi_calculate_crc32
,
802 .copy_mem
= efi_copy_mem
,
803 .set_mem
= efi_set_mem
,
807 static uint16_t __efi_runtime_data firmware_vendor
[] =
808 { 'D','a','s',' ','U','-','b','o','o','t',0 };
810 struct efi_system_table __efi_runtime_data systab
= {
812 .signature
= EFI_SYSTEM_TABLE_SIGNATURE
,
813 .revision
= 0x20005, /* 2.5 */
814 .headersize
= sizeof(struct efi_table_hdr
),
816 .fw_vendor
= (long)firmware_vendor
,
817 .con_in
= (void*)&efi_con_in
,
818 .con_out
= (void*)&efi_con_out
,
819 .std_err
= (void*)&efi_con_out
,
820 .runtime
= (void*)&efi_runtime_services
,
821 .boottime
= (void*)&efi_boot_services
,
823 .tables
= (void*)efi_conf_table
,