Beispiel #1
0
/**
  Measure CRTM version.

  @param[in]      PeiServices   Describes the list of possible PEI Services.

  @retval EFI_SUCCESS           Operation completed successfully.
  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.
  @retval EFI_DEVICE_ERROR      The command was unsuccessful.

**/
EFI_STATUS
EFIAPI
MeasureCRTMVersion (
  IN      EFI_PEI_SERVICES          **PeiServices
  )
{
  TCG_PCR_EVENT_HDR                 TcgEventHdr;

  //
  // Use FirmwareVersion string to represent CRTM version.
  // OEMs should get real CRTM version string and measure it.
  //

  TcgEventHdr.PCRIndex  = 0;
  TcgEventHdr.EventType = EV_S_CRTM_VERSION;
  TcgEventHdr.EventSize = (UINT32) StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString));

  return HashLogExtendEvent (
           PeiServices,
           (UINT8*)PcdGetPtr (PcdFirmwareVersionString),
           TcgEventHdr.EventSize,
           &TcgEventHdr,
           (UINT8*)PcdGetPtr (PcdFirmwareVersionString)
           );
}
/**
  Initialize Unicode Collation support.

  It tries to locate Unicode Collation 2 protocol and matches it with current
  platform language code. If for any reason the first attempt fails, it then tries to
  use Unicode Collation Protocol.

  @param  AgentHandle          The handle used to open Unicode Collation (2) protocol.

  @retval EFI_SUCCESS          The Unicode Collation (2) protocol has been successfully located.
  @retval Others               The Unicode Collation (2) protocol has not been located.

**/
EFI_STATUS
InitializeUnicodeCollationSupport (
  IN EFI_HANDLE    AgentHandle
  )
{

  EFI_STATUS       Status;

  Status = EFI_UNSUPPORTED;

  //
  // First try to use RFC 4646 Unicode Collation 2 Protocol.
  //
  Status = InitializeUnicodeCollationSupportWorker (
             AgentHandle,
             &gEfiUnicodeCollation2ProtocolGuid,
             L"PlatformLang",
             (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang)
             );
  //
  // If the attempt to use Unicode Collation 2 Protocol fails, then we fall back
  // on the ISO 639-2 Unicode Collation Protocol.
  //
  if (EFI_ERROR (Status)) {
    Status = InitializeUnicodeCollationSupportWorker (
               AgentHandle,
               &gEfiUnicodeCollationProtocolGuid,
               L"Lang",
               (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang)
               );
  }

  return Status;
}
/**
  This function provides early platform initialization.

  @param  PlatformInfo  Pointer to platform Info structure.

**/
VOID
EFIAPI
EarlyPlatformInit (
  VOID
  )
{

  DEBUG ((EFI_D_INFO, "EarlyBoardInit for PlatType=0x%02x\n", PcdGet16 (PcdPlatformType)));

  //
  // Check if system reset due to error condition.
  //
  if (CheckForResetDueToErrors (TRUE)) {
    if(FeaturePcdGet (WaitIfResetDueToError)) {
      DEBUG ((EFI_D_ERROR, "Press any key to continue.\n"));
      PlatformDebugPortGetChar8 ();
    }
  }

  //
  // Display platform info messages.
  //
  EarlyPlatformInfoMessages ();

  //
  // Early Legacy Gpio Init.
  //
  EarlyPlatformLegacyGpioInit (&mBoardLegacyGpioConfigTable);

  //
  // Early platform Legacy GPIO manipulation depending on GPIOs
  // setup by EarlyPlatformLegacyGpioInit.
  //
  EarlyPlatformLegacyGpioManipulation ();

  //
  // Early platform specific GPIO Controller init & manipulation.
  // Combined for sharing of temp. memory bar.
  //
  EarlyPlatformGpioCtrlerInit (&mBoardGpioControllerConfigTable);
  
  EarlyPlatformGpioCtrlerManipulation ();

  //
  // Early Thermal Sensor Init.
  //
  EarlyPlatformThermalSensorInit ();

  //
  // Early Lan Ethernet Mac Init.
  //
  EarlyPlatformMacInit (
    PcdGetPtr (PcdIohEthernetMac0),
    PcdGetPtr (PcdIohEthernetMac1)
    );
}
Beispiel #4
0
/**
  The constructor function.

  @retval EFI_SUCCESS   The constructor successfully .
**/
EFI_STATUS
EFIAPI
EdkiiSystemCapsuleLibConstructor (
  VOID
  )
{
  mImageFmpInfoSize = PcdGetSize(PcdEdkiiSystemFirmwareImageDescriptor);
  mImageFmpInfo = AllocateCopyPool (mImageFmpInfoSize, PcdGetPtr(PcdEdkiiSystemFirmwareImageDescriptor));
  ASSERT(mImageFmpInfo != NULL);
  CopyGuid(&mEdkiiSystemFirmwareFileGuid, PcdGetPtr(PcdEdkiiSystemFirmwareFileGuid));
  return EFI_SUCCESS;
}
Beispiel #5
0
/**
  Determine the current language that will be used
  based on language related EFI Variables.

  @param LangCodesSettingRequired - If required to set LangCodes variable

**/
VOID
InitializeLanguage (
  BOOLEAN LangCodesSettingRequired
  )
{
  EFI_STATUS  Status;
  CHAR8       *LangCodes;
  CHAR8       *PlatformLangCodes;

  ExportFonts ();

  LangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultLangCodes);
  PlatformLangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes);
  if (LangCodesSettingRequired) {
    if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
      //
      // UEFI 2.0 depricated this variable so we support turning it off
      //
      Status = gRT->SetVariable (
                      L"LangCodes",
                      &gEfiGlobalVariableGuid,
                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                      AsciiStrSize (LangCodes),
                      LangCodes
                      );
      //
      // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.
      //
      ASSERT_EFI_ERROR (Status);
    }

    Status = gRT->SetVariable (
                    L"PlatformLangCodes",
                    &gEfiGlobalVariableGuid,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                    AsciiStrSize (PlatformLangCodes),
                    PlatformLangCodes
                    );
    //
    // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.
    //
    ASSERT_EFI_ERROR (Status);
  }

  if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
    //
    // UEFI 2.0 depricated this variable so we support turning it off
    //
    InitializeLangVariable (L"Lang", LangCodes, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang), TRUE);
  }
  InitializeLangVariable (L"PlatformLang", PlatformLangCodes, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang), FALSE);
}
/**
  Main entry for this driver.

  @param ImageHandle     Image handle this driver.
  @param SystemTable     Pointer to SystemTable.

  @retval EFI_SUCESS     This function always complete successfully.

**/
EFI_STATUS
EFIAPI
PlatfomrSmbiosDriverEntryPoint (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  EFI_STATUS                  Status;
  EFI_SMBIOS_HANDLE           SmbiosHandle;
  SMBIOS_STRUCTURE_POINTER    Smbios;

  // Phase 0 - Patch table to make SMBIOS 2.7 structures smaller to conform 
  //           to an early version of the specification.

  // Phase 1 - Initialize SMBIOS tables from template
  Status = SmbiosLibInitializeFromTemplate (gSmbiosTemplate);
  ASSERT_EFI_ERROR (Status);

  // Phase 2 - Patch SMBIOS table entries

  Smbios.Hdr = SmbiosLibGetRecord (EFI_SMBIOS_TYPE_BIOS_INFORMATION, 0, &SmbiosHandle);
  if (Smbios.Type0 != NULL) {
    // 64K * (n+1) bytes
    Smbios.Type0->BiosSize = (UINT8)DivU64x32 (FixedPcdGet64 (PcdEmuFirmwareFdSize), 64*1024) - 1;

    SmbiosLibUpdateUnicodeString (
      SmbiosHandle, 
      Smbios.Type0->BiosVersion, 
      (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString)
      );
    SmbiosLibUpdateUnicodeString (
      SmbiosHandle, 
      Smbios.Type0->BiosReleaseDate, 
      (CHAR16 *) PcdGetPtr (PcdFirmwareReleaseDateString)
      );
  }

  // Phase 3 - Create tables from scratch 

  // Create Type 13 record from EFI Variables
  // Do we need this record for EFI as the info is availible from EFI varaibles
  // Also language types don't always match between EFI and SMBIOS
  // CreateSmbiosLanguageInformation (1, gSmbiosLangToEfiLang);

  CreatePlatformSmbiosMemoryRecords ();

  return EFI_SUCCESS;
}
/**
  This service register TPM2 device.

  @param Tpm2Device  TPM2 device

  @retval EFI_SUCCESS          This TPM2 device is registered successfully.
  @retval EFI_UNSUPPORTED      System does not support register this TPM2 device.
  @retval EFI_ALREADY_STARTED  System already register this TPM2 device.
**/
EFI_STATUS
EFIAPI
Tpm2RegisterTpm2DeviceLib (
  IN TPM2_DEVICE_INTERFACE   *Tpm2Device
  )
{
  TPM2_DEVICE_INTERFACE *Tpm2DeviceInterface;

  if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &Tpm2Device->ProviderGuid)){
    DEBUG ((EFI_D_ERROR, "WARNING: Tpm2RegisterTpm2DeviceLib - does not support %g registration\n", &Tpm2Device->ProviderGuid));
    return EFI_UNSUPPORTED;
  }

  Tpm2DeviceInterface = InternalGetTpm2DeviceInterface ();
  if (Tpm2DeviceInterface != NULL) {
    //
    // In PEI phase, there will be shadow driver dispatched again.
    //
    DEBUG ((EFI_D_INFO, "Tpm2RegisterTpm2DeviceLib - Override\n"));
    CopyMem (Tpm2DeviceInterface, Tpm2Device, sizeof(*Tpm2Device));
    return EFI_SUCCESS;
  } else {
    Tpm2Device = BuildGuidDataHob (&mInternalTpm2DeviceInterfaceGuid, Tpm2Device, sizeof(*Tpm2Device));
    if (Tpm2Device != NULL) {
      return EFI_SUCCESS;
    } else {
      return EFI_OUT_OF_RESOURCES;
    }
  }
}
Beispiel #8
0
/**
  The user Entry Point for Application. The user code starts with this function
  as the real entry point for the application.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  
  @param[in] SystemTable    A pointer to the EFI System Table.
  
  @retval EFI_SUCCESS       The entry point is executed successfully.
  @retval other             Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
UefiMain (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
	UINT32 Index;
	
	Index = 0;
  
  //
  // Three PCD type (FeatureFlag, UINT32 and String) are used as the sample.
  //
  if (FeaturePcdGet (PcdHelloWorldPrintEnable)) {
  	for (Index = 0; Index < PcdGet32 (PcdHelloWorldPrintTimes); Index ++) {
  	  //
  	  // Use UefiLib Print API to print string to UEFI console
  	  //
    	Print ((CHAR16*)PcdGetPtr (PcdHelloWorldPrintString));
    }
  }

  return EFI_SUCCESS;
}
/**
  This is the standard EFI driver point that detects whether there is a
  MemoryConfigurationData Variable and, if so, reports memory configuration info
  to the DataHub.

  @param  ImageHandle  Handle for the image of this driver
  @param  SystemTable  Pointer to the EFI System Table

  @return EFI_SUCCESS if the data is successfully reported
  @return EFI_NOT_FOUND if the HOB list could not be located.

**/
EFI_STATUS
LogMemorySmbiosRecord (
  VOID
  )
{
  EFI_STATUS                      Status;
  UINT64                          TotalMemorySize;
  UINT8                           NumSlots;
  SMBIOS_TABLE_TYPE19             *Type19Record;
  EFI_SMBIOS_HANDLE               MemArrayMappedAddrSmbiosHandle;
  EFI_SMBIOS_PROTOCOL             *Smbios;
  CHAR16                          *MemString;

  Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
  ASSERT_EFI_ERROR (Status);

  NumSlots        = 1;

  //
  // Process Memory String in form size!size ...
  // So 64!64 is 128 MB
  //
  MemString   = (CHAR16 *)PcdGetPtr (PcdEmuMemorySize);
  for (TotalMemorySize = 0; *MemString != '\0';) {
    TotalMemorySize += StrDecimalToUint64 (MemString);
    while (*MemString != '\0') {
      if (*MemString == '!') {
        MemString++;
        break;
      }
      MemString++;
    }
  }

  //
  // Convert Total Memory Size to based on KiloByte
  //
  TotalMemorySize = LShiftU64 (TotalMemorySize, 20);
  //
  // Generate Memory Array Mapped Address info
  //
  Type19Record = AllocateZeroPool(sizeof (SMBIOS_TABLE_TYPE19) + 2);
  Type19Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS;
  Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19);
  Type19Record->Hdr.Handle = 0;
  Type19Record->StartingAddress = 0;
  Type19Record->EndingAddress =  (UINT32)RShiftU64(TotalMemorySize, 10) - 1;
  Type19Record->MemoryArrayHandle = 0;
  Type19Record->PartitionWidth = (UINT8)(NumSlots);

  //
  // Generate Memory Array Mapped Address info (TYPE 19)
  //
  Status = AddSmbiosRecord (Smbios, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type19Record);

  FreePool(Type19Record);
  ASSERT_EFI_ERROR (Status);

  return Status;
}
Beispiel #10
0
/**
  Perform the platform diagnostic, such like test memory. OEM/IBV also
  can customize this function to support specific platform diagnostic.

  @param MemoryTestLevel  The memory test intensive level
  @param QuietBoot        Indicate if need to enable the quiet boot
  @param BaseMemoryTest   A pointer to BdsMemoryTest()

**/
VOID
PlatformBdsDiagnostics (
  IN EXTENDMEM_COVERAGE_LEVEL    MemoryTestLevel,
  IN BOOLEAN                     QuietBoot,
  IN BASEM_MEMORY_TEST           BaseMemoryTest
  )
{
	EFI_STATUS                     Status;
  
  DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n"));
  //
  // Here we can decide if we need to show
  // the diagnostics screen
  // Notes: this quiet boot code should be remove
  // from the graphic lib
  //
  if (QuietBoot) {
    EnableQuietBoot (PcdGetPtr(PcdLogoFile));

    //
    // Perform system diagnostic
    //
    Status = BaseMemoryTest (MemoryTestLevel);
    if (EFI_ERROR (Status)) {
      DisableQuietBoot ();
    }

    return;
  }
  
  //
  // Perform system diagnostic
  //
  Status = BaseMemoryTest (MemoryTestLevel);
}
Beispiel #11
0
EFI_STATUS
InitializeConsole (
  VOID
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH*          ConOutDevicePaths;
  EFI_DEVICE_PATH*          ConInDevicePaths;
  EFI_DEVICE_PATH*          ConErrDevicePaths;

  // By getting the Console Device Paths from the environment variables before initializing the console pipe, we
  // create the 3 environment variables (ConIn, ConOut, ConErr) that allows to initialize all the console interface
  // of newly installed console drivers
  Status = GetConsoleDevicePathFromVariable (L"ConOut", (CHAR16*)PcdGetPtr(PcdDefaultConOutPaths), &ConOutDevicePaths);
  ASSERT_EFI_ERROR (Status);
  Status = GetConsoleDevicePathFromVariable (L"ConIn", (CHAR16*)PcdGetPtr(PcdDefaultConInPaths), &ConInDevicePaths);
  ASSERT_EFI_ERROR (Status);
  Status = GetConsoleDevicePathFromVariable (L"ErrOut", (CHAR16*)PcdGetPtr(PcdDefaultConOutPaths), &ConErrDevicePaths);
  ASSERT_EFI_ERROR (Status);

  // Initialize the Consoles
  Status = InitializeConsolePipe (ConOutDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **)&gST->ConOut);
  ASSERT_EFI_ERROR (Status);
  Status = InitializeConsolePipe (ConInDevicePaths, &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **)&gST->ConIn);
  ASSERT_EFI_ERROR (Status);
  Status = InitializeConsolePipe (ConErrDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **)&gST->StdErr);
  if (EFI_ERROR(Status)) {
    // In case of error, we reuse the console output for the error output
    gST->StandardErrorHandle = gST->ConsoleOutHandle;
    gST->StdErr = gST->ConOut;
  }

  // Free Memory allocated for reading the UEFI Variables
  if (ConOutDevicePaths) {
    FreePool (ConOutDevicePaths);
  }
  if (ConInDevicePaths) {
    FreePool (ConInDevicePaths);
  }
  if (ConErrDevicePaths) {
    FreePool (ConErrDevicePaths);
  }

  return EFI_SUCCESS;
}
Beispiel #12
0
/**
  The driver's entry point.

  It install callbacks for TPM physical presence and MemoryClear, and locate 
  SMM variable to be used in the callback function.

  @param[in] ImageHandle  The firmware allocated handle for the EFI image.  
  @param[in] SystemTable  A pointer to the EFI System Table.
  
  @retval EFI_SUCCESS     The entry point is executed successfully.
  @retval Others          Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
InitializeTcgSmm (
  IN EFI_HANDLE                  ImageHandle,
  IN EFI_SYSTEM_TABLE            *SystemTable
  )
{
  EFI_STATUS                     Status;
  EFI_SMM_SW_DISPATCH2_PROTOCOL  *SwDispatch;
  EFI_SMM_SW_REGISTER_CONTEXT    SwContext;
  EFI_HANDLE                     SwHandle;

  if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid)){
    DEBUG ((EFI_D_ERROR, "No TPM2 DTPM instance required!\n"));
    return EFI_UNSUPPORTED;
  }

  Status = PublishAcpiTable ();
  ASSERT_EFI_ERROR (Status);

  //
  // Get the Sw dispatch protocol and register SMI callback functions.
  //
  Status = gSmst->SmmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, NULL, (VOID**)&SwDispatch);
  ASSERT_EFI_ERROR (Status);
  SwContext.SwSmiInputValue = (UINTN) -1;
  Status = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, &SwContext, &SwHandle);
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  mTcgNvs->PhysicalPresence.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue;

  SwContext.SwSmiInputValue = (UINTN) -1;
  Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, &SwContext, &SwHandle);
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  mTcgNvs->MemoryClear.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue;
  
  //
  // Locate SmmVariableProtocol.
  //
  Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mSmmVariable);
  ASSERT_EFI_ERROR (Status);

  //
  // Set TPM2 ACPI table
  //
  Status = PublishTpm2 ();
  ASSERT_EFI_ERROR (Status);


  return EFI_SUCCESS;
}
Beispiel #13
0
/**
  Initialize and publish TPM items in ACPI table.

  @retval   EFI_SUCCESS     The TCG ACPI table is published successfully.
  @retval   Others          The TCG ACPI table is not published.

**/
EFI_STATUS
PublishAcpiTable (
  VOID
  )
{
  EFI_STATUS                     Status;
  EFI_ACPI_TABLE_PROTOCOL        *AcpiTable;
  UINTN                          TableKey;
  EFI_ACPI_DESCRIPTION_HEADER    *Table;
  UINTN                          TableSize;

  Status = GetSectionFromFv (
             &gEfiCallerIdGuid,
             EFI_SECTION_RAW,
             0,
             (VOID **) &Table,
             &TableSize
             );
  ASSERT_EFI_ERROR (Status);


  //
  // Measure to PCR[0] with event EV_POST_CODE ACPI DATA
  //
  TpmMeasureAndLogData(
    0,
    EV_POST_CODE,
    EV_POSTCODE_INFO_ACPI_DATA,
    ACPI_DATA_LEN,
    Table,
    TableSize
    );


  ASSERT (Table->OemTableId == SIGNATURE_64 ('T', 'p', 'm', '2', 'T', 'a', 'b', 'l'));
  CopyMem (Table->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->OemId) );
  mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16) sizeof (TCG_NVS));
  ASSERT (mTcgNvs != NULL);

  //
  // Publish the TPM ACPI table
  //
  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
  ASSERT_EFI_ERROR (Status);

  TableKey = 0;
  Status = AcpiTable->InstallAcpiTable (
                        AcpiTable,
                        Table,
                        TableSize,
                        &TableKey
                        );
  ASSERT_EFI_ERROR (Status);

  return Status;
}
Beispiel #14
0
UINTN
GetMaxSystemMemoryCount (
  VOID
  )
{
  UINTN  SystemMemoryCount;
  
  SystemMemoryCount = CountSeperatorsInString(PcdGetPtr(PcdWinNtMemorySizeForSecMain), '!') + 1;
  return SystemMemoryCount;
}
Beispiel #15
0
/**
  Print the prompt for the EBL.
**/
VOID
EblPrompt (
  VOID
  )
{
  EblSetTextColor (EFI_YELLOW);
  AsciiPrint ("%a %a",(CHAR8 *)PcdGetPtr (PcdEmbeddedPrompt), EfiGetCwd ());
  EblSetTextColor (0);
  AsciiPrint ("%a", ">");
}
Beispiel #16
0
EFI_STATUS
BdsLoadOptionFileSystemCreatePcdDevicePath (
  OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePathNodes
  )
{
  EFI_STATUS  Status=EFI_SUCCESS;
  FILEPATH_DEVICE_PATH* FilePathDevicePath;
  CHAR16*      BootFilePath;
  UINTN       BootFilePathSize;

  if (*(CHAR16*)PcdGetPtr (PcdDefaultBootDevicePath) == L'\0')
  {
      BootFilePath=(CHAR16*)PcdGetPtr(PcdDefaultBootInitrdPath);
  }
  else
  {
      BootFilePath=(CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath);
  }
    
  BootFilePathSize = StrSize (BootFilePath);
  if (BootFilePathSize == 2) {
    *DevicePathNodes = NULL;
    return EFI_NOT_FOUND;
  }
  
  // Create the FilePath Device Path node
  FilePathDevicePath = (FILEPATH_DEVICE_PATH*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH);
  if (NULL == FilePathDevicePath)
  {
    Print(L"AllocatePool FilePathDevicePath fail!!!\n");
    return EFI_OUT_OF_RESOURCES;
  }
  FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH;
  FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP;
  SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);
  //CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize);
  memcpy_s(FilePathDevicePath->PathName, BootFilePathSize,BootFilePath, BootFilePathSize);
  SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize));
  *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)FilePathDevicePath;

  return Status;
}
Beispiel #17
0
VOID
PlatformBdsDiagnostics (
  IN EXTENDMEM_COVERAGE_LEVEL    MemoryTestLevel,
  IN BOOLEAN                     QuietBoot,
  IN BASEM_MEMORY_TEST           BaseMemoryTest
  )
