Home | History | Annotate | Download | only in PlatformIntelBdsLib
      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   // Connect _all_ devices, to pick up plug-in and removable devices
    358   // TODO: do this more cleanly, permitting faster boot times when boot config
    359   //       is known
    360   //
    361   BdsLibConnectAll ();
    362 }
    363 
    364 /**
    365   Hook point after a boot attempt succeeds. We don't expect a boot option to
    366   return, so the UEFI 2.0 specification defines that you will default to an
    367   interactive mode and stop processing the BootOrder list in this case. This
    368   is also a platform implementation and can be customized by IBV/OEM.
    369 
    370   @param  Option                  Pointer to Boot Option that succeeded to boot.
    371 
    372 **/
    373 VOID
    374 EFIAPI
    375 PlatformBdsBootSuccess (
    376   IN  BDS_COMMON_OPTION *Option
    377   )
    378 {
    379 }
    380 
    381 /**
    382   Hook point after a boot attempt fails.
    383 
    384   @param  Option                  Pointer to Boot Option that failed to boot.
    385   @param  Status                  Status returned from failed boot.
    386   @param  ExitData                Exit data returned from failed boot.
    387   @param  ExitDataSize            Exit data size returned from failed boot.
    388 
    389 **/
    390 VOID
    391 EFIAPI
    392 PlatformBdsBootFail (
    393   IN  BDS_COMMON_OPTION  *Option,
    394   IN  EFI_STATUS         Status,
    395   IN  CHAR16             *ExitData,
    396   IN  UINTN              ExitDataSize
    397   )
    398 {
    399 }
    400 
    401 /**
    402   This function locks platform flash that is not allowed to be updated during normal boot path.
    403   The flash layout is platform specific.
    404 **/
    405 VOID
    406 EFIAPI
    407 PlatformBdsLockNonUpdatableFlash (
    408   VOID
    409   )
    410 {
    411   return;
    412 }
    413 
    414 
    415 /**
    416   Lock the ConsoleIn device in system table. All key
    417   presses will be ignored until the Password is typed in. The only way to
    418   disable the password is to type it in to a ConIn device.
    419 
    420   @param  Password        Password used to lock ConIn device.
    421 
    422   @retval EFI_SUCCESS     lock the Console In Spliter virtual handle successfully.
    423   @retval EFI_UNSUPPORTED Password not found
    424 
    425 **/
    426 EFI_STATUS
    427 EFIAPI
    428 LockKeyboards (
    429   IN  CHAR16    *Password
    430   )
    431 {
    432     return EFI_UNSUPPORTED;
    433 }
    434