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