3 * Copyright (c) 2011, ARM Limited. All rights reserved.
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
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.
15 #include "BdsInternal.h"
18 GetEnvironmentVariable (
19 IN CONST CHAR16
* VariableName
,
20 IN VOID
* DefaultValue
,
28 // Try to get the variable size.
31 Status
= gRT
->GetVariable ((CHAR16
*) VariableName
, &gEfiGlobalVariableGuid
, NULL
, &VariableSize
, *Value
);
32 if (Status
== EFI_NOT_FOUND
) {
33 if ((DefaultValue
!= NULL
) && (Size
!= NULL
) && (*Size
!= 0)) {
34 // If the environment variable does not exist yet then set it with the default value
35 Status
= gRT
->SetVariable (
36 (CHAR16
*)VariableName
,
37 &gEfiGlobalVariableGuid
,
38 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
42 *Value
= DefaultValue
;
46 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
47 // Get the environment variable value
48 *Value
= AllocatePool (VariableSize
);
50 return EFI_OUT_OF_RESOURCES
;
53 Status
= gRT
->GetVariable ((CHAR16
*)VariableName
, &gEfiGlobalVariableGuid
, NULL
, &VariableSize
, *Value
);
54 if (EFI_ERROR (Status
)) {
56 return EFI_INVALID_PARAMETER
;
63 *Value
= DefaultValue
;
72 IN OUT CHAR16
*CmdLine
,
84 for (CmdLineIndex
= StrLen (CmdLine
); CmdLineIndex
< MaxCmdLine
; ) {
85 Status
= gBS
->WaitForEvent (1, &gST
->ConIn
->WaitForKey
, &WaitIndex
);
86 ASSERT_EFI_ERROR (Status
);
88 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
89 ASSERT_EFI_ERROR (Status
);
91 // Unicode character is valid when Scancode is NUll
92 if (Key
.ScanCode
== SCAN_NULL
) {
93 // Scan code is NUll, hence read Unicode character
94 Char
= (CHAR8
)Key
.UnicodeChar
;
99 if ((Char
== CHAR_LINEFEED
) || (Char
== CHAR_CARRIAGE_RETURN
) || (Char
== 0x7f)) {
100 CmdLine
[CmdLineIndex
] = '\0';
104 } else if ((Key
.UnicodeChar
== L
'\b') || (Key
.ScanCode
== SCAN_LEFT
) || (Key
.ScanCode
== SCAN_DELETE
)){
105 if (CmdLineIndex
!= 0) {
109 } else if ((Key
.ScanCode
== SCAN_ESC
) || (Char
== 0x1B) || (Char
== 0x0)) {
110 return EFI_INVALID_PARAMETER
;
112 CmdLine
[CmdLineIndex
++] = Key
.UnicodeChar
;
113 Print (L
"%c", Key
.UnicodeChar
);
122 IN OUT CHAR16
*CmdLine
,
128 // For a new input just passed an empty string
131 Status
= EditHIInputStr (CmdLine
, MaxCmdLine
);
138 IN OUT CHAR8
*CmdLine
,
145 Str
= (CHAR16
*)AllocatePool (MaxCmdLine
* sizeof(CHAR16
));
146 AsciiStrToUnicodeStr (CmdLine
, Str
);
148 Status
= EditHIInputStr (Str
, MaxCmdLine
);
150 if (!EFI_ERROR(Status
)) {
151 UnicodeStrToAsciiStr (Str
, CmdLine
);
160 IN OUT CHAR8
*CmdLine
,
164 // For a new input just passed an empty string
167 return EditHIInputAscii (CmdLine
,MaxCmdLine
);
179 Status
= EditHIInputStr (CmdLine
, 255);
180 if (!EFI_ERROR(Status
)) {
181 *Integer
= StrDecimalToUintn (CmdLine
);
189 OUT EFI_IP_ADDRESS
*Ip
197 Status
= EditHIInputStr (CmdLine
,255);
198 if (!EFI_ERROR(Status
)) {
200 Ip
->v4
.Addr
[0] = (UINT8
)StrDecimalToUintn (Str
);
202 Str
= StrStr (Str
, L
".");
204 return EFI_INVALID_PARAMETER
;
207 Ip
->v4
.Addr
[1] = (UINT8
)StrDecimalToUintn (++Str
);
209 Str
= StrStr (Str
, L
".");
211 return EFI_INVALID_PARAMETER
;
214 Ip
->v4
.Addr
[2] = (UINT8
)StrDecimalToUintn (++Str
);
216 Str
= StrStr (Str
, L
".");
218 return EFI_INVALID_PARAMETER
;
221 Ip
->v4
.Addr
[3] = (UINT8
)StrDecimalToUintn (++Str
);
232 CHAR16 CmdBoolean
[2];
237 Status
= GetHIInputStr (CmdBoolean
,2);
238 if (EFI_ERROR(Status
)) {
240 } else if ((CmdBoolean
[0] == L
'y') || (CmdBoolean
[0] == L
'Y')) {
241 if (Value
) *Value
= TRUE
;
243 } else if ((CmdBoolean
[0] == L
'n') || (CmdBoolean
[0] == L
'N')) {
244 if (Value
) *Value
= FALSE
;
251 HasFilePathEfiExtension (
255 return (StrCmp (FilePath
+ (StrSize(FilePath
)/sizeof(CHAR16
)) - 5, L
".efi") == 0);
258 // Return the last non end-type Device Path Node from a Device Path
260 GetLastDevicePathNode (
261 IN EFI_DEVICE_PATH
* DevicePath
264 EFI_DEVICE_PATH
* PrevDevicePathNode
;
266 PrevDevicePathNode
= DevicePath
;
267 while (!IsDevicePathEndType (DevicePath
)) {
268 PrevDevicePathNode
= DevicePath
;
269 DevicePath
= NextDevicePathNode (DevicePath
);
272 return PrevDevicePathNode
;
276 GenerateDeviceDescriptionName (
277 IN EFI_HANDLE Handle
,
278 IN OUT CHAR16
* Description
282 EFI_COMPONENT_NAME_PROTOCOL
* ComponentName2Protocol
;
283 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL
* DevicePathToTextProtocol
;
284 EFI_DEVICE_PATH_PROTOCOL
* DevicePathProtocol
;
286 CHAR16
* DevicePathTxt
;
287 EFI_DEVICE_PATH
* DevicePathNode
;
289 ComponentName2Protocol
= NULL
;
290 Status
= gBS
->HandleProtocol (Handle
, &gEfiComponentName2ProtocolGuid
, (VOID
**)&ComponentName2Protocol
);
291 if (!EFI_ERROR(Status
)) {
292 //TODO: Fixme. we must find the best langague
293 Status
= ComponentName2Protocol
->GetDriverName (ComponentName2Protocol
,"en",&DriverName
);
294 if (!EFI_ERROR(Status
)) {
295 StrnCpy (Description
,DriverName
,BOOT_DEVICE_DESCRIPTION_MAX
);
299 if (EFI_ERROR(Status
)) {
300 // Use the lastest non null entry of the Device path as a description
301 Status
= gBS
->HandleProtocol (Handle
, &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePathProtocol
);
302 if (EFI_ERROR(Status
)) {
306 // Convert the last non end-type Device Path Node in text for the description
307 DevicePathNode
= GetLastDevicePathNode (DevicePathProtocol
);
308 Status
= gBS
->LocateProtocol (&gEfiDevicePathToTextProtocolGuid
, NULL
, (VOID
**)&DevicePathToTextProtocol
);
309 ASSERT_EFI_ERROR(Status
);
310 DevicePathTxt
= DevicePathToTextProtocol
->ConvertDevicePathToText(DevicePathNode
,TRUE
,TRUE
);
311 StrnCpy (Description
, DevicePathTxt
, BOOT_DEVICE_DESCRIPTION_MAX
);
312 FreePool (DevicePathTxt
);
320 IN CHAR16
* BootOption
324 EFI_LOAD_OPTION EfiLoadOption
;
325 UINTN EfiLoadOptionSize
;
326 BDS_LOAD_OPTION
*BdsLoadOption
;
328 Status
= GetEnvironmentVariable (BootOption
, NULL
, &EfiLoadOptionSize
, (VOID
**)&EfiLoadOption
);
329 if (!EFI_ERROR(Status
)) {
330 Status
= BootOptionParseLoadOption (EfiLoadOption
, EfiLoadOptionSize
, &BdsLoadOption
);
331 if (!EFI_ERROR(Status
)) {
332 Status
= BootOptionStart (BdsLoadOption
);
333 FreePool (BdsLoadOption
);
336 if (!EFI_ERROR(Status
)) {
337 Status
= EFI_SUCCESS
;
339 Status
= EFI_NOT_STARTED
;
342 Status
= EFI_NOT_FOUND
;
348 GetUnalignedDevicePathSize (
349 IN EFI_DEVICE_PATH
* DevicePath
353 EFI_DEVICE_PATH
* AlignedDevicePath
;
355 if ((UINTN
)DevicePath
& 0x1) {
356 AlignedDevicePath
= DuplicateDevicePath (DevicePath
);
357 Size
= GetDevicePathSize (AlignedDevicePath
);
358 FreePool (AlignedDevicePath
);
360 Size
= GetDevicePathSize (DevicePath
);
366 GetAlignedDevicePath (
367 IN EFI_DEVICE_PATH
* DevicePath
370 if ((UINTN
)DevicePath
& 0x1) {
371 return DuplicateDevicePath (DevicePath
);