/*++

Routine Description:

  Perform the platform diagnostic, such like test memory. OEM/IBV also
  can customize this fuction to support specific platform diagnostic.

Arguments:

  MemoryTestLevel  - The memory test intensive level

  QuietBoot        - Indicate if need to enable the quiet boot

  BaseMemoryTest   - A pointer to BaseMemoryTest()

Returns:

  None.

--*/
{
  EFI_STATUS  Status;

  DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n"));

  //
  // Here we can decide if we need to show
  // the diagnostics screen
  // Notes: this quiet boot code should be remove
  // from the graphic lib
  //
  if (QuietBoot) {
    EnableQuietBoot (PcdGetPtr(PcdLogoFile));
    //
    // Perform system diagnostic
    //
    Status = BaseMemoryTest (MemoryTestLevel);
    if (EFI_ERROR (Status)) {
      DisableQuietBoot ();
    }

    return ;
  }
  //
  // Perform system diagnostic
  //
  Status = BaseMemoryTest (MemoryTestLevel);
}
Beispiel #18
0
STATIC
EFI_STATUS
SupportedDevicePathsInit (
  VOID
  )
{
  EFI_STATUS                          Status;
  CHAR16*                             DevicePathListStr;
  CHAR16*                             DevicePathStr;
  CHAR16*                             NextDevicePathStr;
  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
  EFI_DEVICE_PATH_PROTOCOL           *Instance;

  Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
  ASSERT_EFI_ERROR (Status);

  // Initialize Variable
  DevicePathListStr = (CHAR16*)PcdGetPtr (PcdBootMonFsSupportedDevicePaths);
  mBootMonFsSupportedDevicePaths = NULL;

  // Extract the Device Path instances from the multi-device path string
  while ((DevicePathListStr != NULL) && (DevicePathListStr[0] != L'\0')) {
    NextDevicePathStr = StrStr (DevicePathListStr, L";");
    if (NextDevicePathStr == NULL) {
      DevicePathStr = DevicePathListStr;
      DevicePathListStr = NULL;
    } else {
      DevicePathStr = (CHAR16*)AllocateCopyPool ((NextDevicePathStr - DevicePathListStr + 1) * sizeof (CHAR16), DevicePathListStr);
      if (DevicePathStr == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }
      *(DevicePathStr + (NextDevicePathStr - DevicePathListStr)) = L'\0';
      DevicePathListStr = NextDevicePathStr;
      if (DevicePathListStr[0] == L';') {
        DevicePathListStr++;
      }
    }

    Instance = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathStr);
    ASSERT (Instance != NULL);
    mBootMonFsSupportedDevicePaths = AppendDevicePathInstance (mBootMonFsSupportedDevicePaths, Instance);

    if (NextDevicePathStr != NULL) {
      FreePool (DevicePathStr);
    }
    FreePool (Instance);
  }

  if (mBootMonFsSupportedDevicePaths == NULL) {
    return EFI_UNSUPPORTED;
  } else {
    return EFI_SUCCESS;
  }
}
/**
  This service register TPM2 device.

  @param Tpm2Device  TPM2 device

  @retval EFI_SUCCESS          This TPM2 device is registered successfully.
  @retval EFI_UNSUPPORTED      System does not support register this TPM2 device.
  @retval EFI_ALREADY_STARTED  System already register this TPM2 device.
**/
EFI_STATUS
EFIAPI
Tpm2RegisterTpm2DeviceLib (
  IN TPM2_DEVICE_INTERFACE   *Tpm2Device
  )
{
  if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &Tpm2Device->ProviderGuid)){
    DEBUG ((DEBUG_WARN, "WARNING: Tpm2RegisterTpm2DeviceLib - does not support %g registration\n", &Tpm2Device->ProviderGuid));
    return EFI_UNSUPPORTED;
  }

  CopyMem (&mInternalTpm2DeviceInterface, Tpm2Device, sizeof(mInternalTpm2DeviceInterface));
  return EFI_SUCCESS;
}
Beispiel #20
0
/**
  Publish TPM2 ACPI table

  @retval   EFI_SUCCESS     The TPM2 ACPI table is published successfully.
  @retval   Others          The TPM2 ACPI table is not published.

**/
EFI_STATUS
PublishTpm2 (
  VOID
  )
{
  EFI_STATUS                     Status;
  EFI_ACPI_TABLE_PROTOCOL        *AcpiTable;
  UINTN                          TableKey;
  UINT64                         OemTableId;

  //
  // Measure to PCR[0] with event EV_POST_CODE ACPI DATA
  //
  TpmMeasureAndLogData(
    0,
    EV_POST_CODE,
    EV_POSTCODE_INFO_ACPI_DATA,
    ACPI_DATA_LEN,
    &mTpm2AcpiTemplate,
    sizeof(mTpm2AcpiTemplate)
    );

  CopyMem (mTpm2AcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTpm2AcpiTemplate.Header.OemId));
  OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
  CopyMem (&mTpm2AcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
  mTpm2AcpiTemplate.Header.OemRevision      = PcdGet32 (PcdAcpiDefaultOemRevision);
  mTpm2AcpiTemplate.Header.CreatorId        = PcdGet32 (PcdAcpiDefaultCreatorId);
  mTpm2AcpiTemplate.Header.CreatorRevision  = PcdGet32 (PcdAcpiDefaultCreatorRevision);

  //
  // Construct ACPI table
  //
  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
  ASSERT_EFI_ERROR (Status);

  Status = AcpiTable->InstallAcpiTable (
                        AcpiTable,
                        &mTpm2AcpiTemplate,
                        sizeof(mTpm2AcpiTemplate),
                        &TableKey
                        );
  ASSERT_EFI_ERROR (Status);

  return Status;
}
Beispiel #21
0
STATIC
VOID
PlatformRegisterOptionsAndKeys (
  VOID
  )
{
  EFI_STATUS                   Status;
  EFI_INPUT_KEY                Enter;
  EFI_INPUT_KEY                F2;
  EFI_INPUT_KEY                Esc;
  EFI_BOOT_MANAGER_LOAD_OPTION BootOption;

  //
  // Register ENTER as CONTINUE key
  //
  Enter.ScanCode    = SCAN_NULL;
  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
  Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
  ASSERT_EFI_ERROR (Status);

  //
  // Map F2 and ESC to Boot Manager Menu
  //
  F2.ScanCode     = SCAN_F2;
  F2.UnicodeChar  = CHAR_NULL;
  Esc.ScanCode    = SCAN_ESC;
  Esc.UnicodeChar = CHAR_NULL;
  Status = EfiBootManagerGetBootManagerMenu (&BootOption);
  ASSERT_EFI_ERROR (Status);
  Status = EfiBootManagerAddKeyOptionVariable (
             NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL
             );
  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
  Status = EfiBootManagerAddKeyOptionVariable (
             NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL
             );
  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
  //
  // Register UEFI Shell
  //
  PlatformRegisterFvBootOption (
    PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE
    );
}
Beispiel #22
0
/**
  Return if this FMP is a system FMP or a device FMP, based upon FmpImageInfo.

  @param[in] FmpImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR

  @return TRUE  It is a system FMP.
  @return FALSE It is a device FMP.
**/
BOOLEAN
IsSystemFmp (
  IN EFI_FIRMWARE_IMAGE_DESCRIPTOR  *FmpImageInfo
  )
{
  GUID   *Guid;
  UINTN  Count;
  UINTN  Index;

  Guid  = PcdGetPtr (PcdSystemFmpCapsuleImageTypeIdGuid);
  Count = PcdGetSize (PcdSystemFmpCapsuleImageTypeIdGuid) / sizeof(GUID);

  for (Index = 0; Index < Count; Index++, Guid++) {
    if (CompareGuid (&FmpImageInfo->ImageTypeId, Guid)) {
      return TRUE;
    }
  }

  return FALSE;
}
Beispiel #23
0
/**
  Return if this FMP is a system FMP or a device FMP, based upon FmpImageInfo.

  @param[in] FmpImageHeader A pointer to EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER

  @return TRUE  It is a system FMP.
  @return FALSE It is a device FMP.
**/
BOOLEAN
IsSystemFmpImage (
  IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER   *FmpImageHeader
  )
{
  GUID      *Guid;
  UINTN     Count;
  UINTN     Index;

  Guid = PcdGetPtr(PcdSystemFmpCapsuleImageTypeIdGuid);
  Count = PcdGetSize(PcdSystemFmpCapsuleImageTypeIdGuid) / sizeof(GUID);

  for (Index = 0; Index < Count; Index++, Guid++) {
    if (CompareGuid(&FmpImageHeader->UpdateImageTypeId, Guid)) {
      return TRUE;
    }
  }

  return FALSE;
}
/**
  Get the chassis type through the PlatformInfoProtocol.

  @retval UINT8                The chassis type.

**/
UINT8
GetChassisType (
  VOID
  )
{
  EFI_PLATFORM_INFO_HOB           *PlatformInfoHob;

  PlatformInfoHob = PcdGetPtr (PcdPlatformInfo);
  
  if ( NULL != PlatformInfoHob) {
    if (PlatformInfoHob->PlatformFlavor == FlavorMobile) {
      return MiscChassisTypeLapTop;
    } else if (PlatformInfoHob->PlatformFlavor == FlavorDesktop) {
      return MiscChassisTypeDeskTop;
    } else if (PlatformInfoHob->PlatformFlavor == FlavorTablet) {
      return MiscChassisTypeHandHeld;
    }
  }
  
  return MiscChassisTypeLapTop;
}
Beispiel #25
0
/**
  Do the platform specific action after the console is ready
  Possible things that can be done in PlatformBootManagerAfterConsole:
  > Console post action:
    > Dynamically switch output mode from 100x31 to 80x25 for certain senarino
    > Signal console ready platform customized event
  > Run diagnostics like memory testing
  > Connect certain devices
  > Dispatch aditional option roms
  > Special boot: e.g.: USB boot, enter UI
**/
VOID
EFIAPI
PlatformBootManagerAfterConsole (
  VOID
  )
{
  //
  // Show the splash screen.
  //
  BootLogoEnableLogo (
    ImageFormatBmp,                          // ImageFormat
    PcdGetPtr (PcdLogoFile),                 // Logo
    EdkiiPlatformLogoDisplayAttributeCenter, // Attribute
    0,                                       // OffsetX
    0                                        // OffsetY
    );

  //
  // Connect the rest of the devices.
  //
  EfiBootManagerConnectAll ();

  //
  // Process QEMU's -kernel command line option. Note that the kernel booted
  // this way should receive ACPI tables, which is why we connect all devices
  // first (see above) -- PCI enumeration blocks ACPI table installation, if
  // there is a PCI host.
  //
  TryRunningQemuKernel ();

  //
  // Enumerate all possible boot options, then filter and reorder them based on
  // the QEMU configuration.
  //
  EfiBootManagerRefreshAllBootOption ();
  SetBootOrderFromQemu ();
}
Beispiel #26
0
/**
  The driver's entry point.

  It publishes EFI TCG Protocol.

  @param[in] ImageHandle  The firmware allocated handle for the EFI image.  
  @param[in] SystemTable  A pointer to the EFI System Table.
  
  @retval EFI_SUCCESS     The entry point is executed successfully.
  @retval other           Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
DriverEntry (
  IN    EFI_HANDLE                  ImageHandle,
  IN    EFI_SYSTEM_TABLE            *SystemTable
  )
{
  EFI_STATUS                        Status;
  EFI_EVENT                         Event;
  VOID                              *Registration;

  if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
    DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
    return EFI_UNSUPPORTED;
  }

  if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
    DEBUG ((EFI_D_ERROR, "TPM error!\n"));
    return EFI_DEVICE_ERROR;
  }

  Status = Tpm12RequestUseTpm ();
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "TPM not detected!\n"));
    return Status;
  }

  Status = GetTpmStatus (&mTcgDxeData.BsCap.TPMDeactivatedFlag);
  if (EFI_ERROR (Status)) {
    DEBUG ((
      EFI_D_ERROR,
      "Line %d in file " __FILE__ ":\n    "
      "DriverEntry: TPM not working properly\n",
      __LINE__
      ));
    return Status;
  }

  Status = gBS->InstallProtocolInterface (
                  &ImageHandle,
                  &gEfiTcgProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &mTcgDxeData.TcgProtocol
                  );
  if (!EFI_ERROR (Status) && (!mTcgDxeData.BsCap.TPMDeactivatedFlag) && mTcgDxeData.BsCap.TPMPresentFlag) {
    //
    // Setup the log area and copy event log from hob list to it
    //
    Status = SetupEventLog ();
    ASSERT_EFI_ERROR (Status);

    //
    // Measure handoff tables, Boot#### variables etc.
    //
    Status = EfiCreateEventReadyToBootEx (
               TPL_CALLBACK,
               OnReadyToBoot,
               NULL,
               &Event
               );

    Status = gBS->CreateEventEx (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    OnExitBootServices,
                    NULL,
                    &gEfiEventExitBootServicesGuid,
                    &Event
                    );

    //
    // Measure Exit Boot Service failed 
    //
    Status = gBS->CreateEventEx (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    OnExitBootServicesFailed,
                    NULL,
                    &gEventExitBootServicesFailedGuid,
                    &Event
                    );
  }

  //
  // Install ACPI Table
  //
  EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration);
  
  return Status;
}
Beispiel #27
0
/**
  Install TCG ACPI Table when ACPI Table Protocol is available.

  A system's firmware uses an ACPI table to identify the system's TCG capabilities 
  to the Post-Boot environment. The information in this ACPI table is not guaranteed 
  to be valid until the Host Platform transitions from pre-boot state to post-boot state.  

  @param[in]  Event     Event whose notification function is being invoked
  @param[in]  Context   Pointer to the notification function's context
**/
VOID
EFIAPI
InstallAcpiTable (
  IN EFI_EVENT                      Event,
  IN VOID*                          Context
  )
{
  UINTN                             TableKey;
  EFI_STATUS                        Status;
  EFI_ACPI_TABLE_PROTOCOL           *AcpiTable;
  UINT8                             Checksum;
  UINT64                            OemTableId;

  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);
  if (EFI_ERROR (Status)) {
    return;
  }

  if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {
    CopyMem (mTcgClientAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgClientAcpiTemplate.Header.OemId));
    OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
    CopyMem (&mTcgClientAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
    mTcgClientAcpiTemplate.Header.OemRevision      = PcdGet32 (PcdAcpiDefaultOemRevision);
    mTcgClientAcpiTemplate.Header.CreatorId        = PcdGet32 (PcdAcpiDefaultCreatorId);
    mTcgClientAcpiTemplate.Header.CreatorRevision  = PcdGet32 (PcdAcpiDefaultCreatorRevision);
    //
    // The ACPI table must be checksumed before calling the InstallAcpiTable() 
    // service of the ACPI table protocol to install it.
    //
    Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate));
    mTcgClientAcpiTemplate.Header.Checksum = Checksum;

    Status = AcpiTable->InstallAcpiTable (
                            AcpiTable,
                            &mTcgClientAcpiTemplate,
                            sizeof (mTcgClientAcpiTemplate),
                            &TableKey
                            );
  } else {
    CopyMem (mTcgServerAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgServerAcpiTemplate.Header.OemId));
    OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
    CopyMem (&mTcgServerAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
    mTcgServerAcpiTemplate.Header.OemRevision      = PcdGet32 (PcdAcpiDefaultOemRevision);
    mTcgServerAcpiTemplate.Header.CreatorId        = PcdGet32 (PcdAcpiDefaultCreatorId);
    mTcgServerAcpiTemplate.Header.CreatorRevision  = PcdGet32 (PcdAcpiDefaultCreatorRevision);
    //
    // The ACPI table must be checksumed before calling the InstallAcpiTable() 
    // service of the ACPI table protocol to install it.
    //
    Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate));
    mTcgServerAcpiTemplate.Header.Checksum = Checksum;

    mTcgServerAcpiTemplate.BaseAddress.Address = PcdGet64 (PcdTpmBaseAddress);
    Status = AcpiTable->InstallAcpiTable (
                            AcpiTable,
                            &mTcgServerAcpiTemplate,
                            sizeof (mTcgServerAcpiTemplate),
                            &TableKey
                            );
  }

  if (EFI_ERROR (Status)) {
    DEBUG((EFI_D_ERROR, "Tcg Acpi Table installation failure"));
  }
}
Beispiel #28
0
/**
  Entry point of this module.

  @param[in] FileHandle   Handle of the file being invoked.
  @param[in] PeiServices  Describes the list of possible PEI Services.

  @return Status.

**/
EFI_STATUS
EFIAPI
PeimEntryMA (
  IN       EFI_PEI_FILE_HANDLE      FileHandle,
  IN CONST EFI_PEI_SERVICES         **PeiServices
  )
{
  EFI_STATUS                        Status;
  EFI_STATUS                        Status2;
  EFI_BOOT_MODE                     BootMode;

  if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
    DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
    return EFI_UNSUPPORTED;
  }

  if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
    DEBUG ((EFI_D_ERROR, "TPM error!\n"));
    return EFI_DEVICE_ERROR;
  }

  //
  // Initialize TPM device
  //
  Status = PeiServicesGetBootMode (&BootMode);
  ASSERT_EFI_ERROR (Status);

  //
  // In S3 path, skip shadow logic. no measurement is required
  //
  if (BootMode != BOOT_ON_S3_RESUME) {
    Status = (**PeiServices).RegisterForShadow(FileHandle);
    if (Status == EFI_ALREADY_STARTED) {
      mImageInMemory = TRUE;
    } else if (Status == EFI_NOT_FOUND) {
      ASSERT_EFI_ERROR (Status);
    }
  }

  if (!mImageInMemory) {
    Status = Tpm12RequestUseTpm ();
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
      goto Done;
    }

    if (PcdGet8 (PcdTpmInitializationPolicy) == 1) {
      if (BootMode == BOOT_ON_S3_RESUME) {
        Status = Tpm12Startup (TPM_ST_STATE);
      } else {
        Status = Tpm12Startup (TPM_ST_CLEAR);
      }
      if (EFI_ERROR (Status) ) {
        goto Done;
      }
    }

    //
    // TpmSelfTest is optional on S3 path, skip it to save S3 time
    //
    if (BootMode != BOOT_ON_S3_RESUME) {
      Status = Tpm12ContinueSelfTest ();
      if (EFI_ERROR (Status)) {
        goto Done;
      }
    }

    //
    // Only intall TpmInitializedPpi on success
    //
    Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
    ASSERT_EFI_ERROR (Status);
  }

  if (mImageInMemory) {
    Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
    return Status;
  }

