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