]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
e27e6d66df9159d80969c2c234f41a6fb8e9c143
[mirror_edk2.git] / ArmPlatformPkg / Library / PlatformIntelBdsLib / IntelBdsPlatform.c
1 /** @file
2
3 Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
4 Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
5
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "IntelBdsPlatform.h"
17
18 ///
19 /// Predefined platform default time out value
20 ///
21 UINT16 gPlatformBootTimeOutDefault;
22
23 EFI_STATUS
24 EFIAPI
25 PlatformIntelBdsConstructor (
26 IN EFI_HANDLE ImageHandle,
27 IN EFI_SYSTEM_TABLE *SystemTable
28 )
29 {
30 gPlatformBootTimeOutDefault = (UINT16)PcdGet16 (PcdPlatformBootTimeOut);
31 return EFI_SUCCESS;
32 }
33
34 /**
35 An empty function to pass error checking of CreateEventEx ().
36
37 @param Event Event whose notification function is being invoked.
38 @param Context Pointer to the notification function's context,
39 which is implementation-dependent.
40
41 **/
42 STATIC
43 VOID
44 EFIAPI
45 EmptyCallbackFunction (
46 IN EFI_EVENT Event,
47 IN VOID *Context
48 )
49 {
50 }
51
52 //
53 // BDS Platform Functions
54 //
55 /**
56 Platform Bds init. Include the platform firmware vendor, revision
57 and so crc check.
58
59 **/
60 VOID
61 EFIAPI
62 PlatformBdsInit (
63 VOID
64 )
65 {
66 EFI_EVENT EndOfDxeEvent;
67 EFI_STATUS Status;
68
69 //
70 // Signal EndOfDxe PI Event
71 //
72 Status = gBS->CreateEventEx (
73 EVT_NOTIFY_SIGNAL,
74 TPL_CALLBACK,
75 EmptyCallbackFunction,
76 NULL,
77 &gEfiEndOfDxeEventGroupGuid,
78 &EndOfDxeEvent
79 );
80 if (!EFI_ERROR (Status)) {
81 gBS->SignalEvent (EndOfDxeEvent);
82 gBS->CloseEvent (EndOfDxeEvent);
83 }
84 }
85
86 STATIC
87 EFI_STATUS
88 GetConsoleDevicePathFromVariable (
89 IN CHAR16* ConsoleVarName,
90 IN CHAR16* DefaultConsolePaths,
91 OUT EFI_DEVICE_PATH** DevicePaths
92 )
93 {
94 EFI_STATUS Status;
95 UINTN Size;
96 EFI_DEVICE_PATH_PROTOCOL* DevicePathInstances;
97 EFI_DEVICE_PATH_PROTOCOL* DevicePathInstance;
98 CHAR16* DevicePathStr;
99 CHAR16* NextDevicePathStr;
100 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
101
102 Status = EFI_SUCCESS;
103 Size = 0;
104
105 DevicePathInstances = BdsLibGetVariableAndSize (ConsoleVarName, &gEfiGlobalVariableGuid, &Size);
106 if (DevicePathInstances == NULL) {
107 // In case no default console device path has been defined we assume a driver handles the console (eg: SimpleTextInOutSerial)
108 if ((DefaultConsolePaths == NULL) || (DefaultConsolePaths[0] == L'\0')) {
109 *DevicePaths = NULL;
110 return EFI_SUCCESS;
111 }
112
113 Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
114 ASSERT_EFI_ERROR(Status);
115
116 // Extract the Device Path instances from the multi-device path string
117 while ((DefaultConsolePaths != NULL) && (DefaultConsolePaths[0] != L'\0')) {
118 NextDevicePathStr = StrStr (DefaultConsolePaths, L";");
119 if (NextDevicePathStr == NULL) {
120 DevicePathStr = DefaultConsolePaths;
121 DefaultConsolePaths = NULL;
122 } else {
123 DevicePathStr = (CHAR16*)AllocateCopyPool ((NextDevicePathStr - DefaultConsolePaths + 1) * sizeof(CHAR16), DefaultConsolePaths);
124 *(DevicePathStr + (NextDevicePathStr - DefaultConsolePaths)) = L'\0';
125 DefaultConsolePaths = NextDevicePathStr;
126 if (DefaultConsolePaths[0] == L';') {
127 DefaultConsolePaths++;
128 }
129 }
130
131 DevicePathInstance = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathStr);
132 ASSERT(DevicePathInstance != NULL);
133 DevicePathInstances = AppendDevicePathInstance (DevicePathInstances, DevicePathInstance);
134
135 if (NextDevicePathStr != NULL) {
136 FreePool (DevicePathStr);
137 }
138 FreePool (DevicePathInstance);
139 }
140
141 // Set the environment variable with this device path multi-instances
142 Size = GetDevicePathSize (DevicePathInstances);
143 if (Size > 0) {
144 gRT->SetVariable (
145 ConsoleVarName,
146 &gEfiGlobalVariableGuid,
147 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
148 Size,
149 DevicePathInstances
150 );
151 } else {
152 Status = EFI_INVALID_PARAMETER;
153 }
154 }
155
156 if (!EFI_ERROR(Status)) {
157 *DevicePaths = DevicePathInstances;
158 }
159 return Status;
160 }
161
162 STATIC
163 EFI_STATUS
164 InitializeConsolePipe (
165 IN EFI_DEVICE_PATH *ConsoleDevicePaths,
166 IN EFI_GUID *Protocol,
167 OUT EFI_HANDLE *Handle,
168 OUT VOID* *Interface
169 )
170 {
171 EFI_STATUS Status;
172 UINTN Size;
173 UINTN NoHandles;
174 EFI_HANDLE *Buffer;
175 EFI_DEVICE_PATH_PROTOCOL* DevicePath;
176
177 // Connect all the Device Path Consoles
178 while (ConsoleDevicePaths != NULL) {
179 DevicePath = GetNextDevicePathInstance (&ConsoleDevicePaths, &Size);
180
181 Status = BdsLibConnectDevicePath (DevicePath);
182 if (!EFI_ERROR (Status)) {
183 //
184 // If BdsLibConnectDevicePath () succeeded, *Handle must have a non-NULL
185 // value. So ASSERT that this is the case.
186 //
187 gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, Handle);
188 ASSERT (*Handle != NULL);
189 }
190 DEBUG_CODE_BEGIN();
191 if (EFI_ERROR(Status)) {
192 // We convert back to the text representation of the device Path
193 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathToTextProtocol;
194 CHAR16 *DevicePathTxt;
195
196 DevicePathToTextProtocol = NULL;
197 gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **) &DevicePathToTextProtocol);
198 if (DevicePathToTextProtocol != NULL) {
199 DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePath, TRUE, TRUE);
200
201 DEBUG((EFI_D_ERROR,"Fail to start the console with the Device Path '%s'. (Error '%r')\n", DevicePathTxt, Status));
202
203 FreePool (DevicePathTxt);
204 }
205 }
206 DEBUG_CODE_END();
207
208 // If the console splitter driver is not supported by the platform then use the first Device Path
209 // instance for the console interface.
210 if (!EFI_ERROR(Status) && (*Interface == NULL)) {
211 Status = gBS->HandleProtocol (*Handle, Protocol, Interface);
212 }
213 }
214
215 // No Device Path has been defined for this console interface. We take the first protocol implementation
216 if (*Interface == NULL) {
217 Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer);
218 if (EFI_ERROR (Status)) {
219 BdsLibConnectAll ();
220 Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer);
221 }
222
223 if (!EFI_ERROR(Status)) {
224 *Handle = Buffer[0];
225 Status = gBS->HandleProtocol (*Handle, Protocol, Interface);
226 ASSERT_EFI_ERROR (Status);
227 FreePool (Buffer);
228 }
229 } else {
230 Status = EFI_SUCCESS;
231 }
232
233 return Status;
234 }
235
236 /**
237 Connect the predefined platform default console device. Always try to find
238 and enable the vga device if have.
239
240 @param PlatformConsole Predefined platform default console device array.
241
242 @retval EFI_SUCCESS Success connect at least one ConIn and ConOut
243 device, there must have one ConOut device is
244 active vga device.
245 @return Return the status of BdsLibConnectAllDefaultConsoles ()
246
247 **/
248 EFI_STATUS
249 PlatformBdsConnectConsole (
250 VOID
251 )
252 {
253 EFI_STATUS Status;
254 EFI_DEVICE_PATH* ConOutDevicePaths;
255 EFI_DEVICE_PATH* ConInDevicePaths;
256 EFI_DEVICE_PATH* ConErrDevicePaths;
257
258 // By getting the Console Device Paths from the environment variables before initializing the console pipe, we
259 // create the 3 environment variables (ConIn, ConOut, ConErr) that allows to initialize all the console interface
260 // of newly installed console drivers
261 Status = GetConsoleDevicePathFromVariable (L"ConOut", (CHAR16*)PcdGetPtr(PcdDefaultConOutPaths), &ConOutDevicePaths);
262 ASSERT_EFI_ERROR (Status);
263 Status = GetConsoleDevicePathFromVariable (L"ConIn", (CHAR16*)PcdGetPtr(PcdDefaultConInPaths), &ConInDevicePaths);
264 ASSERT_EFI_ERROR (Status);
265 Status = GetConsoleDevicePathFromVariable (L"ErrOut", (CHAR16*)PcdGetPtr(PcdDefaultConOutPaths), &ConErrDevicePaths);
266 ASSERT_EFI_ERROR (Status);
267
268 // Initialize the Consoles
269 Status = InitializeConsolePipe (ConOutDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **)&gST->ConOut);
270 ASSERT_EFI_ERROR (Status);
271 Status = InitializeConsolePipe (ConInDevicePaths, &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **)&gST->ConIn);
272 ASSERT_EFI_ERROR (Status);
273 Status = InitializeConsolePipe (ConErrDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **)&gST->StdErr);
274 if (EFI_ERROR(Status)) {
275 // In case of error, we reuse the console output for the error output
276 gST->StandardErrorHandle = gST->ConsoleOutHandle;
277 gST->StdErr = gST->ConOut;
278 }
279
280 return Status;
281 }
282
283 /**
284 Connect with predefined platform connect sequence,
285 the OEM/IBV can customize with their own connect sequence.
286 **/
287 VOID
288 PlatformBdsConnectSequence (
289 VOID
290 )
291 {
292 }
293
294 /**
295 Load the predefined driver option, OEM/IBV can customize this
296 to load their own drivers
297
298 @param BdsDriverLists - The header of the driver option link list.
299
300 **/
301 VOID
302 PlatformBdsGetDriverOption (
303 IN OUT LIST_ENTRY *BdsDriverLists
304 )
305 {
306 }
307
308 /**
309 Perform the platform diagnostic, such like test memory. OEM/IBV also
310 can customize this function to support specific platform diagnostic.
311
312 @param MemoryTestLevel The memory test intensive level
313 @param QuietBoot Indicate if need to enable the quiet boot
314 @param BaseMemoryTest A pointer to BdsMemoryTest()
315
316 **/
317 VOID
318 PlatformBdsDiagnostics (
319 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,
320 IN BOOLEAN QuietBoot,
321 IN BASEM_MEMORY_TEST BaseMemoryTest
322 )
323 {
324 }
325
326 /**
327 The function will execute with as the platform policy, current policy
328 is driven by boot mode. IBV/OEM can customize this code for their specific
329 policy action.
330
331 @param DriverOptionList The header of the driver option link list
332 @param BootOptionList The header of the boot option link list
333 @param ProcessCapsules A pointer to ProcessCapsules()
334 @param BaseMemoryTest A pointer to BaseMemoryTest()
335
336 **/
337 VOID
338 EFIAPI
339 PlatformBdsPolicyBehavior (
340 IN LIST_ENTRY *DriverOptionList,
341 IN LIST_ENTRY *BootOptionList,
342 IN PROCESS_CAPSULES ProcessCapsules,
343 IN BASEM_MEMORY_TEST BaseMemoryTest
344 )
345 {
346 EFI_STATUS Status;
347
348 Status = PlatformBdsConnectConsole ();
349 ASSERT_EFI_ERROR (Status);
350
351 //
352 // Show the splash screen.
353 //
354 EnableQuietBoot (PcdGetPtr (PcdLogoFile));
355 }
356
357 /**
358 Hook point after a boot attempt succeeds. We don't expect a boot option to
359 return, so the UEFI 2.0 specification defines that you will default to an
360 interactive mode and stop processing the BootOrder list in this case. This
361 is also a platform implementation and can be customized by IBV/OEM.
362
363 @param Option Pointer to Boot Option that succeeded to boot.
364
365 **/
366 VOID
367 EFIAPI
368 PlatformBdsBootSuccess (
369 IN BDS_COMMON_OPTION *Option
370 )
371 {
372 }
373
374 /**
375 Hook point after a boot attempt fails.
376
377 @param Option Pointer to Boot Option that failed to boot.
378 @param Status Status returned from failed boot.
379 @param ExitData Exit data returned from failed boot.
380 @param ExitDataSize Exit data size returned from failed boot.
381
382 **/
383 VOID
384 EFIAPI
385 PlatformBdsBootFail (
386 IN BDS_COMMON_OPTION *Option,
387 IN EFI_STATUS Status,
388 IN CHAR16 *ExitData,
389 IN UINTN ExitDataSize
390 )
391 {
392 }
393
394 /**
395 This function locks platform flash that is not allowed to be updated during normal boot path.
396 The flash layout is platform specific.
397 **/
398 VOID
399 EFIAPI
400 PlatformBdsLockNonUpdatableFlash (
401 VOID
402 )
403 {
404 return;
405 }
406
407
408 /**
409 Lock the ConsoleIn device in system table. All key
410 presses will be ignored until the Password is typed in. The only way to
411 disable the password is to type it in to a ConIn device.
412
413 @param Password Password used to lock ConIn device.
414
415 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
416 @retval EFI_UNSUPPORTED Password not found
417
418 **/
419 EFI_STATUS
420 EFIAPI
421 LockKeyboards (
422 IN CHAR16 *Password
423 )
424 {
425 return EFI_UNSUPPORTED;
426 }