]> git.ipfire.org Git - people/ms/u-boot.git/blame - lib/efi_loader/efi_boottime.c
efi_loader: refactor efi_create_event
[people/ms/u-boot.git] / lib / efi_loader / efi_boottime.c
CommitLineData
bee91169
AG
1/*
2 * EFI application boot time services
3 *
4 * Copyright (c) 2016 Alexander Graf
5 *
6 * SPDX-License-Identifier: GPL-2.0+
7 */
8
bee91169
AG
9#include <common.h>
10#include <efi_loader.h>
11#include <malloc.h>
12#include <asm/global_data.h>
13#include <libfdt_env.h>
14#include <u-boot/crc.h>
15#include <bootm.h>
16#include <inttypes.h>
17#include <watchdog.h>
18
19DECLARE_GLOBAL_DATA_PTR;
20
21/* This list contains all the EFI objects our payload has access to */
22LIST_HEAD(efi_obj_list);
23
24/*
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).
29 */
30static bool efi_is_direct_boot = true;
31
32/*
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.
36 *
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().
39 */
3c63db9c 40static struct efi_configuration_table __efi_runtime_data efi_conf_table[2];
bee91169 41
65e4c0b1 42#ifdef CONFIG_ARM
bee91169
AG
43/*
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.
48 */
49static volatile void *efi_gd, *app_gd;
65e4c0b1 50#endif
bee91169
AG
51
52/* Called from do_bootefi_exec() */
53void efi_save_gd(void)
54{
65e4c0b1 55#ifdef CONFIG_ARM
bee91169 56 efi_gd = gd;
65e4c0b1 57#endif
bee91169
AG
58}
59
60/* Called on every callback entry */
61void efi_restore_gd(void)
62{
65e4c0b1 63#ifdef CONFIG_ARM
bee91169
AG
64 /* Only restore if we're already in EFI context */
65 if (!efi_gd)
66 return;
67
68 if (gd != efi_gd)
69 app_gd = gd;
70 gd = efi_gd;
65e4c0b1 71#endif
bee91169
AG
72}
73
74/* Called on every callback exit */
75efi_status_t efi_exit_func(efi_status_t ret)
76{
65e4c0b1 77#ifdef CONFIG_ARM
bee91169 78 gd = app_gd;
65e4c0b1
SG
79#endif
80
bee91169
AG
81 return ret;
82}
83
c6841592 84static void efi_signal_event(struct efi_event *event)
85{
86 if (event->signaled)
87 return;
88 event->signaled = 1;
89 if (event->type & EVT_NOTIFY_SIGNAL) {
90 EFI_EXIT(EFI_SUCCESS);
91 event->notify_function(event, event->notify_context);
92 EFI_ENTRY("returning from notification function");
93 }
94}
95
bee91169
AG
96static efi_status_t efi_unsupported(const char *funcname)
97{
edcef3ba 98 debug("EFI: App called into unimplemented function %s\n", funcname);
bee91169
AG
99 return EFI_EXIT(EFI_UNSUPPORTED);
100}
101
102static int guidcmp(const efi_guid_t *g1, const efi_guid_t *g2)
103{
104 return memcmp(g1, g2, sizeof(efi_guid_t));
105}
106
503f2695 107static unsigned long EFIAPI efi_raise_tpl(UINTN new_tpl)
bee91169 108{
503f2695 109 EFI_ENTRY("0x%zx", new_tpl);
bee91169
AG
110 return EFI_EXIT(0);
111}
112
503f2695 113static void EFIAPI efi_restore_tpl(UINTN old_tpl)
bee91169 114{
503f2695 115 EFI_ENTRY("0x%zx", old_tpl);
bee91169
AG
116 EFI_EXIT(efi_unsupported(__func__));
117}
118
6e0bf8d8
MY
119static efi_status_t EFIAPI efi_allocate_pages_ext(int type, int memory_type,
120 unsigned long pages,
121 uint64_t *memory)
bee91169
AG
122{
123 efi_status_t r;
124
125 EFI_ENTRY("%d, %d, 0x%lx, %p", type, memory_type, pages, memory);
126 r = efi_allocate_pages(type, memory_type, pages, memory);
127 return EFI_EXIT(r);
128}
129
6e0bf8d8
MY
130static efi_status_t EFIAPI efi_free_pages_ext(uint64_t memory,
131 unsigned long pages)
bee91169
AG
132{
133 efi_status_t r;
134
135 EFI_ENTRY("%"PRIx64", 0x%lx", memory, pages);
136 r = efi_free_pages(memory, pages);
137 return EFI_EXIT(r);
138}
139
6e0bf8d8
MY
140static efi_status_t EFIAPI efi_get_memory_map_ext(
141 unsigned long *memory_map_size,
142 struct efi_mem_desc *memory_map,
143 unsigned long *map_key,
144 unsigned long *descriptor_size,
145 uint32_t *descriptor_version)
bee91169
AG
146{
147 efi_status_t r;
148
149 EFI_ENTRY("%p, %p, %p, %p, %p", memory_map_size, memory_map,
150 map_key, descriptor_size, descriptor_version);
151 r = efi_get_memory_map(memory_map_size, memory_map, map_key,
152 descriptor_size, descriptor_version);
153 return EFI_EXIT(r);
154}
155
ead1274b
SB
156static efi_status_t EFIAPI efi_allocate_pool_ext(int pool_type,
157 unsigned long size,
158 void **buffer)
bee91169 159{
1cd29f0a
AG
160 efi_status_t r;
161
162 EFI_ENTRY("%d, %ld, %p", pool_type, size, buffer);
ead1274b 163 r = efi_allocate_pool(pool_type, size, buffer);
1cd29f0a 164 return EFI_EXIT(r);
bee91169
AG
165}
166
42417bc8 167static efi_status_t EFIAPI efi_free_pool_ext(void *buffer)
bee91169 168{
1cd29f0a
AG
169 efi_status_t r;
170
171 EFI_ENTRY("%p", buffer);
42417bc8 172 r = efi_free_pool(buffer);
1cd29f0a 173 return EFI_EXIT(r);
bee91169
AG
174}
175
176/*
c6841592 177 * Our event capabilities are very limited. Only a small limited
178 * number of events is allowed to coexist.
bee91169 179 */
c6841592 180static struct efi_event efi_events[16];
bee91169 181
49deb455 182efi_status_t efi_create_event(enum efi_event_type type, UINTN notify_tpl,
183 void (EFIAPI *notify_function) (
2fd945fe 184 struct efi_event *event,
185 void *context),
49deb455 186 void *notify_context, struct efi_event **event)
bee91169 187{
c6841592 188 int i;
189
a95343b8 190 if (event == NULL)
49deb455 191 return EFI_INVALID_PARAMETER;
a95343b8
JG
192
193 if ((type & EVT_NOTIFY_SIGNAL) && (type & EVT_NOTIFY_WAIT))
49deb455 194 return EFI_INVALID_PARAMETER;
a95343b8
JG
195
196 if ((type & (EVT_NOTIFY_SIGNAL|EVT_NOTIFY_WAIT)) &&
197 notify_function == NULL)
49deb455 198 return EFI_INVALID_PARAMETER;
a95343b8 199
c6841592 200 for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
201 if (efi_events[i].type)
202 continue;
203 efi_events[i].type = type;
204 efi_events[i].notify_tpl = notify_tpl;
205 efi_events[i].notify_function = notify_function;
206 efi_events[i].notify_context = notify_context;
207 /* Disable timers on bootup */
208 efi_events[i].trigger_next = -1ULL;
209 efi_events[i].signaled = 0;
210 *event = &efi_events[i];
49deb455 211 return EFI_SUCCESS;
c6841592 212 }
49deb455 213 return EFI_OUT_OF_RESOURCES;
bee91169
AG
214}
215
49deb455 216static efi_status_t EFIAPI efi_create_event_ext(
217 enum efi_event_type type, UINTN notify_tpl,
218 void (EFIAPI *notify_function) (
219 struct efi_event *event,
220 void *context),
221 void *notify_context, struct efi_event **event)
222{
223 EFI_ENTRY("%d, 0x%zx, %p, %p", type, notify_tpl, notify_function,
224 notify_context);
225 return EFI_EXIT(efi_create_event(type, notify_tpl, notify_function,
226 notify_context, event));
227}
228
229
bee91169
AG
230/*
231 * Our timers have to work without interrupts, so we check whenever keyboard
232 * input or disk accesses happen if enough time elapsed for it to fire.
233 */
234void efi_timer_check(void)
235{
c6841592 236 int i;
bee91169
AG
237 u64 now = timer_get_us();
238
c6841592 239 for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
240 if (!efi_events[i].type ||
241 !(efi_events[i].type & EVT_TIMER) ||
242 efi_events[i].trigger_type == EFI_TIMER_STOP ||
243 now < efi_events[i].trigger_next)
244 continue;
245 if (efi_events[i].trigger_type == EFI_TIMER_PERIODIC) {
246 efi_events[i].trigger_next +=
247 efi_events[i].trigger_time / 10;
248 efi_events[i].signaled = 0;
249 }
250 efi_signal_event(&efi_events[i]);
bee91169 251 }
bee91169
AG
252 WATCHDOG_RESET();
253}
254
2fd945fe 255static efi_status_t EFIAPI efi_set_timer(struct efi_event *event, int type,
bee91169
AG
256 uint64_t trigger_time)
257{
258 /* We don't have 64bit division available everywhere, so limit timer
259 * distances to 32bit bits. */
260 u32 trigger32 = trigger_time;
c6841592 261 int i;
bee91169
AG
262
263 EFI_ENTRY("%p, %d, %"PRIx64, event, type, trigger_time);
264
265 if (trigger32 < trigger_time) {
266 printf("WARNING: Truncating timer from %"PRIx64" to %x\n",
267 trigger_time, trigger32);
268 }
269
c6841592 270 for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
271 if (event != &efi_events[i])
272 continue;
bee91169 273
c6841592 274 if (!(event->type & EVT_TIMER))
275 break;
276 switch (type) {
277 case EFI_TIMER_STOP:
278 event->trigger_next = -1ULL;
279 break;
280 case EFI_TIMER_PERIODIC:
281 case EFI_TIMER_RELATIVE:
282 event->trigger_next =
283 timer_get_us() + (trigger32 / 10);
284 break;
285 default:
286 return EFI_EXIT(EFI_INVALID_PARAMETER);
287 }
288 event->trigger_type = type;
289 event->trigger_time = trigger_time;
290 return EFI_EXIT(EFI_SUCCESS);
bee91169 291 }
c6841592 292 return EFI_EXIT(EFI_INVALID_PARAMETER);
bee91169
AG
293}
294
295static efi_status_t EFIAPI efi_wait_for_event(unsigned long num_events,
2fd945fe 296 struct efi_event **event,
297 unsigned long *index)
bee91169 298{
c6841592 299 int i, j;
bee91169
AG
300
301 EFI_ENTRY("%ld, %p, %p", num_events, event, index);
302
c6841592 303 /* Check parameters */
304 if (!num_events || !event)
305 return EFI_EXIT(EFI_INVALID_PARAMETER);
306 for (i = 0; i < num_events; ++i) {
307 for (j = 0; j < ARRAY_SIZE(efi_events); ++j) {
308 if (event[i] == &efi_events[j])
309 goto known_event;
310 }
311 return EFI_EXIT(EFI_INVALID_PARAMETER);
312known_event:
313 if (!event[i]->type || event[i]->type & EVT_NOTIFY_SIGNAL)
314 return EFI_EXIT(EFI_INVALID_PARAMETER);
315 }
316
317 /* Wait for signal */
318 for (;;) {
319 for (i = 0; i < num_events; ++i) {
320 if (event[i]->signaled)
321 goto out;
322 }
323 /* Allow events to occur. */
324 efi_timer_check();
325 }
326
327out:
328 /*
329 * Reset the signal which is passed to the caller to allow periodic
330 * events to occur.
331 */
332 event[i]->signaled = 0;
333 if (index)
334 *index = i;
bee91169
AG
335
336 return EFI_EXIT(EFI_SUCCESS);
337}
338
c6841592 339static efi_status_t EFIAPI efi_signal_event_ext(struct efi_event *event)
bee91169 340{
c6841592 341 int i;
342
bee91169 343 EFI_ENTRY("%p", event);
c6841592 344 for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
345 if (event != &efi_events[i])
346 continue;
347 efi_signal_event(event);
348 break;
349 }
bee91169
AG
350 return EFI_EXIT(EFI_SUCCESS);
351}
352
2fd945fe 353static efi_status_t EFIAPI efi_close_event(struct efi_event *event)
bee91169 354{
c6841592 355 int i;
356
bee91169 357 EFI_ENTRY("%p", event);
c6841592 358 for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
359 if (event == &efi_events[i]) {
360 event->type = 0;
361 event->trigger_next = -1ULL;
362 event->signaled = 0;
363 return EFI_EXIT(EFI_SUCCESS);
364 }
365 }
366 return EFI_EXIT(EFI_INVALID_PARAMETER);
bee91169
AG
367}
368
2fd945fe 369static efi_status_t EFIAPI efi_check_event(struct efi_event *event)
bee91169 370{
c6841592 371 int i;
372
bee91169 373 EFI_ENTRY("%p", event);
c6841592 374 efi_timer_check();
375 for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
376 if (event != &efi_events[i])
377 continue;
378 if (!event->type || event->type & EVT_NOTIFY_SIGNAL)
379 break;
380 if (event->signaled)
381 return EFI_EXIT(EFI_SUCCESS);
382 return EFI_EXIT(EFI_NOT_READY);
383 }
384 return EFI_EXIT(EFI_INVALID_PARAMETER);
bee91169
AG
385}
386
387static efi_status_t EFIAPI efi_install_protocol_interface(void **handle,
388 efi_guid_t *protocol, int protocol_interface_type,
389 void *protocol_interface)
390{
e0549f8a 391 struct list_head *lhandle;
392 int i;
393 efi_status_t r;
394
e0549f8a 395 if (!handle || !protocol ||
396 protocol_interface_type != EFI_NATIVE_INTERFACE) {
397 r = EFI_INVALID_PARAMETER;
398 goto out;
399 }
400
401 /* Create new handle if requested. */
402 if (!*handle) {
403 r = EFI_OUT_OF_RESOURCES;
404 goto out;
405 }
406 /* Find object. */
407 list_for_each(lhandle, &efi_obj_list) {
408 struct efi_object *efiobj;
409 efiobj = list_entry(lhandle, struct efi_object, link);
410
411 if (efiobj->handle != *handle)
412 continue;
413 /* Check if protocol is already installed on the handle. */
414 for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
415 struct efi_handler *handler = &efiobj->protocols[i];
416
417 if (!handler->guid)
418 continue;
419 if (!guidcmp(handler->guid, protocol)) {
420 r = EFI_INVALID_PARAMETER;
421 goto out;
422 }
423 }
424 /* Install protocol in first empty slot. */
425 for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
426 struct efi_handler *handler = &efiobj->protocols[i];
427
428 if (handler->guid)
429 continue;
430
431 handler->guid = protocol;
432 handler->protocol_interface = protocol_interface;
433 r = EFI_SUCCESS;
434 goto out;
435 }
436 r = EFI_OUT_OF_RESOURCES;
437 goto out;
438 }
439 r = EFI_INVALID_PARAMETER;
440out:
8bee5a3c 441 return r;
442}
443
444static efi_status_t EFIAPI efi_install_protocol_interface_ext(void **handle,
445 efi_guid_t *protocol, int protocol_interface_type,
446 void *protocol_interface)
447{
448 EFI_ENTRY("%p, %p, %d, %p", handle, protocol, protocol_interface_type,
449 protocol_interface);
450
451 return EFI_EXIT(efi_install_protocol_interface(handle, protocol,
452 protocol_interface_type,
453 protocol_interface));
bee91169 454}
e0549f8a 455
bee91169
AG
456static efi_status_t EFIAPI efi_reinstall_protocol_interface(void *handle,
457 efi_guid_t *protocol, void *old_interface,
458 void *new_interface)
459{
460 EFI_ENTRY("%p, %p, %p, %p", handle, protocol, old_interface,
461 new_interface);
462 return EFI_EXIT(EFI_ACCESS_DENIED);
463}
464
465static efi_status_t EFIAPI efi_uninstall_protocol_interface(void *handle,
466 efi_guid_t *protocol, void *protocol_interface)
467{
4b6ed0d7 468 struct list_head *lhandle;
469 int i;
470 efi_status_t r = EFI_NOT_FOUND;
471
4b6ed0d7 472 if (!handle || !protocol) {
473 r = EFI_INVALID_PARAMETER;
474 goto out;
475 }
476
477 list_for_each(lhandle, &efi_obj_list) {
478 struct efi_object *efiobj;
479 efiobj = list_entry(lhandle, struct efi_object, link);
480
481 if (efiobj->handle != handle)
482 continue;
483
484 for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
485 struct efi_handler *handler = &efiobj->protocols[i];
486 const efi_guid_t *hprotocol = handler->guid;
487
488 if (!hprotocol)
489 continue;
490 if (!guidcmp(hprotocol, protocol)) {
491 if (handler->protocol_interface) {
492 r = EFI_ACCESS_DENIED;
493 } else {
494 handler->guid = 0;
495 r = EFI_SUCCESS;
496 }
497 goto out;
498 }
499 }
500 }
501
502out:
3d8e1456 503 return r;
504}
505
506static efi_status_t EFIAPI efi_uninstall_protocol_interface_ext(void *handle,
507 efi_guid_t *protocol, void *protocol_interface)
508{
509 EFI_ENTRY("%p, %p, %p", handle, protocol, protocol_interface);
510
511 return EFI_EXIT(efi_uninstall_protocol_interface(handle, protocol,
512 protocol_interface));
bee91169
AG
513}
514
515static efi_status_t EFIAPI efi_register_protocol_notify(efi_guid_t *protocol,
2fd945fe 516 struct efi_event *event,
bee91169
AG
517 void **registration)
518{
519 EFI_ENTRY("%p, %p, %p", protocol, event, registration);
520 return EFI_EXIT(EFI_OUT_OF_RESOURCES);
521}
522
523static int efi_search(enum efi_locate_search_type search_type,
524 efi_guid_t *protocol, void *search_key,
525 struct efi_object *efiobj)
526{
527 int i;
528
529 switch (search_type) {
530 case all_handles:
531 return 0;
532 case by_register_notify:
533 return -1;
534 case by_protocol:
535 for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
536 const efi_guid_t *guid = efiobj->protocols[i].guid;
537 if (guid && !guidcmp(guid, protocol))
538 return 0;
539 }
540 return -1;
541 }
542
543 return -1;
544}
545
546static efi_status_t EFIAPI efi_locate_handle(
547 enum efi_locate_search_type search_type,
548 efi_guid_t *protocol, void *search_key,
549 unsigned long *buffer_size, efi_handle_t *buffer)
550{
551 struct list_head *lhandle;
552 unsigned long size = 0;
553
bee91169
AG
554 /* Count how much space we need */
555 list_for_each(lhandle, &efi_obj_list) {
556 struct efi_object *efiobj;
557 efiobj = list_entry(lhandle, struct efi_object, link);
558 if (!efi_search(search_type, protocol, search_key, efiobj)) {
559 size += sizeof(void*);
560 }
561 }
562
563 if (*buffer_size < size) {
564 *buffer_size = size;
26329584 565 return EFI_BUFFER_TOO_SMALL;
bee91169
AG
566 }
567
568 /* Then fill the array */
569 list_for_each(lhandle, &efi_obj_list) {
570 struct efi_object *efiobj;
571 efiobj = list_entry(lhandle, struct efi_object, link);
572 if (!efi_search(search_type, protocol, search_key, efiobj)) {
573 *(buffer++) = efiobj->handle;
574 }
575 }
576
577 *buffer_size = size;
26329584 578 return EFI_SUCCESS;
579}
580
581static efi_status_t EFIAPI efi_locate_handle_ext(
582 enum efi_locate_search_type search_type,
583 efi_guid_t *protocol, void *search_key,
584 unsigned long *buffer_size, efi_handle_t *buffer)
585{
586 EFI_ENTRY("%d, %p, %p, %p, %p", search_type, protocol, search_key,
587 buffer_size, buffer);
588
589 return EFI_EXIT(efi_locate_handle(search_type, protocol, search_key,
590 buffer_size, buffer));
bee91169
AG
591}
592
593static efi_status_t EFIAPI efi_locate_device_path(efi_guid_t *protocol,
594 struct efi_device_path **device_path,
595 efi_handle_t *device)
596{
597 EFI_ENTRY("%p, %p, %p", protocol, device_path, device);
598 return EFI_EXIT(EFI_NOT_FOUND);
599}
600
488bf12d 601efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table)
bee91169
AG
602{
603 int i;
604
bee91169
AG
605 /* Check for guid override */
606 for (i = 0; i < systab.nr_tables; i++) {
607 if (!guidcmp(guid, &efi_conf_table[i].guid)) {
608 efi_conf_table[i].table = table;
488bf12d 609 return EFI_SUCCESS;
bee91169
AG
610 }
611 }
612
613 /* No override, check for overflow */
614 if (i >= ARRAY_SIZE(efi_conf_table))
488bf12d 615 return EFI_OUT_OF_RESOURCES;
bee91169
AG
616
617 /* Add a new entry */
618 memcpy(&efi_conf_table[i].guid, guid, sizeof(*guid));
619 efi_conf_table[i].table = table;
aba5e919 620 systab.nr_tables = i + 1;
bee91169 621
488bf12d
AG
622 return EFI_SUCCESS;
623}
624
625static efi_status_t EFIAPI efi_install_configuration_table_ext(efi_guid_t *guid,
626 void *table)
627{
628 EFI_ENTRY("%p, %p", guid, table);
629 return EFI_EXIT(efi_install_configuration_table(guid, table));
bee91169
AG
630}
631
632static efi_status_t EFIAPI efi_load_image(bool boot_policy,
633 efi_handle_t parent_image,
634 struct efi_device_path *file_path,
635 void *source_buffer,
636 unsigned long source_size,
637 efi_handle_t *image_handle)
638{
639 static struct efi_object loaded_image_info_obj = {
640 .protocols = {
641 {
642 .guid = &efi_guid_loaded_image,
bee91169
AG
643 },
644 },
645 };
646 struct efi_loaded_image *info;
647 struct efi_object *obj;
648
649 EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy, parent_image,
650 file_path, source_buffer, source_size, image_handle);
651 info = malloc(sizeof(*info));
b5349f74 652 loaded_image_info_obj.protocols[0].protocol_interface = info;
bee91169
AG
653 obj = malloc(sizeof(loaded_image_info_obj));
654 memset(info, 0, sizeof(*info));
655 memcpy(obj, &loaded_image_info_obj, sizeof(loaded_image_info_obj));
656 obj->handle = info;
657 info->file_path = file_path;
658 info->reserved = efi_load_pe(source_buffer, info);
659 if (!info->reserved) {
660 free(info);
661 free(obj);
662 return EFI_EXIT(EFI_UNSUPPORTED);
663 }
664
665 *image_handle = info;
666 list_add_tail(&obj->link, &efi_obj_list);
667
668 return EFI_EXIT(EFI_SUCCESS);
669}
670
671static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
672 unsigned long *exit_data_size,
673 s16 **exit_data)
674{
675 ulong (*entry)(void *image_handle, struct efi_system_table *st);
676 struct efi_loaded_image *info = image_handle;
677
678 EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
679 entry = info->reserved;
680
681 efi_is_direct_boot = false;
682
683 /* call the image! */
a86aeaf2
AG
684 if (setjmp(&info->exit_jmp)) {
685 /* We returned from the child image */
686 return EFI_EXIT(info->exit_status);
687 }
688
bee91169
AG
689 entry(image_handle, &systab);
690
691 /* Should usually never get here */
692 return EFI_EXIT(EFI_SUCCESS);
693}
694
a86aeaf2
AG
695static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
696 efi_status_t exit_status, unsigned long exit_data_size,
697 int16_t *exit_data)
bee91169 698{
a86aeaf2
AG
699 struct efi_loaded_image *loaded_image_info = (void*)image_handle;
700
bee91169
AG
701 EFI_ENTRY("%p, %ld, %ld, %p", image_handle, exit_status,
702 exit_data_size, exit_data);
a86aeaf2
AG
703
704 loaded_image_info->exit_status = exit_status;
692fcdd8 705 longjmp(&loaded_image_info->exit_jmp, 1);
a86aeaf2
AG
706
707 panic("EFI application exited");
bee91169
AG
708}
709
710static struct efi_object *efi_search_obj(void *handle)
711{
712 struct list_head *lhandle;
713
714 list_for_each(lhandle, &efi_obj_list) {
715 struct efi_object *efiobj;
716 efiobj = list_entry(lhandle, struct efi_object, link);
717 if (efiobj->handle == handle)
718 return efiobj;
719 }
720
721 return NULL;
722}
723
724static efi_status_t EFIAPI efi_unload_image(void *image_handle)
725{
726 struct efi_object *efiobj;
727
728 EFI_ENTRY("%p", image_handle);
729 efiobj = efi_search_obj(image_handle);
730 if (efiobj)
731 list_del(&efiobj->link);
732
733 return EFI_EXIT(EFI_SUCCESS);
734}
735
736static void efi_exit_caches(void)
737{
738#if defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
739 /*
740 * Grub on 32bit ARM needs to have caches disabled before jumping into
741 * a zImage, but does not know of all cache layers. Give it a hand.
742 */
743 if (efi_is_direct_boot)
744 cleanup_before_linux();
745#endif
746}
747
748static efi_status_t EFIAPI efi_exit_boot_services(void *image_handle,
749 unsigned long map_key)
750{
751 EFI_ENTRY("%p, %ld", image_handle, map_key);
752
b7b8410a
AG
753 board_quiesce_devices();
754
bee91169
AG
755 /* Fix up caches for EFI payloads if necessary */
756 efi_exit_caches();
757
758 /* This stops all lingering devices */
759 bootm_disable_interrupts();
760
761 /* Give the payload some time to boot */
762 WATCHDOG_RESET();
763
764 return EFI_EXIT(EFI_SUCCESS);
765}
766
767static efi_status_t EFIAPI efi_get_next_monotonic_count(uint64_t *count)
768{
769 static uint64_t mono = 0;
770 EFI_ENTRY("%p", count);
771 *count = mono++;
772 return EFI_EXIT(EFI_SUCCESS);
773}
774
775static efi_status_t EFIAPI efi_stall(unsigned long microseconds)
776{
777 EFI_ENTRY("%ld", microseconds);
778 udelay(microseconds);
779 return EFI_EXIT(EFI_SUCCESS);
780}
781
782static efi_status_t EFIAPI efi_set_watchdog_timer(unsigned long timeout,
783 uint64_t watchdog_code,
784 unsigned long data_size,
785 uint16_t *watchdog_data)
786{
787 EFI_ENTRY("%ld, 0x%"PRIx64", %ld, %p", timeout, watchdog_code,
788 data_size, watchdog_data);
789 return EFI_EXIT(efi_unsupported(__func__));
790}
791
792static efi_status_t EFIAPI efi_connect_controller(
793 efi_handle_t controller_handle,
794 efi_handle_t *driver_image_handle,
795 struct efi_device_path *remain_device_path,
796 bool recursive)
797{
798 EFI_ENTRY("%p, %p, %p, %d", controller_handle, driver_image_handle,
799 remain_device_path, recursive);
800 return EFI_EXIT(EFI_NOT_FOUND);
801}
802
803static efi_status_t EFIAPI efi_disconnect_controller(void *controller_handle,
804 void *driver_image_handle,
805 void *child_handle)
806{
807 EFI_ENTRY("%p, %p, %p", controller_handle, driver_image_handle,
808 child_handle);
809 return EFI_EXIT(EFI_INVALID_PARAMETER);
810}
811
812static efi_status_t EFIAPI efi_close_protocol(void *handle,
813 efi_guid_t *protocol,
814 void *agent_handle,
815 void *controller_handle)
816{
817 EFI_ENTRY("%p, %p, %p, %p", handle, protocol, agent_handle,
818 controller_handle);
819 return EFI_EXIT(EFI_NOT_FOUND);
820}
821
822static efi_status_t EFIAPI efi_open_protocol_information(efi_handle_t handle,
823 efi_guid_t *protocol,
824 struct efi_open_protocol_info_entry **entry_buffer,
825 unsigned long *entry_count)
826{
827 EFI_ENTRY("%p, %p, %p, %p", handle, protocol, entry_buffer,
828 entry_count);
829 return EFI_EXIT(EFI_NOT_FOUND);
830}
831
832static efi_status_t EFIAPI efi_protocols_per_handle(void *handle,
833 efi_guid_t ***protocol_buffer,
834 unsigned long *protocol_buffer_count)
835{
836 EFI_ENTRY("%p, %p, %p", handle, protocol_buffer,
837 protocol_buffer_count);
838 return EFI_EXIT(EFI_OUT_OF_RESOURCES);
839}
840
841static efi_status_t EFIAPI efi_locate_handle_buffer(
842 enum efi_locate_search_type search_type,
843 efi_guid_t *protocol, void *search_key,
844 unsigned long *no_handles, efi_handle_t **buffer)
845{
c2e703f9 846 efi_status_t r;
847 unsigned long buffer_size = 0;
848
bee91169
AG
849 EFI_ENTRY("%d, %p, %p, %p, %p", search_type, protocol, search_key,
850 no_handles, buffer);
c2e703f9 851
852 if (!no_handles || !buffer) {
853 r = EFI_INVALID_PARAMETER;
854 goto out;
855 }
856 *no_handles = 0;
857 *buffer = NULL;
858 r = efi_locate_handle(search_type, protocol, search_key, &buffer_size,
859 *buffer);
860 if (r != EFI_BUFFER_TOO_SMALL)
861 goto out;
862 r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, buffer_size,
863 (void **)buffer);
864 if (r != EFI_SUCCESS)
865 goto out;
866 r = efi_locate_handle(search_type, protocol, search_key, &buffer_size,
867 *buffer);
868 if (r == EFI_SUCCESS)
869 *no_handles = buffer_size / sizeof(void *);
870out:
871 return EFI_EXIT(r);
bee91169
AG
872}
873
bee91169
AG
874static efi_status_t EFIAPI efi_locate_protocol(efi_guid_t *protocol,
875 void *registration,
876 void **protocol_interface)
877{
88adae5e 878 struct list_head *lhandle;
bee91169
AG
879 int i;
880
881 EFI_ENTRY("%p, %p, %p", protocol, registration, protocol_interface);
88adae5e 882
883 if (!protocol || !protocol_interface)
884 return EFI_EXIT(EFI_INVALID_PARAMETER);
885
886 list_for_each(lhandle, &efi_obj_list) {
887 struct efi_object *efiobj;
888
889 efiobj = list_entry(lhandle, struct efi_object, link);
890 for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
891 struct efi_handler *handler = &efiobj->protocols[i];
892
893 if (!handler->guid)
894 continue;
895 if (!guidcmp(handler->guid, protocol)) {
896 *protocol_interface =
897 handler->protocol_interface;
898 return EFI_EXIT(EFI_SUCCESS);
899 }
bee91169
AG
900 }
901 }
88adae5e 902 *protocol_interface = NULL;
bee91169
AG
903
904 return EFI_EXIT(EFI_NOT_FOUND);
905}
906
907static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
908 void **handle, ...)
909{
910 EFI_ENTRY("%p", handle);
58b83586 911
912 va_list argptr;
913 efi_guid_t *protocol;
914 void *protocol_interface;
915 efi_status_t r = EFI_SUCCESS;
916 int i = 0;
917
918 if (!handle)
919 return EFI_EXIT(EFI_INVALID_PARAMETER);
920
921 va_start(argptr, handle);
922 for (;;) {
923 protocol = va_arg(argptr, efi_guid_t*);
924 if (!protocol)
925 break;
926 protocol_interface = va_arg(argptr, void*);
927 r = efi_install_protocol_interface(handle, protocol,
928 EFI_NATIVE_INTERFACE,
929 protocol_interface);
930 if (r != EFI_SUCCESS)
931 break;
932 i++;
933 }
934 va_end(argptr);
935 if (r == EFI_SUCCESS)
936 return EFI_EXIT(r);
937
938 /* If an error occured undo all changes. */
939 va_start(argptr, handle);
940 for (; i; --i) {
941 protocol = va_arg(argptr, efi_guid_t*);
942 protocol_interface = va_arg(argptr, void*);
943 efi_uninstall_protocol_interface(handle, protocol,
944 protocol_interface);
945 }
946 va_end(argptr);
947
948 return EFI_EXIT(r);
bee91169
AG
949}
950
951static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
952 void *handle, ...)
953{
954 EFI_ENTRY("%p", handle);
955 return EFI_EXIT(EFI_INVALID_PARAMETER);
956}
957
958static efi_status_t EFIAPI efi_calculate_crc32(void *data,
959 unsigned long data_size,
960 uint32_t *crc32_p)
961{
962 EFI_ENTRY("%p, %ld", data, data_size);
963 *crc32_p = crc32(0, data, data_size);
964 return EFI_EXIT(EFI_SUCCESS);
965}
966
967static void EFIAPI efi_copy_mem(void *destination, void *source,
968 unsigned long length)
969{
970 EFI_ENTRY("%p, %p, %ld", destination, source, length);
971 memcpy(destination, source, length);
972}
973
974static void EFIAPI efi_set_mem(void *buffer, unsigned long size, uint8_t value)
975{
976 EFI_ENTRY("%p, %ld, 0x%x", buffer, size, value);
977 memset(buffer, value, size);
978}
979
980static efi_status_t EFIAPI efi_open_protocol(
981 void *handle, efi_guid_t *protocol,
982 void **protocol_interface, void *agent_handle,
983 void *controller_handle, uint32_t attributes)
984{
985 struct list_head *lhandle;
986 int i;
69baec67 987 efi_status_t r = EFI_INVALID_PARAMETER;
bee91169
AG
988
989 EFI_ENTRY("%p, %p, %p, %p, %p, 0x%x", handle, protocol,
990 protocol_interface, agent_handle, controller_handle,
991 attributes);
b5349f74 992
69baec67 993 if (!handle || !protocol ||
994 (!protocol_interface && attributes !=
995 EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) {
996 goto out;
997 }
998
999 switch (attributes) {
1000 case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL:
1001 case EFI_OPEN_PROTOCOL_GET_PROTOCOL:
1002 case EFI_OPEN_PROTOCOL_TEST_PROTOCOL:
1003 break;
1004 case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER:
1005 if (controller_handle == handle)
1006 goto out;
1007 case EFI_OPEN_PROTOCOL_BY_DRIVER:
1008 case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE:
1009 if (controller_handle == NULL)
1010 goto out;
1011 case EFI_OPEN_PROTOCOL_EXCLUSIVE:
1012 if (agent_handle == NULL)
1013 goto out;
1014 break;
1015 default:
b5349f74 1016 goto out;
1017 }
1018
bee91169
AG
1019 list_for_each(lhandle, &efi_obj_list) {
1020 struct efi_object *efiobj;
1021 efiobj = list_entry(lhandle, struct efi_object, link);
1022
1023 if (efiobj->handle != handle)
1024 continue;
1025
1026 for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
1027 struct efi_handler *handler = &efiobj->protocols[i];
1028 const efi_guid_t *hprotocol = handler->guid;
1029 if (!hprotocol)
4b6ed0d7 1030 continue;
bee91169 1031 if (!guidcmp(hprotocol, protocol)) {
b5349f74 1032 if (attributes !=
1033 EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
1034 *protocol_interface =
1035 handler->protocol_interface;
1036 }
1037 r = EFI_SUCCESS;
bee91169
AG
1038 goto out;
1039 }
1040 }
69baec67 1041 goto unsupported;
bee91169
AG
1042 }
1043
69baec67 1044unsupported:
1045 r = EFI_UNSUPPORTED;
bee91169
AG
1046out:
1047 return EFI_EXIT(r);
1048}
1049
1050static efi_status_t EFIAPI efi_handle_protocol(void *handle,
1051 efi_guid_t *protocol,
1052 void **protocol_interface)
1053{
8e1d329f 1054 return efi_open_protocol(handle, protocol, protocol_interface, NULL,
1055 NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
bee91169
AG
1056}
1057
1058static const struct efi_boot_services efi_boot_services = {
1059 .hdr = {
1060 .headersize = sizeof(struct efi_table_hdr),
1061 },
1062 .raise_tpl = efi_raise_tpl,
1063 .restore_tpl = efi_restore_tpl,
1064 .allocate_pages = efi_allocate_pages_ext,
1065 .free_pages = efi_free_pages_ext,
1066 .get_memory_map = efi_get_memory_map_ext,
ead1274b 1067 .allocate_pool = efi_allocate_pool_ext,
42417bc8 1068 .free_pool = efi_free_pool_ext,
49deb455 1069 .create_event = efi_create_event_ext,
bee91169
AG
1070 .set_timer = efi_set_timer,
1071 .wait_for_event = efi_wait_for_event,
c6841592 1072 .signal_event = efi_signal_event_ext,
bee91169
AG
1073 .close_event = efi_close_event,
1074 .check_event = efi_check_event,
8bee5a3c 1075 .install_protocol_interface = efi_install_protocol_interface_ext,
bee91169 1076 .reinstall_protocol_interface = efi_reinstall_protocol_interface,
3d8e1456 1077 .uninstall_protocol_interface = efi_uninstall_protocol_interface_ext,
bee91169
AG
1078 .handle_protocol = efi_handle_protocol,
1079 .reserved = NULL,
1080 .register_protocol_notify = efi_register_protocol_notify,
26329584 1081 .locate_handle = efi_locate_handle_ext,
bee91169 1082 .locate_device_path = efi_locate_device_path,
488bf12d 1083 .install_configuration_table = efi_install_configuration_table_ext,
bee91169
AG
1084 .load_image = efi_load_image,
1085 .start_image = efi_start_image,
a86aeaf2 1086 .exit = efi_exit,
bee91169
AG
1087 .unload_image = efi_unload_image,
1088 .exit_boot_services = efi_exit_boot_services,
1089 .get_next_monotonic_count = efi_get_next_monotonic_count,
1090 .stall = efi_stall,
1091 .set_watchdog_timer = efi_set_watchdog_timer,
1092 .connect_controller = efi_connect_controller,
1093 .disconnect_controller = efi_disconnect_controller,
1094 .open_protocol = efi_open_protocol,
1095 .close_protocol = efi_close_protocol,
1096 .open_protocol_information = efi_open_protocol_information,
1097 .protocols_per_handle = efi_protocols_per_handle,
1098 .locate_handle_buffer = efi_locate_handle_buffer,
1099 .locate_protocol = efi_locate_protocol,
1100 .install_multiple_protocol_interfaces = efi_install_multiple_protocol_interfaces,
1101 .uninstall_multiple_protocol_interfaces = efi_uninstall_multiple_protocol_interfaces,
1102 .calculate_crc32 = efi_calculate_crc32,
1103 .copy_mem = efi_copy_mem,
1104 .set_mem = efi_set_mem,
1105};
1106
1107
3c63db9c 1108static uint16_t __efi_runtime_data firmware_vendor[] =
bee91169
AG
1109 { 'D','a','s',' ','U','-','b','o','o','t',0 };
1110
3c63db9c 1111struct efi_system_table __efi_runtime_data systab = {
bee91169
AG
1112 .hdr = {
1113 .signature = EFI_SYSTEM_TABLE_SIGNATURE,
1114 .revision = 0x20005, /* 2.5 */
1115 .headersize = sizeof(struct efi_table_hdr),
1116 },
1117 .fw_vendor = (long)firmware_vendor,
1118 .con_in = (void*)&efi_con_in,
1119 .con_out = (void*)&efi_con_out,
1120 .std_err = (void*)&efi_con_out,
1121 .runtime = (void*)&efi_runtime_services,
1122 .boottime = (void*)&efi_boot_services,
1123 .nr_tables = 0,
1124 .tables = (void*)efi_conf_table,
1125};