Beispiel #1
0
/**
  Check if it's a valid FFS file.
  Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first.

  @param  ErasePolarity  Erase polarity attribute of the firmware volume
  @param  FfsHeader      Points to the FFS file to be checked

  @retval TRUE           Valid FFS file
  @retval FALSE          Invalid FFS file

**/
BOOLEAN
IsValidFfsFile (
  IN UINT8                ErasePolarity,
  IN EFI_FFS_FILE_HEADER  *FfsHeader
  )
{
  EFI_FFS_FILE_STATE  FileState;
  UINT8               DataCheckSum;

  FileState = GetFileState (ErasePolarity, FfsHeader);
  switch (FileState) {

  case EFI_FILE_DELETED:
  case EFI_FILE_DATA_VALID:
  case EFI_FILE_MARKED_FOR_UPDATE:
    DataCheckSum = FFS_FIXED_CHECKSUM;
    if ((FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) {
      if (IS_FFS_FILE2 (FfsHeader)) {
        DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2), FFS_FILE2_SIZE (FfsHeader) - sizeof(EFI_FFS_FILE_HEADER2));
      } else {
        DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER), FFS_FILE_SIZE (FfsHeader) - sizeof(EFI_FFS_FILE_HEADER));
      }
    }
    if (FfsHeader->IntegrityCheck.Checksum.File == DataCheckSum) {
      return TRUE;
    }

  default:
    return FALSE;
  }
}
Beispiel #2
0
/**
  Calculate the checksum for a PAD file.

  @param PadFileHeader   The Pad File to be caculeted the checksum.

**/
VOID
SetPadFileChecksum (
  IN EFI_FFS_FILE_HEADER *PadFileHeader
  )
{
  if ((PadFileHeader->Attributes & FFS_ATTRIB_CHECKSUM) != 0) {

    if (IS_FFS_FILE2 (PadFileHeader)) {
      //
      // Calculate checksum of Pad File Data
      //
      PadFileHeader->IntegrityCheck.Checksum.File =
        CalculateCheckSum8 ((UINT8 *) PadFileHeader + sizeof (EFI_FFS_FILE_HEADER2), FFS_FILE2_SIZE (PadFileHeader) - sizeof (EFI_FFS_FILE_HEADER2));

      } else {
      //
      // Calculate checksum of Pad File Data
      //
      PadFileHeader->IntegrityCheck.Checksum.File =
        CalculateCheckSum8 ((UINT8 *) PadFileHeader + sizeof (EFI_FFS_FILE_HEADER), FFS_FILE_SIZE (PadFileHeader) - sizeof (EFI_FFS_FILE_HEADER));
    }

  } else {

    PadFileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;

  }

  return ;
}
Beispiel #3
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;

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

  if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {
 
    //
    // 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 {

    //
    // 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;

    Status = AcpiTable->InstallAcpiTable (
                            AcpiTable,
                            &mTcgServerAcpiTemplate,
                            sizeof (mTcgServerAcpiTemplate),
                            &TableKey
                            );
  }
  ASSERT_EFI_ERROR (Status);
}
Beispiel #4
0
/**
  This function calculates and updates an UINT8 checksum.

  @param  Buffer          Pointer to buffer to checksum
  @param  Size            Number of bytes to checksum

**/
VOID
AcpiPlatformChecksum (
  IN UINT8      *Buffer,
  IN UINTN      Size
  )
{
	UINTN ChecksumOffset;
	
	ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);
	//
	// Set checksum to 0 first
	//
	Buffer[ChecksumOffset] = 0;
	//
	// Update checksum value
	//
	Buffer[ChecksumOffset] = CalculateCheckSum8(Buffer, Size);
}
Beispiel #5
0
VOID *FindSignature(VOID* Start, UINT32 Signature, BOOLEAN NoChecksum)
{
  UINT8 *Ptr = (UINT8*)Start;
  UINT32 Count = 0x10000; // 16 pages

  while (Count-- > 0) {
    if (   *(UINT32*)Ptr == Signature
        && ((EFI_ACPI_DESCRIPTION_HEADER *)Ptr)->Length <= Count
        && (NoChecksum ||
            CalculateCheckSum8(Ptr, ((EFI_ACPI_DESCRIPTION_HEADER *)Ptr)->Length) == 0
            )) {
      return Ptr;
    }

    Ptr++;
  }
  return NULL;
}
Beispiel #6
0
VOID
ErstSetAcpiTable (
  ERST_BOOT_CONTEXT *Context
)
{
  UINTN                     AcpiTableHandle;
  EFI_STATUS                Status;
  UINT8                     Checksum;
  mErst.ErstTableHeader.Header.Length = sizeof (ERST_TABLE);
  Checksum = CalculateCheckSum8 ((UINT8*)(&mErst), mErst.ErstTableHeader.Header.Length);
  mErst.ErstTableHeader.Header.Checksum = Checksum;
  AcpiTableHandle = 0;
  Status = mAcpiTableProtocol->InstallAcpiTable (
             mAcpiTableProtocol,
             &mErst,
             mErst.ErstTableHeader.Header.Length,
             &AcpiTableHandle
             );
  ASSERT_EFI_ERROR (Status) ;
}
Beispiel #7
0
/**
  Process a QEMU_LOADER_ADD_CHECKSUM command.

  @param[in] AddChecksum  The QEMU_LOADER_ADD_CHECKSUM command to process.

  @param[in] Tracker      The ORDERED_COLLECTION tracking the BLOB user
                          structures created thus far.

  @retval EFI_PROTOCOL_ERROR  Malformed fw_cfg file name has been found in
                              AddChecksum, or the AddChecksum command
                              references a file unknown to Tracker, or the
                              range to checksum is invalid.

  @retval EFI_SUCCESS         The requested range has been checksummed.
**/
STATIC
EFI_STATUS
EFIAPI
ProcessCmdAddChecksum (
  IN CONST QEMU_LOADER_ADD_CHECKSUM *AddChecksum,
  IN CONST ORDERED_COLLECTION       *Tracker
  )
{
  ORDERED_COLLECTION_ENTRY *TrackerEntry;
  BLOB                     *Blob;

  if (AddChecksum->File[QEMU_LOADER_FNAME_SIZE - 1] != '\0') {
    DEBUG ((EFI_D_ERROR, "%a: malformed file name\n", __FUNCTION__));
    return EFI_PROTOCOL_ERROR;
  }

  TrackerEntry = OrderedCollectionFind (Tracker, AddChecksum->File);
  if (TrackerEntry == NULL) {
    DEBUG ((EFI_D_ERROR, "%a: invalid blob reference \"%a\"\n", __FUNCTION__,
      AddChecksum->File));
    return EFI_PROTOCOL_ERROR;
  }

  Blob = OrderedCollectionUserStruct (TrackerEntry);
  if (Blob->Size <= AddChecksum->ResultOffset ||
      Blob->Size < AddChecksum->Length ||
      Blob->Size - AddChecksum->Length < AddChecksum->Start) {
    DEBUG ((EFI_D_ERROR, "%a: invalid checksum range in \"%a\"\n",
      __FUNCTION__, AddChecksum->File));
    return EFI_PROTOCOL_ERROR;
  }

  Blob->Base[AddChecksum->ResultOffset] = CalculateCheckSum8 (
                                           Blob->Base + AddChecksum->Start,
                                           AddChecksum->Length
                                           );
  DEBUG ((EFI_D_VERBOSE, "%a: File=\"%a\" ResultOffset=0x%x Start=0x%x "
    "Length=0x%x\n", __FUNCTION__, AddChecksum->File,
    AddChecksum->ResultOffset, AddChecksum->Start, AddChecksum->Length));
  return EFI_SUCCESS;
}
Beispiel #8
0
VOID
BertSetAcpiTable (
  IN BERT_CONTEXT *Context
)
{
  UINTN          AcpiTableHandle;
  EFI_STATUS     Status;
  if (Context == NULL) {
    return;
  }
  EFI_ACPI_6_0_BOOT_ERROR_RECORD_TABLE_HEADER* Bert = Context->BertHeader;
  Bert->Header.Checksum = CalculateCheckSum8 ((UINT8*)(Bert), Bert->Header.Length);
  AcpiTableHandle = 0;
  Status = mAcpiTableProtocol->InstallAcpiTable (
                                 mAcpiTableProtocol,
                                 Bert,
                                 Bert->Header.Length,
                                 &AcpiTableHandle);
  ASSERT_EFI_ERROR (Status);
  return;
}
Beispiel #9
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 #10
0
/**

  This function set TXT HEAP.

  @param MleLoadAddress  MLE address
  @param MleLoadSize     MLE size
  @param PageTableBase   page table base

**/
VOID
TxtSetupHeap (
  IN UINT64  MleLoadAddress,
  IN UINT64  MleLoadSize,
  IN UINT64  PageTableBase
  )
{
  VOID                              *TxtOsMleData;
  MLE_PRIVATE_DATA                  *MlePrivateData;
  DCE_PRIVATE_DATA                  *DcePrivateData;
  TXT_OS_TO_SINIT_DATA              *OsSinitData;
  TXT_SINIT_TO_MLE_DATA             *SinitMleData;
  TXT_ACM_FORMAT                    *SinitAcm;
  TXT_CHIPSET_ACM_INFORMATION_TABLE *ChipsetAcmInformationTable;
  UINTN                             TxtHeapSize;
  UINTN                             TxtHeapOccupiedSize;

  //
  // MlePrivateData
  //
  TxtOsMleData = GetTxtOsToMleData();
  DEBUG((EFI_D_INFO, "(TXT) TxtOsMleData - 0x%x\n", TxtOsMleData));
  *((UINT64 *)TxtOsMleData - 1) = sizeof(UINT64) + sizeof(TXT_OS_TO_MLE_DATA_STRUCT);

  MlePrivateData = GetMlePrivateData ();
  DcePrivateData = &MlePrivateData->DcePrivateData;
  AsmReadGdtr (&MlePrivateData->Gdtr);
  AsmReadIdtr (&MlePrivateData->Idtr);
  MlePrivateData->Ds = AsmReadDs ();

  MlePrivateData->TempEsp = (UINT32)(UINT32)((UINTN)GetTxtHeap () + GetTxtHeapSize () - MLE_TEMP_STACK_SIZE_RLP - 0x20);

  //
  // Patch CS/Offset in stack
  //
  // +---------+
  // |  Offset |
  // +---------+
  // |    CS   |
  // +---------+
  // |  Dummy  |
  // +---------+
  // |  Dummy  |
  // +---------+
  // |  Dummy  |
  // +---------+
  // |  Dummy  |
  // +---------+ <- TempEsp
  if (PostInitAddr != 0) {
    MlePrivateData->PostSinitOffset  = (UINT32)((UINTN)AsmMleEntryPoint + PostInitAddr);
    MlePrivateData->PostSinitSegment = (UINT32)AsmReadCs();
  }

  MlePrivateData->Lock = 0;
  MlePrivateData->RlpInitializedNumber = 0;

  //
  // OsSinitData
  //
  OsSinitData = GetTxtOsToSinitData ();
  DEBUG((EFI_D_INFO, "(TXT) OsSinitData - 0x%x\n", OsSinitData));
  *((UINT64 *)OsSinitData - 1) = sizeof(UINT64) + sizeof(*OsSinitData);
  OsSinitData->Version = TXT_OS_TO_SINIT_DATA_VERSION;
  OsSinitData->Flags = 0;
  OsSinitData->MLEPageTableBase = PageTableBase;

  //
  // We copy MleHeader to DPR
  //
  {
    TXT_MLE_HEADER   *MleHeader;

    MleHeader = (TXT_MLE_HEADER *)(UINTN)MleLoadAddress;
    CopyMem (&MleHeader->Uuid, &gMleHeaderUuid, sizeof(gMleHeaderUuid));
    MleHeader->HeaderLen = sizeof(*MleHeader);
    MleHeader->Version = TXT_MLE_HEADER_VERSION;

    MleHeader->EntryPoint = (UINT32)(UINTN)MleHeader + sizeof(*MleHeader);
    if (MleHeader->Version < TXT_MLE_HEADER_VERSION_2_1) {
      MleHeader->EntryPoint -= (sizeof(MleHeader->CmdlineStart) + sizeof(MleHeader->CmdlineEnd));
    }
    //
    // Patch the instruction for ILP
    //
    *(UINT8 *)(UINTN)MleHeader->EntryPoint = 0x90; // nop
    *(UINT8 *)((UINTN)MleHeader->EntryPoint + 1) = 0xE9; // near jmp
    *(UINT32 *)((UINTN)MleHeader->EntryPoint + 2) = (UINT32)((UINTN)AsmMleEntryPoint - ((UINTN)MleHeader->EntryPoint + 6)); // minus next instruction
    //
    // Patch the instrution for RLPs: cli, hlt, and jmp $-2
    //
    *(UINT32 *)((UINTN)MleHeader->EntryPoint + 6) = 0xFCEBF4FA;

    MleHeader->EntryPoint -= (UINT32)PageTableBase;

    if (MleHeader->Version >= TXT_MLE_HEADER_VERSION_1_1) {
      MleHeader->FirstValidPage = (UINT32)MleLoadAddress;
      MleHeader->FirstValidPage -= (UINT32)PageTableBase;
      MleHeader->MleStart = MleHeader->FirstValidPage;
      //MleHeader->MleEnd = MleHeader->MleStart + sizeof(*MleHeader) + 10; // Offset (1 nop + 5 jmp + 4 deadloop)
      MleHeader->MleEnd = MleHeader->MleStart + (UINT32)MleLoadSize;
    }

    if (MleHeader->Version >= TXT_MLE_HEADER_VERSION_2) {
      MleHeader->Capabilities = TXT_MLE_SINIT_CAPABILITY_GETSET_WAKEUP | TXT_MLE_SINIT_CAPABILITY_MONITOR_ADDRESS_RLP_WAKEUP;
      MleHeader->Capabilities |= TXT_MLE_SINIT_CAPABILITY_ECX_HAS_PAGE_TABLE;
#ifdef STM_SUPPORT
      MleHeader->Capabilities |= TXT_MLE_SINIT_CAPABILITY_STM;
#endif
    }

    if (MleHeader->Version >= TXT_MLE_HEADER_VERSION_2_1) {
      MleHeader->CmdlineStart = 0; // Not use
      MleHeader->CmdlineEnd   = 0; // Not use
    }

    //
    // Done
    //
    OsSinitData->MLEHeaderBase = (UINT64)(UINTN)MleHeader;
    OsSinitData->MLEHeaderBase -= PageTableBase;
    OsSinitData->MLESize = (UINT64)(MleHeader->MleEnd - MleHeader->MleStart);
  }

  OsSinitData->PMRLowBase  = MlePrivateData->DcePrivateData.PmrLowBase;
  OsSinitData->PMRLowSize  = MlePrivateData->DcePrivateData.PmrLowSize;
  OsSinitData->PMRHighBase = MlePrivateData->DcePrivateData.PmrHighBase;
  OsSinitData->PMRHighSize = MlePrivateData->DcePrivateData.PmrHighSize;
  OsSinitData->LCPPOBase   = MlePrivateData->DcePrivateData.LcpPoBase;
  OsSinitData->LCPPOSize   = MlePrivateData->DcePrivateData.LcpPoSize;

  SinitAcm = (TXT_ACM_FORMAT *)(UINTN)TxtPubRead32 (TXT_SINIT_BASE);
  ChipsetAcmInformationTable = (TXT_CHIPSET_ACM_INFORMATION_TABLE *) \
                               ((UINTN)(SinitAcm + 1) + 
                               SinitAcm->KeySize * 4 + 
                               sizeof(UINT32) + 
                               ACM_PKCS_1_5_RSA_SIGNATURE_SIZE + 
                               SinitAcm->ScratchSize * 4
                               );

  if ((ChipsetAcmInformationTable->Capabilities & TXT_MLE_SINIT_CAPABILITY_MONITOR_ADDRESS_RLP_WAKEUP) != 0) {
    OsSinitData->Capabilities = TXT_MLE_SINIT_CAPABILITY_MONITOR_ADDRESS_RLP_WAKEUP;
  } else {
    OsSinitData->Capabilities = TXT_MLE_SINIT_CAPABILITY_GETSET_WAKEUP;
  }
  OsSinitData->Version = ChipsetAcmInformationTable->OsSinitTableVer;
  if (ChipsetAcmInformationTable->OsSinitTableVer >= TXT_OS_TO_SINIT_DATA_VERSION_5) {
    OsSinitData->RsdpPtr = (UINT64)(UINTN)FindAcpiRsdPtr ();
    if (OsSinitData->RsdpPtr == 0) {
      OsSinitData->RsdpPtr = (UINT64)(UINTN)&MlePrivateData->UefiRsdp;
    }
    if (ChipsetAcmInformationTable->OsSinitTableVer >= TXT_OS_TO_SINIT_DATA_VERSION_6) {
      if (ChipsetAcmInformationTable->OsSinitTableVer >= TXT_OS_TO_SINIT_DATA_VERSION_7) {
        OsSinitData->Flags = TXT_OS_TO_SINIT_DATA_FLAGS_MAX_AGILE_POLICY;
      }
      //
      // Fill Event Log data there
      //
      TXT_HEAP_EXT_DATA_ELEMENT             *Element;
      TXT_HEAP_EVENTLOG_EXT_ELEMENT         *EventLogElement;
      TXT_EVENT_LOG_CONTAINER               *EventLog;
      TXT_HEAP_EVENT_LOG_POINTER_ELEMENT2   *EventLogPointerElement2;
      TXT_HEAP_EVENT_LOG_POINTER_ELEMENT2_1 *EventLogPointerElement2_1;
      TXT_HEAP_EVENT_LOG_DESCR              *EventLogDesc;
      UINTN                                 Index;
      TCG_LOG_DESCRIPTOR                    *TcgLogDesc;
      TCG_PCR_EVENT_HDR                     *PcrEvent;

      *((UINT64 *)OsSinitData - 1) = sizeof(UINT64) + sizeof(*OsSinitData);

      Element = (TXT_HEAP_EXT_DATA_ELEMENT *)(OsSinitData + 1);

      if (DcePrivateData->TpmType == FRM_TPM_TYPE_TPM12) {
        // TPM1.2
        Element->Type = TXT_HEAP_EXTDATA_TYPE_EVENTLOG_PTR;
        Element->Size = sizeof(TXT_HEAP_EXT_DATA_ELEMENT) + sizeof(TXT_HEAP_EVENTLOG_EXT_ELEMENT);
        EventLogElement = (TXT_HEAP_EVENTLOG_EXT_ELEMENT *)(Element + 1);
        DcePrivateData->EventLogElement = EventLogElement;

        //
        // Init EventLogContainer
        //
        EventLog = (TXT_EVENT_LOG_CONTAINER *)(UINTN)(MlePrivateData->DcePrivateData.EventLogBase);
        ZeroMem(EventLog, MAX_EVENT_LOG_BUFFER_SIZE);
        CopyMem(EventLog->Signature, TXT_EVENTLOG_SIGNATURE, sizeof(TXT_EVENTLOG_SIGNATURE));
        EventLog->ContainerVersionMajor = TXT_EVENTLOG_CONTAINER_MAJOR_VERSION;
        EventLog->ContainerVersionMinor = TXT_EVENTLOG_CONTAINER_MINOR_VERSION;
        EventLog->PcrEventVersionMajor = TXT_EVENTLOG_EVENT_MAJOR_VERSION;
        EventLog->PcrEventVersionMinor = TXT_EVENTLOG_EVENT_MINOR_VERSION;
        EventLog->Size = MAX_EVENT_LOG_BUFFER_SIZE;
        EventLog->PcrEventsOffset = sizeof(*EventLog);
        EventLog->NextEventOffset = sizeof(*EventLog);

        EventLogElement->EventLogAddress = (UINT64)(UINTN)EventLog;

        *((UINT64 *)OsSinitData - 1) += Element->Size;
        Element = (TXT_HEAP_EXT_DATA_ELEMENT *)((UINTN)Element + Element->Size);

      }
      if (DcePrivateData->TpmType == FRM_TPM_TYPE_TPM2) {
        // TPM2.0
        UINT16 TpmHashAlgo[] = { TPM_ALG_SHA1, TPM_ALG_SHA256, TPM_ALG_SHA384, TPM_ALG_SHA512, TPM_ALG_SM3_256 };
        UINTN  SubIndex;

        DcePrivateData->EventHashAlgoIDCount = 0;
        for (Index = 0; Index < sizeof(TpmHashAlgo) / sizeof(TpmHashAlgo[0]); Index++) {
          if ((DcePrivateData->ActivePcrBanks & (1 << Index)) != 0) {
            for (SubIndex = 0; SubIndex < DcePrivateData->AcmTpmHashAlgoIDCount; SubIndex++) {
              if (DcePrivateData->AcmTpmHashAlgoID[SubIndex] == TpmHashAlgo[Index]) {
                // Both TPM and ACM support this hash algo.
                DcePrivateData->EventHashAlgoID[DcePrivateData->EventHashAlgoIDCount] = TpmHashAlgo[Index];
                DcePrivateData->EventHashAlgoIDCount++;
              }
            }
          }
        }

        if ((DcePrivateData->AcmCapabilities & TXT_MLE_SINIT_CAPABILITY_TCG2_COMPATIBILE_EVENTLOG) == 0) {
          Element->Type = TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2;
          EventLogPointerElement2 = (TXT_HEAP_EVENT_LOG_POINTER_ELEMENT2 *)(Element + 1);
          DcePrivateData->EventLogPointerElement2 = EventLogPointerElement2;
          EventLogPointerElement2->Count = DcePrivateData->EventHashAlgoIDCount;
          EventLogDesc = (TXT_HEAP_EVENT_LOG_DESCR *)(EventLogPointerElement2 + 1);

          Element->Size = sizeof(TXT_HEAP_EXT_DATA_ELEMENT) + sizeof(TXT_HEAP_EVENT_LOG_POINTER_ELEMENT2) + EventLogPointerElement2->Count * sizeof(TXT_HEAP_EVENT_LOG_DESCR);

          for (Index = 0; Index < EventLogPointerElement2->Count; Index++, EventLogDesc++) {
            EventLogDesc->HashAlgID = DcePrivateData->EventHashAlgoID[Index];
            EventLogDesc->Reserved = 0;
            EventLogDesc->PhysicalAddress = (UINT64)(UINTN)(MlePrivateData->DcePrivateData.EventLogBase + MAX_EVENT_LOG_BUFFER_SIZE * (Index + 1));
            ZeroMem((VOID *)(UINTN)EventLogDesc->PhysicalAddress, MAX_EVENT_LOG_BUFFER_SIZE);
            EventLogDesc->AllocatedEventContainerSize = MAX_EVENT_LOG_BUFFER_SIZE;
            if (EventLogDesc->HashAlgID == TPM_ALG_SHA) {
              PcrEvent = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogDesc->PhysicalAddress;
              TcgLogDesc = (TCG_LOG_DESCRIPTOR *)(PcrEvent + 1);
              PcrEvent->PCRIndex = 0;
              PcrEvent->EventType = EV_NO_ACTION;
              ZeroMem(&PcrEvent->Digest, sizeof(PcrEvent->Digest));
              PcrEvent->EventSize = sizeof(TCG_LOG_DESCRIPTOR);
              CopyMem(TcgLogDesc->Signature, TCG_LOG_DESCRIPTOR_SIGNATURE, sizeof(TCG_LOG_DESCRIPTOR_SIGNATURE));
              TcgLogDesc->Revision    = TCG_LOG_DESCRIPTOR_REVISION;
              TcgLogDesc->DigestAlgID = DIGEST_ALG_ID_SHA_1;
              TcgLogDesc->DigestSize  = SHA1_DIGEST_SIZE;
              EventLogDesc->FirstRecordOffset = sizeof(TCG_PCR_EVENT_HDR) + PcrEvent->EventSize;
              EventLogDesc->NextRecordOffset = sizeof(TCG_PCR_EVENT_HDR) + PcrEvent->EventSize;
            } else {
              EventLogDesc->FirstRecordOffset = 0;
              EventLogDesc->NextRecordOffset = 0;
            }
          }
        } else {
          Element->Type = TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1;
          EventLogPointerElement2_1 = (TXT_HEAP_EVENT_LOG_POINTER_ELEMENT2_1 *)(Element + 1);
          DcePrivateData->EventLogPointerElement2_1 = EventLogPointerElement2_1;
          EventLogPointerElement2_1->PhysicalAddress = (UINT64)(UINTN)(MlePrivateData->DcePrivateData.EventLogBase + MAX_EVENT_LOG_BUFFER_SIZE);
          ZeroMem((VOID *)(UINTN)EventLogPointerElement2_1->PhysicalAddress, MAX_EVENT_LOG_BUFFER_SIZE);
          EventLogPointerElement2_1->AllocatedEventContainerSize = MAX_EVENT_LOG_BUFFER_SIZE * 5;
          EventLogPointerElement2_1->FirstRecordOffset = 0;
          EventLogPointerElement2_1->NextRecordOffset = 0;
        }

        *((UINT64 *)OsSinitData - 1) += Element->Size;
        Element = (TXT_HEAP_EXT_DATA_ELEMENT *)((UINTN)Element + Element->Size);

      }

      Element->Type = TXT_HEAP_EXTDATA_TYPE_END;
      Element->Size = sizeof(TXT_HEAP_END_ELEMENT);

      *((UINT64 *)OsSinitData - 1) += sizeof(TXT_HEAP_END_ELEMENT);
    }
  } else {
    // Version 4
    *((UINT64 *)OsSinitData - 1) = sizeof(UINT64) + sizeof(*OsSinitData) - sizeof(UINT64);
  }

  //
  // SinitMleData
  //
  SinitMleData = GetTxtSinitToMleData ();
  DEBUG((EFI_D_INFO, "(TXT) SinitMleData - 0x%x\n", SinitMleData));
  *((UINT64 *)SinitMleData - 1) = 0;
  ZeroMem (SinitMleData, sizeof(*SinitMleData));

  TxtHeapSize = GetTxtHeapSize ();
  TxtHeapOccupiedSize = GetTxtHeapOccupiedSize ();
  DEBUG ((EFI_D_INFO, "(TXT) TXT Heap base    - %08x\n", GetTxtHeap ()));
  DEBUG ((EFI_D_INFO, "(TXT) TXT Heap size    - %08x\n", TxtHeapSize));
  DEBUG ((EFI_D_INFO, "(TXT) TXT BiosOsData   - %08x\n", GetTxtBiosToOsData()));
  DEBUG ((EFI_D_INFO, "(TXT) TXT OsMleData    - %08x\n", (UINTN)TxtOsMleData));
  DEBUG ((EFI_D_INFO, "(TXT) TXT OsSinitData  - %08x\n", (UINTN)OsSinitData));
  DEBUG ((EFI_D_INFO, "(TXT) TXT SinitMleData - %08x\n", (UINTN)SinitMleData));
  DEBUG ((EFI_D_INFO, "(TXT) TXT OccupiedSize - %08x\n", TxtHeapOccupiedSize));

  //
  // Check heap
  //
  if (TxtHeapOccupiedSize >= TxtHeapSize) {
    DEBUG ((EFI_D_ERROR, "(TXT) ERROR: TXT Heap overflow - Occupied (%08x), Allocated (%08x)\n", TxtHeapOccupiedSize, TxtHeapSize));
    ASSERT(FALSE);
  }

  if (OsSinitData->RsdpPtr != 0) {
    EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER   *Rsdp;
    EFI_ACPI_DESCRIPTION_HEADER                    *Rsdt;
    EFI_ACPI_DESCRIPTION_HEADER                    *Xsdt;
    // validate ACPI RSDP/RSDT/XSDT
    Rsdp = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)OsSinitData->RsdpPtr;
    DEBUG ((EFI_D_INFO, "(TXT) RSDP Address  - %08x\n", Rsdp));
    DEBUG ((EFI_D_INFO, "(TXT) RSDP Checksum - %02x\n", CalculateCheckSum8((UINT8 *)Rsdp, sizeof(EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER))));
    if (Rsdp->Revision >= 2) {
      DEBUG ((EFI_D_INFO, "(TXT) RSDP Length   - %08x\n", Rsdp->Length));
      DEBUG ((EFI_D_INFO, "(TXT) RSDP ExtendedChecksum - %02x\n", CalculateCheckSum8((UINT8 *)Rsdp, Rsdp->Length)));
    }
    Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->RsdtAddress;
    DEBUG ((EFI_D_INFO, "(TXT) RSDT Address  - %08x\n", Rsdt));
    DEBUG ((EFI_D_INFO, "(TXT) RSDT Length   - %08x\n", Rsdt->Length));
    DEBUG ((EFI_D_INFO, "(TXT) RSDT Checksum - %02x\n", CalculateCheckSum8((UINT8 *)Rsdt, Rsdt->Length)));
    if (Rsdp->Revision >= 2) {
      Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->XsdtAddress;
      DEBUG ((EFI_D_INFO, "(TXT) XSDT Address  - %016lx\n", Xsdt));
      DEBUG ((EFI_D_INFO, "(TXT) XSDT Length   - %08x\n", Xsdt->Length));
      DEBUG ((EFI_D_INFO, "(TXT) XSDT Checksum - %02x\n", CalculateCheckSum8((UINT8 *)Xsdt, Xsdt->Length)));
    }
  }

  return ;
}
Beispiel #11
0
/**
  Publish and remove the iSCSI Boot Firmware Table according to the iSCSI
  session status.
**/
VOID
IScsiPublishIbft (
  VOID
  )
{
  EFI_STATUS                                Status;
  EFI_ACPI_TABLE_PROTOCOL                   *AcpiTableProtocol;
  EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table;
  UINTN                                     HandleCount;
  EFI_HANDLE                                *HandleBuffer;
  UINT8                                     *Heap;
  UINT8                                     Checksum;
  UINTN                                         Index;
  EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *Rsdp;
  EFI_ACPI_DESCRIPTION_HEADER                   *Rsdt;

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


  //
  // Find ACPI table RSD_PTR from system table
  //
  for (Index = 0, Rsdp = NULL; Index < gST->NumberOfTableEntries; Index++) {
    if (CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpi20TableGuid) ||
      CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpi10TableGuid) ||
      CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpiTableGuid)
      ) {
      //
      // A match was found.
      //
      Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) gST->ConfigurationTable[Index].VendorTable;
      break;
    }
  }

  if (Rsdp == NULL) {
    return ;
  } else {
    Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress;
  }


  if (mIbftInstalled) {
    Status = AcpiTableProtocol->UninstallAcpiTable (
                                  AcpiTableProtocol,
                                  mTableKey
                                  );
    if (EFI_ERROR (Status)) {
      return ;
    }
    mIbftInstalled = FALSE;
  }

  //
  // Get all iSCSI private protocols.
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiCallerIdGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    return ;
  }
  //
  // Allocate 4k bytes to hold the ACPI table.
  //
  Table = AllocateZeroPool (IBFT_MAX_SIZE);
  if (Table == NULL) {
    return ;
  }

  Heap = (UINT8 *) Table + IBFT_HEAP_OFFSET;

  //
  // Fill in the various section of the iSCSI Boot Firmware Table.
  //
  IScsiInitIbfTableHeader (Table, Rsdt->OemId, &Rsdt->OemTableId);
  IScsiInitControlSection (Table, HandleCount);
  IScsiFillInitiatorSection (Table, &Heap, HandleBuffer[0]);
  IScsiFillNICAndTargetSections (Table, &Heap, HandleCount, HandleBuffer);

  Checksum = CalculateCheckSum8((UINT8 *)Table, Table->Length);
  Table->Checksum = Checksum;

  FreePool (HandleBuffer);

  //
  // Install or update the iBFT table.
  //
  Status = AcpiTableProtocol->InstallAcpiTable (
                                AcpiTableProtocol,
                                Table,
                                Table->Length,
                                &mTableKey
                                );
  if (EFI_ERROR(Status)) {
    return;
  }

  mIbftInstalled = TRUE;
  FreePool (Table);
}
Beispiel #12
0
EFI_STATUS
AcpiPlatformEntryPoint (
  IN EFI_HANDLE     ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  EFI_STATUS                   Status;
  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
  INTN                         Instance;
  EFI_ACPI_COMMON_HEADER       *CurrentTable;
  UINTN                        TableHandle;
  UINT32                       FvStatus;
  UINTN                        Size;
  EFI_ACPI_TABLE_VERSION       Version;
  QNC_DEVICE_ENABLES           QNCDeviceEnables;
  EFI_HANDLE                   Handle;
  UINTN                         Index;
  PCI_DEVICE_INFO               *PciDeviceInfo;
  EFI_ACPI_HANDLE               PciRootHandle;
  BOOLEAN                       UpdatePRT;
  BOOLEAN                       UpdatePRW;
  PCI_DEVICE_SETTING            *mConfigData;

  Instance = 0;
  TableHandle = 0;
  CurrentTable = NULL;
  mConfigData  = NULL;
  QNCDeviceEnables.Uint32 = PcdGet32 (PcdDeviceEnables);

  //
  // Initialize the EFI Driver Library
  //

  ASSERT (sizeof (EFI_GLOBAL_NVS_AREA) == 512);

  Status = gBS->AllocatePool (
                   EfiACPIMemoryNVS,
                   sizeof (EFI_GLOBAL_NVS_AREA),
                   (VOID**)&mGlobalNvsArea.Area
                   );

  Handle = NULL;
  Status = gBS->InstallProtocolInterface (
                  &Handle,
                  &gEfiGlobalNvsAreaProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &mGlobalNvsArea
                  );

  ASSERT_EFI_ERROR (Status);
  if (!EFI_ERROR (Status)) {
    SetMem (
      mGlobalNvsArea.Area,
      sizeof (EFI_GLOBAL_NVS_AREA),
      0
      );
  }

  //
  // Initialize the data.  Eventually, this will be controlled by setup options.
  //
  mGlobalNvsArea.Area->HpetEnable           =  PcdGetBool (PcdHpetEnable);  
  mGlobalNvsArea.Area->Pm1blkIoBaseAddress  =  PcdGet16(PcdPm1blkIoBaseAddress);
  mGlobalNvsArea.Area->PmbaIoBaseAddress    =  PcdGet16(PcdPmbaIoBaseAddress);   
  mGlobalNvsArea.Area->Gpe0blkIoBaseAddress =  PcdGet16(PcdGpe0blkIoBaseAddress);
  mGlobalNvsArea.Area->GbaIoBaseAddress     =  PcdGet16(PcdGbaIoBaseAddress);                        
  mGlobalNvsArea.Area->SmbaIoBaseAddress    =  PcdGet16(PcdSmbaIoBaseAddress);
  mGlobalNvsArea.Area->SpiDmaIoBaseAddress  =  PcdGet16(PcdSpiDmaIoBaseAddress);
  mGlobalNvsArea.Area->WdtbaIoBaseAddress   =  PcdGet16(PcdWdtbaIoBaseAddress);
  mGlobalNvsArea.Area->HpetBaseAddress      =  (UINT32)PcdGet64(PcdHpetBaseAddress);       
  mGlobalNvsArea.Area->HpetSize             =  (UINT32)PcdGet64(PcdHpetSize);              
  mGlobalNvsArea.Area->PciExpressBaseAddress=  (UINT32)PcdGet64(PcdPciExpressBaseAddress); 
  mGlobalNvsArea.Area->PciExpressSize       =  (UINT32)PcdGet64(PcdPciExpressSize);        
  mGlobalNvsArea.Area->RcbaMmioBaseAddress  =  (UINT32)PcdGet64(PcdRcbaMmioBaseAddress); 
  mGlobalNvsArea.Area->RcbaMmioSize         =  (UINT32)PcdGet64(PcdRcbaMmioSize);        
  mGlobalNvsArea.Area->IoApicBaseAddress    =  (UINT32)PcdGet64(PcdIoApicBaseAddress);     
  mGlobalNvsArea.Area->IoApicSize           =  (UINT32)PcdGet64(PcdIoApicSize);
  mGlobalNvsArea.Area->TpmPresent           =  (UINT32)(FALSE);

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

  //
  // Initialize MADT table
  // 
  Status = MadtTableInitialize (&CurrentTable, &Size);
  ASSERT_EFI_ERROR (Status);
  //
  // Perform any table specific updates.
  //
  AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version);

  //
  // Update the check sum 
  // It needs to be zeroed before the checksum calculation
  //
  ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;  
  ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 
    CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);
    
  //
  // Add the table
  //
  TableHandle = 0;
  Status = AcpiTable->InstallAcpiTable (
                            AcpiTable,
                            CurrentTable,
                            CurrentTable->Length,
                          &TableHandle
                          );
  ASSERT_EFI_ERROR (Status);
  CurrentTable = NULL;

  //
  // Init Pci Device PRT PRW information structure from PCD
  //
  mConfigData = (PCI_DEVICE_SETTING *)AllocateZeroPool (sizeof (PCI_DEVICE_SETTING));
  ASSERT_EFI_ERROR (mConfigData);
  InitPciDeviceInfoStructure (mConfigData);
  //
  // Get the Acpi SDT protocol for manipulation on acpi table
  //
  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&mAcpiSdt);
  ASSERT_EFI_ERROR (Status);
  //
  // Locate the firmware volume protocol
  //
  Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol, 1);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }
  //
  // Read tables from the storage file.
  //

  while (Status == EFI_SUCCESS) {

    Status = FwVol->ReadSection (
                      FwVol,
                      (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
                      EFI_SECTION_RAW,
                      Instance,
                      (VOID**)&CurrentTable,
                      &Size,
                      &FvStatus
                      );

    if (!EFI_ERROR(Status)) {
      //
      // Perform any table specific updates.
      //
      AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version);

      //
      // Update the check sum 
      // It needs to be zeroed before the checksum calculation
      //
      ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;   
      ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 
        CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);
        
      //
      // Add the table
      //
      TableHandle = 0;
      Status = AcpiTable->InstallAcpiTable (
                            AcpiTable,
                              CurrentTable,
                            ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length,
                              &TableHandle
                              );
      if (EFI_ERROR(Status)) {
        return EFI_ABORTED;
      }
      //
      // If this table is the DSDT table, then update the _PRT and _PRW based on
      // the settings from pcds
      //
      if (CurrentTable->Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
        //
        // Create the root handle for DSDT table
        //
        Status = mAcpiSdt->OpenSdt (TableHandle, &mDsdtHandle);
        ASSERT_EFI_ERROR (Status);

        PciRootHandle = NULL;
        PciRootHandle = SdtGetRootBridgeHandle (mAcpiSdt, mDsdtHandle);
        ASSERT (PciRootHandle != NULL);	

        PciDeviceInfo = NULL;
        for (Index = 0; Index < mConfigData->PciDeviceInfoNumber; Index++) {
          PciDeviceInfo = &(mConfigData->PciDeviceInfo[Index]);

          //
          // Check whether this is a valid item
          //
          if ((PciDeviceInfo->BridgeAddress != 0xFFFFFFFF) && (PciDeviceInfo->DeviceAddress != 0xFFFFFFFF)) {

            //DEBUG ((EFI_D_ERROR, "Valid pci info structure: bridge address:0x%x, device address:0x%x\n", PciDeviceInfo->BridgeAddress, PciDeviceInfo->DeviceAddress));

            UpdatePRT = FALSE;
            UpdatePRW = FALSE;

            SdtCheckPciDeviceInfoChanged (PciDeviceInfo, &UpdatePRT, &UpdatePRW);
            //
            // Check whether there is any valid pci routing item
            //
            if (UpdatePRT) {
              //
              // Update the pci routing information
              //
              //DEBUG ((EFI_D_ERROR, "Update _PRT\n"));
              SdtUpdatePciRouting (mAcpiSdt, PciRootHandle, PciDeviceInfo);  						
            }
            //
            // Check whether there is any valid pci routing item
            //
            if (UpdatePRW) {
              //
              // Update the pci wakeup information
              //
              //DEBUG ((EFI_D_ERROR, "Update _PRW\n"));
              SdtUpdatePowerWake (mAcpiSdt, PciRootHandle, PciDeviceInfo);				
            }
          }
        }
        Status = mAcpiSdt->Close (PciRootHandle);
        ASSERT_EFI_ERROR (Status);
        //
        // Mark the root handle as modified , let SDT protocol recaculate the checksum
        //
        ((EFI_AML_HANDLE *)mDsdtHandle)->Modified = TRUE;
        Status = mAcpiSdt->Close (mDsdtHandle);
        ASSERT_EFI_ERROR (Status);
      } 
      //
      // Increment the instance
      //
      Instance++;
      CurrentTable = NULL;
    }
  }

  gBS->FreePool (mConfigData);
  return EFI_SUCCESS;
}
Beispiel #13
0
/**
  Publish and remove the iSCSI Boot Firmware Table according to the iSCSI
  session status.
**/
VOID
IScsiPublishIbft (
  VOID
  )
{
  EFI_STATUS                                Status;
  EFI_ACPI_TABLE_PROTOCOL                   *AcpiTableProtocol;
  EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table;
  UINTN                                     HandleCount;
  EFI_HANDLE                                *HandleBuffer;
  UINT8                                     *Heap;
  UINT8                                     Checksum;
  EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *Rsdp;
  EFI_ACPI_DESCRIPTION_HEADER                   *Rsdt;
  EFI_ACPI_DESCRIPTION_HEADER                   *Xsdt;

  Rsdt = NULL;
  Xsdt = NULL;

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


  //
  // Find ACPI table RSD_PTR from system table
  //
  Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID **) &Rsdp);
  if (EFI_ERROR (Status)) {
    Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **) &Rsdp);
  }

  if (EFI_ERROR (Status) || (Rsdp == NULL)) {
    return ;
  } else if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION && Rsdp->XsdtAddress != 0) {
    Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->XsdtAddress;
  } else if (Rsdp->RsdtAddress != 0) {
    Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress;
  }

  if ((Xsdt == NULL) && (Rsdt == NULL)) {
    return ;
  }

  if (mIbftInstalled) {
    Status = AcpiTableProtocol->UninstallAcpiTable (
                                  AcpiTableProtocol,
                                  mTableKey
                                  );
    if (EFI_ERROR (Status)) {
      return ;
    }
    mIbftInstalled = FALSE;
  }

  //
  // Get all iSCSI private protocols.
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiCallerIdGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    return ;
  }
  //
  // Allocate 4k bytes to hold the ACPI table.
  //
  Table = AllocateZeroPool (IBFT_MAX_SIZE);
  if (Table == NULL) {
    return ;
  }

  Heap = (UINT8 *) Table + IBFT_HEAP_OFFSET;

  //
  // Fill in the various section of the iSCSI Boot Firmware Table.
  //
  if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {
    IScsiInitIbfTableHeader (Table, Xsdt->OemId, &Xsdt->OemTableId);
  } else {
    IScsiInitIbfTableHeader (Table, Rsdt->OemId, &Rsdt->OemTableId);
  }

  IScsiInitControlSection (Table, HandleCount);
  IScsiFillInitiatorSection (Table, &Heap, HandleBuffer[0]);
  IScsiFillNICAndTargetSections (Table, &Heap, HandleCount, HandleBuffer);

  Checksum = CalculateCheckSum8((UINT8 *)Table, Table->Length);
  Table->Checksum = Checksum;

  FreePool (HandleBuffer);

  //
  // Install or update the iBFT table.
  //
  Status = AcpiTableProtocol->InstallAcpiTable (
                                AcpiTableProtocol,
                                Table,
                                Table->Length,
                                &mTableKey
                                );
  if (EFI_ERROR(Status)) {
    return;
  }

  mIbftInstalled = TRUE;
  FreePool (Table);
}
Beispiel #14
0
/**
  Create UX capsule.

  @retval EFI_SUCCESS            The capsule header is appended.
  @retval EFI_UNSUPPORTED        Input parameter is not valid.
  @retval EFI_OUT_OF_RESOURCES   No enough resource to create UX capsule.
**/
EFI_STATUS
CreateBmpFmp (
  VOID
  )
{
  CHAR16                                        *OutputCapsuleName;
  VOID                                          *BmpBuffer;
  UINTN                                         FileSize;
  CHAR16                                        *BmpName;
  UINT8                                         *FullCapsuleBuffer;
  UINTN                                         FullCapsuleBufferSize;
  EFI_DISPLAY_CAPSULE                           *DisplayCapsule;
  EFI_STATUS                                    Status;
  EFI_GRAPHICS_OUTPUT_PROTOCOL                  *Gop;

  Status = gBS->LocateProtocol(&gEfiGraphicsOutputProtocolGuid, NULL, (VOID **)&Gop);
  if (EFI_ERROR(Status)) {
    Print(L"CapsuleApp: NO GOP is found.\n");
    return EFI_UNSUPPORTED;
  }
  Print(L"Current GOP: Mode - %d, ", Gop->Mode->Mode);
  Print(L"HorizontalResolution - %d, ", Gop->Mode->Info->HorizontalResolution);
  Print(L"VerticalResolution - %d\n", Gop->Mode->Info->VerticalResolution);
  // HorizontalResolution >= BMP_IMAGE_HEADER.PixelWidth
  // VerticalResolution   >= BMP_IMAGE_HEADER.PixelHeight

  if (Argc != 5) {
    Print(L"CapsuleApp: Invalid Parameter.\n");
    return EFI_UNSUPPORTED;
  }

  if (StrCmp(Argv[3], L"-O") != 0) {
    Print(L"CapsuleApp: NO output capsule name.\n");
    return EFI_UNSUPPORTED;
  }
  OutputCapsuleName = Argv[4];

  BmpBuffer = NULL;
  FileSize = 0;
  FullCapsuleBuffer = NULL;

  BmpName = Argv[2];
  Status = ReadFileToBuffer(BmpName, &FileSize, &BmpBuffer);
  if (EFI_ERROR(Status)) {
    Print(L"CapsuleApp: BMP image (%s) is not found.\n", BmpName);
    goto Done;
  }

  FullCapsuleBufferSize = sizeof(EFI_DISPLAY_CAPSULE) + FileSize;
  FullCapsuleBuffer = AllocatePool(FullCapsuleBufferSize);
  if (FullCapsuleBuffer == NULL) {
    Print(L"CapsuleApp: Capsule Buffer size (0x%x) too big.\n", FullCapsuleBufferSize);
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  DisplayCapsule = (EFI_DISPLAY_CAPSULE *)FullCapsuleBuffer;
  CopyGuid(&DisplayCapsule->CapsuleHeader.CapsuleGuid, &gWindowsUxCapsuleGuid);
  DisplayCapsule->CapsuleHeader.HeaderSize = sizeof(DisplayCapsule->CapsuleHeader);
  DisplayCapsule->CapsuleHeader.Flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET;
  DisplayCapsule->CapsuleHeader.CapsuleImageSize = (UINT32)FullCapsuleBufferSize;

  DisplayCapsule->ImagePayload.Version = 1;
  DisplayCapsule->ImagePayload.Checksum = 0;
  DisplayCapsule->ImagePayload.ImageType = 0; // BMP
  DisplayCapsule->ImagePayload.Reserved = 0;
  DisplayCapsule->ImagePayload.Mode = Gop->Mode->Mode;
  DisplayCapsule->ImagePayload.OffsetX = 0;
  DisplayCapsule->ImagePayload.OffsetY = 0;

  CopyMem((DisplayCapsule + 1), BmpBuffer, FileSize);

  DisplayCapsule->ImagePayload.Checksum = CalculateCheckSum8(FullCapsuleBuffer, FullCapsuleBufferSize);

  Status = WriteFileFromBuffer(OutputCapsuleName, FullCapsuleBufferSize, FullCapsuleBuffer);
  Print(L"CapsuleApp: Write %s %r\n", OutputCapsuleName, Status);

Done:
  if (BmpBuffer != NULL) {
    FreePool(BmpBuffer);
  }

  if (FullCapsuleBuffer != NULL) {
    FreePool(FullCapsuleBuffer);
  }

  return Status;
}
EFI_STATUS
ConvertMpsTable (
    IN OUT VOID          **Table
                 )
/*++

  Routine Description:

  Convert MP Table if the Location of the SMBios Table is lower than Address 0x100000
  Assumption here:
  As in legacy Bios, MP table is required to place in E/F Seg,
  So here we just check if the range is E/F seg,
  and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData
  Arguments:
  Table     - pointer to the table

  Returns:
  EFI_SUCCESS - Convert Table successfully
  Other       - Failed

  --*/
{
    UINT32                                       Data32;
    UINT32                                       FPLength;
    EFI_LEGACY_MP_TABLE_FLOATING_POINTER         *MpsFloatingPointerOri;
    EFI_LEGACY_MP_TABLE_FLOATING_POINTER         *MpsFloatingPointerNew;
    EFI_LEGACY_MP_TABLE_HEADER                   *MpsTableOri;
    EFI_LEGACY_MP_TABLE_HEADER                   *MpsTableNew;
    VOID                                         *OemTableOri;
    VOID                                         *OemTableNew;
    EFI_STATUS                                   Status;
    EFI_PHYSICAL_ADDRESS                         BufferPtr;

    //
    // Get MP configuration Table
    //
    MpsFloatingPointerOri = (EFI_LEGACY_MP_TABLE_FLOATING_POINTER *)(UINTN)(*Table);
    //
    // Get Floating pointer structure length
    //
    FPLength = MpsFloatingPointerOri->Length * 16;
    ASSERT(CalculateSum8((UINT8*)MpsFloatingPointerOri, FPLength) == 0);
    Data32   = FPLength + SYS_TABLE_PAD (FPLength);
    MpsTableOri = (EFI_LEGACY_MP_TABLE_HEADER *)(UINTN)(MpsFloatingPointerOri->PhysicalAddress);
    ASSERT(MpsTableOri != NULL);
    ASSERT(CalculateSum8((UINT8*)MpsTableOri, MpsTableOri->BaseTableLength) == 0);

    Data32 += MpsTableOri->BaseTableLength;
    Data32 += MpsTableOri->ExtendedTableLength;
    if (MpsTableOri->OemTablePointer != 0x00) {
        Data32 += SYS_TABLE_PAD (Data32);
        Data32 += MpsTableOri->OemTableSize;
    }

    //
    // Relocate memory
    //
    BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;
    Status = gBS->AllocatePages (
        AllocateMaxAddress,
        EfiACPIMemoryNVS,
        EFI_SIZE_TO_PAGES(Data32),
        &BufferPtr
                                 );
    ASSERT_EFI_ERROR (Status);
    MpsFloatingPointerNew = (EFI_LEGACY_MP_TABLE_FLOATING_POINTER *)(UINTN)BufferPtr;
    CopyMem (MpsFloatingPointerNew, MpsFloatingPointerOri, FPLength);
    //
    // If Mp Table exists
    //
    if (MpsTableOri != NULL) {
        //
        // Get Mps table length, including Ext table
        //
        BufferPtr = BufferPtr + FPLength + SYS_TABLE_PAD (FPLength);
        MpsTableNew = (EFI_LEGACY_MP_TABLE_HEADER *)(UINTN)BufferPtr;
        CopyMem (MpsTableNew, MpsTableOri, MpsTableOri->BaseTableLength + MpsTableOri->ExtendedTableLength);

        if ((MpsTableOri->OemTableSize != 0x0000) && (MpsTableOri->OemTablePointer != 0x0000)){
            BufferPtr += MpsTableOri->BaseTableLength + MpsTableOri->ExtendedTableLength;
            BufferPtr += SYS_TABLE_PAD (BufferPtr);
            OemTableNew = (VOID *)(UINTN)BufferPtr;
            OemTableOri = (VOID *)(UINTN)MpsTableOri->OemTablePointer;
            CopyMem (OemTableNew, OemTableOri, MpsTableOri->OemTableSize);
            MpsTableNew->OemTablePointer = (UINT32)(UINTN)OemTableNew;
        }
        MpsTableNew->Checksum = 0;
        MpsTableNew->Checksum = CalculateCheckSum8 ((UINT8*)MpsTableNew, MpsTableOri->BaseTableLength);
        MpsFloatingPointerNew->PhysicalAddress = (UINT32)(UINTN)MpsTableNew;
        MpsFloatingPointerNew->Checksum = 0;
        MpsFloatingPointerNew->Checksum = CalculateCheckSum8 ((UINT8*)MpsFloatingPointerNew, FPLength);
    }
    //
    // Change the pointer
    //
    *Table = MpsFloatingPointerNew;

    return EFI_SUCCESS;
}
EFI_STATUS
ConvertSmbiosTable (
    IN OUT VOID        **Table
                    )
/*++

  Routine Description:

  Convert Smbios Table if the Location of the SMBios Table is lower than Address 0x100000
  Assumption here:
  As in legacy Bios, Smbios table is required to place in E/F Seg,
  So here we just check if the range is F seg,
  and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData
  Arguments:
  Table     - pointer to the table

  Returns:
  EFI_SUCCESS - Convert Table successfully
  Other       - Failed

  --*/
{
    SMBIOS_TABLE_ENTRY_POINT *SmbiosTableNew;
    SMBIOS_TABLE_ENTRY_POINT *SmbiosTableOri;
    EFI_STATUS               Status;
    UINT32                   SmbiosEntryLen;
    UINT32                   BufferLen;
    EFI_PHYSICAL_ADDRESS     BufferPtr;

    SmbiosTableNew  = NULL;
    SmbiosTableOri  = NULL;

    //
    // Get Smibos configuration Table
    //
    SmbiosTableOri =  (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)((*Table));


    ASSERT(CalculateSum8((UINT8*)SmbiosTableOri, sizeof(SMBIOS_TABLE_ENTRY_POINT)) == 0);
    //
    // Relocate the Smibos memory
    //
    BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;
    if (SmbiosTableOri->SmbiosBcdRevision != 0x21) {
        SmbiosEntryLen  = SmbiosTableOri->EntryPointLength;
    } else {
        //
        // According to Smbios Spec 2.4, we should set entry point length as 0x1F if version is 2.1
        //
        SmbiosEntryLen = 0x1F;
    }
    BufferLen = SmbiosEntryLen + SYS_TABLE_PAD(SmbiosEntryLen) + SmbiosTableOri->TableLength;
    Status = gBS->AllocatePages (
        AllocateMaxAddress,
        EfiACPIMemoryNVS,
        EFI_SIZE_TO_PAGES(BufferLen),
        &BufferPtr
                                 );
    ASSERT_EFI_ERROR (Status);
    SmbiosTableNew = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)BufferPtr;
    CopyMem (
        SmbiosTableNew,
        SmbiosTableOri,
        SmbiosEntryLen
             );
    //
    // Get Smbios Structure table address, and make sure the start address is 32-bit align
    //
    BufferPtr += SmbiosEntryLen + SYS_TABLE_PAD(SmbiosEntryLen);
    CopyMem (
        (VOID *)(UINTN)BufferPtr,
        (VOID *)(UINTN)(SmbiosTableOri->TableAddress),
        SmbiosTableOri->TableLength
             );
    SmbiosTableNew->TableAddress = (UINT32)BufferPtr;
    SmbiosTableNew->IntermediateChecksum = 0;
    SmbiosTableNew->IntermediateChecksum =
            CalculateCheckSum8 ((UINT8*)SmbiosTableNew + 0x10, SmbiosEntryLen -0x10);
    //
    // Change the SMBIOS pointer
    //
    *Table = SmbiosTableNew;

    return EFI_SUCCESS;
}
Beispiel #17
0
/**
  Create UX capsule.

  @retval EFI_SUCCESS            The capsule header is appended.
  @retval EFI_UNSUPPORTED        Input parameter is not valid.
  @retval EFI_OUT_OF_RESOURCES   No enough resource to create UX capsule.
**/
EFI_STATUS
CreateBmpFmp (
  VOID
  )
{
  CHAR16                                        *OutputCapsuleName;
  VOID                                          *BmpBuffer;
  UINTN                                         FileSize;
  CHAR16                                        *BmpName;
  UINT8                                         *FullCapsuleBuffer;
  UINTN                                         FullCapsuleBufferSize;
  EFI_DISPLAY_CAPSULE                           *DisplayCapsule;
  EFI_STATUS                                    Status;
  EFI_GRAPHICS_OUTPUT_PROTOCOL                  *Gop;
  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION          *Info;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL                 *GopBlt;
  UINTN                                         GopBltSize;
  UINTN                                         Height;
  UINTN                                         Width;

  Status = gBS->LocateProtocol(&gEfiGraphicsOutputProtocolGuid, NULL, (VOID **)&Gop);
  if (EFI_ERROR(Status)) {
    Print(L"CapsuleApp: NO GOP is found.\n");
    return EFI_UNSUPPORTED;
  }
  Info = Gop->Mode->Info;
  Print(L"Current GOP: Mode - %d, ", Gop->Mode->Mode);
  Print(L"HorizontalResolution - %d, ", Info->HorizontalResolution);
  Print(L"VerticalResolution - %d\n", Info->VerticalResolution);
  // HorizontalResolution >= BMP_IMAGE_HEADER.PixelWidth
  // VerticalResolution   >= BMP_IMAGE_HEADER.PixelHeight

  if (Argc != 5) {
    Print(L"CapsuleApp: Incorrect parameter count.\n");
    return EFI_UNSUPPORTED;
  }

  if (StrCmp(Argv[3], L"-O") != 0) {
    Print(L"CapsuleApp: NO output capsule name.\n");
    return EFI_UNSUPPORTED;
  }
  OutputCapsuleName = Argv[4];

  BmpBuffer = NULL;
  FileSize = 0;
  FullCapsuleBuffer = NULL;

  BmpName = Argv[2];
  Status = ReadFileToBuffer(BmpName, &FileSize, &BmpBuffer);
  if (EFI_ERROR(Status)) {
    Print(L"CapsuleApp: BMP image (%s) is not found.\n", BmpName);
    goto Done;
  }

  GopBlt = NULL;
  Status = TranslateBmpToGopBlt (
             BmpBuffer,
             FileSize,
             &GopBlt,
             &GopBltSize,
             &Height,
             &Width
             );
  if (EFI_ERROR(Status)) {
    Print(L"CapsuleApp: BMP image (%s) is not valid.\n", BmpName);
    goto Done;
  }
  if (GopBlt != NULL) {
    FreePool (GopBlt);
  }
  Print(L"BMP image (%s), Width - %d, Height - %d\n", BmpName, Width, Height);

  if (Height > Info->VerticalResolution) {
    Status = EFI_INVALID_PARAMETER;
    Print(L"CapsuleApp: BMP image (%s) height is larger than current resolution.\n", BmpName);
    goto Done;
  }
  if (Width > Info->HorizontalResolution) {
    Status = EFI_INVALID_PARAMETER;
    Print(L"CapsuleApp: BMP image (%s) width is larger than current resolution.\n", BmpName);
    goto Done;
  }

  FullCapsuleBufferSize = sizeof(EFI_DISPLAY_CAPSULE) + FileSize;
  FullCapsuleBuffer = AllocatePool(FullCapsuleBufferSize);
  if (FullCapsuleBuffer == NULL) {
    Print(L"CapsuleApp: Capsule Buffer size (0x%x) too big.\n", FullCapsuleBufferSize);
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  DisplayCapsule = (EFI_DISPLAY_CAPSULE *)FullCapsuleBuffer;
  CopyGuid(&DisplayCapsule->CapsuleHeader.CapsuleGuid, &gWindowsUxCapsuleGuid);
  DisplayCapsule->CapsuleHeader.HeaderSize = sizeof(DisplayCapsule->CapsuleHeader);
  DisplayCapsule->CapsuleHeader.Flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET;
  DisplayCapsule->CapsuleHeader.CapsuleImageSize = (UINT32)FullCapsuleBufferSize;

  DisplayCapsule->ImagePayload.Version = 1;
  DisplayCapsule->ImagePayload.Checksum = 0;
  DisplayCapsule->ImagePayload.ImageType = 0; // BMP
  DisplayCapsule->ImagePayload.Reserved = 0;
  DisplayCapsule->ImagePayload.Mode = Gop->Mode->Mode;

  //
  // Center the bitmap horizontally
  //
  DisplayCapsule->ImagePayload.OffsetX = (UINT32)((Info->HorizontalResolution - Width) / 2);

  //
  // Put bitmap 3/4 down the display.  If bitmap is too tall, then align bottom
  // of bitmap at bottom of display.
  //
  DisplayCapsule->ImagePayload.OffsetY =
    MIN (
      (UINT32)(Info->VerticalResolution - Height),
      (UINT32)(((3 * Info->VerticalResolution) - (2 * Height)) / 4)
      );

  Print(L"BMP image (%s), OffsetX - %d, OffsetY - %d\n",
    BmpName,
    DisplayCapsule->ImagePayload.OffsetX,
    DisplayCapsule->ImagePayload.OffsetY
    );

  CopyMem((DisplayCapsule + 1), BmpBuffer, FileSize);

  DisplayCapsule->ImagePayload.Checksum = CalculateCheckSum8(FullCapsuleBuffer, FullCapsuleBufferSize);

  Status = WriteFileFromBuffer(OutputCapsuleName, FullCapsuleBufferSize, FullCapsuleBuffer);
  Print(L"CapsuleApp: Write %s %r\n", OutputCapsuleName, Status);

Done:
  if (BmpBuffer != NULL) {
    FreePool(BmpBuffer);
  }

  if (FullCapsuleBuffer != NULL) {
    FreePool(FullCapsuleBuffer);
  }

  return Status;
}