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