Done:
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "TPM error! Build Hob\n"));
    BuildGuidHob (&gTpmErrorHobGuid,0);
    REPORT_STATUS_CODE (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
      );
  }
  //
  // Always intall TpmInitializationDonePpi no matter success or fail.
  // Other driver can know TPM initialization state by TpmInitializedPpi.
  //
  Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);
  ASSERT_EFI_ERROR (Status2);

  return Status;
}
/**

  Extraction handler tries to extract raw data from the input guided section.
  It also does authentication check for RSA 2048 SHA 256 signature in the input guided section.
  It first checks whether the input guid section is supported. 
  If not, EFI_INVALID_PARAMETER will return.

  @param InputSection    Buffer containing the input GUIDed section to be processed.
  @param OutputBuffer    Buffer to contain the output raw data allocated by the caller.
  @param ScratchBuffer   A pointer to a caller-allocated buffer for function internal use.
  @param AuthenticationStatus A pointer to a caller-allocated UINT32 that indicates the
                              authentication status of the output buffer.

  @retval EFI_SUCCESS            Section Data and Auth Status is extracted successfully.
  @retval EFI_INVALID_PARAMETER  The GUID in InputSection does not match this instance guid.

**/
EFI_STATUS
EFIAPI
Rsa2048Sha256GuidedSectionHandler (
  IN CONST  VOID    *InputSection,
  OUT       VOID    **OutputBuffer,
  IN        VOID    *ScratchBuffer,        OPTIONAL
  OUT       UINT32  *AuthenticationStatus
  )
{
  EFI_STATUS                      Status;
  UINT32                          OutputBufferSize;
  VOID                            *DummyInterface;
  EFI_CERT_BLOCK_RSA_2048_SHA256  *CertBlockRsa2048Sha256;
  BOOLEAN                         CryptoStatus;
  UINT8                           Digest[SHA256_DIGEST_SIZE];
  UINT8                           *PublicKey;
  UINTN                           PublicKeyBufferSize;
  VOID                            *HashContext;
  VOID                            *Rsa;
  
  HashContext = NULL;
  Rsa         = NULL;
  
  if (IS_SECTION2 (InputSection)) {
    //
    // Check whether the input guid section is recognized.
    //
    if (!CompareGuid (
        &gEfiCertTypeRsa2048Sha256Guid,
        &(((EFI_GUID_DEFINED_SECTION2 *)InputSection)->SectionDefinitionGuid))) {
      return EFI_INVALID_PARAMETER;
    }
  
    //
    // Get the RSA 2048 SHA 256 information.
    //
    CertBlockRsa2048Sha256 = &((RSA_2048_SHA_256_SECTION2_HEADER *) InputSection)->CertBlockRsa2048Sha256;
    OutputBufferSize       = SECTION2_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION2_HEADER);
    if ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) {
      PERF_START (NULL, "RsaCopy", "DXE", 0);
      CopyMem (*OutputBuffer, (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION2_HEADER), OutputBufferSize);
      PERF_END (NULL, "RsaCopy", "DXE", 0);
    } else {
      *OutputBuffer = (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION2_HEADER);
    }

    //
    // Implicitly RSA 2048 SHA 256 GUIDed section should have STATUS_VALID bit set
    //
    ASSERT ((((EFI_GUID_DEFINED_SECTION2 *)InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0);
    *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED;
  } else {
    //
    // Check whether the input guid section is recognized.
    //
    if (!CompareGuid (
        &gEfiCertTypeRsa2048Sha256Guid,
        &(((EFI_GUID_DEFINED_SECTION *)InputSection)->SectionDefinitionGuid))) {
      return EFI_INVALID_PARAMETER;
    }
  
    //
    // Get the RSA 2048 SHA 256 information.
    //
    CertBlockRsa2048Sha256 = &((RSA_2048_SHA_256_SECTION_HEADER *)InputSection)->CertBlockRsa2048Sha256;
    OutputBufferSize       = SECTION_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION_HEADER);
    if ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) {
      PERF_START (NULL, "RsaCopy", "DXE", 0);
      CopyMem (*OutputBuffer, (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION_HEADER), OutputBufferSize);
      PERF_END (NULL, "RsaCopy", "DXE", 0);
    } else {
      *OutputBuffer = (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION_HEADER);
    }

    //
    // Implicitly RSA 2048 SHA 256 GUIDed section should have STATUS_VALID bit set
    //
    ASSERT ((((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0);
    *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED;
  }

  //
  // Check whether there exists EFI_SECURITY_POLICY_PROTOCOL_GUID.
  //
  Status = gBS->LocateProtocol (&gEfiSecurityPolicyProtocolGuid, NULL, &DummyInterface);
  if (!EFI_ERROR (Status)) {
    //
    // If SecurityPolicy Protocol exist, AUTH platform override bit is set.
    //
    *AuthenticationStatus |= EFI_AUTH_STATUS_PLATFORM_OVERRIDE;
    
    return EFI_SUCCESS;
  }

  //
  // All paths from here return EFI_SUCESS and result is returned in AuthenticationStatus
  //
  Status = EFI_SUCCESS;
  
  //
  // Fail if the HashType is not SHA 256
  //
  if (!CompareGuid (&gEfiHashAlgorithmSha256Guid, &CertBlockRsa2048Sha256->HashType)) {
    DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: HASH type of section is not supported\n"));
    *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
    goto Done;
  }

  //
  // Allocate hash context buffer required for SHA 256
  //
  HashContext = AllocatePool (Sha256GetContextSize ());
  if (HashContext == NULL) {
    DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Can not allocate hash context\n"));
    *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
    goto Done;
  }

  //
  // Hash public key from data payload with SHA256.
  //
  ZeroMem (Digest, SHA256_DIGEST_SIZE);
  CryptoStatus = Sha256Init (HashContext);
  if (!CryptoStatus) {
    DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Init() failed\n"));
    *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
    goto Done;
  }
  CryptoStatus = Sha256Update (HashContext, &CertBlockRsa2048Sha256->PublicKey, sizeof(CertBlockRsa2048Sha256->PublicKey));
  if (!CryptoStatus) {
    DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Update() failed\n"));
    *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
    goto Done;
  }
  CryptoStatus  = Sha256Final (HashContext, Digest);
  if (!CryptoStatus) {
    DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Final() failed\n"));
    *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
    goto Done;
  }
  
  //
  // Fail if the PublicKey is not one of the public keys in PcdRsa2048Sha256PublicKeyBuffer
  //
  PublicKey = (UINT8 *)PcdGetPtr (PcdRsa2048Sha256PublicKeyBuffer);
  DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer = %p\n", PublicKey));
  ASSERT (PublicKey != NULL);
  DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer Token = %08x\n", PcdToken (PcdRsa2048Sha256PublicKeyBuffer)));
  PublicKeyBufferSize = LibPcdGetExSize (&gEfiSecurityPkgTokenSpaceGuid, PcdToken (PcdRsa2048Sha256PublicKeyBuffer));
  DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer Size = %08x\n", PublicKeyBufferSize));
  ASSERT ((PublicKeyBufferSize % SHA256_DIGEST_SIZE) == 0);
  CryptoStatus = FALSE;
  while (PublicKeyBufferSize != 0) {
    if (CompareMem (Digest, PublicKey, SHA256_DIGEST_SIZE) == 0) {
      CryptoStatus = TRUE;
      break;
    }
    PublicKey = PublicKey + SHA256_DIGEST_SIZE;
    PublicKeyBufferSize = PublicKeyBufferSize - SHA256_DIGEST_SIZE;
  }
  if (!CryptoStatus) {
    DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Public key in section is not supported\n"));
    *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
    goto Done;
  }

  //
  // Generate & Initialize RSA Context.
  //
  Rsa = RsaNew ();
  if (Rsa == NULL) {
    DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaNew() failed\n"));
    *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
    goto Done;
  }
  
  // 
  // Set RSA Key Components.
  // NOTE: Only N and E are needed to be set as RSA public key for signature verification.
  //
  CryptoStatus = RsaSetKey (Rsa, RsaKeyN, CertBlockRsa2048Sha256->PublicKey, sizeof(CertBlockRsa2048Sha256->PublicKey));
  if (!CryptoStatus) {
    DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaSetKey(RsaKeyN) failed\n"));
    *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
    goto Done;
  }
  CryptoStatus = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE));
  if (!CryptoStatus) {
    DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaSetKey(RsaKeyE) failed\n"));
    *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
    goto Done;
  }

  //
  // Hash data payload with SHA256.
  //
  ZeroMem (Digest, SHA256_DIGEST_SIZE);
  CryptoStatus = Sha256Init (HashContext);
  if (!CryptoStatus) {
    DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Init() failed\n"));
    *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
    goto Done;
  }
  PERF_START (NULL, "RsaShaData", "DXE", 0);
  CryptoStatus = Sha256Update (HashContext, *OutputBuffer, OutputBufferSize);
  PERF_END (NULL, "RsaShaData", "DXE", 0);
  if (!CryptoStatus) {
    DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Update() failed\n"));
    *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
    goto Done;
  }
  CryptoStatus  = Sha256Final (HashContext, Digest);
  if (!CryptoStatus) {
    DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Final() failed\n"));
    *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
    goto Done;
  }

  //
  // Verify the RSA 2048 SHA 256 signature.
  //
  PERF_START (NULL, "RsaVerify", "DXE", 0);
  CryptoStatus = RsaPkcs1Verify (
                   Rsa, 
                   Digest, 
                   SHA256_DIGEST_SIZE, 
                   CertBlockRsa2048Sha256->Signature, 
                   sizeof (CertBlockRsa2048Sha256->Signature)
                   );
  PERF_END (NULL, "RsaVerify", "DXE", 0);
  if (!CryptoStatus) {
    //
    // If RSA 2048 SHA 256 signature verification fails, AUTH tested failed bit is set.
    //
    DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaPkcs1Verify() failed\n"));
    *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
  }

