]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/Bds/BdsHelper.c
d306eea39be71e0e3475e7675ca30a59df8335c1
[mirror_edk2.git] / ArmPlatformPkg / Bds / BdsHelper.c
1 /** @file
2 *
3 * Copyright (c) 2011, ARM Limited. All rights reserved.
4 *
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
9 *
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 *
13 **/
14
15 #include "BdsInternal.h"
16
17 EFI_STATUS
18 EditHIInputStr (
19 IN OUT CHAR16 *CmdLine,
20 IN UINTN MaxCmdLine
21 )
22 {
23 UINTN CmdLineIndex;
24 UINTN WaitIndex;
25 CHAR8 Char;
26 EFI_INPUT_KEY Key;
27 EFI_STATUS Status;
28
29 Print (CmdLine);
30
31 for (CmdLineIndex = StrLen (CmdLine); CmdLineIndex < MaxCmdLine; ) {
32 Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex);
33 ASSERT_EFI_ERROR (Status);
34
35 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
36 ASSERT_EFI_ERROR (Status);
37
38 // Unicode character is valid when Scancode is NUll
39 if (Key.ScanCode == SCAN_NULL) {
40 // Scan code is NUll, hence read Unicode character
41 Char = (CHAR8)Key.UnicodeChar;
42 } else {
43 Char = CHAR_NULL;
44 }
45
46 if ((Char == CHAR_LINEFEED) || (Char == CHAR_CARRIAGE_RETURN) || (Char == 0x7f)) {
47 CmdLine[CmdLineIndex] = '\0';
48 Print (L"\n\r");
49
50 return EFI_SUCCESS;
51 } else if ((Key.UnicodeChar == L'\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){
52 if (CmdLineIndex != 0) {
53 CmdLineIndex--;
54 Print (L"\b \b");
55 }
56 } else if ((Key.ScanCode == SCAN_ESC) || (Char == 0x1B) || (Char == 0x0)) {
57 return EFI_INVALID_PARAMETER;
58 } else {
59 CmdLine[CmdLineIndex++] = Key.UnicodeChar;
60 Print (L"%c", Key.UnicodeChar);
61 }
62 }
63
64 return EFI_SUCCESS;
65 }
66
67 EFI_STATUS
68 GetHIInputStr (
69 IN OUT CHAR16 *CmdLine,
70 IN UINTN MaxCmdLine
71 )
72 {
73 EFI_STATUS Status;
74
75 // For a new input just passed an empty string
76 CmdLine[0] = L'\0';
77
78 Status = EditHIInputStr (CmdLine, MaxCmdLine);
79
80 return Status;
81 }
82
83 EFI_STATUS
84 EditHIInputAscii (
85 IN OUT CHAR8 *CmdLine,
86 IN UINTN MaxCmdLine
87 )
88 {
89 CHAR16* Str;
90 EFI_STATUS Status;
91
92 Str = (CHAR16*)AllocatePool (MaxCmdLine * sizeof(CHAR16));
93 AsciiStrToUnicodeStr (CmdLine, Str);
94
95 Status = EditHIInputStr (Str, MaxCmdLine);
96
97 if (!EFI_ERROR(Status)) {
98 UnicodeStrToAsciiStr (Str, CmdLine);
99 }
100 FreePool (Str);
101
102 return Status;
103 }
104
105 EFI_STATUS
106 GetHIInputAscii (
107 IN OUT CHAR8 *CmdLine,
108 IN UINTN MaxCmdLine
109 )
110 {
111 // For a new input just passed an empty string
112 CmdLine[0] = '\0';
113
114 return EditHIInputAscii (CmdLine,MaxCmdLine);
115 }
116
117 EFI_STATUS
118 GetHIInputInteger (
119 OUT UINTN *Integer
120 )
121 {
122 CHAR16 CmdLine[255];
123 EFI_STATUS Status;
124
125 CmdLine[0] = '\0';
126 Status = EditHIInputStr (CmdLine, 255);
127 if (!EFI_ERROR(Status)) {
128 *Integer = StrDecimalToUintn (CmdLine);
129 }
130
131 return Status;
132 }
133
134 EFI_STATUS
135 GetHIInputIP (
136 OUT EFI_IP_ADDRESS *Ip
137 )
138 {
139 CHAR16 CmdLine[255];
140 CHAR16 *Str;
141 EFI_STATUS Status;
142
143 CmdLine[0] = '\0';
144 Status = EditHIInputStr (CmdLine,255);
145 if (!EFI_ERROR(Status)) {
146 Str = CmdLine;
147 Ip->v4.Addr[0] = (UINT8)StrDecimalToUintn (Str);
148
149 Str = StrStr (Str, L".");
150 if (Str == NULL) {
151 return EFI_INVALID_PARAMETER;
152 }
153
154 Ip->v4.Addr[1] = (UINT8)StrDecimalToUintn (++Str);
155
156 Str = StrStr (Str, L".");
157 if (Str == NULL) {
158 return EFI_INVALID_PARAMETER;
159 }
160
161 Ip->v4.Addr[2] = (UINT8)StrDecimalToUintn (++Str);
162
163 Str = StrStr (Str, L".");
164 if (Str == NULL) {
165 return EFI_INVALID_PARAMETER;
166 }
167
168 Ip->v4.Addr[3] = (UINT8)StrDecimalToUintn (++Str);
169 }
170
171 return Status;
172 }
173
174 EFI_STATUS
175 GetHIInputBoolean (
176 OUT BOOLEAN *Value
177 )
178 {
179 CHAR16 CmdBoolean[2];
180 EFI_STATUS Status;
181
182 while(1) {
183 Print (L"[y/n] ");
184 Status = GetHIInputStr (CmdBoolean, 2);
185 if (EFI_ERROR(Status)) {
186 return Status;
187 } else if ((CmdBoolean[0] == L'y') || (CmdBoolean[0] == L'Y')) {
188 if (Value) *Value = TRUE;
189 return EFI_SUCCESS;
190 } else if ((CmdBoolean[0] == L'n') || (CmdBoolean[0] == L'N')) {
191 if (Value) *Value = FALSE;
192 return EFI_SUCCESS;
193 }
194 }
195 }
196
197 BOOLEAN
198 HasFilePathEfiExtension (
199 IN CHAR16* FilePath
200 )
201 {
202 return (StrCmp (FilePath + (StrSize(FilePath)/sizeof(CHAR16)) - 5, L".efi") == 0);
203 }
204
205 // Return the last non end-type Device Path Node from a Device Path
206 EFI_DEVICE_PATH*
207 GetLastDevicePathNode (
208 IN EFI_DEVICE_PATH* DevicePath
209 )
210 {
211 EFI_DEVICE_PATH* PrevDevicePathNode;
212
213 PrevDevicePathNode = DevicePath;
214 while (!IsDevicePathEndType (DevicePath)) {
215 PrevDevicePathNode = DevicePath;
216 DevicePath = NextDevicePathNode (DevicePath);
217 }
218
219 return PrevDevicePathNode;
220 }
221
222 EFI_STATUS
223 GenerateDeviceDescriptionName (
224 IN EFI_HANDLE Handle,
225 IN OUT CHAR16* Description
226 )
227 {
228 EFI_STATUS Status;
229 EFI_COMPONENT_NAME_PROTOCOL* ComponentName2Protocol;
230 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
231 EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;
232 CHAR16* DriverName;
233 CHAR16* DevicePathTxt;
234 EFI_DEVICE_PATH* DevicePathNode;
235
236 ComponentName2Protocol = NULL;
237 Status = gBS->HandleProtocol (Handle, &gEfiComponentName2ProtocolGuid, (VOID **)&ComponentName2Protocol);
238 if (!EFI_ERROR(Status)) {
239 //TODO: Fixme. we must find the best langague
240 Status = ComponentName2Protocol->GetDriverName (ComponentName2Protocol,"en",&DriverName);
241 if (!EFI_ERROR(Status)) {
242 StrnCpy (Description, DriverName, BOOT_DEVICE_DESCRIPTION_MAX);
243 }
244 }
245
246 if (EFI_ERROR(Status)) {
247 // Use the lastest non null entry of the Device path as a description
248 Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);
249 if (EFI_ERROR(Status)) {
250 return Status;
251 }
252
253 // Convert the last non end-type Device Path Node in text for the description
254 DevicePathNode = GetLastDevicePathNode (DevicePathProtocol);
255 Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
256 ASSERT_EFI_ERROR(Status);
257 DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePathNode, TRUE, TRUE);
258 StrnCpy (Description, DevicePathTxt, BOOT_DEVICE_DESCRIPTION_MAX);
259 FreePool (DevicePathTxt);
260 }
261
262 return EFI_SUCCESS;
263 }
264
265 EFI_STATUS
266 BdsStartBootOption (
267 IN CHAR16* BootOption
268 )
269 {
270 EFI_STATUS Status;
271 BDS_LOAD_OPTION *BdsLoadOption;
272
273 Status = BootOptionFromLoadOptionVariable (BootOption, &BdsLoadOption);
274 if (!EFI_ERROR(Status)) {
275 Status = BootOptionStart (BdsLoadOption);
276 FreePool (BdsLoadOption);
277
278 if (!EFI_ERROR(Status)) {
279 Status = EFI_SUCCESS;
280 } else {
281 Status = EFI_NOT_STARTED;
282 }
283 } else {
284 Status = EFI_NOT_FOUND;
285 }
286 return Status;
287 }
288
289 UINTN
290 GetUnalignedDevicePathSize (
291 IN EFI_DEVICE_PATH* DevicePath
292 )
293 {
294 UINTN Size;
295 EFI_DEVICE_PATH* AlignedDevicePath;
296
297 if ((UINTN)DevicePath & 0x1) {
298 AlignedDevicePath = DuplicateDevicePath (DevicePath);
299 Size = GetDevicePathSize (AlignedDevicePath);
300 FreePool (AlignedDevicePath);
301 } else {
302 Size = GetDevicePathSize (DevicePath);
303 }
304 return Size;
305 }
306
307 EFI_DEVICE_PATH*
308 GetAlignedDevicePath (
309 IN EFI_DEVICE_PATH* DevicePath
310 )
311 {
312 if ((UINTN)DevicePath & 0x1) {
313 return DuplicateDevicePath (DevicePath);
314 } else {
315 return DevicePath;
316 }
317 }
318