]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
ArmPlatformPkg/ArmVirtualizationPkg: Added support for Intel BDS
[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 // BDS Platform Functions
36 //
37 /**
38 Platform Bds init. Include the platform firmware vendor, revision
39 and so crc check.
40
41 **/
42 VOID
43 EFIAPI
44 PlatformBdsInit (
45 VOID
46 )
47 {
48 }
49
50 STATIC
51 EFI_STATUS
52 GetConsoleDevicePathFromVariable (
53 IN CHAR16* ConsoleVarName,
54 IN CHAR16* DefaultConsolePaths,
55 OUT EFI_DEVICE_PATH** DevicePaths
56 )
57 {
58 EFI_STATUS Status;
59 UINTN Size;
60 EFI_DEVICE_PATH_PROTOCOL* DevicePathInstances;
61 EFI_DEVICE_PATH_PROTOCOL* DevicePathInstance;
62 CHAR16* DevicePathStr;
63 CHAR16* NextDevicePathStr;
64 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
65
66 Status = GetGlobalEnvironmentVariable (ConsoleVarName, NULL, NULL, (VOID**)&DevicePathInstances);
67 if (EFI_ERROR(Status)) {
68 // In case no default console device path has been defined we assume a driver handles the console (eg: SimpleTextInOutSerial)
69 if ((DefaultConsolePaths == NULL) || (DefaultConsolePaths[0] == L'\0')) {
70 *DevicePaths = NULL;
71 return EFI_SUCCESS;
72 }
73
74 Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
75 ASSERT_EFI_ERROR(Status);
76
77 DevicePathInstances = NULL;
78
79 // Extract the Device Path instances from the multi-device path string
80 while ((DefaultConsolePaths != NULL) && (DefaultConsolePaths[0] != L'\0')) {
81 NextDevicePathStr = StrStr (DefaultConsolePaths, L";");
82 if (NextDevicePathStr == NULL) {
83 DevicePathStr = DefaultConsolePaths;
84 DefaultConsolePaths = NULL;
85 } else {
86 DevicePathStr = (CHAR16*)AllocateCopyPool ((NextDevicePathStr - DefaultConsolePaths + 1) * sizeof(CHAR16), DefaultConsolePaths);
87 *(DevicePathStr + (NextDevicePathStr - DefaultConsolePaths)) = L'\0';
88 DefaultConsolePaths = NextDevicePathStr;
89 if (DefaultConsolePaths[0] == L';') {
90 DefaultConsolePaths++;
91 }
92 }
93
94 DevicePathInstance = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathStr);
95 ASSERT(DevicePathInstance != NULL);
96 DevicePathInstances = AppendDevicePathInstance (DevicePathInstances, DevicePathInstance);
97
98 if (NextDevicePathStr != NULL) {
99 FreePool (DevicePathStr);
100 }
101 FreePool (DevicePathInstance);
102 }
103
104 // Set the environment variable with this device path multi-instances
105 Size = GetDevicePathSize (DevicePathInstances);
106 if (Size > 0) {
107 gRT->SetVariable (
108 ConsoleVarName,
109 &gEfiGlobalVariableGuid,
110 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
111 Size,
112 DevicePathInstances
113 );
114 } else {
115 Status = EFI_INVALID_PARAMETER;
116 }
117 }
118
119 if (!EFI_ERROR(Status)) {
120 *DevicePaths = DevicePathInstances;
121 }
122 return Status;
123 }
124
125 STATIC
126 EFI_STATUS
127 InitializeConsolePipe (
128 IN EFI_DEVICE_PATH *ConsoleDevicePaths,
129 IN EFI_GUID *Protocol,
130 OUT EFI_HANDLE *Handle,
131 OUT VOID* *Interface
132 )
133 {
134 EFI_STATUS Status;
135 UINTN Size;
136 UINTN NoHandles;
137 EFI_HANDLE *Buffer;
138 EFI_DEVICE_PATH_PROTOCOL* DevicePath;
139
140 // Connect all the Device Path Consoles
141 while (ConsoleDevicePaths != NULL) {
142 DevicePath = GetNextDevicePathInstance (&ConsoleDevicePaths, &Size);
143
144 Status = BdsConnectDevicePath (DevicePath, Handle, NULL);
145 DEBUG_CODE_BEGIN();
146 if (EFI_ERROR(Status)) {
147 // We convert back to the text representation of the device Path
148 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
149 CHAR16* DevicePathTxt;
150 EFI_STATUS Status;
151
152 Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
153 if (!EFI_ERROR(Status)) {
154 DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePath, TRUE, TRUE);
155
156 DEBUG((EFI_D_ERROR,"Fail to start the console with the Device Path '%s'. (Error '%r')\n", DevicePathTxt, Status));
157
158 FreePool (DevicePathTxt);
159 }
160 }
161 DEBUG_CODE_END();
162
163 // If the console splitter driver is not supported by the platform then use the first Device Path
164 // instance for the console interface.
165 if (!EFI_ERROR(Status) && (*Interface == NULL)) {
166 Status = gBS->HandleProtocol (*Handle, Protocol, Interface);
167 }
168 }
169
170 // No Device Path has been defined for this console interface. We take the first protocol implementation
171 if (*Interface == NULL) {
172 Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer);
173 if (EFI_ERROR (Status)) {
174 BdsConnectAllDrivers ();
175 Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer);
176 }
177
178 if (!EFI_ERROR(Status)) {
179 *Handle = Buffer[0];
180 Status = gBS->HandleProtocol (*Handle, Protocol, Interface);
181 ASSERT_EFI_ERROR (Status);
182 }
183 FreePool (Buffer);
184 } else {
185 Status = EFI_SUCCESS;
186 }
187
188 return Status;
189 }
190
191 /**
192 Connect the predefined platform default console device. Always try to find
193 and enable the vga device if have.
194
195 @param PlatformConsole Predefined platform default console device array.
196
197 @retval EFI_SUCCESS Success connect at least one ConIn and ConOut
198 device, there must have one ConOut device is
199 active vga device.
200 @return Return the status of BdsLibConnectAllDefaultConsoles ()
201
202 **/
203 EFI_STATUS
204 PlatformBdsConnectConsole (
205 VOID
206 )
207 {
208 EFI_STATUS Status;
209 EFI_DEVICE_PATH* ConOutDevicePaths;
210 EFI_DEVICE_PATH* ConInDevicePaths;
211 EFI_DEVICE_PATH* ConErrDevicePaths;
212
213 // By getting the Console Device Paths from the environment variables before initializing the console pipe, we
214 // create the 3 environment variables (ConIn, ConOut, ConErr) that allows to initialize all the console interface
215 // of newly installed console drivers
216 Status = GetConsoleDevicePathFromVariable (L"ConOut", (CHAR16*)PcdGetPtr(PcdDefaultConOutPaths), &ConOutDevicePaths);
217 ASSERT_EFI_ERROR (Status);
218 Status = GetConsoleDevicePathFromVariable (L"ConIn", (CHAR16*)PcdGetPtr(PcdDefaultConInPaths), &ConInDevicePaths);
219 ASSERT_EFI_ERROR (Status);
220 Status = GetConsoleDevicePathFromVariable (L"ErrOut", (CHAR16*)PcdGetPtr(PcdDefaultConOutPaths), &ConErrDevicePaths);
221 ASSERT_EFI_ERROR (Status);
222
223 // Initialize the Consoles
224 Status = InitializeConsolePipe (ConOutDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **)&gST->ConOut);
225 ASSERT_EFI_ERROR (Status);
226 Status = InitializeConsolePipe (ConInDevicePaths, &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **)&gST->ConIn);
227 ASSERT_EFI_ERROR (Status);
228 Status = InitializeConsolePipe (ConErrDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **)&gST->StdErr);
229 if (EFI_ERROR(Status)) {
230 // In case of error, we reuse the console output for the error output
231 gST->StandardErrorHandle = gST->ConsoleOutHandle;
232 gST->StdErr = gST->ConOut;
233 }
234
235 return Status;
236 }
237
238 /**
239 Connect with predefined platform connect sequence,
240 the OEM/IBV can customize with their own connect sequence.
241 **/
242 VOID
243 PlatformBdsConnectSequence (
244 VOID
245 )
246 {
247 }
248
249 /**
250 Load the predefined driver option, OEM/IBV can customize this
251 to load their own drivers
252
253 @param BdsDriverLists - The header of the driver option link list.
254
255 **/
256 VOID
257 PlatformBdsGetDriverOption (
258 IN OUT LIST_ENTRY *BdsDriverLists
259 )
260 {
261 }
262
263 /**
264 Perform the platform diagnostic, such like test memory. OEM/IBV also
265 can customize this function to support specific platform diagnostic.
266
267 @param MemoryTestLevel The memory test intensive level
268 @param QuietBoot Indicate if need to enable the quiet boot
269 @param BaseMemoryTest A pointer to BdsMemoryTest()
270
271 **/
272 VOID
273 PlatformBdsDiagnostics (
274 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,
275 IN BOOLEAN QuietBoot,
276 IN BASEM_MEMORY_TEST BaseMemoryTest
277 )
278 {
279 }
280
281 /**
282 The function will execute with as the platform policy, current policy
283 is driven by boot mode. IBV/OEM can customize this code for their specific
284 policy action.
285
286 @param DriverOptionList The header of the driver option link list
287 @param BootOptionList The header of the boot option link list
288 @param ProcessCapsules A pointer to ProcessCapsules()
289 @param BaseMemoryTest A pointer to BaseMemoryTest()
290
291 **/
292 VOID
293 EFIAPI
294 PlatformBdsPolicyBehavior (
295 IN LIST_ENTRY *DriverOptionList,
296 IN LIST_ENTRY *BootOptionList,
297 IN PROCESS_CAPSULES ProcessCapsules,
298 IN BASEM_MEMORY_TEST BaseMemoryTest
299 )
300 {
301 EFI_STATUS Status;
302
303 Status = PlatformBdsConnectConsole ();
304 ASSERT_EFI_ERROR (Status);
305 }
306
307 /**
308 Hook point after a boot attempt succeeds. We don't expect a boot option to
309 return, so the UEFI 2.0 specification defines that you will default to an
310 interactive mode and stop processing the BootOrder list in this case. This
311 is also a platform implementation and can be customized by IBV/OEM.
312
313 @param Option Pointer to Boot Option that succeeded to boot.
314
315 **/
316 VOID
317 EFIAPI
318 PlatformBdsBootSuccess (
319 IN BDS_COMMON_OPTION *Option
320 )
321 {
322 }
323
324 /**
325 Hook point after a boot attempt fails.
326
327 @param Option Pointer to Boot Option that failed to boot.
328 @param Status Status returned from failed boot.
329 @param ExitData Exit data returned from failed boot.
330 @param ExitDataSize Exit data size returned from failed boot.
331
332 **/
333 VOID
334 EFIAPI
335 PlatformBdsBootFail (
336 IN BDS_COMMON_OPTION *Option,
337 IN EFI_STATUS Status,
338 IN CHAR16 *ExitData,
339 IN UINTN ExitDataSize
340 )
341 {
342 }
343
344 /**
345 This function locks platform flash that is not allowed to be updated during normal boot path.
346 The flash layout is platform specific.
347 **/
348 VOID
349 EFIAPI
350 PlatformBdsLockNonUpdatableFlash (
351 VOID
352 )
353 {
354 return;
355 }
356
357
358 /**
359 Lock the ConsoleIn device in system table. All key
360 presses will be ignored until the Password is typed in. The only way to
361 disable the password is to type it in to a ConIn device.
362
363 @param Password Password used to lock ConIn device.
364
365 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
366 @retval EFI_UNSUPPORTED Password not found
367
368 **/
369 EFI_STATUS
370 EFIAPI
371 LockKeyboards (
372 IN CHAR16 *Password
373 )
374 {
375 return EFI_UNSUPPORTED;
376 }