Done:
  //
  // Free allocated resources used to perform RSA 2048 SHA 256 signature verification
  //
  if (Rsa != NULL) {
    RsaFree (Rsa);
  }
  if (HashContext != NULL) {
    FreePool (HashContext);
  }

  DEBUG ((DEBUG_VERBOSE, "DxeRsa2048Sha256: Status = %r  AuthenticationStatus = %08x\n", Status, *AuthenticationStatus));

  return Status;
}
Beispiel #30
0
INTN
EFIAPI
main (
  IN  INTN  Argc,
  IN  CHAR8 **Argv,
  IN  CHAR8 **Envp
  )
/*++

Routine Description:
  Main entry point to SEC for WinNt. This is a Windows program

Arguments:
  Argc - Number of command line arguments
  Argv - Array of command line argument strings
  Envp - Array of environment variable strings

Returns:
  0 - Normal exit
  1 - Abnormal exit

--*/
{
  EFI_STATUS            Status;
  HANDLE                Token;
  TOKEN_PRIVILEGES      TokenPrivileges;
  EFI_PHYSICAL_ADDRESS  InitialStackMemory;
  UINT64                InitialStackMemorySize;
  UINTN                 Index;
  UINTN                 Index1;
  UINTN                 Index2;
  CHAR16                *FileName;
  CHAR16                *FileNamePtr;
  BOOLEAN               Done;
  VOID                  *PeiCoreFile;
  CHAR16                *MemorySizeStr;
  CHAR16                *FirmwareVolumesStr;
  UINTN                 *StackPointer;
  UINT32                ProcessAffinityMask;
  UINT32                SystemAffinityMask;
  INT32                 LowBit;


  //
  // Enable the privilege so that RTC driver can successfully run SetTime()
  //
  OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &Token);
  if (LookupPrivilegeValue(NULL, SE_TIME_ZONE_NAME, &TokenPrivileges.Privileges[0].Luid)) {
    TokenPrivileges.PrivilegeCount = 1;
    TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(Token, FALSE, &TokenPrivileges, 0, (PTOKEN_PRIVILEGES) NULL, 0);
  }

  MemorySizeStr      = (CHAR16 *) PcdGetPtr (PcdWinNtMemorySizeForSecMain);
  FirmwareVolumesStr = (CHAR16 *) PcdGetPtr (PcdWinNtFirmwareVolume);

  SecPrint ("\nEDK II SEC Main NT Emulation Environment from www.TianoCore.org\n");

  //
  // Determine the first thread available to this process.
  //
  if (GetProcessAffinityMask (GetCurrentProcess (), &ProcessAffinityMask, &SystemAffinityMask)) {
    LowBit = (INT32)LowBitSet32 (ProcessAffinityMask);
    if (LowBit != -1) {
      //
      // Force the system to bind the process to a single thread to work
      // around odd semaphore type crashes.
      //
      SetProcessAffinityMask (GetCurrentProcess (), (INTN)(BIT0 << LowBit));
    }
  }

  //
  // Make some Windows calls to Set the process to the highest priority in the
  //  idle class. We need this to have good performance.
  //
  SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS);
  SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);

  //
  // Allocate space for gSystemMemory Array
  //
  gSystemMemoryCount  = CountSeparatorsInString (MemorySizeStr, '!') + 1;
  gSystemMemory       = calloc (gSystemMemoryCount, sizeof (NT_SYSTEM_MEMORY));
  if (gSystemMemory == NULL) {
    SecPrint ("ERROR : Can not allocate memory for %S.  Exiting.\n", MemorySizeStr);
    exit (1);
  }
  //
  // Allocate space for gSystemMemory Array
  //
  gFdInfoCount  = CountSeparatorsInString (FirmwareVolumesStr, '!') + 1;
  gFdInfo       = calloc (gFdInfoCount, sizeof (NT_FD_INFO));
  if (gFdInfo == NULL) {
    SecPrint ("ERROR : Can not allocate memory for %S.  Exiting.\n", FirmwareVolumesStr);
    exit (1);
  }
  //
  // Setup Boot Mode. If BootModeStr == "" then BootMode = 0 (BOOT_WITH_FULL_CONFIGURATION)
  //
  SecPrint ("  BootMode 0x%02x\n", PcdGet32 (PcdWinNtBootMode));

  //
  //  Allocate 128K memory to emulate temp memory for PEI.
  //  on a real platform this would be SRAM, or using the cache as RAM.
  //  Set InitialStackMemory to zero so WinNtOpenFile will allocate a new mapping
  //
  InitialStackMemorySize  = STACK_SIZE;
  InitialStackMemory = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (InitialStackMemorySize), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  if (InitialStackMemory == 0) {
    SecPrint ("ERROR : Can not allocate enough space for SecStack\n");
    exit (1);
  }

  for (StackPointer = (UINTN*) (UINTN) InitialStackMemory;
       StackPointer < (UINTN*) ((UINTN)InitialStackMemory + (SIZE_T) InitialStackMemorySize);
       StackPointer ++) {
    *StackPointer = 0x5AA55AA5;
  }
  
  SecPrint ("  SEC passing in %d bytes of temp RAM to PEI\n", InitialStackMemorySize);

  //
  // Open All the firmware volumes and remember the info in the gFdInfo global
  //
  FileNamePtr = (CHAR16 *)malloc (StrLen ((CHAR16 *)FirmwareVolumesStr) * sizeof(CHAR16));
  if (FileNamePtr == NULL) {
    SecPrint ("ERROR : Can not allocate memory for firmware volume string\n");
    exit (1);
  }

  StrCpy (FileNamePtr, (CHAR16*)FirmwareVolumesStr);

  for (Done = FALSE, Index = 0, PeiCoreFile = NULL; !Done; Index++) {
    FileName = FileNamePtr;
    for (Index1 = 0; (FileNamePtr[Index1] != '!') && (FileNamePtr[Index1] != 0); Index1++)
      ;
    if (FileNamePtr[Index1] == 0) {
      Done = TRUE;
    } else {
      FileNamePtr[Index1]  = '\0';
      FileNamePtr = FileNamePtr + Index1 + 1;
    }

    //
    // Open the FD and remember where it got mapped into our processes address space
    //
    Status = WinNtOpenFile (
              FileName,
              0,
              OPEN_EXISTING,
              &gFdInfo[Index].Address,
              &gFdInfo[Index].Size
              );
    if (EFI_ERROR (Status)) {
      SecPrint ("ERROR : Can not open Firmware Device File %S (0x%X).  Exiting.\n", FileName, Status);
      exit (1);
    }

    SecPrint ("  FD loaded from");
    //
    // printf can't print filenames directly as the \ gets interpreted as an
    //  escape character.
    //
    for (Index2 = 0; FileName[Index2] != '\0'; Index2++) {
      SecPrint ("%c", FileName[Index2]);
    }

    if (PeiCoreFile == NULL) {
      //
      // Assume the beginning of the FD is an FV and look for the PEI Core.
      // Load the first one we find.
      //
      Status = SecFfsFindPeiCore ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) gFdInfo[Index].Address, &PeiCoreFile);
      if (!EFI_ERROR (Status)) {
        SecPrint (" contains SEC Core");
      }
    }

    SecPrint ("\n");
  }
  //
  // Calculate memory regions and store the information in the gSystemMemory
  //  global for later use. The autosizing code will use this data to
  //  map this memory into the SEC process memory space.
  //
  for (Index = 0, Done = FALSE; !Done; Index++) {
    //
    // Save the size of the memory and make a Unicode filename SystemMemory00, ...
    //
    gSystemMemory[Index].Size = _wtoi (MemorySizeStr) * 0x100000;

    //
    // Find the next region
    //
    for (Index1 = 0; MemorySizeStr[Index1] != '!' && MemorySizeStr[Index1] != 0; Index1++)
      ;
    if (MemorySizeStr[Index1] == 0) {
      Done = TRUE;
    }

    MemorySizeStr = MemorySizeStr + Index1 + 1;
  }

  SecPrint ("\n");

  //
  // Hand off to PEI Core
  //
  SecLoadFromCore ((UINTN) InitialStackMemory, (UINTN) InitialStackMemorySize, (UINTN) gFdInfo[0].Address, PeiCoreFile);

  //
  // If we get here, then the PEI Core returned. This is an error as PEI should
  //  always hand off to DXE.
  //
  SecPrint ("ERROR : PEI Core returned\n");
  exit (1);
}