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
);
192 efi_event
.type
= type
;
193 efi_event
.notify_tpl
= notify_tpl
;
194 efi_event
.notify_function
= notify_function
;
195 efi_event
.notify_context
= notify_context
;
198 return EFI_EXIT(EFI_SUCCESS
);
202 * Our timers have to work without interrupts, so we check whenever keyboard
203 * input or disk accesses happen if enough time elapsed for it to fire.
205 void efi_timer_check(void)
207 u64 now
= timer_get_us();
209 if (now
>= efi_event
.trigger_next
) {
211 if (efi_event
.trigger_type
== EFI_TIMER_PERIODIC
)
212 efi_event
.trigger_next
+= efi_event
.trigger_time
/ 10;
213 efi_event
.notify_function(&efi_event
, efi_event
.notify_context
);
219 static efi_status_t EFIAPI
efi_set_timer(void *event
, int type
,
220 uint64_t trigger_time
)
222 /* We don't have 64bit division available everywhere, so limit timer
223 * distances to 32bit bits. */
224 u32 trigger32
= trigger_time
;
226 EFI_ENTRY("%p, %d, %"PRIx64
, event
, type
, trigger_time
);
228 if (trigger32
< trigger_time
) {
229 printf("WARNING: Truncating timer from %"PRIx64
" to %x\n",
230 trigger_time
, trigger32
);
233 if (event
!= &efi_event
) {
234 /* We only support one event at a time */
235 return EFI_EXIT(EFI_INVALID_PARAMETER
);
240 efi_event
.trigger_next
= -1ULL;
242 case EFI_TIMER_PERIODIC
:
243 case EFI_TIMER_RELATIVE
:
244 efi_event
.trigger_next
= timer_get_us() + (trigger32
/ 10);
247 return EFI_EXIT(EFI_INVALID_PARAMETER
);
249 efi_event
.trigger_type
= type
;
250 efi_event
.trigger_time
= trigger_time
;
252 return EFI_EXIT(EFI_SUCCESS
);
255 static efi_status_t EFIAPI
efi_wait_for_event(unsigned long num_events
,
256 void *event
, unsigned long *index
)
260 EFI_ENTRY("%ld, %p, %p", num_events
, event
, index
);
262 now
= timer_get_us();
263 while (now
< efi_event
.trigger_next
) { }
266 return EFI_EXIT(EFI_SUCCESS
);
269 static efi_status_t EFIAPI
efi_signal_event(void *event
)
271 EFI_ENTRY("%p", event
);
272 return EFI_EXIT(EFI_SUCCESS
);
275 static efi_status_t EFIAPI
efi_close_event(void *event
)
277 EFI_ENTRY("%p", event
);
278 efi_event
.trigger_next
= -1ULL;
279 return EFI_EXIT(EFI_SUCCESS
);
282 static efi_status_t EFIAPI
efi_check_event(void *event
)
284 EFI_ENTRY("%p", event
);
285 return EFI_EXIT(EFI_NOT_READY
);
288 static efi_status_t EFIAPI
efi_install_protocol_interface(void **handle
,
289 efi_guid_t
*protocol
, int protocol_interface_type
,
290 void *protocol_interface
)
292 EFI_ENTRY("%p, %p, %d, %p", handle
, protocol
, protocol_interface_type
,
294 return EFI_EXIT(EFI_OUT_OF_RESOURCES
);
296 static efi_status_t EFIAPI
efi_reinstall_protocol_interface(void *handle
,
297 efi_guid_t
*protocol
, void *old_interface
,
300 EFI_ENTRY("%p, %p, %p, %p", handle
, protocol
, old_interface
,
302 return EFI_EXIT(EFI_ACCESS_DENIED
);
305 static efi_status_t EFIAPI
efi_uninstall_protocol_interface(void *handle
,
306 efi_guid_t
*protocol
, void *protocol_interface
)
308 EFI_ENTRY("%p, %p, %p", handle
, protocol
, protocol_interface
);
309 return EFI_EXIT(EFI_NOT_FOUND
);
312 static efi_status_t EFIAPI
efi_register_protocol_notify(efi_guid_t
*protocol
,
316 EFI_ENTRY("%p, %p, %p", protocol
, event
, registration
);
317 return EFI_EXIT(EFI_OUT_OF_RESOURCES
);
320 static int efi_search(enum efi_locate_search_type search_type
,
321 efi_guid_t
*protocol
, void *search_key
,
322 struct efi_object
*efiobj
)
326 switch (search_type
) {
329 case by_register_notify
:
332 for (i
= 0; i
< ARRAY_SIZE(efiobj
->protocols
); i
++) {
333 const efi_guid_t
*guid
= efiobj
->protocols
[i
].guid
;
334 if (guid
&& !guidcmp(guid
, protocol
))
343 static efi_status_t EFIAPI
efi_locate_handle(
344 enum efi_locate_search_type search_type
,
345 efi_guid_t
*protocol
, void *search_key
,
346 unsigned long *buffer_size
, efi_handle_t
*buffer
)
348 struct list_head
*lhandle
;
349 unsigned long size
= 0;
351 EFI_ENTRY("%d, %p, %p, %p, %p", search_type
, protocol
, search_key
,
352 buffer_size
, buffer
);
354 /* Count how much space we need */
355 list_for_each(lhandle
, &efi_obj_list
) {
356 struct efi_object
*efiobj
;
357 efiobj
= list_entry(lhandle
, struct efi_object
, link
);
358 if (!efi_search(search_type
, protocol
, search_key
, efiobj
)) {
359 size
+= sizeof(void*);
363 if (*buffer_size
< size
) {
365 return EFI_EXIT(EFI_BUFFER_TOO_SMALL
);
368 /* Then fill the array */
369 list_for_each(lhandle
, &efi_obj_list
) {
370 struct efi_object
*efiobj
;
371 efiobj
= list_entry(lhandle
, struct efi_object
, link
);
372 if (!efi_search(search_type
, protocol
, search_key
, efiobj
)) {
373 *(buffer
++) = efiobj
->handle
;
378 return EFI_EXIT(EFI_SUCCESS
);
381 static efi_status_t EFIAPI
efi_locate_device_path(efi_guid_t
*protocol
,
382 struct efi_device_path
**device_path
,
383 efi_handle_t
*device
)
385 EFI_ENTRY("%p, %p, %p", protocol
, device_path
, device
);
386 return EFI_EXIT(EFI_NOT_FOUND
);
389 efi_status_t
efi_install_configuration_table(const efi_guid_t
*guid
, void *table
)
393 /* Check for guid override */
394 for (i
= 0; i
< systab
.nr_tables
; i
++) {
395 if (!guidcmp(guid
, &efi_conf_table
[i
].guid
)) {
396 efi_conf_table
[i
].table
= table
;
401 /* No override, check for overflow */
402 if (i
>= ARRAY_SIZE(efi_conf_table
))
403 return EFI_OUT_OF_RESOURCES
;
405 /* Add a new entry */
406 memcpy(&efi_conf_table
[i
].guid
, guid
, sizeof(*guid
));
407 efi_conf_table
[i
].table
= table
;
408 systab
.nr_tables
= i
+ 1;
413 static efi_status_t EFIAPI
efi_install_configuration_table_ext(efi_guid_t
*guid
,
416 EFI_ENTRY("%p, %p", guid
, table
);
417 return EFI_EXIT(efi_install_configuration_table(guid
, table
));
420 static efi_status_t EFIAPI
efi_load_image(bool boot_policy
,
421 efi_handle_t parent_image
,
422 struct efi_device_path
*file_path
,
424 unsigned long source_size
,
425 efi_handle_t
*image_handle
)
427 static struct efi_object loaded_image_info_obj
= {
430 .guid
= &efi_guid_loaded_image
,
431 .open
= &efi_return_handle
,
435 struct efi_loaded_image
*info
;
436 struct efi_object
*obj
;
438 EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy
, parent_image
,
439 file_path
, source_buffer
, source_size
, image_handle
);
440 info
= malloc(sizeof(*info
));
441 obj
= malloc(sizeof(loaded_image_info_obj
));
442 memset(info
, 0, sizeof(*info
));
443 memcpy(obj
, &loaded_image_info_obj
, sizeof(loaded_image_info_obj
));
445 info
->file_path
= file_path
;
446 info
->reserved
= efi_load_pe(source_buffer
, info
);
447 if (!info
->reserved
) {
450 return EFI_EXIT(EFI_UNSUPPORTED
);
453 *image_handle
= info
;
454 list_add_tail(&obj
->link
, &efi_obj_list
);
456 return EFI_EXIT(EFI_SUCCESS
);
459 static efi_status_t EFIAPI
efi_start_image(efi_handle_t image_handle
,
460 unsigned long *exit_data_size
,
463 ulong (*entry
)(void *image_handle
, struct efi_system_table
*st
);
464 struct efi_loaded_image
*info
= image_handle
;
466 EFI_ENTRY("%p, %p, %p", image_handle
, exit_data_size
, exit_data
);
467 entry
= info
->reserved
;
469 efi_is_direct_boot
= false;
471 /* call the image! */
472 if (setjmp(&info
->exit_jmp
)) {
473 /* We returned from the child image */
474 return EFI_EXIT(info
->exit_status
);
477 entry(image_handle
, &systab
);
479 /* Should usually never get here */
480 return EFI_EXIT(EFI_SUCCESS
);
483 static efi_status_t EFIAPI
efi_exit(efi_handle_t image_handle
,
484 efi_status_t exit_status
, unsigned long exit_data_size
,
487 struct efi_loaded_image
*loaded_image_info
= (void*)image_handle
;
489 EFI_ENTRY("%p, %ld, %ld, %p", image_handle
, exit_status
,
490 exit_data_size
, exit_data
);
492 loaded_image_info
->exit_status
= exit_status
;
493 longjmp(&loaded_image_info
->exit_jmp
, 1);
495 panic("EFI application exited");
498 static struct efi_object
*efi_search_obj(void *handle
)
500 struct list_head
*lhandle
;
502 list_for_each(lhandle
, &efi_obj_list
) {
503 struct efi_object
*efiobj
;
504 efiobj
= list_entry(lhandle
, struct efi_object
, link
);
505 if (efiobj
->handle
== handle
)
512 static efi_status_t EFIAPI
efi_unload_image(void *image_handle
)
514 struct efi_object
*efiobj
;
516 EFI_ENTRY("%p", image_handle
);
517 efiobj
= efi_search_obj(image_handle
);
519 list_del(&efiobj
->link
);
521 return EFI_EXIT(EFI_SUCCESS
);
524 static void efi_exit_caches(void)
526 #if defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
528 * Grub on 32bit ARM needs to have caches disabled before jumping into
529 * a zImage, but does not know of all cache layers. Give it a hand.
531 if (efi_is_direct_boot
)
532 cleanup_before_linux();
536 static efi_status_t EFIAPI
efi_exit_boot_services(void *image_handle
,
537 unsigned long map_key
)
539 EFI_ENTRY("%p, %ld", image_handle
, map_key
);
541 board_quiesce_devices();
543 /* Fix up caches for EFI payloads if necessary */
546 /* This stops all lingering devices */
547 bootm_disable_interrupts();
549 /* Give the payload some time to boot */
552 return EFI_EXIT(EFI_SUCCESS
);
555 static efi_status_t EFIAPI
efi_get_next_monotonic_count(uint64_t *count
)
557 static uint64_t mono
= 0;
558 EFI_ENTRY("%p", count
);
560 return EFI_EXIT(EFI_SUCCESS
);
563 static efi_status_t EFIAPI
efi_stall(unsigned long microseconds
)
565 EFI_ENTRY("%ld", microseconds
);
566 udelay(microseconds
);
567 return EFI_EXIT(EFI_SUCCESS
);
570 static efi_status_t EFIAPI
efi_set_watchdog_timer(unsigned long timeout
,
571 uint64_t watchdog_code
,
572 unsigned long data_size
,
573 uint16_t *watchdog_data
)
575 EFI_ENTRY("%ld, 0x%"PRIx64
", %ld, %p", timeout
, watchdog_code
,
576 data_size
, watchdog_data
);
577 return EFI_EXIT(efi_unsupported(__func__
));
580 static efi_status_t EFIAPI
efi_connect_controller(
581 efi_handle_t controller_handle
,
582 efi_handle_t
*driver_image_handle
,
583 struct efi_device_path
*remain_device_path
,
586 EFI_ENTRY("%p, %p, %p, %d", controller_handle
, driver_image_handle
,
587 remain_device_path
, recursive
);
588 return EFI_EXIT(EFI_NOT_FOUND
);
591 static efi_status_t EFIAPI
efi_disconnect_controller(void *controller_handle
,
592 void *driver_image_handle
,
595 EFI_ENTRY("%p, %p, %p", controller_handle
, driver_image_handle
,
597 return EFI_EXIT(EFI_INVALID_PARAMETER
);
600 static efi_status_t EFIAPI
efi_close_protocol(void *handle
,
601 efi_guid_t
*protocol
,
603 void *controller_handle
)
605 EFI_ENTRY("%p, %p, %p, %p", handle
, protocol
, agent_handle
,
607 return EFI_EXIT(EFI_NOT_FOUND
);
610 static efi_status_t EFIAPI
efi_open_protocol_information(efi_handle_t handle
,
611 efi_guid_t
*protocol
,
612 struct efi_open_protocol_info_entry
**entry_buffer
,
613 unsigned long *entry_count
)
615 EFI_ENTRY("%p, %p, %p, %p", handle
, protocol
, entry_buffer
,
617 return EFI_EXIT(EFI_NOT_FOUND
);
620 static efi_status_t EFIAPI
efi_protocols_per_handle(void *handle
,
621 efi_guid_t
***protocol_buffer
,
622 unsigned long *protocol_buffer_count
)
624 EFI_ENTRY("%p, %p, %p", handle
, protocol_buffer
,
625 protocol_buffer_count
);
626 return EFI_EXIT(EFI_OUT_OF_RESOURCES
);
629 static efi_status_t EFIAPI
efi_locate_handle_buffer(
630 enum efi_locate_search_type search_type
,
631 efi_guid_t
*protocol
, void *search_key
,
632 unsigned long *no_handles
, efi_handle_t
**buffer
)
634 EFI_ENTRY("%d, %p, %p, %p, %p", search_type
, protocol
, search_key
,
636 return EFI_EXIT(EFI_NOT_FOUND
);
639 static struct efi_class_map efi_class_maps
[] = {
641 .guid
= &efi_guid_console_control
,
642 .interface
= &efi_console_control
646 static efi_status_t EFIAPI
efi_locate_protocol(efi_guid_t
*protocol
,
648 void **protocol_interface
)
652 EFI_ENTRY("%p, %p, %p", protocol
, registration
, protocol_interface
);
653 for (i
= 0; i
< ARRAY_SIZE(efi_class_maps
); i
++) {
654 struct efi_class_map
*curmap
= &efi_class_maps
[i
];
655 if (!guidcmp(protocol
, curmap
->guid
)) {
656 *protocol_interface
= (void*)curmap
->interface
;
657 return EFI_EXIT(EFI_SUCCESS
);
661 return EFI_EXIT(EFI_NOT_FOUND
);
664 static efi_status_t EFIAPI
efi_install_multiple_protocol_interfaces(
667 EFI_ENTRY("%p", handle
);
668 return EFI_EXIT(EFI_OUT_OF_RESOURCES
);
671 static efi_status_t EFIAPI
efi_uninstall_multiple_protocol_interfaces(
674 EFI_ENTRY("%p", handle
);
675 return EFI_EXIT(EFI_INVALID_PARAMETER
);
678 static efi_status_t EFIAPI
efi_calculate_crc32(void *data
,
679 unsigned long data_size
,
682 EFI_ENTRY("%p, %ld", data
, data_size
);
683 *crc32_p
= crc32(0, data
, data_size
);
684 return EFI_EXIT(EFI_SUCCESS
);
687 static void EFIAPI
efi_copy_mem(void *destination
, void *source
,
688 unsigned long length
)
690 EFI_ENTRY("%p, %p, %ld", destination
, source
, length
);
691 memcpy(destination
, source
, length
);
694 static void EFIAPI
efi_set_mem(void *buffer
, unsigned long size
, uint8_t value
)
696 EFI_ENTRY("%p, %ld, 0x%x", buffer
, size
, value
);
697 memset(buffer
, value
, size
);
700 static efi_status_t EFIAPI
efi_open_protocol(
701 void *handle
, efi_guid_t
*protocol
,
702 void **protocol_interface
, void *agent_handle
,
703 void *controller_handle
, uint32_t attributes
)
705 struct list_head
*lhandle
;
707 efi_status_t r
= EFI_UNSUPPORTED
;
709 EFI_ENTRY("%p, %p, %p, %p, %p, 0x%x", handle
, protocol
,
710 protocol_interface
, agent_handle
, controller_handle
,
712 list_for_each(lhandle
, &efi_obj_list
) {
713 struct efi_object
*efiobj
;
714 efiobj
= list_entry(lhandle
, struct efi_object
, link
);
716 if (efiobj
->handle
!= handle
)
719 for (i
= 0; i
< ARRAY_SIZE(efiobj
->protocols
); i
++) {
720 struct efi_handler
*handler
= &efiobj
->protocols
[i
];
721 const efi_guid_t
*hprotocol
= handler
->guid
;
724 if (!guidcmp(hprotocol
, protocol
)) {
725 r
= handler
->open(handle
, protocol
,
726 protocol_interface
, agent_handle
,
727 controller_handle
, attributes
);
737 static efi_status_t EFIAPI
efi_handle_protocol(void *handle
,
738 efi_guid_t
*protocol
,
739 void **protocol_interface
)
741 return efi_open_protocol(handle
, protocol
, protocol_interface
,
745 static const struct efi_boot_services efi_boot_services
= {
747 .headersize
= sizeof(struct efi_table_hdr
),
749 .raise_tpl
= efi_raise_tpl
,
750 .restore_tpl
= efi_restore_tpl
,
751 .allocate_pages
= efi_allocate_pages_ext
,
752 .free_pages
= efi_free_pages_ext
,
753 .get_memory_map
= efi_get_memory_map_ext
,
754 .allocate_pool
= efi_allocate_pool_ext
,
755 .free_pool
= efi_free_pool_ext
,
756 .create_event
= efi_create_event
,
757 .set_timer
= efi_set_timer
,
758 .wait_for_event
= efi_wait_for_event
,
759 .signal_event
= efi_signal_event
,
760 .close_event
= efi_close_event
,
761 .check_event
= efi_check_event
,
762 .install_protocol_interface
= efi_install_protocol_interface
,
763 .reinstall_protocol_interface
= efi_reinstall_protocol_interface
,
764 .uninstall_protocol_interface
= efi_uninstall_protocol_interface
,
765 .handle_protocol
= efi_handle_protocol
,
767 .register_protocol_notify
= efi_register_protocol_notify
,
768 .locate_handle
= efi_locate_handle
,
769 .locate_device_path
= efi_locate_device_path
,
770 .install_configuration_table
= efi_install_configuration_table_ext
,
771 .load_image
= efi_load_image
,
772 .start_image
= efi_start_image
,
774 .unload_image
= efi_unload_image
,
775 .exit_boot_services
= efi_exit_boot_services
,
776 .get_next_monotonic_count
= efi_get_next_monotonic_count
,
778 .set_watchdog_timer
= efi_set_watchdog_timer
,
779 .connect_controller
= efi_connect_controller
,
780 .disconnect_controller
= efi_disconnect_controller
,
781 .open_protocol
= efi_open_protocol
,
782 .close_protocol
= efi_close_protocol
,
783 .open_protocol_information
= efi_open_protocol_information
,
784 .protocols_per_handle
= efi_protocols_per_handle
,
785 .locate_handle_buffer
= efi_locate_handle_buffer
,
786 .locate_protocol
= efi_locate_protocol
,
787 .install_multiple_protocol_interfaces
= efi_install_multiple_protocol_interfaces
,
788 .uninstall_multiple_protocol_interfaces
= efi_uninstall_multiple_protocol_interfaces
,
789 .calculate_crc32
= efi_calculate_crc32
,
790 .copy_mem
= efi_copy_mem
,
791 .set_mem
= efi_set_mem
,
795 static uint16_t __efi_runtime_data firmware_vendor
[] =
796 { 'D','a','s',' ','U','-','b','o','o','t',0 };
798 struct efi_system_table __efi_runtime_data systab
= {
800 .signature
= EFI_SYSTEM_TABLE_SIGNATURE
,
801 .revision
= 0x20005, /* 2.5 */
802 .headersize
= sizeof(struct efi_table_hdr
),
804 .fw_vendor
= (long)firmware_vendor
,
805 .con_in
= (void*)&efi_con_in
,
806 .con_out
= (void*)&efi_con_out
,
807 .std_err
= (void*)&efi_con_out
,
808 .runtime
= (void*)&efi_runtime_services
,
809 .boottime
= (void*)&efi_boot_services
,
811 .tables
= (void*)efi_conf_table
,