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