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