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