1*bee91169SAlexander Graf /* 2*bee91169SAlexander Graf * EFI application boot time services 3*bee91169SAlexander Graf * 4*bee91169SAlexander Graf * Copyright (c) 2016 Alexander Graf 5*bee91169SAlexander Graf * 6*bee91169SAlexander Graf * SPDX-License-Identifier: GPL-2.0+ 7*bee91169SAlexander Graf */ 8*bee91169SAlexander Graf 9*bee91169SAlexander Graf /* #define DEBUG_EFI */ 10*bee91169SAlexander Graf 11*bee91169SAlexander Graf #include <common.h> 12*bee91169SAlexander Graf #include <efi_loader.h> 13*bee91169SAlexander Graf #include <malloc.h> 14*bee91169SAlexander Graf #include <asm/global_data.h> 15*bee91169SAlexander Graf #include <libfdt_env.h> 16*bee91169SAlexander Graf #include <u-boot/crc.h> 17*bee91169SAlexander Graf #include <bootm.h> 18*bee91169SAlexander Graf #include <inttypes.h> 19*bee91169SAlexander Graf #include <watchdog.h> 20*bee91169SAlexander Graf 21*bee91169SAlexander Graf DECLARE_GLOBAL_DATA_PTR; 22*bee91169SAlexander Graf 23*bee91169SAlexander Graf /* This list contains all the EFI objects our payload has access to */ 24*bee91169SAlexander Graf LIST_HEAD(efi_obj_list); 25*bee91169SAlexander Graf 26*bee91169SAlexander Graf /* 27*bee91169SAlexander Graf * If we're running on nasty systems (32bit ARM booting into non-EFI Linux) 28*bee91169SAlexander Graf * we need to do trickery with caches. Since we don't want to break the EFI 29*bee91169SAlexander Graf * aware boot path, only apply hacks when loading exiting directly (breaking 30*bee91169SAlexander Graf * direct Linux EFI booting along the way - oh well). 31*bee91169SAlexander Graf */ 32*bee91169SAlexander Graf static bool efi_is_direct_boot = true; 33*bee91169SAlexander Graf 34*bee91169SAlexander Graf /* 35*bee91169SAlexander Graf * EFI can pass arbitrary additional "tables" containing vendor specific 36*bee91169SAlexander Graf * information to the payload. One such table is the FDT table which contains 37*bee91169SAlexander Graf * a pointer to a flattened device tree blob. 38*bee91169SAlexander Graf * 39*bee91169SAlexander Graf * In most cases we want to pass an FDT to the payload, so reserve one slot of 40*bee91169SAlexander Graf * config table space for it. The pointer gets populated by do_bootefi_exec(). 41*bee91169SAlexander Graf */ 42*bee91169SAlexander Graf static struct efi_configuration_table efi_conf_table[1]; 43*bee91169SAlexander Graf 44*bee91169SAlexander Graf /* 45*bee91169SAlexander Graf * The "gd" pointer lives in a register on ARM and AArch64 that we declare 46*bee91169SAlexander Graf * fixed when compiling U-Boot. However, the payload does not know about that 47*bee91169SAlexander Graf * restriction so we need to manually swap its and our view of that register on 48*bee91169SAlexander Graf * EFI callback entry/exit. 49*bee91169SAlexander Graf */ 50*bee91169SAlexander Graf static volatile void *efi_gd, *app_gd; 51*bee91169SAlexander Graf 52*bee91169SAlexander Graf /* Called from do_bootefi_exec() */ 53*bee91169SAlexander Graf void efi_save_gd(void) 54*bee91169SAlexander Graf { 55*bee91169SAlexander Graf efi_gd = gd; 56*bee91169SAlexander Graf } 57*bee91169SAlexander Graf 58*bee91169SAlexander Graf /* Called on every callback entry */ 59*bee91169SAlexander Graf void efi_restore_gd(void) 60*bee91169SAlexander Graf { 61*bee91169SAlexander Graf /* Only restore if we're already in EFI context */ 62*bee91169SAlexander Graf if (!efi_gd) 63*bee91169SAlexander Graf return; 64*bee91169SAlexander Graf 65*bee91169SAlexander Graf if (gd != efi_gd) 66*bee91169SAlexander Graf app_gd = gd; 67*bee91169SAlexander Graf gd = efi_gd; 68*bee91169SAlexander Graf } 69*bee91169SAlexander Graf 70*bee91169SAlexander Graf /* Called on every callback exit */ 71*bee91169SAlexander Graf efi_status_t efi_exit_func(efi_status_t ret) 72*bee91169SAlexander Graf { 73*bee91169SAlexander Graf gd = app_gd; 74*bee91169SAlexander Graf return ret; 75*bee91169SAlexander Graf } 76*bee91169SAlexander Graf 77*bee91169SAlexander Graf static efi_status_t efi_unsupported(const char *funcname) 78*bee91169SAlexander Graf { 79*bee91169SAlexander Graf #ifdef DEBUG_EFI 80*bee91169SAlexander Graf printf("EFI: App called into unimplemented function %s\n", funcname); 81*bee91169SAlexander Graf #endif 82*bee91169SAlexander Graf return EFI_EXIT(EFI_UNSUPPORTED); 83*bee91169SAlexander Graf } 84*bee91169SAlexander Graf 85*bee91169SAlexander Graf static int guidcmp(const efi_guid_t *g1, const efi_guid_t *g2) 86*bee91169SAlexander Graf { 87*bee91169SAlexander Graf return memcmp(g1, g2, sizeof(efi_guid_t)); 88*bee91169SAlexander Graf } 89*bee91169SAlexander Graf 90*bee91169SAlexander Graf static unsigned long EFIAPI efi_raise_tpl(unsigned long new_tpl) 91*bee91169SAlexander Graf { 92*bee91169SAlexander Graf EFI_ENTRY("0x%lx", new_tpl); 93*bee91169SAlexander Graf return EFI_EXIT(0); 94*bee91169SAlexander Graf } 95*bee91169SAlexander Graf 96*bee91169SAlexander Graf static void EFIAPI efi_restore_tpl(unsigned long old_tpl) 97*bee91169SAlexander Graf { 98*bee91169SAlexander Graf EFI_ENTRY("0x%lx", old_tpl); 99*bee91169SAlexander Graf EFI_EXIT(efi_unsupported(__func__)); 100*bee91169SAlexander Graf } 101*bee91169SAlexander Graf 102*bee91169SAlexander Graf efi_status_t EFIAPI efi_allocate_pages_ext(int type, int memory_type, 103*bee91169SAlexander Graf unsigned long pages, 104*bee91169SAlexander Graf uint64_t *memory) 105*bee91169SAlexander Graf { 106*bee91169SAlexander Graf efi_status_t r; 107*bee91169SAlexander Graf 108*bee91169SAlexander Graf EFI_ENTRY("%d, %d, 0x%lx, %p", type, memory_type, pages, memory); 109*bee91169SAlexander Graf r = efi_allocate_pages(type, memory_type, pages, memory); 110*bee91169SAlexander Graf return EFI_EXIT(r); 111*bee91169SAlexander Graf } 112*bee91169SAlexander Graf 113*bee91169SAlexander Graf efi_status_t EFIAPI efi_free_pages_ext(uint64_t memory, unsigned long pages) 114*bee91169SAlexander Graf { 115*bee91169SAlexander Graf efi_status_t r; 116*bee91169SAlexander Graf 117*bee91169SAlexander Graf EFI_ENTRY("%"PRIx64", 0x%lx", memory, pages); 118*bee91169SAlexander Graf r = efi_free_pages(memory, pages); 119*bee91169SAlexander Graf return EFI_EXIT(r); 120*bee91169SAlexander Graf } 121*bee91169SAlexander Graf 122*bee91169SAlexander Graf efi_status_t EFIAPI efi_get_memory_map_ext(unsigned long *memory_map_size, 123*bee91169SAlexander Graf struct efi_mem_desc *memory_map, 124*bee91169SAlexander Graf unsigned long *map_key, 125*bee91169SAlexander Graf unsigned long *descriptor_size, 126*bee91169SAlexander Graf uint32_t *descriptor_version) 127*bee91169SAlexander Graf { 128*bee91169SAlexander Graf efi_status_t r; 129*bee91169SAlexander Graf 130*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %p, %p, %p", memory_map_size, memory_map, 131*bee91169SAlexander Graf map_key, descriptor_size, descriptor_version); 132*bee91169SAlexander Graf r = efi_get_memory_map(memory_map_size, memory_map, map_key, 133*bee91169SAlexander Graf descriptor_size, descriptor_version); 134*bee91169SAlexander Graf return EFI_EXIT(r); 135*bee91169SAlexander Graf } 136*bee91169SAlexander Graf 137*bee91169SAlexander Graf static efi_status_t EFIAPI efi_allocate_pool(int pool_type, unsigned long size, 138*bee91169SAlexander Graf void **buffer) 139*bee91169SAlexander Graf { 140*bee91169SAlexander Graf return efi_allocate_pages(0, pool_type, (size + 0xfff) >> 12, (void*)buffer); 141*bee91169SAlexander Graf } 142*bee91169SAlexander Graf 143*bee91169SAlexander Graf static efi_status_t EFIAPI efi_free_pool(void *buffer) 144*bee91169SAlexander Graf { 145*bee91169SAlexander Graf return efi_free_pages((ulong)buffer, 0); 146*bee91169SAlexander Graf } 147*bee91169SAlexander Graf 148*bee91169SAlexander Graf /* 149*bee91169SAlexander Graf * Our event capabilities are very limited. Only support a single 150*bee91169SAlexander Graf * event to exist, so we don't need to maintain lists. 151*bee91169SAlexander Graf */ 152*bee91169SAlexander Graf static struct { 153*bee91169SAlexander Graf enum efi_event_type type; 154*bee91169SAlexander Graf u32 trigger_type; 155*bee91169SAlexander Graf u32 trigger_time; 156*bee91169SAlexander Graf u64 trigger_next; 157*bee91169SAlexander Graf unsigned long notify_tpl; 158*bee91169SAlexander Graf void (*notify_function) (void *event, void *context); 159*bee91169SAlexander Graf void *notify_context; 160*bee91169SAlexander Graf } efi_event = { 161*bee91169SAlexander Graf /* Disable timers on bootup */ 162*bee91169SAlexander Graf .trigger_next = -1ULL, 163*bee91169SAlexander Graf }; 164*bee91169SAlexander Graf 165*bee91169SAlexander Graf static efi_status_t EFIAPI efi_create_event( 166*bee91169SAlexander Graf enum efi_event_type type, ulong notify_tpl, 167*bee91169SAlexander Graf void (*notify_function) (void *event, void *context), 168*bee91169SAlexander Graf void *notify_context, void **event) 169*bee91169SAlexander Graf { 170*bee91169SAlexander Graf EFI_ENTRY("%d, 0x%lx, %p, %p", type, notify_tpl, notify_function, 171*bee91169SAlexander Graf notify_context); 172*bee91169SAlexander Graf if (efi_event.notify_function) { 173*bee91169SAlexander Graf /* We only support one event at a time */ 174*bee91169SAlexander Graf return EFI_EXIT(EFI_OUT_OF_RESOURCES); 175*bee91169SAlexander Graf } 176*bee91169SAlexander Graf 177*bee91169SAlexander Graf efi_event.type = type; 178*bee91169SAlexander Graf efi_event.notify_tpl = notify_tpl; 179*bee91169SAlexander Graf efi_event.notify_function = notify_function; 180*bee91169SAlexander Graf efi_event.notify_context = notify_context; 181*bee91169SAlexander Graf *event = &efi_event; 182*bee91169SAlexander Graf 183*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 184*bee91169SAlexander Graf } 185*bee91169SAlexander Graf 186*bee91169SAlexander Graf /* 187*bee91169SAlexander Graf * Our timers have to work without interrupts, so we check whenever keyboard 188*bee91169SAlexander Graf * input or disk accesses happen if enough time elapsed for it to fire. 189*bee91169SAlexander Graf */ 190*bee91169SAlexander Graf void efi_timer_check(void) 191*bee91169SAlexander Graf { 192*bee91169SAlexander Graf u64 now = timer_get_us(); 193*bee91169SAlexander Graf 194*bee91169SAlexander Graf if (now >= efi_event.trigger_next) { 195*bee91169SAlexander Graf /* Triggering! */ 196*bee91169SAlexander Graf if (efi_event.trigger_type == EFI_TIMER_PERIODIC) 197*bee91169SAlexander Graf efi_event.trigger_next += efi_event.trigger_time / 10; 198*bee91169SAlexander Graf efi_event.notify_function(&efi_event, efi_event.notify_context); 199*bee91169SAlexander Graf } 200*bee91169SAlexander Graf 201*bee91169SAlexander Graf WATCHDOG_RESET(); 202*bee91169SAlexander Graf } 203*bee91169SAlexander Graf 204*bee91169SAlexander Graf static efi_status_t EFIAPI efi_set_timer(void *event, int type, 205*bee91169SAlexander Graf uint64_t trigger_time) 206*bee91169SAlexander Graf { 207*bee91169SAlexander Graf /* We don't have 64bit division available everywhere, so limit timer 208*bee91169SAlexander Graf * distances to 32bit bits. */ 209*bee91169SAlexander Graf u32 trigger32 = trigger_time; 210*bee91169SAlexander Graf 211*bee91169SAlexander Graf EFI_ENTRY("%p, %d, %"PRIx64, event, type, trigger_time); 212*bee91169SAlexander Graf 213*bee91169SAlexander Graf if (trigger32 < trigger_time) { 214*bee91169SAlexander Graf printf("WARNING: Truncating timer from %"PRIx64" to %x\n", 215*bee91169SAlexander Graf trigger_time, trigger32); 216*bee91169SAlexander Graf } 217*bee91169SAlexander Graf 218*bee91169SAlexander Graf if (event != &efi_event) { 219*bee91169SAlexander Graf /* We only support one event at a time */ 220*bee91169SAlexander Graf return EFI_EXIT(EFI_INVALID_PARAMETER); 221*bee91169SAlexander Graf } 222*bee91169SAlexander Graf 223*bee91169SAlexander Graf switch (type) { 224*bee91169SAlexander Graf case EFI_TIMER_STOP: 225*bee91169SAlexander Graf efi_event.trigger_next = -1ULL; 226*bee91169SAlexander Graf break; 227*bee91169SAlexander Graf case EFI_TIMER_PERIODIC: 228*bee91169SAlexander Graf case EFI_TIMER_RELATIVE: 229*bee91169SAlexander Graf efi_event.trigger_next = timer_get_us() + (trigger32 / 10); 230*bee91169SAlexander Graf break; 231*bee91169SAlexander Graf default: 232*bee91169SAlexander Graf return EFI_EXIT(EFI_INVALID_PARAMETER); 233*bee91169SAlexander Graf } 234*bee91169SAlexander Graf efi_event.trigger_type = type; 235*bee91169SAlexander Graf efi_event.trigger_time = trigger_time; 236*bee91169SAlexander Graf 237*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 238*bee91169SAlexander Graf } 239*bee91169SAlexander Graf 240*bee91169SAlexander Graf static efi_status_t EFIAPI efi_wait_for_event(unsigned long num_events, 241*bee91169SAlexander Graf void *event, unsigned long *index) 242*bee91169SAlexander Graf { 243*bee91169SAlexander Graf u64 now; 244*bee91169SAlexander Graf 245*bee91169SAlexander Graf EFI_ENTRY("%ld, %p, %p", num_events, event, index); 246*bee91169SAlexander Graf 247*bee91169SAlexander Graf now = timer_get_us(); 248*bee91169SAlexander Graf while (now < efi_event.trigger_next) { } 249*bee91169SAlexander Graf efi_timer_check(); 250*bee91169SAlexander Graf 251*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 252*bee91169SAlexander Graf } 253*bee91169SAlexander Graf 254*bee91169SAlexander Graf static efi_status_t EFIAPI efi_signal_event(void *event) 255*bee91169SAlexander Graf { 256*bee91169SAlexander Graf EFI_ENTRY("%p", event); 257*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 258*bee91169SAlexander Graf } 259*bee91169SAlexander Graf 260*bee91169SAlexander Graf static efi_status_t EFIAPI efi_close_event(void *event) 261*bee91169SAlexander Graf { 262*bee91169SAlexander Graf EFI_ENTRY("%p", event); 263*bee91169SAlexander Graf efi_event.trigger_next = -1ULL; 264*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 265*bee91169SAlexander Graf } 266*bee91169SAlexander Graf 267*bee91169SAlexander Graf static efi_status_t EFIAPI efi_check_event(void *event) 268*bee91169SAlexander Graf { 269*bee91169SAlexander Graf EFI_ENTRY("%p", event); 270*bee91169SAlexander Graf return EFI_EXIT(EFI_NOT_READY); 271*bee91169SAlexander Graf } 272*bee91169SAlexander Graf 273*bee91169SAlexander Graf static efi_status_t EFIAPI efi_install_protocol_interface(void **handle, 274*bee91169SAlexander Graf efi_guid_t *protocol, int protocol_interface_type, 275*bee91169SAlexander Graf void *protocol_interface) 276*bee91169SAlexander Graf { 277*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %d, %p", handle, protocol, protocol_interface_type, 278*bee91169SAlexander Graf protocol_interface); 279*bee91169SAlexander Graf return EFI_EXIT(EFI_OUT_OF_RESOURCES); 280*bee91169SAlexander Graf } 281*bee91169SAlexander Graf static efi_status_t EFIAPI efi_reinstall_protocol_interface(void *handle, 282*bee91169SAlexander Graf efi_guid_t *protocol, void *old_interface, 283*bee91169SAlexander Graf void *new_interface) 284*bee91169SAlexander Graf { 285*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %p, %p", handle, protocol, old_interface, 286*bee91169SAlexander Graf new_interface); 287*bee91169SAlexander Graf return EFI_EXIT(EFI_ACCESS_DENIED); 288*bee91169SAlexander Graf } 289*bee91169SAlexander Graf 290*bee91169SAlexander Graf static efi_status_t EFIAPI efi_uninstall_protocol_interface(void *handle, 291*bee91169SAlexander Graf efi_guid_t *protocol, void *protocol_interface) 292*bee91169SAlexander Graf { 293*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %p", handle, protocol, protocol_interface); 294*bee91169SAlexander Graf return EFI_EXIT(EFI_NOT_FOUND); 295*bee91169SAlexander Graf } 296*bee91169SAlexander Graf 297*bee91169SAlexander Graf static efi_status_t EFIAPI efi_register_protocol_notify(efi_guid_t *protocol, 298*bee91169SAlexander Graf void *event, 299*bee91169SAlexander Graf void **registration) 300*bee91169SAlexander Graf { 301*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %p", protocol, event, registration); 302*bee91169SAlexander Graf return EFI_EXIT(EFI_OUT_OF_RESOURCES); 303*bee91169SAlexander Graf } 304*bee91169SAlexander Graf 305*bee91169SAlexander Graf static int efi_search(enum efi_locate_search_type search_type, 306*bee91169SAlexander Graf efi_guid_t *protocol, void *search_key, 307*bee91169SAlexander Graf struct efi_object *efiobj) 308*bee91169SAlexander Graf { 309*bee91169SAlexander Graf int i; 310*bee91169SAlexander Graf 311*bee91169SAlexander Graf switch (search_type) { 312*bee91169SAlexander Graf case all_handles: 313*bee91169SAlexander Graf return 0; 314*bee91169SAlexander Graf case by_register_notify: 315*bee91169SAlexander Graf return -1; 316*bee91169SAlexander Graf case by_protocol: 317*bee91169SAlexander Graf for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) { 318*bee91169SAlexander Graf const efi_guid_t *guid = efiobj->protocols[i].guid; 319*bee91169SAlexander Graf if (guid && !guidcmp(guid, protocol)) 320*bee91169SAlexander Graf return 0; 321*bee91169SAlexander Graf } 322*bee91169SAlexander Graf return -1; 323*bee91169SAlexander Graf } 324*bee91169SAlexander Graf 325*bee91169SAlexander Graf return -1; 326*bee91169SAlexander Graf } 327*bee91169SAlexander Graf 328*bee91169SAlexander Graf static efi_status_t EFIAPI efi_locate_handle( 329*bee91169SAlexander Graf enum efi_locate_search_type search_type, 330*bee91169SAlexander Graf efi_guid_t *protocol, void *search_key, 331*bee91169SAlexander Graf unsigned long *buffer_size, efi_handle_t *buffer) 332*bee91169SAlexander Graf { 333*bee91169SAlexander Graf struct list_head *lhandle; 334*bee91169SAlexander Graf unsigned long size = 0; 335*bee91169SAlexander Graf 336*bee91169SAlexander Graf EFI_ENTRY("%d, %p, %p, %p, %p", search_type, protocol, search_key, 337*bee91169SAlexander Graf buffer_size, buffer); 338*bee91169SAlexander Graf 339*bee91169SAlexander Graf /* Count how much space we need */ 340*bee91169SAlexander Graf list_for_each(lhandle, &efi_obj_list) { 341*bee91169SAlexander Graf struct efi_object *efiobj; 342*bee91169SAlexander Graf efiobj = list_entry(lhandle, struct efi_object, link); 343*bee91169SAlexander Graf if (!efi_search(search_type, protocol, search_key, efiobj)) { 344*bee91169SAlexander Graf size += sizeof(void*); 345*bee91169SAlexander Graf } 346*bee91169SAlexander Graf } 347*bee91169SAlexander Graf 348*bee91169SAlexander Graf if (*buffer_size < size) { 349*bee91169SAlexander Graf *buffer_size = size; 350*bee91169SAlexander Graf return EFI_EXIT(EFI_BUFFER_TOO_SMALL); 351*bee91169SAlexander Graf } 352*bee91169SAlexander Graf 353*bee91169SAlexander Graf /* Then fill the array */ 354*bee91169SAlexander Graf list_for_each(lhandle, &efi_obj_list) { 355*bee91169SAlexander Graf struct efi_object *efiobj; 356*bee91169SAlexander Graf efiobj = list_entry(lhandle, struct efi_object, link); 357*bee91169SAlexander Graf if (!efi_search(search_type, protocol, search_key, efiobj)) { 358*bee91169SAlexander Graf *(buffer++) = efiobj->handle; 359*bee91169SAlexander Graf } 360*bee91169SAlexander Graf } 361*bee91169SAlexander Graf 362*bee91169SAlexander Graf *buffer_size = size; 363*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 364*bee91169SAlexander Graf } 365*bee91169SAlexander Graf 366*bee91169SAlexander Graf static efi_status_t EFIAPI efi_locate_device_path(efi_guid_t *protocol, 367*bee91169SAlexander Graf struct efi_device_path **device_path, 368*bee91169SAlexander Graf efi_handle_t *device) 369*bee91169SAlexander Graf { 370*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %p", protocol, device_path, device); 371*bee91169SAlexander Graf return EFI_EXIT(EFI_NOT_FOUND); 372*bee91169SAlexander Graf } 373*bee91169SAlexander Graf 374*bee91169SAlexander Graf static efi_status_t EFIAPI efi_install_configuration_table(efi_guid_t *guid, 375*bee91169SAlexander Graf void *table) 376*bee91169SAlexander Graf { 377*bee91169SAlexander Graf int i; 378*bee91169SAlexander Graf 379*bee91169SAlexander Graf EFI_ENTRY("%p, %p", guid, table); 380*bee91169SAlexander Graf 381*bee91169SAlexander Graf /* Check for guid override */ 382*bee91169SAlexander Graf for (i = 0; i < systab.nr_tables; i++) { 383*bee91169SAlexander Graf if (!guidcmp(guid, &efi_conf_table[i].guid)) { 384*bee91169SAlexander Graf efi_conf_table[i].table = table; 385*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 386*bee91169SAlexander Graf } 387*bee91169SAlexander Graf } 388*bee91169SAlexander Graf 389*bee91169SAlexander Graf /* No override, check for overflow */ 390*bee91169SAlexander Graf if (i >= ARRAY_SIZE(efi_conf_table)) 391*bee91169SAlexander Graf return EFI_EXIT(EFI_OUT_OF_RESOURCES); 392*bee91169SAlexander Graf 393*bee91169SAlexander Graf /* Add a new entry */ 394*bee91169SAlexander Graf memcpy(&efi_conf_table[i].guid, guid, sizeof(*guid)); 395*bee91169SAlexander Graf efi_conf_table[i].table = table; 396*bee91169SAlexander Graf systab.nr_tables = i; 397*bee91169SAlexander Graf 398*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 399*bee91169SAlexander Graf } 400*bee91169SAlexander Graf 401*bee91169SAlexander Graf static efi_status_t EFIAPI efi_load_image(bool boot_policy, 402*bee91169SAlexander Graf efi_handle_t parent_image, 403*bee91169SAlexander Graf struct efi_device_path *file_path, 404*bee91169SAlexander Graf void *source_buffer, 405*bee91169SAlexander Graf unsigned long source_size, 406*bee91169SAlexander Graf efi_handle_t *image_handle) 407*bee91169SAlexander Graf { 408*bee91169SAlexander Graf static struct efi_object loaded_image_info_obj = { 409*bee91169SAlexander Graf .protocols = { 410*bee91169SAlexander Graf { 411*bee91169SAlexander Graf .guid = &efi_guid_loaded_image, 412*bee91169SAlexander Graf .open = &efi_return_handle, 413*bee91169SAlexander Graf }, 414*bee91169SAlexander Graf }, 415*bee91169SAlexander Graf }; 416*bee91169SAlexander Graf struct efi_loaded_image *info; 417*bee91169SAlexander Graf struct efi_object *obj; 418*bee91169SAlexander Graf 419*bee91169SAlexander Graf EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy, parent_image, 420*bee91169SAlexander Graf file_path, source_buffer, source_size, image_handle); 421*bee91169SAlexander Graf info = malloc(sizeof(*info)); 422*bee91169SAlexander Graf obj = malloc(sizeof(loaded_image_info_obj)); 423*bee91169SAlexander Graf memset(info, 0, sizeof(*info)); 424*bee91169SAlexander Graf memcpy(obj, &loaded_image_info_obj, sizeof(loaded_image_info_obj)); 425*bee91169SAlexander Graf obj->handle = info; 426*bee91169SAlexander Graf info->file_path = file_path; 427*bee91169SAlexander Graf info->reserved = efi_load_pe(source_buffer, info); 428*bee91169SAlexander Graf if (!info->reserved) { 429*bee91169SAlexander Graf free(info); 430*bee91169SAlexander Graf free(obj); 431*bee91169SAlexander Graf return EFI_EXIT(EFI_UNSUPPORTED); 432*bee91169SAlexander Graf } 433*bee91169SAlexander Graf 434*bee91169SAlexander Graf *image_handle = info; 435*bee91169SAlexander Graf list_add_tail(&obj->link, &efi_obj_list); 436*bee91169SAlexander Graf 437*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 438*bee91169SAlexander Graf } 439*bee91169SAlexander Graf 440*bee91169SAlexander Graf static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, 441*bee91169SAlexander Graf unsigned long *exit_data_size, 442*bee91169SAlexander Graf s16 **exit_data) 443*bee91169SAlexander Graf { 444*bee91169SAlexander Graf ulong (*entry)(void *image_handle, struct efi_system_table *st); 445*bee91169SAlexander Graf struct efi_loaded_image *info = image_handle; 446*bee91169SAlexander Graf 447*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data); 448*bee91169SAlexander Graf entry = info->reserved; 449*bee91169SAlexander Graf 450*bee91169SAlexander Graf efi_is_direct_boot = false; 451*bee91169SAlexander Graf 452*bee91169SAlexander Graf /* call the image! */ 453*bee91169SAlexander Graf entry(image_handle, &systab); 454*bee91169SAlexander Graf 455*bee91169SAlexander Graf /* Should usually never get here */ 456*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 457*bee91169SAlexander Graf } 458*bee91169SAlexander Graf 459*bee91169SAlexander Graf static efi_status_t EFIAPI efi_exit(void *image_handle, long exit_status, 460*bee91169SAlexander Graf unsigned long exit_data_size, 461*bee91169SAlexander Graf uint16_t *exit_data) 462*bee91169SAlexander Graf { 463*bee91169SAlexander Graf EFI_ENTRY("%p, %ld, %ld, %p", image_handle, exit_status, 464*bee91169SAlexander Graf exit_data_size, exit_data); 465*bee91169SAlexander Graf return EFI_EXIT(efi_unsupported(__func__)); 466*bee91169SAlexander Graf } 467*bee91169SAlexander Graf 468*bee91169SAlexander Graf static struct efi_object *efi_search_obj(void *handle) 469*bee91169SAlexander Graf { 470*bee91169SAlexander Graf struct list_head *lhandle; 471*bee91169SAlexander Graf 472*bee91169SAlexander Graf list_for_each(lhandle, &efi_obj_list) { 473*bee91169SAlexander Graf struct efi_object *efiobj; 474*bee91169SAlexander Graf efiobj = list_entry(lhandle, struct efi_object, link); 475*bee91169SAlexander Graf if (efiobj->handle == handle) 476*bee91169SAlexander Graf return efiobj; 477*bee91169SAlexander Graf } 478*bee91169SAlexander Graf 479*bee91169SAlexander Graf return NULL; 480*bee91169SAlexander Graf } 481*bee91169SAlexander Graf 482*bee91169SAlexander Graf static efi_status_t EFIAPI efi_unload_image(void *image_handle) 483*bee91169SAlexander Graf { 484*bee91169SAlexander Graf struct efi_object *efiobj; 485*bee91169SAlexander Graf 486*bee91169SAlexander Graf EFI_ENTRY("%p", image_handle); 487*bee91169SAlexander Graf efiobj = efi_search_obj(image_handle); 488*bee91169SAlexander Graf if (efiobj) 489*bee91169SAlexander Graf list_del(&efiobj->link); 490*bee91169SAlexander Graf 491*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 492*bee91169SAlexander Graf } 493*bee91169SAlexander Graf 494*bee91169SAlexander Graf static void efi_exit_caches(void) 495*bee91169SAlexander Graf { 496*bee91169SAlexander Graf #if defined(CONFIG_ARM) && !defined(CONFIG_ARM64) 497*bee91169SAlexander Graf /* 498*bee91169SAlexander Graf * Grub on 32bit ARM needs to have caches disabled before jumping into 499*bee91169SAlexander Graf * a zImage, but does not know of all cache layers. Give it a hand. 500*bee91169SAlexander Graf */ 501*bee91169SAlexander Graf if (efi_is_direct_boot) 502*bee91169SAlexander Graf cleanup_before_linux(); 503*bee91169SAlexander Graf #endif 504*bee91169SAlexander Graf } 505*bee91169SAlexander Graf 506*bee91169SAlexander Graf static efi_status_t EFIAPI efi_exit_boot_services(void *image_handle, 507*bee91169SAlexander Graf unsigned long map_key) 508*bee91169SAlexander Graf { 509*bee91169SAlexander Graf EFI_ENTRY("%p, %ld", image_handle, map_key); 510*bee91169SAlexander Graf 511*bee91169SAlexander Graf /* Fix up caches for EFI payloads if necessary */ 512*bee91169SAlexander Graf efi_exit_caches(); 513*bee91169SAlexander Graf 514*bee91169SAlexander Graf /* This stops all lingering devices */ 515*bee91169SAlexander Graf bootm_disable_interrupts(); 516*bee91169SAlexander Graf 517*bee91169SAlexander Graf /* Give the payload some time to boot */ 518*bee91169SAlexander Graf WATCHDOG_RESET(); 519*bee91169SAlexander Graf 520*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 521*bee91169SAlexander Graf } 522*bee91169SAlexander Graf 523*bee91169SAlexander Graf static efi_status_t EFIAPI efi_get_next_monotonic_count(uint64_t *count) 524*bee91169SAlexander Graf { 525*bee91169SAlexander Graf static uint64_t mono = 0; 526*bee91169SAlexander Graf EFI_ENTRY("%p", count); 527*bee91169SAlexander Graf *count = mono++; 528*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 529*bee91169SAlexander Graf } 530*bee91169SAlexander Graf 531*bee91169SAlexander Graf static efi_status_t EFIAPI efi_stall(unsigned long microseconds) 532*bee91169SAlexander Graf { 533*bee91169SAlexander Graf EFI_ENTRY("%ld", microseconds); 534*bee91169SAlexander Graf udelay(microseconds); 535*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 536*bee91169SAlexander Graf } 537*bee91169SAlexander Graf 538*bee91169SAlexander Graf static efi_status_t EFIAPI efi_set_watchdog_timer(unsigned long timeout, 539*bee91169SAlexander Graf uint64_t watchdog_code, 540*bee91169SAlexander Graf unsigned long data_size, 541*bee91169SAlexander Graf uint16_t *watchdog_data) 542*bee91169SAlexander Graf { 543*bee91169SAlexander Graf EFI_ENTRY("%ld, 0x%"PRIx64", %ld, %p", timeout, watchdog_code, 544*bee91169SAlexander Graf data_size, watchdog_data); 545*bee91169SAlexander Graf return EFI_EXIT(efi_unsupported(__func__)); 546*bee91169SAlexander Graf } 547*bee91169SAlexander Graf 548*bee91169SAlexander Graf static efi_status_t EFIAPI efi_connect_controller( 549*bee91169SAlexander Graf efi_handle_t controller_handle, 550*bee91169SAlexander Graf efi_handle_t *driver_image_handle, 551*bee91169SAlexander Graf struct efi_device_path *remain_device_path, 552*bee91169SAlexander Graf bool recursive) 553*bee91169SAlexander Graf { 554*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %p, %d", controller_handle, driver_image_handle, 555*bee91169SAlexander Graf remain_device_path, recursive); 556*bee91169SAlexander Graf return EFI_EXIT(EFI_NOT_FOUND); 557*bee91169SAlexander Graf } 558*bee91169SAlexander Graf 559*bee91169SAlexander Graf static efi_status_t EFIAPI efi_disconnect_controller(void *controller_handle, 560*bee91169SAlexander Graf void *driver_image_handle, 561*bee91169SAlexander Graf void *child_handle) 562*bee91169SAlexander Graf { 563*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %p", controller_handle, driver_image_handle, 564*bee91169SAlexander Graf child_handle); 565*bee91169SAlexander Graf return EFI_EXIT(EFI_INVALID_PARAMETER); 566*bee91169SAlexander Graf } 567*bee91169SAlexander Graf 568*bee91169SAlexander Graf static efi_status_t EFIAPI efi_close_protocol(void *handle, 569*bee91169SAlexander Graf efi_guid_t *protocol, 570*bee91169SAlexander Graf void *agent_handle, 571*bee91169SAlexander Graf void *controller_handle) 572*bee91169SAlexander Graf { 573*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %p, %p", handle, protocol, agent_handle, 574*bee91169SAlexander Graf controller_handle); 575*bee91169SAlexander Graf return EFI_EXIT(EFI_NOT_FOUND); 576*bee91169SAlexander Graf } 577*bee91169SAlexander Graf 578*bee91169SAlexander Graf static efi_status_t EFIAPI efi_open_protocol_information(efi_handle_t handle, 579*bee91169SAlexander Graf efi_guid_t *protocol, 580*bee91169SAlexander Graf struct efi_open_protocol_info_entry **entry_buffer, 581*bee91169SAlexander Graf unsigned long *entry_count) 582*bee91169SAlexander Graf { 583*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %p, %p", handle, protocol, entry_buffer, 584*bee91169SAlexander Graf entry_count); 585*bee91169SAlexander Graf return EFI_EXIT(EFI_NOT_FOUND); 586*bee91169SAlexander Graf } 587*bee91169SAlexander Graf 588*bee91169SAlexander Graf static efi_status_t EFIAPI efi_protocols_per_handle(void *handle, 589*bee91169SAlexander Graf efi_guid_t ***protocol_buffer, 590*bee91169SAlexander Graf unsigned long *protocol_buffer_count) 591*bee91169SAlexander Graf { 592*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %p", handle, protocol_buffer, 593*bee91169SAlexander Graf protocol_buffer_count); 594*bee91169SAlexander Graf return EFI_EXIT(EFI_OUT_OF_RESOURCES); 595*bee91169SAlexander Graf } 596*bee91169SAlexander Graf 597*bee91169SAlexander Graf static efi_status_t EFIAPI efi_locate_handle_buffer( 598*bee91169SAlexander Graf enum efi_locate_search_type search_type, 599*bee91169SAlexander Graf efi_guid_t *protocol, void *search_key, 600*bee91169SAlexander Graf unsigned long *no_handles, efi_handle_t **buffer) 601*bee91169SAlexander Graf { 602*bee91169SAlexander Graf EFI_ENTRY("%d, %p, %p, %p, %p", search_type, protocol, search_key, 603*bee91169SAlexander Graf no_handles, buffer); 604*bee91169SAlexander Graf return EFI_EXIT(EFI_NOT_FOUND); 605*bee91169SAlexander Graf } 606*bee91169SAlexander Graf 607*bee91169SAlexander Graf static struct efi_class_map efi_class_maps[] = { 608*bee91169SAlexander Graf { 609*bee91169SAlexander Graf .guid = &efi_guid_console_control, 610*bee91169SAlexander Graf .interface = &efi_console_control 611*bee91169SAlexander Graf }, 612*bee91169SAlexander Graf }; 613*bee91169SAlexander Graf 614*bee91169SAlexander Graf static efi_status_t EFIAPI efi_locate_protocol(efi_guid_t *protocol, 615*bee91169SAlexander Graf void *registration, 616*bee91169SAlexander Graf void **protocol_interface) 617*bee91169SAlexander Graf { 618*bee91169SAlexander Graf int i; 619*bee91169SAlexander Graf 620*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %p", protocol, registration, protocol_interface); 621*bee91169SAlexander Graf for (i = 0; i < ARRAY_SIZE(efi_class_maps); i++) { 622*bee91169SAlexander Graf struct efi_class_map *curmap = &efi_class_maps[i]; 623*bee91169SAlexander Graf if (!guidcmp(protocol, curmap->guid)) { 624*bee91169SAlexander Graf *protocol_interface = (void*)curmap->interface; 625*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 626*bee91169SAlexander Graf } 627*bee91169SAlexander Graf } 628*bee91169SAlexander Graf 629*bee91169SAlexander Graf return EFI_EXIT(EFI_NOT_FOUND); 630*bee91169SAlexander Graf } 631*bee91169SAlexander Graf 632*bee91169SAlexander Graf static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces( 633*bee91169SAlexander Graf void **handle, ...) 634*bee91169SAlexander Graf { 635*bee91169SAlexander Graf EFI_ENTRY("%p", handle); 636*bee91169SAlexander Graf return EFI_EXIT(EFI_OUT_OF_RESOURCES); 637*bee91169SAlexander Graf } 638*bee91169SAlexander Graf 639*bee91169SAlexander Graf static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces( 640*bee91169SAlexander Graf void *handle, ...) 641*bee91169SAlexander Graf { 642*bee91169SAlexander Graf EFI_ENTRY("%p", handle); 643*bee91169SAlexander Graf return EFI_EXIT(EFI_INVALID_PARAMETER); 644*bee91169SAlexander Graf } 645*bee91169SAlexander Graf 646*bee91169SAlexander Graf static efi_status_t EFIAPI efi_calculate_crc32(void *data, 647*bee91169SAlexander Graf unsigned long data_size, 648*bee91169SAlexander Graf uint32_t *crc32_p) 649*bee91169SAlexander Graf { 650*bee91169SAlexander Graf EFI_ENTRY("%p, %ld", data, data_size); 651*bee91169SAlexander Graf *crc32_p = crc32(0, data, data_size); 652*bee91169SAlexander Graf return EFI_EXIT(EFI_SUCCESS); 653*bee91169SAlexander Graf } 654*bee91169SAlexander Graf 655*bee91169SAlexander Graf static void EFIAPI efi_copy_mem(void *destination, void *source, 656*bee91169SAlexander Graf unsigned long length) 657*bee91169SAlexander Graf { 658*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %ld", destination, source, length); 659*bee91169SAlexander Graf memcpy(destination, source, length); 660*bee91169SAlexander Graf } 661*bee91169SAlexander Graf 662*bee91169SAlexander Graf static void EFIAPI efi_set_mem(void *buffer, unsigned long size, uint8_t value) 663*bee91169SAlexander Graf { 664*bee91169SAlexander Graf EFI_ENTRY("%p, %ld, 0x%x", buffer, size, value); 665*bee91169SAlexander Graf memset(buffer, value, size); 666*bee91169SAlexander Graf } 667*bee91169SAlexander Graf 668*bee91169SAlexander Graf static efi_status_t EFIAPI efi_open_protocol( 669*bee91169SAlexander Graf void *handle, efi_guid_t *protocol, 670*bee91169SAlexander Graf void **protocol_interface, void *agent_handle, 671*bee91169SAlexander Graf void *controller_handle, uint32_t attributes) 672*bee91169SAlexander Graf { 673*bee91169SAlexander Graf struct list_head *lhandle; 674*bee91169SAlexander Graf int i; 675*bee91169SAlexander Graf efi_status_t r = EFI_UNSUPPORTED; 676*bee91169SAlexander Graf 677*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %p, %p, %p, 0x%x", handle, protocol, 678*bee91169SAlexander Graf protocol_interface, agent_handle, controller_handle, 679*bee91169SAlexander Graf attributes); 680*bee91169SAlexander Graf list_for_each(lhandle, &efi_obj_list) { 681*bee91169SAlexander Graf struct efi_object *efiobj; 682*bee91169SAlexander Graf efiobj = list_entry(lhandle, struct efi_object, link); 683*bee91169SAlexander Graf 684*bee91169SAlexander Graf if (efiobj->handle != handle) 685*bee91169SAlexander Graf continue; 686*bee91169SAlexander Graf 687*bee91169SAlexander Graf for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) { 688*bee91169SAlexander Graf struct efi_handler *handler = &efiobj->protocols[i]; 689*bee91169SAlexander Graf const efi_guid_t *hprotocol = handler->guid; 690*bee91169SAlexander Graf if (!hprotocol) 691*bee91169SAlexander Graf break; 692*bee91169SAlexander Graf if (!guidcmp(hprotocol, protocol)) { 693*bee91169SAlexander Graf r = handler->open(handle, protocol, 694*bee91169SAlexander Graf protocol_interface, agent_handle, 695*bee91169SAlexander Graf controller_handle, attributes); 696*bee91169SAlexander Graf goto out; 697*bee91169SAlexander Graf } 698*bee91169SAlexander Graf } 699*bee91169SAlexander Graf } 700*bee91169SAlexander Graf 701*bee91169SAlexander Graf out: 702*bee91169SAlexander Graf return EFI_EXIT(r); 703*bee91169SAlexander Graf } 704*bee91169SAlexander Graf 705*bee91169SAlexander Graf static efi_status_t EFIAPI efi_handle_protocol(void *handle, 706*bee91169SAlexander Graf efi_guid_t *protocol, 707*bee91169SAlexander Graf void **protocol_interface) 708*bee91169SAlexander Graf { 709*bee91169SAlexander Graf EFI_ENTRY("%p, %p, %p", handle, protocol, protocol_interface); 710*bee91169SAlexander Graf return efi_open_protocol(handle, protocol, protocol_interface, 711*bee91169SAlexander Graf NULL, NULL, 0); 712*bee91169SAlexander Graf } 713*bee91169SAlexander Graf 714*bee91169SAlexander Graf static const struct efi_boot_services efi_boot_services = { 715*bee91169SAlexander Graf .hdr = { 716*bee91169SAlexander Graf .headersize = sizeof(struct efi_table_hdr), 717*bee91169SAlexander Graf }, 718*bee91169SAlexander Graf .raise_tpl = efi_raise_tpl, 719*bee91169SAlexander Graf .restore_tpl = efi_restore_tpl, 720*bee91169SAlexander Graf .allocate_pages = efi_allocate_pages_ext, 721*bee91169SAlexander Graf .free_pages = efi_free_pages_ext, 722*bee91169SAlexander Graf .get_memory_map = efi_get_memory_map_ext, 723*bee91169SAlexander Graf .allocate_pool = efi_allocate_pool, 724*bee91169SAlexander Graf .free_pool = efi_free_pool, 725*bee91169SAlexander Graf .create_event = efi_create_event, 726*bee91169SAlexander Graf .set_timer = efi_set_timer, 727*bee91169SAlexander Graf .wait_for_event = efi_wait_for_event, 728*bee91169SAlexander Graf .signal_event = efi_signal_event, 729*bee91169SAlexander Graf .close_event = efi_close_event, 730*bee91169SAlexander Graf .check_event = efi_check_event, 731*bee91169SAlexander Graf .install_protocol_interface = efi_install_protocol_interface, 732*bee91169SAlexander Graf .reinstall_protocol_interface = efi_reinstall_protocol_interface, 733*bee91169SAlexander Graf .uninstall_protocol_interface = efi_uninstall_protocol_interface, 734*bee91169SAlexander Graf .handle_protocol = efi_handle_protocol, 735*bee91169SAlexander Graf .reserved = NULL, 736*bee91169SAlexander Graf .register_protocol_notify = efi_register_protocol_notify, 737*bee91169SAlexander Graf .locate_handle = efi_locate_handle, 738*bee91169SAlexander Graf .locate_device_path = efi_locate_device_path, 739*bee91169SAlexander Graf .install_configuration_table = efi_install_configuration_table, 740*bee91169SAlexander Graf .load_image = efi_load_image, 741*bee91169SAlexander Graf .start_image = efi_start_image, 742*bee91169SAlexander Graf .exit = (void*)efi_exit, 743*bee91169SAlexander Graf .unload_image = efi_unload_image, 744*bee91169SAlexander Graf .exit_boot_services = efi_exit_boot_services, 745*bee91169SAlexander Graf .get_next_monotonic_count = efi_get_next_monotonic_count, 746*bee91169SAlexander Graf .stall = efi_stall, 747*bee91169SAlexander Graf .set_watchdog_timer = efi_set_watchdog_timer, 748*bee91169SAlexander Graf .connect_controller = efi_connect_controller, 749*bee91169SAlexander Graf .disconnect_controller = efi_disconnect_controller, 750*bee91169SAlexander Graf .open_protocol = efi_open_protocol, 751*bee91169SAlexander Graf .close_protocol = efi_close_protocol, 752*bee91169SAlexander Graf .open_protocol_information = efi_open_protocol_information, 753*bee91169SAlexander Graf .protocols_per_handle = efi_protocols_per_handle, 754*bee91169SAlexander Graf .locate_handle_buffer = efi_locate_handle_buffer, 755*bee91169SAlexander Graf .locate_protocol = efi_locate_protocol, 756*bee91169SAlexander Graf .install_multiple_protocol_interfaces = efi_install_multiple_protocol_interfaces, 757*bee91169SAlexander Graf .uninstall_multiple_protocol_interfaces = efi_uninstall_multiple_protocol_interfaces, 758*bee91169SAlexander Graf .calculate_crc32 = efi_calculate_crc32, 759*bee91169SAlexander Graf .copy_mem = efi_copy_mem, 760*bee91169SAlexander Graf .set_mem = efi_set_mem, 761*bee91169SAlexander Graf }; 762*bee91169SAlexander Graf 763*bee91169SAlexander Graf 764*bee91169SAlexander Graf static uint16_t firmware_vendor[] = 765*bee91169SAlexander Graf { 'D','a','s',' ','U','-','b','o','o','t',0 }; 766*bee91169SAlexander Graf 767*bee91169SAlexander Graf struct efi_system_table systab = { 768*bee91169SAlexander Graf .hdr = { 769*bee91169SAlexander Graf .signature = EFI_SYSTEM_TABLE_SIGNATURE, 770*bee91169SAlexander Graf .revision = 0x20005, /* 2.5 */ 771*bee91169SAlexander Graf .headersize = sizeof(struct efi_table_hdr), 772*bee91169SAlexander Graf }, 773*bee91169SAlexander Graf .fw_vendor = (long)firmware_vendor, 774*bee91169SAlexander Graf .con_in = (void*)&efi_con_in, 775*bee91169SAlexander Graf .con_out = (void*)&efi_con_out, 776*bee91169SAlexander Graf .std_err = (void*)&efi_con_out, 777*bee91169SAlexander Graf .runtime = (void*)&efi_runtime_services, 778*bee91169SAlexander Graf .boottime = (void*)&efi_boot_services, 779*bee91169SAlexander Graf .nr_tables = 0, 780*bee91169SAlexander Graf .tables = (void*)efi_conf_table, 781*bee91169SAlexander Graf }; 782