1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <efi/types.h>
6 #include <efi/protocol/device-path-to-text.h>
7 #include <efi/protocol/file.h>
8 #include <efi/protocol/simple-file-system.h>
9
10 #include <stdlib.h>
11 #include <string.h>
12 #include <printf.h>
13 #include <xefi.h>
14
15 xefi_global xefi_global_state;
16
xefi_init(efi_handle img,efi_system_table * sys)17 void xefi_init(efi_handle img, efi_system_table* sys) {
18 gSys = sys;
19 gImg = img;
20 gBS = sys->BootServices;
21 gConOut = sys->ConOut;
22 }
23
xefi_wait_any_key(void)24 void xefi_wait_any_key(void) {
25 efi_simple_text_input_protocol* sii = gSys->ConIn;
26 efi_input_key key;
27 while (sii->ReadKeyStroke(sii, &key) != EFI_SUCCESS)
28 ;
29 }
30
xefi_fatal(const char * msg,efi_status status)31 void xefi_fatal(const char* msg, efi_status status) {
32 printf("\nERROR: %s (%s)\n", msg, xefi_strerror(status));
33 xefi_wait_any_key();
34 gBS->Exit(gImg, 1, 0, NULL);
35 }
36
xefi_devpath_to_str(efi_device_path_protocol * path)37 char16_t* xefi_devpath_to_str(efi_device_path_protocol* path) {
38 efi_device_path_to_text_protocol* prot;
39 efi_status status = gBS->LocateProtocol(&DevicePathToTextProtocol, NULL, (void**)&prot);
40 if (EFI_ERROR(status)) {
41 return NULL;
42 }
43 return prot->ConvertDevicePathToText(path, false, false);
44 }
45
xefi_cmp_guid(efi_guid * guid1,efi_guid * guid2)46 int xefi_cmp_guid(efi_guid* guid1, efi_guid* guid2) {
47 return memcmp(guid1, guid2, sizeof(efi_guid));
48 }
49
xefi_handle_to_str(efi_handle h)50 char16_t* xefi_handle_to_str(efi_handle h) {
51 efi_device_path_protocol* path;
52 efi_status status = gBS->HandleProtocol(h, &DevicePathProtocol, (void*)&path);
53 if (EFI_ERROR(status)) {
54 char16_t* err;
55 status = gBS->AllocatePool(EfiLoaderData, sizeof(L"<NoPath>"), (void**)&err);
56 if (EFI_ERROR(status)) {
57 return NULL;
58 }
59 gBS->CopyMem(err, L"<NoPath>", sizeof(L"<NoPath>"));
60 return err;
61 }
62 char16_t* str = xefi_devpath_to_str(path);
63 if (str == NULL) {
64 char16_t* err;
65 status = gBS->AllocatePool(EfiLoaderData, sizeof(L"<NoString>"), (void**)&err);
66 if (EFI_ERROR(status)) {
67 return NULL;
68 }
69 gBS->CopyMem(err, L"<NoString>", sizeof(L"<NoString>"));
70 return err;
71 }
72 return str;
73 }
74
xefi_open_protocol(efi_handle h,efi_guid * guid,void ** ifc)75 efi_status xefi_open_protocol(efi_handle h, efi_guid* guid, void** ifc) {
76 return gBS->OpenProtocol(h, guid, ifc, gImg, NULL,
77 EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
78 }
79
xefi_close_protocol(efi_handle h,efi_guid * guid)80 efi_status xefi_close_protocol(efi_handle h, efi_guid* guid) {
81 return gBS->CloseProtocol(h, guid, gImg, NULL);
82 }
83
xefi_strerror(efi_status status)84 const char *xefi_strerror(efi_status status) {
85 switch (status) {
86 #define ERR_ENTRY(x) \
87 case x: { \
88 return #x; \
89 }
90 ERR_ENTRY(EFI_SUCCESS);
91 ERR_ENTRY(EFI_LOAD_ERROR);
92 ERR_ENTRY(EFI_INVALID_PARAMETER);
93 ERR_ENTRY(EFI_UNSUPPORTED);
94 ERR_ENTRY(EFI_BAD_BUFFER_SIZE);
95 ERR_ENTRY(EFI_BUFFER_TOO_SMALL);
96 ERR_ENTRY(EFI_NOT_READY);
97 ERR_ENTRY(EFI_DEVICE_ERROR);
98 ERR_ENTRY(EFI_WRITE_PROTECTED);
99 ERR_ENTRY(EFI_OUT_OF_RESOURCES);
100 ERR_ENTRY(EFI_VOLUME_CORRUPTED);
101 ERR_ENTRY(EFI_VOLUME_FULL);
102 ERR_ENTRY(EFI_NO_MEDIA);
103 ERR_ENTRY(EFI_MEDIA_CHANGED);
104 ERR_ENTRY(EFI_NOT_FOUND);
105 ERR_ENTRY(EFI_ACCESS_DENIED);
106 ERR_ENTRY(EFI_NO_RESPONSE);
107 ERR_ENTRY(EFI_NO_MAPPING);
108 ERR_ENTRY(EFI_TIMEOUT);
109 ERR_ENTRY(EFI_NOT_STARTED);
110 ERR_ENTRY(EFI_ALREADY_STARTED);
111 ERR_ENTRY(EFI_ABORTED);
112 ERR_ENTRY(EFI_ICMP_ERROR);
113 ERR_ENTRY(EFI_TFTP_ERROR);
114 ERR_ENTRY(EFI_PROTOCOL_ERROR);
115 ERR_ENTRY(EFI_INCOMPATIBLE_VERSION);
116 ERR_ENTRY(EFI_SECURITY_VIOLATION);
117 ERR_ENTRY(EFI_CRC_ERROR);
118 ERR_ENTRY(EFI_END_OF_MEDIA);
119 ERR_ENTRY(EFI_END_OF_FILE);
120 ERR_ENTRY(EFI_INVALID_LANGUAGE);
121 ERR_ENTRY(EFI_COMPROMISED_DATA);
122 ERR_ENTRY(EFI_IP_ADDRESS_CONFLICT);
123 ERR_ENTRY(EFI_HTTP_ERROR);
124 #undef ERR_ENTRY
125 }
126
127 return "<Unknown error>";
128 }
129
xefi_wstrerror(efi_status status)130 const char16_t* xefi_wstrerror(efi_status status) {
131 switch (status) {
132 #define ERR_ENTRY(x) \
133 case x: { \
134 return L"" #x; \
135 }
136 ERR_ENTRY(EFI_SUCCESS);
137 ERR_ENTRY(EFI_LOAD_ERROR);
138 ERR_ENTRY(EFI_INVALID_PARAMETER);
139 ERR_ENTRY(EFI_UNSUPPORTED);
140 ERR_ENTRY(EFI_BAD_BUFFER_SIZE);
141 ERR_ENTRY(EFI_BUFFER_TOO_SMALL);
142 ERR_ENTRY(EFI_NOT_READY);
143 ERR_ENTRY(EFI_DEVICE_ERROR);
144 ERR_ENTRY(EFI_WRITE_PROTECTED);
145 ERR_ENTRY(EFI_OUT_OF_RESOURCES);
146 ERR_ENTRY(EFI_VOLUME_CORRUPTED);
147 ERR_ENTRY(EFI_VOLUME_FULL);
148 ERR_ENTRY(EFI_NO_MEDIA);
149 ERR_ENTRY(EFI_MEDIA_CHANGED);
150 ERR_ENTRY(EFI_NOT_FOUND);
151 ERR_ENTRY(EFI_ACCESS_DENIED);
152 ERR_ENTRY(EFI_NO_RESPONSE);
153 ERR_ENTRY(EFI_NO_MAPPING);
154 ERR_ENTRY(EFI_TIMEOUT);
155 ERR_ENTRY(EFI_NOT_STARTED);
156 ERR_ENTRY(EFI_ALREADY_STARTED);
157 ERR_ENTRY(EFI_ABORTED);
158 ERR_ENTRY(EFI_ICMP_ERROR);
159 ERR_ENTRY(EFI_TFTP_ERROR);
160 ERR_ENTRY(EFI_PROTOCOL_ERROR);
161 ERR_ENTRY(EFI_INCOMPATIBLE_VERSION);
162 ERR_ENTRY(EFI_SECURITY_VIOLATION);
163 ERR_ENTRY(EFI_CRC_ERROR);
164 ERR_ENTRY(EFI_END_OF_MEDIA);
165 ERR_ENTRY(EFI_END_OF_FILE);
166 ERR_ENTRY(EFI_INVALID_LANGUAGE);
167 ERR_ENTRY(EFI_COMPROMISED_DATA);
168 ERR_ENTRY(EFI_IP_ADDRESS_CONFLICT);
169 ERR_ENTRY(EFI_HTTP_ERROR);
170 #undef ERR_ENTRY
171 }
172
173 return L"<Unknown error>";
174 }
175
strlen_16(char16_t * str)176 size_t strlen_16(char16_t* str) {
177 size_t len = 0;
178 while (*(str + len) != '\0') {
179 len++;
180 }
181
182 return len;
183 }
184