xref: /rk3399_rockchip-uboot/lib/efi/efi.c (revision 1a2728ae4faf12874173de156b8a7e66cfbbeae5)
1*867a6ac8SSimon Glass /*
2*867a6ac8SSimon Glass  * Copyright (c) 2015 Google, Inc
3*867a6ac8SSimon Glass  *
4*867a6ac8SSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
5*867a6ac8SSimon Glass  *
6*867a6ac8SSimon Glass  * EFI information obtained here:
7*867a6ac8SSimon Glass  * http://wiki.phoenix.com/wiki/index.php/EFI_BOOT_SERVICES
8*867a6ac8SSimon Glass  *
9*867a6ac8SSimon Glass  * Common EFI functions
10*867a6ac8SSimon Glass  */
11*867a6ac8SSimon Glass 
12*867a6ac8SSimon Glass #include <common.h>
13*867a6ac8SSimon Glass #include <debug_uart.h>
14*867a6ac8SSimon Glass #include <errno.h>
15*867a6ac8SSimon Glass #include <linux/err.h>
16*867a6ac8SSimon Glass #include <linux/types.h>
17*867a6ac8SSimon Glass #include <efi.h>
18*867a6ac8SSimon Glass #include <efi_api.h>
19*867a6ac8SSimon Glass 
20*867a6ac8SSimon Glass DECLARE_GLOBAL_DATA_PTR;
21*867a6ac8SSimon Glass 
22*867a6ac8SSimon Glass /*
23*867a6ac8SSimon Glass  * Unfortunately we cannot access any code outside what is built especially
24*867a6ac8SSimon Glass  * for the stub. lib/string.c is already being built for the U-Boot payload
25*867a6ac8SSimon Glass  * so it uses the wrong compiler flags. Add our own memset() here.
26*867a6ac8SSimon Glass  */
efi_memset(void * ptr,int ch,int size)27*867a6ac8SSimon Glass static void efi_memset(void *ptr, int ch, int size)
28*867a6ac8SSimon Glass {
29*867a6ac8SSimon Glass 	char *dest = ptr;
30*867a6ac8SSimon Glass 
31*867a6ac8SSimon Glass 	while (size-- > 0)
32*867a6ac8SSimon Glass 		*dest++ = ch;
33*867a6ac8SSimon Glass }
34*867a6ac8SSimon Glass 
35*867a6ac8SSimon Glass /*
36*867a6ac8SSimon Glass  * Since the EFI stub cannot access most of the U-Boot code, add our own
37*867a6ac8SSimon Glass  * simple console output functions here. The EFI app will not use these since
38*867a6ac8SSimon Glass  * it can use the normal console.
39*867a6ac8SSimon Glass  */
efi_putc(struct efi_priv * priv,const char ch)40*867a6ac8SSimon Glass void efi_putc(struct efi_priv *priv, const char ch)
41*867a6ac8SSimon Glass {
42*867a6ac8SSimon Glass 	struct efi_simple_text_output_protocol *con = priv->sys_table->con_out;
43*867a6ac8SSimon Glass 	uint16_t ucode[2];
44*867a6ac8SSimon Glass 
45*867a6ac8SSimon Glass 	ucode[0] = ch;
46*867a6ac8SSimon Glass 	ucode[1] = '\0';
47*867a6ac8SSimon Glass 	con->output_string(con, ucode);
48*867a6ac8SSimon Glass }
49*867a6ac8SSimon Glass 
efi_puts(struct efi_priv * priv,const char * str)50*867a6ac8SSimon Glass void efi_puts(struct efi_priv *priv, const char *str)
51*867a6ac8SSimon Glass {
52*867a6ac8SSimon Glass 	while (*str)
53*867a6ac8SSimon Glass 		efi_putc(priv, *str++);
54*867a6ac8SSimon Glass }
55*867a6ac8SSimon Glass 
efi_init(struct efi_priv * priv,const char * banner,efi_handle_t image,struct efi_system_table * sys_table)56*867a6ac8SSimon Glass int efi_init(struct efi_priv *priv, const char *banner, efi_handle_t image,
57*867a6ac8SSimon Glass 	     struct efi_system_table *sys_table)
58*867a6ac8SSimon Glass {
59*867a6ac8SSimon Glass 	efi_guid_t loaded_image_guid = LOADED_IMAGE_PROTOCOL_GUID;
60*867a6ac8SSimon Glass 	struct efi_boot_services *boot = sys_table->boottime;
61*867a6ac8SSimon Glass 	struct efi_loaded_image *loaded_image;
62*867a6ac8SSimon Glass 	int ret;
63*867a6ac8SSimon Glass 
64*867a6ac8SSimon Glass 	efi_memset(priv, '\0', sizeof(*priv));
65*867a6ac8SSimon Glass 	priv->sys_table = sys_table;
66*867a6ac8SSimon Glass 	priv->boot = sys_table->boottime;
67*867a6ac8SSimon Glass 	priv->parent_image = image;
68*867a6ac8SSimon Glass 	priv->run = sys_table->runtime;
69*867a6ac8SSimon Glass 
70*867a6ac8SSimon Glass 	efi_puts(priv, "U-Boot EFI ");
71*867a6ac8SSimon Glass 	efi_puts(priv, banner);
72*867a6ac8SSimon Glass 	efi_putc(priv, ' ');
73*867a6ac8SSimon Glass 
74*867a6ac8SSimon Glass 	ret = boot->open_protocol(priv->parent_image, &loaded_image_guid,
75*867a6ac8SSimon Glass 				  (void **)&loaded_image, &priv->parent_image,
76*867a6ac8SSimon Glass 				  NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
77*867a6ac8SSimon Glass 	if (ret) {
78*867a6ac8SSimon Glass 		efi_puts(priv, "Failed to get loaded image protocol\n");
79*867a6ac8SSimon Glass 		return ret;
80*867a6ac8SSimon Glass 	}
81*867a6ac8SSimon Glass 	priv->image_data_type = loaded_image->image_data_type;
82*867a6ac8SSimon Glass 
83*867a6ac8SSimon Glass 	return 0;
84*867a6ac8SSimon Glass }
85*867a6ac8SSimon Glass 
efi_malloc(struct efi_priv * priv,int size,efi_status_t * retp)86*867a6ac8SSimon Glass void *efi_malloc(struct efi_priv *priv, int size, efi_status_t *retp)
87*867a6ac8SSimon Glass {
88*867a6ac8SSimon Glass 	struct efi_boot_services *boot = priv->boot;
89*867a6ac8SSimon Glass 	void *buf = NULL;
90*867a6ac8SSimon Glass 
91*867a6ac8SSimon Glass 	*retp = boot->allocate_pool(priv->image_data_type, size, &buf);
92*867a6ac8SSimon Glass 
93*867a6ac8SSimon Glass 	return buf;
94*867a6ac8SSimon Glass }
95*867a6ac8SSimon Glass 
efi_free(struct efi_priv * priv,void * ptr)96*867a6ac8SSimon Glass void efi_free(struct efi_priv *priv, void *ptr)
97*867a6ac8SSimon Glass {
98*867a6ac8SSimon Glass 	struct efi_boot_services *boot = priv->boot;
99*867a6ac8SSimon Glass 
100*867a6ac8SSimon Glass 	boot->free_pool(ptr);
101*867a6ac8SSimon Glass }
102