示例#1
0
文件: CapsuleApp.c 项目: b-man/edk2
/**
  Get ESRT FwType according to ImageTypeId

  @param[in]  ImageTypeId   ImageTypeId of an FMP capsule.

  @return ESRT FwType
**/
UINT32
GetEsrtFwType (
  IN  EFI_GUID                                      *ImageTypeId
  )
{
  EFI_STATUS                 Status;
  EFI_SYSTEM_RESOURCE_TABLE  *Esrt;
  EFI_SYSTEM_RESOURCE_ENTRY  *EsrtEntry;
  UINTN                      Index;

  //
  // Check ESRT
  //
  Status = EfiGetSystemConfigurationTable(&gEfiSystemResourceTableGuid, (VOID **)&Esrt);
  if (!EFI_ERROR(Status)) {
    ASSERT(Esrt != NULL);
    EsrtEntry = (VOID *)(Esrt + 1);
    for (Index = 0; Index < Esrt->FwResourceCount; Index++, EsrtEntry++) {
      if (CompareGuid(&EsrtEntry->FwClass, ImageTypeId)) {
        return EsrtEntry->FwType;
      }
    }
  }

  return ESRT_FW_TYPE_UNKNOWN;
}
示例#2
0
EFI_STATUS
EblDumpFdt (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS  Status;
  VOID        *FdtBlob;
  UINTN       Ret;

  // If no FDT file is passed to the argument then get the one from the platform
  if (Argc < 2) {
    Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &FdtBlob);
    if (EFI_ERROR (Status)) {
      Print (L"ERROR: Did not find the Fdt Blob.\n");
      return Status;
    }
  } else {
    return EFI_NOT_FOUND;
  }

  Ret = fdt_check_header (FdtBlob);
  if (Ret != 0) {
    Print (L"ERROR: Device Tree header not valid (err:%d)\n", Ret);
    return EFI_INVALID_PARAMETER;
  }

  DumpFdt (FdtBlob);

  return EFI_SUCCESS;
}
/**
  Called to initialize the memory service.

  @param   SmramRangeCount       Number of SMRAM Regions
  @param   SmramRanges           Pointer to SMRAM Descriptors

**/
VOID
SmmInitializeMemoryServices (
  IN UINTN                 SmramRangeCount,
  IN EFI_SMRAM_DESCRIPTOR  *SmramRanges
  )
{
  UINTN                  Index;
  EFI_STATUS             Status;
  UINTN                  SmmPoolTypeIndex;
  EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE *LMFAConfigurationTable;

  //
  // Initialize Pool list
  //
  for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) {
    for (Index = 0; Index < ARRAY_SIZE (mSmmPoolLists[SmmPoolTypeIndex]); Index++) {
      InitializeListHead (&mSmmPoolLists[SmmPoolTypeIndex][Index]);
    }
  }

  Status = EfiGetSystemConfigurationTable (
            &gLoadFixedAddressConfigurationTableGuid,
           (VOID **) &LMFAConfigurationTable
           );
  if (!EFI_ERROR (Status) && LMFAConfigurationTable != NULL) {
    gLoadModuleAtFixAddressSmramBase = LMFAConfigurationTable->SmramBase;
  }

  //
  // Add Free SMRAM regions
  // Need add Free memory at first, to let gSmmMemoryMap record data
  //
  for (Index = 0; Index < SmramRangeCount; Index++) {
    if ((SmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
      continue;
    }
    SmmAddMemoryRegion (
      SmramRanges[Index].CpuStart,
      SmramRanges[Index].PhysicalSize,
      EfiConventionalMemory,
      SmramRanges[Index].RegionState
      );
  }

  //
  // Add the allocated SMRAM regions
  //
  for (Index = 0; Index < SmramRangeCount; Index++) {
    if ((SmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) == 0) {
      continue;
    }
    SmmAddMemoryRegion (
      SmramRanges[Index].CpuStart,
      SmramRanges[Index].PhysicalSize,
      EfiConventionalMemory,
      SmramRanges[Index].RegionState
      );
  }

}
示例#4
0
/**
  This is the shell command "dumpfdt" handler function. This function handles
  the command when it is invoked in the shell.

  @param[in]  This             The instance of the
                               EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
  @param[in]  SystemTable      The pointer to the UEFI system table.
  @param[in]  ShellParameters  The parameters associated with the command.
  @param[in]  Shell            The instance of the shell protocol used in the
                               context of processing this command.

  @return  SHELL_SUCCESS            The operation was successful.
  @return  SHELL_ABORTED            Operation aborted due to internal error.
  @return  SHELL_NOT_FOUND          Failed to locate the Device Tree into the EFI Configuration Table
  @return  SHELL_OUT_OF_RESOURCES   A memory allocation failed.

**/
SHELL_STATUS
EFIAPI
ShellDynCmdDumpFdtHandler (
  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *This,
  IN EFI_SYSTEM_TABLE                    *SystemTable,
  IN EFI_SHELL_PARAMETERS_PROTOCOL       *ShellParameters,
  IN EFI_SHELL_PROTOCOL                  *Shell
  )
{
  SHELL_STATUS  ShellStatus;
  EFI_STATUS    Status;
  VOID          *FdtBlob;

  ShellStatus  = SHELL_SUCCESS;

  //
  // Install the Shell and Shell Parameters Protocols on the driver
  // image. This is necessary for the initialisation of the Shell
  // Library to succeed in the next step.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &gImageHandle,
                  &gEfiShellProtocolGuid, Shell,
                  &gEfiShellParametersProtocolGuid, ShellParameters,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    return SHELL_ABORTED;
  }

  //
  // Initialise the Shell Library as we are going to use it.
  // Assert that the return code is EFI_SUCCESS as it should.
  // To anticipate any change is the codes returned by
  // ShellInitialize(), leave in case of error.
  //
  Status = ShellInitialize ();
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return SHELL_ABORTED;
  }

  Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &FdtBlob);
  if (EFI_ERROR (Status)) {
    Print (L"ERROR: Did not find the Fdt Blob.\n");
    return EfiCodeToShellCode (Status);
  }

  DumpFdt (FdtBlob);

  gBS->UninstallMultipleProtocolInterfaces (
         gImageHandle,
         &gEfiShellProtocolGuid, Shell,
         &gEfiShellParametersProtocolGuid, ShellParameters,
         NULL
         );

  return ShellStatus;
}
示例#5
0
VOID
EblInitializeDeviceCmd (
  VOID
  )
{
  EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);
  EblAddCommands (mCmdDeviceTemplate, sizeof (mCmdDeviceTemplate)/sizeof (EBL_COMMAND_TABLE));
}
示例#6
0
文件: EblCmdLib.c 项目: Cutty/edk2
/**
  Simple arm disassembler via a library

  Argv[0] - symboltable
  Argv[1] - Optional qoted format string 
  Argv[2] - Optional flag

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line. 
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EblSymbolTable (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS                        Status;
  EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *DebugImageTableHeader = NULL;
  EFI_DEBUG_IMAGE_INFO              *DebugTable;
  UINTN                             Entry;
  CHAR8                             *Format;
  CHAR8                             *Pdb;
  UINT32                            PeCoffSizeOfHeaders;
  UINT32                            ImageBase;
  BOOLEAN                           Elf;
  
  // Need to add lots of error checking on the passed in string
  // Default string is for RealView debugger
#if (__ARMCC_VERSION < 500000)
  Format = (Argc > 1) ? Argv[1] : "load /a /ni /np %a &0x%x";
#else
  Format = (Argc > 1) ? Argv[1] : "add-symbol-file %a 0x%x";
#endif
  Elf = (Argc > 2) ? FALSE : TRUE;
  
  Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&DebugImageTableHeader);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  DebugTable = DebugImageTableHeader->EfiDebugImageInfoTable;
  if (DebugTable == NULL) {
    return EFI_SUCCESS;
  }

  for (Entry = 0; Entry < DebugImageTableHeader->TableSize; Entry++, DebugTable++) {
    if (DebugTable->NormalImage != NULL) {
      if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) && (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {
        ImageBase = (UINTN)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase;
        PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)ImageBase);
        Pdb = PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase);
        if (Pdb != NULL) {
          if (Elf) {
            // ELF and Mach-O images don't include the header so the linked address does not include header
            ImageBase += PeCoffSizeOfHeaders;
          } 
          AsciiPrint (Format, Pdb, ImageBase);
          AsciiPrint ("\n");
        } else {
        }
      }
    }  
  }

  return EFI_SUCCESS;
}
示例#7
0
/**
  This function gets system guid and serial number from the smbios table.

  @param  SystemGuid          The pointer of returned system guid.
  @param  SystemSerialNumber  The pointer of returned system serial number.

  @retval EFI_SUCCESS         Successfully get the system guid and system serial
                              number.
  @retval EFI_NOT_FOUND       Not find the SMBIOS table.

**/
EFI_STATUS
GetSmbiosSystemGuidAndSerialNumber (
  IN  EFI_GUID  *SystemGuid,
  OUT CHAR8     **SystemSerialNumber
  )
{
  EFI_STATUS                Status;
  SMBIOS_TABLE_ENTRY_POINT  *SmbiosTable;
  SMBIOS_STRUCTURE_POINTER  Smbios;
  SMBIOS_STRUCTURE_POINTER  SmbiosEnd;
  UINT16                    Index;

  Status = EfiGetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID **) &SmbiosTable);

  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }
  ASSERT (SmbiosTable != NULL);

  Smbios.Hdr    = (SMBIOS_STRUCTURE *) (UINTN) SmbiosTable->TableAddress;
  SmbiosEnd.Raw = (UINT8 *) (UINTN) (SmbiosTable->TableAddress + SmbiosTable->TableLength);

  for (Index = 0; Index < SmbiosTable->TableLength; Index++) {
    if (Smbios.Hdr->Type == 1) {
      if (Smbios.Hdr->Length < 0x19) {
        //
        // Older version did not support Guid and Serial number
        //
        continue;
      }
      //
      // SMBIOS tables are byte packed so we need to do a byte copy to
      // prevend alignment faults on Itanium-based platform.
      //
      CopyMem (SystemGuid, &Smbios.Type1->Uuid, sizeof (EFI_GUID));
      *SystemSerialNumber = GetSmbiosString (&Smbios, Smbios.Type1->SerialNumber);

      return EFI_SUCCESS;
    }
    //
    // Make Smbios point to the next record
    //
    GetSmbiosString (&Smbios, 0);

    if (Smbios.Raw >= SmbiosEnd.Raw) {
      //
      // SMBIOS 2.1 incorrectly stated the length of SmbiosTable as 0x1e.
      // given this we must double check against the length of the structure.
      //
      return EFI_SUCCESS;
    }
  }

  return EFI_SUCCESS;
}
示例#8
0
EFI_STATUS
PciRomLoadEfiDriversFromOptionRomTable (
  IN EFI_DRIVER_BINDING_PROTOCOL      *This,
  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo
  )
/*++

Routine Description:

Arguments:

Returns:

--*/
{
  EFI_STATUS                        Status;
  EFI_PCI_OPTION_ROM_TABLE          *PciOptionRomTable;
  EFI_PCI_OPTION_ROM_DESCRIPTOR     *PciOptionRomDescriptor;
  UINTN                             Index;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
  UINT16                            MinBus;
  UINT16                            MaxBus;

  Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  Status = EFI_NOT_FOUND;

  for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {
    PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];
    if (!PciOptionRomDescriptor->DontLoadEfiRom) {
      if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber) {
        Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);
        if (EFI_ERROR (Status)) {
          return Status;
        }

        PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL);
        if ((MinBus <= PciOptionRomDescriptor->Bus) && (PciOptionRomDescriptor->Bus <= MaxBus)) {
          Status = PciRomLoadEfiDriversFromRomImage (This, PciOptionRomDescriptor);
          PciOptionRomDescriptor->DontLoadEfiRom |= 2;
        }
      }
    }
  }

  return Status;
}
示例#9
0
文件: HobLib.c 项目: baranee/edk2
EFIAPI
GetHobList (
  VOID
  )
{
  EFI_STATUS  Status;

  if (mHobList == NULL) {
    Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &mHobList);
    ASSERT_EFI_ERROR (Status);
    ASSERT (mHobList != NULL);
  }
  return mHobList;
}
示例#10
0
EFI_STATUS
PciRomGetRomResourceFromPciOptionRomTable (
  IN EFI_DRIVER_BINDING_PROTOCOL      *This,
  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,
  PCI_IO_DEVICE                       *PciIoDevice
  )
/*++

Routine Description:

Arguments:

Returns:

--*/
{
  EFI_STATUS                    Status;
  EFI_PCI_OPTION_ROM_TABLE      *PciOptionRomTable;
  EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;
  UINTN                         Index;

  Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {
    PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];
    if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber &&
        PciOptionRomDescriptor->Bus == PciIoDevice->BusNumber         &&
        PciOptionRomDescriptor->Dev == PciIoDevice->DeviceNumber      &&
        PciOptionRomDescriptor->Func == PciIoDevice->FunctionNumber ) {

      PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;
      PciIoDevice->PciIo.RomSize  = (UINTN) PciOptionRomDescriptor->RomLength;
    }
  }

  for (Index = 0; Index < mNumberOfPciRomImages; Index++) {
    if (mRomImageTable[Index].Seg  == PciRootBridgeIo->SegmentNumber &&
        mRomImageTable[Index].Bus  == PciIoDevice->BusNumber         &&
        mRomImageTable[Index].Dev  == PciIoDevice->DeviceNumber      &&
        mRomImageTable[Index].Func == PciIoDevice->FunctionNumber    ) {

      AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);
    }
  }

  return EFI_SUCCESS;
}
示例#11
0
文件: HobLib.c 项目: etiago/vbox
/**
  The constructor function caches the pointer to HOB list.
  
  The constructor function gets the start address of HOB list from system configuration table.
  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. 

  @param  ImageHandle   The firmware allocated handle for the EFI image.
  @param  SystemTable   A pointer to the EFI System Table.
  
  @retval EFI_SUCCESS   The constructor successfully gets HobList.
  @retval Other value   The constructor can't get HobList.

**/
EFI_STATUS
EFIAPI
HobLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &mHobList);
  ASSERT_EFI_ERROR (Status);
  ASSERT (mHobList != NULL);

  return Status;
}
示例#12
0
/**
  Get the pointer to Mailbox from the configuration table.

  @return Pointer to Mailbox.

**/
DEBUG_AGENT_MAILBOX *
GetMailboxFromConfigurationTable (
  VOID
  )
{
  EFI_STATUS               Status;
  DEBUG_AGENT_MAILBOX      *Mailbox;

  Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **) &Mailbox);
  if (Status == EFI_SUCCESS && Mailbox != NULL) {
    VerifyMailboxChecksum (Mailbox);
    return Mailbox;
  } else {
    return NULL;
  }
}
示例#13
0
/**
  Return if there is a FMP header below capsule header.

  @param[in] CapsuleHeader A pointer to EFI_CAPSULE_HEADER

  @retval TRUE  There is a FMP header below capsule header.
  @retval FALSE There is not a FMP header below capsule header
**/
BOOLEAN
IsNestedFmpCapsule (
  IN EFI_CAPSULE_HEADER         *CapsuleHeader
  )
{
  EFI_STATUS                 Status;
  EFI_SYSTEM_RESOURCE_TABLE  *Esrt;
  EFI_SYSTEM_RESOURCE_ENTRY  *EsrtEntry;
  UINTN                      Index;
  BOOLEAN                    EsrtGuidFound;
  EFI_CAPSULE_HEADER         *NestedCapsuleHeader;
  UINTN                      NestedCapsuleSize;

  //
  // Check ESRT
  //
  EsrtGuidFound = FALSE;
  Status = EfiGetSystemConfigurationTable(&gEfiSystemResourceTableGuid, (VOID **)&Esrt);
  if (!EFI_ERROR(Status)) {
    ASSERT (Esrt != NULL);
    EsrtEntry = (VOID *)(Esrt + 1);
    for (Index = 0; Index < Esrt->FwResourceCount; Index++, EsrtEntry++) {
      if (CompareGuid(&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {
        EsrtGuidFound = TRUE;
        break;
      }
    }
  }

  if (!EsrtGuidFound) {
    return FALSE;
  }

  //
  // Check nested capsule header
  // FMP GUID after ESRT one
  //
  NestedCapsuleHeader = (EFI_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
  NestedCapsuleSize = (UINTN)CapsuleHeader + CapsuleHeader->HeaderSize - (UINTN)NestedCapsuleHeader;
  if (NestedCapsuleSize < sizeof(EFI_CAPSULE_HEADER)) {
    return FALSE;
  }
  if (!CompareGuid(&NestedCapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {
    return FALSE;
  }
  return TRUE;
}
示例#14
0
/**
  The constructor function caches the pointer of DXE Services Table.

  The constructor function caches the pointer of DXE Services Table.
  It will ASSERT() if that operation fails.
  It will ASSERT() if the pointer of DXE Services Table is NULL.
  It will always return EFI_SUCCESS.

  @param  ImageHandle   The firmware allocated handle for the EFI image.
  @param  SystemTable   A pointer to the EFI System Table.

  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

**/
EFI_STATUS
EFIAPI
DxeServicesTableLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  //
  // Cache copy of the DXE Services Table
  //
  Status = EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);
  ASSERT_EFI_ERROR (Status);
  ASSERT (gDS != NULL);

  return Status;
}
示例#15
0
/**
  Dump ESRT info.
**/
VOID
DumpEsrtData (
  VOID
  )
{
  EFI_STATUS                 Status;
  EFI_SYSTEM_RESOURCE_TABLE  *Esrt;

  Print(L"##############\n");
  Print(L"# ESRT TABLE #\n");
  Print(L"##############\n");

  Status = EfiGetSystemConfigurationTable (&gEfiSystemResourceTableGuid, (VOID **)&Esrt);
  if (EFI_ERROR(Status)) {
    Print(L"ESRT - %r\n", Status);
    return;
  }
  DumpEsrt(Esrt);
  Print(L"\n");
}
示例#16
0
文件: TcgDxe.c 项目: etiago/vbox
/**
  Measure and log EFI handoff tables, and extend the measurement result into PCR[1].

  @retval EFI_SUCCESS         Operation completed successfully.
  @retval EFI_DEVICE_ERROR    The operation was unsuccessful.

**/
EFI_STATUS
EFIAPI
MeasureHandoffTables (
  VOID
  )
{
  EFI_STATUS                        Status;
  SMBIOS_TABLE_ENTRY_POINT          *SmbiosTable;
  TCG_PCR_EVENT_HDR                 TcgEvent;
  EFI_HANDOFF_TABLE_POINTERS        HandoffTables;

  Status = EfiGetSystemConfigurationTable (
             &gEfiSmbiosTableGuid,
             (VOID **) &SmbiosTable
             );

  if (!EFI_ERROR (Status)) {
    ASSERT (SmbiosTable != NULL);

    TcgEvent.PCRIndex  = 1;
    TcgEvent.EventType = EV_EFI_HANDOFF_TABLES;
    TcgEvent.EventSize = sizeof (HandoffTables);

    HandoffTables.NumberOfTables = 1;
    HandoffTables.TableEntry[0].VendorGuid  = gEfiSmbiosTableGuid;
    HandoffTables.TableEntry[0].VendorTable = SmbiosTable;

    DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTable->TableAddress));
    DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", SmbiosTable->TableLength));

    Status = TcgDxeHashLogExtendEventI (
               &mTcgDxeData,
               (UINT8*)(UINTN)SmbiosTable->TableAddress,
               SmbiosTable->TableLength,
               &TcgEvent,
               (UINT8*)&HandoffTables
               );
  }

  return Status;
}
示例#17
0
文件: UefiSalLib.c 项目: b-man/edk2
/**
  The constructor function of UEFI SAL Lib.

  The constructor function looks up the SAL System Table in the EFI System Configuration
  Table. Once the SAL System Table is found, the SAL Entry Point in the SAL System Table
  will be derived and stored into a global variable for library usage.
  It will ASSERT() if the SAL System Table cannot be found or the data in the SAL System
  Table is not the valid data.

  @param  ImageHandle   The firmware allocated handle for the EFI image.
  @param  SystemTable   A pointer to the EFI System Table.

  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

**/
EFI_STATUS
EFIAPI
UefiSalLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                     Status;
  SAL_ST_ENTRY_POINT_DESCRIPTOR  *SalStEntryDes;
  SAL_SYSTEM_TABLE_HEADER        *SalSystemTable;

  Status = EfiGetSystemConfigurationTable (
             &gEfiSalSystemTableGuid,
             (VOID **) &SalSystemTable
             );
  ASSERT_EFI_ERROR (Status);
  ASSERT (SalSystemTable != NULL);

  //
  // Check the first entry of SAL System Table,
  // because the SAL entry is in ascending order with the entry type,
  // the type 0 entry should be the first if exist.
  //
  SalStEntryDes = (SAL_ST_ENTRY_POINT_DESCRIPTOR *)(SalSystemTable + 1);

  //
  // Assure the SAL ENTRY Type is 0
  //
  ASSERT (SalStEntryDes->Type == EFI_SAL_ST_ENTRY_POINT);

  mPlabel.EntryPoint = SalStEntryDes->SalProcEntry;
  mPlabel.GP = SalStEntryDes->SalGlobalDataPointer;
  //
  // Make sure the EntryPoint has the valid value
  //
  ASSERT ((mPlabel.EntryPoint != 0) && (mPlabel.GP != 0));

  mSalProcEntry = (SAL_PROC)((UINT64)&(mPlabel.EntryPoint));

  return EFI_SUCCESS;
}
示例#18
0
STATIC
VOID
EFIAPI
ApplyDeviceTreeOverlay (
  EFI_EVENT           Event,
  VOID                *Context
  )
{
  VOID                    *Dtb;
  MEZZANINE_PROTOCOL      *Mezzanine;
  EFI_STATUS              Status;

  //
  // Find the DTB in the configuration table array. If it isn't there, just
  // bail without an error: we may be running on an ACPI platform even if
  // this driver does not support it [yet].
  //
  Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &Dtb);
  if (Status == EFI_NOT_FOUND) {
    return;
  }
  ASSERT_EFI_ERROR (Status);

  Status = gBS->LocateProtocol (&g96BoardsMezzanineProtocolGuid, NULL,
                  (VOID **)&Mezzanine);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_INFO, "%a: no mezzanine driver active\n", __FUNCTION__));
    return;
  }

  Status = Mezzanine->ApplyDeviceTreeOverlay (Mezzanine, Dtb);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_WARN, "%a: failed to apply DT overlay - %r\n", __FUNCTION__,
      Status));
  }
}
示例#19
0
文件: GdbStub.c 项目: lersek/edk2
/**
  The user Entry Point for Application. The user code starts with this function
  as the real entry point for the image goes into a library that calls this
  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 other             Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
GdbStubEntry (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                  Status;
  EFI_DEBUG_SUPPORT_PROTOCOL  *DebugSupport;
  UINTN                       HandleCount;
  EFI_HANDLE                  *Handles;
  UINTN                       Index;
  UINTN                       Processor;
  BOOLEAN                     IsaSupported;

  Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&gDebugImageTableHeader);
  if (EFI_ERROR (Status)) {
    gDebugImageTableHeader = NULL;
  }

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiDebugSupportProtocolGuid,
                  NULL,
                  &HandleCount,
                  &Handles
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Debug Support Protocol not found\n"));

    return Status;
  }

  DebugSupport = NULL;
  IsaSupported = FALSE;
  do {
    HandleCount--;
    Status = gBS->HandleProtocol (
                    Handles[HandleCount],
                    &gEfiDebugSupportProtocolGuid,
                    (VOID **) &DebugSupport
                    );
    if (!EFI_ERROR (Status)) {
      if (CheckIsa (DebugSupport->Isa)) {
        // We found what we are looking for so break out of the loop
        IsaSupported = TRUE;
        break;
      }
    }
  } while (HandleCount > 0);
  FreePool (Handles);

  if (!IsaSupported) {
    DEBUG ((EFI_D_ERROR, "Debug Support Protocol does not support our ISA\n"));

    return EFI_NOT_FOUND;
  }

  Status = DebugSupport->GetMaximumProcessorIndex (DebugSupport, &gMaxProcessorIndex);
  ASSERT_EFI_ERROR (Status);

  DEBUG ((EFI_D_INFO, "Debug Support Protocol ISA %x\n", DebugSupport->Isa));
  DEBUG ((EFI_D_INFO, "Debug Support Protocol Processor Index %d\n", gMaxProcessorIndex));

  // Call processor-specific init routine
  InitializeProcessor ();

  for (Processor = 0; Processor <= gMaxProcessorIndex; Processor++) {
    for (Index = 0; Index < MaxEfiException (); Index++) {
      Status = DebugSupport->RegisterExceptionCallback (DebugSupport, Processor,  GdbExceptionHandler, gExceptionType[Index].Exception);
      ASSERT_EFI_ERROR (Status);
    }
    //
    // Current edk2 DebugPort is not interrupt context safe so we can not use it
    //
    Status = DebugSupport->RegisterPeriodicCallback (DebugSupport, Processor, GdbPeriodicCallBack);
    ASSERT_EFI_ERROR (Status);
  }

  //
  // This even fires every time an image is added. This allows the stub to know when gdb needs
  // to update the symbol table.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  GdbSymbolEventHandler,
                  NULL,
                  &gEvent
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Register for protocol notifications on this event
  //
  Status = gBS->RegisterProtocolNotify (
                  &gEfiLoadedImageProtocolGuid,
                  gEvent,
                  &gGdbSymbolEventHandlerRegistration
                  );
  ASSERT_EFI_ERROR (Status);


 if (PcdGetBool (PcdGdbSerial)) {
   GdbInitializeSerialConsole ();
 }

  return EFI_SUCCESS;
}
/**
  Get SMI handler profile database.
**/
VOID
GetSmiHandlerProfileDatabase(
  VOID
  )
{
  EFI_STATUS                                          Status;
  UINTN                                               CommSize;
  UINT8                                               *CommBuffer;
  EFI_SMM_COMMUNICATE_HEADER                          *CommHeader;
  SMI_HANDLER_PROFILE_PARAMETER_GET_INFO              *CommGetInfo;
  SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET    *CommGetData;
  EFI_SMM_COMMUNICATION_PROTOCOL                      *SmmCommunication;
  UINTN                                               MinimalSizeNeeded;
  EDKII_PI_SMM_COMMUNICATION_REGION_TABLE             *PiSmmCommunicationRegionTable;
  UINT32                                              Index;
  EFI_MEMORY_DESCRIPTOR                               *Entry;
  VOID                                                *Buffer;
  UINTN                                               Size;
  UINTN                                               Offset;

  Status = gBS->LocateProtocol(&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **)&SmmCommunication);
  if (EFI_ERROR(Status)) {
    Print(L"SmiHandlerProfile: Locate SmmCommunication protocol - %r\n", Status);
    return ;
  }

  MinimalSizeNeeded = EFI_PAGE_SIZE;

  Status = EfiGetSystemConfigurationTable(
             &gEdkiiPiSmmCommunicationRegionTableGuid,
             (VOID **)&PiSmmCommunicationRegionTable
             );
  if (EFI_ERROR(Status)) {
    Print(L"SmiHandlerProfile: Get PiSmmCommunicationRegionTable - %r\n", Status);
    return ;
  }
  ASSERT(PiSmmCommunicationRegionTable != NULL);
  Entry = (EFI_MEMORY_DESCRIPTOR *)(PiSmmCommunicationRegionTable + 1);
  Size = 0;
  for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {
    if (Entry->Type == EfiConventionalMemory) {
      Size = EFI_PAGES_TO_SIZE((UINTN)Entry->NumberOfPages);
      if (Size >= MinimalSizeNeeded) {
        break;
      }
    }
    Entry = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Entry + PiSmmCommunicationRegionTable->DescriptorSize);
  }
  ASSERT(Index < PiSmmCommunicationRegionTable->NumberOfEntries);
  CommBuffer = (UINT8 *)(UINTN)Entry->PhysicalStart;

  //
  // Get Size
  //
  CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
  CopyMem(&CommHeader->HeaderGuid, &gSmiHandlerProfileGuid, sizeof(gSmiHandlerProfileGuid));
  CommHeader->MessageLength = sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_INFO);

  CommGetInfo = (SMI_HANDLER_PROFILE_PARAMETER_GET_INFO *)&CommBuffer[OFFSET_OF(EFI_SMM_COMMUNICATE_HEADER, Data)];
  CommGetInfo->Header.Command = SMI_HANDLER_PROFILE_COMMAND_GET_INFO;
  CommGetInfo->Header.DataLength = sizeof(*CommGetInfo);
  CommGetInfo->Header.ReturnStatus = (UINT64)-1;
  CommGetInfo->DataSize = 0;

  CommSize = sizeof(EFI_GUID) + sizeof(UINTN) + CommHeader->MessageLength;
  Status = SmmCommunication->Communicate(SmmCommunication, CommBuffer, &CommSize);
  if (EFI_ERROR(Status)) {
    Print(L"SmiHandlerProfile: SmmCommunication - %r\n", Status);
    return ;
  }

  if (CommGetInfo->Header.ReturnStatus != 0) {
    Print(L"SmiHandlerProfile: GetInfo - 0x%0x\n", CommGetInfo->Header.ReturnStatus);
    return ;
  }

  mSmiHandlerProfileDatabaseSize = (UINTN)CommGetInfo->DataSize;

  //
  // Get Data
  //
  mSmiHandlerProfileDatabase = AllocateZeroPool(mSmiHandlerProfileDatabaseSize);
  if (mSmiHandlerProfileDatabase == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    Print(L"SmiHandlerProfile: AllocateZeroPool (0x%x) for dump buffer - %r\n", mSmiHandlerProfileDatabaseSize, Status);
    return ;
  }

  CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
  CopyMem(&CommHeader->HeaderGuid, &gSmiHandlerProfileGuid, sizeof(gSmiHandlerProfileGuid));
  CommHeader->MessageLength = sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET);

  CommGetData = (SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET *)&CommBuffer[OFFSET_OF(EFI_SMM_COMMUNICATE_HEADER, Data)];
  CommGetData->Header.Command = SMI_HANDLER_PROFILE_COMMAND_GET_DATA_BY_OFFSET;
  CommGetData->Header.DataLength = sizeof(*CommGetData);
  CommGetData->Header.ReturnStatus = (UINT64)-1;

  CommSize = sizeof(EFI_GUID) + sizeof(UINTN) + CommHeader->MessageLength;
  Buffer = (UINT8 *)CommHeader + CommSize;
  Size -= CommSize;

  CommGetData->DataBuffer = (PHYSICAL_ADDRESS)(UINTN)Buffer;
  CommGetData->DataOffset = 0;
  while (CommGetData->DataOffset < mSmiHandlerProfileDatabaseSize) {
    Offset = (UINTN)CommGetData->DataOffset;
    if (Size <= (mSmiHandlerProfileDatabaseSize - CommGetData->DataOffset)) {
      CommGetData->DataSize = (UINT64)Size;
    } else {
      CommGetData->DataSize = (UINT64)(mSmiHandlerProfileDatabaseSize - CommGetData->DataOffset);
    }
    Status = SmmCommunication->Communicate(SmmCommunication, CommBuffer, &CommSize);
    ASSERT_EFI_ERROR(Status);

    if (CommGetData->Header.ReturnStatus != 0) {
      FreePool(mSmiHandlerProfileDatabase);
      mSmiHandlerProfileDatabase = NULL;
      Print(L"SmiHandlerProfile: GetData - 0x%x\n", CommGetData->Header.ReturnStatus);
      return ;
    }
    CopyMem((UINT8 *)mSmiHandlerProfileDatabase + Offset, (VOID *)(UINTN)CommGetData->DataBuffer, (UINTN)CommGetData->DataSize);
  }

  DEBUG ((DEBUG_INFO, "SmiHandlerProfileSize - 0x%x\n", mSmiHandlerProfileDatabaseSize));

  return ;
}
示例#21
0
文件: EdbHook.c 项目: efidroid/edk2
/**

  The hook in InitializeEbcDriver.
  It will init the EbcDebuggerPrivate data structure.

  @param Handle           - The EbcDebugProtocol handle.
  @param EbcDebugProtocol - The EbcDebugProtocol interface.

**/
VOID
EbcDebuggerHookInit (
  IN EFI_HANDLE                  Handle,
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *EbcDebugProtocol
  )
{
  EFI_STATUS                 Status;
  UINTN                      Index;
  EFI_DEBUGGER_SYMBOL_OBJECT *Object;
  EFI_DEBUGGER_SYMBOL_ENTRY  *Entry;


  //
  // Register all exception handler
  //
  for (Index = EXCEPT_EBC_UNDEFINED; Index <= EXCEPT_EBC_STEP; Index++) {
    EbcDebugProtocol->RegisterExceptionCallback (
      EbcDebugProtocol,
      0,
      NULL,
      Index
      );
    EbcDebugProtocol->RegisterExceptionCallback (
      EbcDebugProtocol,
      0,
      EdbExceptionHandler,
      Index
      );
  }

  //
  // Init Symbol
  //
  Object = AllocateZeroPool (sizeof(EFI_DEBUGGER_SYMBOL_OBJECT) * EFI_DEBUGGER_SYMBOL_OBJECT_MAX);
  ASSERT (Object != NULL);
  mDebuggerPrivate.DebuggerSymbolContext.Object = Object;
  mDebuggerPrivate.DebuggerSymbolContext.ObjectCount = 0;
  mDebuggerPrivate.DebuggerSymbolContext.MaxObjectCount = EFI_DEBUGGER_SYMBOL_OBJECT_MAX;
  for (Index = 0; Index < EFI_DEBUGGER_SYMBOL_OBJECT_MAX; Index++) {
    Entry = AllocateZeroPool (sizeof(EFI_DEBUGGER_SYMBOL_ENTRY) * EFI_DEBUGGER_SYMBOL_ENTRY_MAX);
    ASSERT (Entry != NULL);
    Object[Index].Entry = Entry;
    Object[Index].MaxEntryCount = EFI_DEBUGGER_SYMBOL_ENTRY_MAX;
    Object[Index].SourceBuffer = AllocateZeroPool (sizeof(VOID *) * (EFI_DEBUGGER_SYMBOL_ENTRY_MAX + 1));
    ASSERT (Object[Index].SourceBuffer != NULL);
  }

  //
  // locate PciRootBridgeIo
  //
  Status = gBS->LocateProtocol (
                  &gEfiPciRootBridgeIoProtocolGuid,
                  NULL,
                  (VOID**) &mDebuggerPrivate.PciRootBridgeIo
                  );

  //
  // locate DebugImageInfoTable
  //
  Status = EfiGetSystemConfigurationTable (
             &gEfiDebugImageInfoTableGuid,
             (VOID**) &mDebuggerPrivate.DebugImageInfoTableHeader
             );

  //
  // Register Debugger Configuration Protocol, for config in shell
  //
  Status = gBS->InstallProtocolInterface (
                  &Handle,
                  &gEfiDebuggerConfigurationProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &mDebuggerPrivate.DebuggerConfiguration
                  );

  //
  //
  // Create break event
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  EbcDebuggerBreakEventFunc,
                  NULL,
                  &mDebuggerPrivate.BreakEvent
                  );
  if (!EFI_ERROR (Status)) {
    Status = gBS->SetTimer (
                    mDebuggerPrivate.BreakEvent,
                    TimerPeriodic,
                    EFI_DEBUG_BREAK_TIMER_INTERVAL
                    );
  }

  return ;
}
示例#22
0
/**
  Get and dump SMRAM profile data.

  @return EFI_SUCCESS   Get the SMRAM profile data successfully.
  @return other         Fail to get the SMRAM profile data.

**/
EFI_STATUS
GetSmramProfileData (
  VOID
  )
{
  EFI_STATUS                                    Status;
  UINTN                                         CommSize;
  UINT8                                         *CommBuffer;
  EFI_SMM_COMMUNICATE_HEADER                    *CommHeader;
  SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO      *CommGetProfileInfo;
  SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *CommGetProfileData;
  UINTN                                         ProfileSize;
  VOID                                          *ProfileBuffer;
  EFI_SMM_COMMUNICATION_PROTOCOL                *SmmCommunication;
  UINTN                                         MinimalSizeNeeded;
  EDKII_PI_SMM_COMMUNICATION_REGION_TABLE       *PiSmmCommunicationRegionTable;
  UINT32                                        Index;
  EFI_MEMORY_DESCRIPTOR                         *Entry;
  VOID                                          *Buffer;
  UINTN                                         Size;
  UINTN                                         Offset;

  Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &SmmCommunication);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status));
    return Status;
  }

  MinimalSizeNeeded = sizeof (EFI_GUID) +
                      sizeof (UINTN) +
                      MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO),
                           sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET));
  MinimalSizeNeeded += MAX (sizeof (MEMORY_PROFILE_CONTEXT),
                            MAX (sizeof (MEMORY_PROFILE_DRIVER_INFO),
                                 MAX (sizeof (MEMORY_PROFILE_ALLOC_INFO),
                                      MAX (sizeof (MEMORY_PROFILE_DESCRIPTOR),
                                           MAX (sizeof (MEMORY_PROFILE_FREE_MEMORY),
                                                sizeof (MEMORY_PROFILE_MEMORY_RANGE))))));

  Status = EfiGetSystemConfigurationTable (
             &gEdkiiPiSmmCommunicationRegionTableGuid,
             (VOID **) &PiSmmCommunicationRegionTable
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "SmramProfile: Get PiSmmCommunicationRegionTable - %r\n", Status));
    return Status;
  }
  ASSERT (PiSmmCommunicationRegionTable != NULL);
  Entry = (EFI_MEMORY_DESCRIPTOR *) (PiSmmCommunicationRegionTable + 1);
  Size = 0;
  for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {
    if (Entry->Type == EfiConventionalMemory) {
      Size = EFI_PAGES_TO_SIZE ((UINTN) Entry->NumberOfPages);
      if (Size >= MinimalSizeNeeded) {
        break;
      }
    }
    Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize);
  }
  ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries);
  CommBuffer = (UINT8 *) (UINTN) Entry->PhysicalStart;

  //
  // Get Size
  //
  CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0];
  CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid));
  CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO);

  CommGetProfileInfo = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
  CommGetProfileInfo->Header.Command      = SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO;
  CommGetProfileInfo->Header.DataLength   = sizeof (*CommGetProfileInfo);
  CommGetProfileInfo->Header.ReturnStatus = (UINT64)-1;
  CommGetProfileInfo->ProfileSize         = 0;

  CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;
  Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "SmramProfile: SmmCommunication - %r\n", Status));
    return Status;
  }

  if (CommGetProfileInfo->Header.ReturnStatus != 0) {
    Print (L"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo->Header.ReturnStatus);
    return EFI_SUCCESS;
  }

  ProfileSize = (UINTN) CommGetProfileInfo->ProfileSize;

  //
  // Get Data
  //
  ProfileBuffer = AllocateZeroPool (ProfileSize);
  if (ProfileBuffer == 0) {
    Status = EFI_OUT_OF_RESOURCES;
    Print (L"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", ProfileSize, Status);
    return Status;
  }

  CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0];
  CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof(gEdkiiMemoryProfileGuid));
  CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET);

  CommGetProfileData = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
  CommGetProfileData->Header.Command      = SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET;
  CommGetProfileData->Header.DataLength   = sizeof (*CommGetProfileData);
  CommGetProfileData->Header.ReturnStatus = (UINT64)-1;

  CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;
  Buffer = (UINT8 *) CommHeader + CommSize;
  Size -= CommSize;

  CommGetProfileData->ProfileBuffer       = (PHYSICAL_ADDRESS) (UINTN) Buffer;
  CommGetProfileData->ProfileOffset       = 0;
  while (CommGetProfileData->ProfileOffset < ProfileSize) {
    Offset = (UINTN) CommGetProfileData->ProfileOffset;
    if (Size <= (ProfileSize - CommGetProfileData->ProfileOffset)) {
      CommGetProfileData->ProfileSize = (UINT64) Size;
    } else {
      CommGetProfileData->ProfileSize = (UINT64) (ProfileSize - CommGetProfileData->ProfileOffset);
    }
    Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);
    ASSERT_EFI_ERROR (Status);

    if (CommGetProfileData->Header.ReturnStatus != 0) {
      FreePool (ProfileBuffer);
      Print (L"GetProfileData - 0x%x\n", CommGetProfileData->Header.ReturnStatus);
      return EFI_SUCCESS;
    }
    CopyMem ((UINT8 *) ProfileBuffer + Offset, (VOID *) (UINTN) CommGetProfileData->ProfileBuffer, (UINTN) CommGetProfileData->ProfileSize);
  }


  Print (L"SmramProfileSize - 0x%x\n", ProfileSize);
  Print (L"======= SmramProfile begin =======\n");
  DumpMemoryProfile ((PHYSICAL_ADDRESS) (UINTN) ProfileBuffer, ProfileSize);
  Print (L"======= SmramProfile end =======\n\n\n");

  FreePool (ProfileBuffer);

  return EFI_SUCCESS;
}
示例#23
0
文件: PiSmmIpl.c 项目: etiago/vbox
/**
  The Entry Point for SMM IPL

  Load SMM Core into SMRAM, register SMM Core entry point for SMIs, install 
  SMM Base 2 Protocol and SMM Communication Protocol, and register for the 
  critical events required to coordinate between DXE and SMM environments.
  
  @param  ImageHandle    The firmware allocated handle for the EFI image.
  @param  SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS    The entry point is executed successfully.
  @retval Other          Some error occurred when executing this entry point.

**/
EFI_STATUS
EFIAPI
SmmIplEntry (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                      Status;
  EFI_SMM_CONFIGURATION_PROTOCOL  *SmmConfiguration;
  UINTN                           Size;
  UINTN                           Index;
  EFI_SMM_RESERVED_SMRAM_REGION   *SmramResRegion;
  UINT64                          MaxSize;
  VOID                            *Registration;
  UINT64                          SmmCodeSize;
  EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE    *LMFAConfigurationTable;
  EFI_CPU_ARCH_PROTOCOL           *CpuArch;

  //
  // Fill in the image handle of the SMM IPL so the SMM Core can use this as the 
  // ParentImageHandle field of the Load Image Protocol for all SMM Drivers loaded 
  // by the SMM Core
  //
  mSmmCorePrivateData.SmmIplImageHandle = ImageHandle;

  //
  // Get SMM Access Protocol
  //
  Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&mSmmAccess);
  ASSERT_EFI_ERROR (Status);

  //
  // Get SMM Control2 Protocol
  //
  Status = gBS->LocateProtocol (&gEfiSmmControl2ProtocolGuid, NULL, (VOID **)&mSmmControl2);
  ASSERT_EFI_ERROR (Status);

  //
  // Get SMM Configuration Protocol if it is present
  //
  SmmConfiguration = NULL;
  Status = gBS->LocateProtocol (&gEfiSmmConfigurationProtocolGuid, NULL, (VOID **) &SmmConfiguration);

  //
  // Get SMRAM information
  //
  Size = 0;
  Status = mSmmAccess->GetCapabilities (mSmmAccess, &Size, NULL);
  ASSERT (Status == EFI_BUFFER_TOO_SMALL);

  gSmmCorePrivate->SmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocatePool (Size);
  ASSERT (gSmmCorePrivate->SmramRanges != NULL);

  Status = mSmmAccess->GetCapabilities (mSmmAccess, &Size, gSmmCorePrivate->SmramRanges);
  ASSERT_EFI_ERROR (Status);

  gSmmCorePrivate->SmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);

  //
  // Open all SMRAM ranges
  //
  Status = mSmmAccess->Open (mSmmAccess);
  ASSERT_EFI_ERROR (Status);

  //
  // Print debug message that the SMRAM window is now open.
  //
  DEBUG ((DEBUG_INFO, "SMM IPL opened SMRAM window\n"));

  //
  // Subtract SMRAM any reserved SMRAM regions.
  //
  if (SmmConfiguration != NULL) {
    SmramResRegion = SmmConfiguration->SmramReservedRegions;
    while (SmramResRegion->SmramReservedSize != 0) {
      for (Index = 0; Index < gSmmCorePrivate->SmramRangeCount; Index ++) {
        if ((SmramResRegion->SmramReservedStart >= gSmmCorePrivate->SmramRanges[Index].CpuStart)  &&      \
           ((SmramResRegion->SmramReservedStart + SmramResRegion->SmramReservedSize) <=   \
           (gSmmCorePrivate->SmramRanges[Index].CpuStart + gSmmCorePrivate->SmramRanges[Index].PhysicalSize))) {
          //
          // This range has reserved area, calculate the left free size
          //
          gSmmCorePrivate->SmramRanges[Index].PhysicalSize = SmramResRegion->SmramReservedStart - gSmmCorePrivate->SmramRanges[Index].CpuStart;
        }
      }
      SmramResRegion++;
    }
  }
  
  //
  // Find the largest SMRAM range between 1MB and 4GB that is at least 256KB - 4K in size
  //
  mCurrentSmramRange = NULL;
  for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < gSmmCorePrivate->SmramRangeCount; Index++) {
    //
    // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization
    //
    if ((gSmmCorePrivate->SmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
      continue;
    }

    if (gSmmCorePrivate->SmramRanges[Index].CpuStart >= BASE_1MB) {
      if ((gSmmCorePrivate->SmramRanges[Index].CpuStart + gSmmCorePrivate->SmramRanges[Index].PhysicalSize) <= BASE_4GB) {
        if (gSmmCorePrivate->SmramRanges[Index].PhysicalSize >= MaxSize) {
          MaxSize = gSmmCorePrivate->SmramRanges[Index].PhysicalSize;
          mCurrentSmramRange = &gSmmCorePrivate->SmramRanges[Index];
        }
      }
    }
  }

  if (mCurrentSmramRange != NULL) {
    //
    // Print debug message showing SMRAM window that will be used by SMM IPL and SMM Core
    //
    DEBUG ((DEBUG_INFO, "SMM IPL found SMRAM window %p - %p\n", 
      (VOID *)(UINTN)mCurrentSmramRange->CpuStart, 
      (VOID *)(UINTN)(mCurrentSmramRange->CpuStart + mCurrentSmramRange->PhysicalSize - 1)
      ));

    GetSmramCacheRange (mCurrentSmramRange, &mSmramCacheBase, &mSmramCacheSize);
    //
    // If CPU AP is present, attempt to set SMRAM cacheability to WB
    // Note that it is expected that cacheability of SMRAM has been set to WB if CPU AP
    // is not available here.
    //
    CpuArch = NULL;
    Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&CpuArch);
    if (!EFI_ERROR (Status)) {
      Status = gDS->SetMemorySpaceAttributes(
                      mSmramCacheBase, 
                      mSmramCacheSize,
                      EFI_MEMORY_WB
                      );
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_WARN, "SMM IPL failed to set SMRAM window to EFI_MEMORY_WB\n"));
      }  
    }
    //
    // if Loading module at Fixed Address feature is enabled, save the SMRAM base to Load
    // Modules At Fixed Address Configuration Table.
    //
    if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {
      //
      // Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber
      //
      SmmCodeSize = LShiftU64 (PcdGet32(PcdLoadFixAddressSmmCodePageNumber), EFI_PAGE_SHIFT);
      //
      // The SMRAM available memory is assumed to be larger than SmmCodeSize
      //
      ASSERT (mCurrentSmramRange->PhysicalSize > SmmCodeSize);
      //
      // Retrieve Load modules At fixed address configuration table and save the SMRAM base.
      //
      Status = EfiGetSystemConfigurationTable (
                &gLoadFixedAddressConfigurationTableGuid,
               (VOID **) &LMFAConfigurationTable
               );
      if (!EFI_ERROR (Status) && LMFAConfigurationTable != NULL) {
        LMFAConfigurationTable->SmramBase = mCurrentSmramRange->CpuStart;
        //
        // Print the SMRAM base
        //
        DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: TSEG BASE is %x. \n", LMFAConfigurationTable->SmramBase));
      }
    }
    //
    // Load SMM Core into SMRAM and execute it from SMRAM
    //
    Status = ExecuteSmmCoreFromSmram (mCurrentSmramRange, gSmmCorePrivate);
    if (EFI_ERROR (Status)) {
      //
      // Print error message that the SMM Core failed to be loaded and executed.
      //
      DEBUG ((DEBUG_ERROR, "SMM IPL could not load and execute SMM Core from SMRAM\n"));

      //
      // Attempt to reset SMRAM cacheability to UC
      //
      if (CpuArch != NULL) {
        Status = gDS->SetMemorySpaceAttributes(
                        mSmramCacheBase, 
                        mSmramCacheSize,
                        EFI_MEMORY_UC
                        );
        if (EFI_ERROR (Status)) {
          DEBUG ((DEBUG_WARN, "SMM IPL failed to reset SMRAM window to EFI_MEMORY_UC\n"));
        }  
      }
    }
  } else {
    //
    // Print error message that there are not enough SMRAM resources to load the SMM Core.
    //
    DEBUG ((DEBUG_ERROR, "SMM IPL could not find a large enough SMRAM region to load SMM Core\n"));
  }

  //
  // If the SMM Core could not be loaded then close SMRAM window, free allocated 
  // resources, and return an error so SMM IPL will be unloaded.
  //
  if (mCurrentSmramRange == NULL || EFI_ERROR (Status)) {
    //
    // Close all SMRAM ranges
    //
    Status = mSmmAccess->Close (mSmmAccess);
    ASSERT_EFI_ERROR (Status);

    //
    // Print debug message that the SMRAM window is now closed.
    //
    DEBUG ((DEBUG_INFO, "SMM IPL closed SMRAM window\n"));

    //
    // Free all allocated resources
    //
    FreePool (gSmmCorePrivate->SmramRanges);
    
    return EFI_UNSUPPORTED;
  }
  
  //
  // Install SMM Base2 Protocol and SMM Communication Protocol
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &mSmmIplHandle,
                  &gEfiSmmBase2ProtocolGuid,         &mSmmBase2,
                  &gEfiSmmCommunicationProtocolGuid, &mSmmCommunication,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Create the set of protocol and event notififcations that the SMM IPL requires
  //
  for (Index = 0; mSmmIplEvents[Index].NotifyFunction != NULL; Index++) {
    if (mSmmIplEvents[Index].Protocol) {
      mSmmIplEvents[Index].Event = EfiCreateProtocolNotifyEvent (
                                     mSmmIplEvents[Index].Guid,
                                     mSmmIplEvents[Index].NotifyTpl,
                                     mSmmIplEvents[Index].NotifyFunction,
                                     mSmmIplEvents[Index].NotifyContext,
                                    &Registration
                                    );
    } else {
      Status = gBS->CreateEventEx (
                      EVT_NOTIFY_SIGNAL,
                      mSmmIplEvents[Index].NotifyTpl,
                      mSmmIplEvents[Index].NotifyFunction,
                      mSmmIplEvents[Index].NotifyContext,
                      mSmmIplEvents[Index].Guid,
                      &mSmmIplEvents[Index].Event
                      );
      ASSERT_EFI_ERROR (Status);
    }
  }

  return EFI_SUCCESS;
}
示例#24
0
文件: BdsMisc.c 项目: jief666/clover
/**
  This routine adjust the memory information for different memory type and 
  save them into the variables for next boot.
**/
VOID
BdsSetMemoryTypeInformationVariable (
  VOID
  )
{
  EFI_STATUS                   Status;
  EFI_MEMORY_TYPE_INFORMATION  *PreviousMemoryTypeInformation;
  EFI_MEMORY_TYPE_INFORMATION  *CurrentMemoryTypeInformation;
  UINTN                        VariableSize;
  UINTN                        Index;
  UINTN                        Index1;
  UINT32                       Previous;
  UINT32                       Current;
  UINT32                       Next;
  EFI_HOB_GUID_TYPE            *GuidHob;
  BOOLEAN                      MemoryTypeInformationModified;
  BOOLEAN                      MemoryTypeInformationVariableExists;
  EFI_BOOT_MODE                BootMode;

  MemoryTypeInformationModified       = FALSE;
  MemoryTypeInformationVariableExists = FALSE;


  BootMode = GetBootModeHob ();
  //
  // In BOOT_IN_RECOVERY_MODE, Variable region is not reliable.
  //
  if (BootMode == BOOT_IN_RECOVERY_MODE) {
    return;
  }

  //
  // Only check the the Memory Type Information variable in the boot mode 
  // other than BOOT_WITH_DEFAULT_SETTINGS because the Memory Type
  // Information is not valid in this boot mode.
  //
  if (BootMode != BOOT_WITH_DEFAULT_SETTINGS) {
    VariableSize = 0;
    Status = gRT->GetVariable (
                    EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
                    &gEfiMemoryTypeInformationGuid,
                    NULL, 
                    &VariableSize, 
                    NULL
                    );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      MemoryTypeInformationVariableExists = TRUE;
    }
  }

  //
  // Retrieve the current memory usage statistics.  If they are not found, then
  // no adjustments can be made to the Memory Type Information variable.
  //
  Status = EfiGetSystemConfigurationTable (
             &gEfiMemoryTypeInformationGuid,
             (VOID **) &CurrentMemoryTypeInformation
             );
  if (EFI_ERROR (Status) || CurrentMemoryTypeInformation == NULL) {
    return;
  }

  //
  // Get the Memory Type Information settings from Hob if they exist,
  // PEI is responsible for getting them from variable and build a Hob to save them.
  // If the previous Memory Type Information is not available, then set defaults
  //
  GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid);
  if (GuidHob == NULL) {
    //
    // If Platform has not built Memory Type Info into the Hob, just return.
    //
    return;
  }
  PreviousMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob);
  VariableSize = GET_GUID_HOB_DATA_SIZE (GuidHob);

  //
  // Use a heuristic to adjust the Memory Type Information for the next boot
  //
//  DEBUG ((EFI_D_INFO, "Memory  Previous  Current    Next   \n"));
//  DEBUG ((EFI_D_INFO, " Type    Pages     Pages     Pages  \n"));
//  DEBUG ((EFI_D_INFO, "======  ========  ========  ========\n"));

  for (Index = 0; PreviousMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {

    for (Index1 = 0; CurrentMemoryTypeInformation[Index1].Type != EfiMaxMemoryType; Index1++) {
      if (PreviousMemoryTypeInformation[Index].Type == CurrentMemoryTypeInformation[Index1].Type) {
        break;
      }
    }
    if (CurrentMemoryTypeInformation[Index1].Type == EfiMaxMemoryType) {
      continue;
    }

    //
    // Previous is the number of pages pre-allocated
    // Current is the number of pages actually needed
    //
    Previous = PreviousMemoryTypeInformation[Index].NumberOfPages;
    Current  = CurrentMemoryTypeInformation[Index1].NumberOfPages;
    Next     = Previous;

    //
    // Inconsistent Memory Reserved across bootings may lead to S4 fail
    // Write next varible to 125% * current when the pre-allocated memory is:
    //  1. More than 150% of needed memory and boot mode is BOOT_WITH_DEFAULT_SETTING
    //  2. Less than the needed memory
    //
    if (Current < Previous) {
      if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
        Next = Current + (Current >> 2);
      } else if (!MemoryTypeInformationVariableExists) {
        Next = MAX (Current + (Current >> 2), Previous);
      }
示例#25
0
/**
  Start a Linux kernel from a Device Path

  @param  LinuxKernelDevicePath  Device Path to the Linux Kernel
  @param  InitrdDevicePath       Device Path to the Initrd
  @param  CommandLineArguments   Linux command line

  @retval EFI_SUCCESS           All drivers have been connected
  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found
  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.

**/
EFI_STATUS
BdsBootLinuxFdt (
  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
  IN  CONST CHAR8*              CommandLineArguments
  )
{
  EFI_STATUS               Status;
  UINT32                   LinuxImageSize;
  UINT32                   InitrdImageBaseSize = 0;
  UINT32                   InitrdImageSize = 0;
  VOID                     *InstalledFdtBase;
  UINT32                   FdtBlobSize;
  EFI_PHYSICAL_ADDRESS     FdtBlobBase;
  EFI_PHYSICAL_ADDRESS     LinuxImage;
  EFI_PHYSICAL_ADDRESS     InitrdImageBase = 0;
  EFI_PHYSICAL_ADDRESS     InitrdImage = 0;

  PERF_START (NULL, "BDS", NULL, 0);

  // Load the Linux kernel from a device path
  LinuxImage = LINUX_KERNEL_MAX_OFFSET;
  Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);
  if (EFI_ERROR(Status)) {
    Print (L"ERROR: Did not find Linux kernel.\n");
    return Status;
  }

  if (InitrdDevicePath) {
    InitrdImageBase = LINUX_KERNEL_MAX_OFFSET;
    Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize);
    if (Status == EFI_OUT_OF_RESOURCES) {
      Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize);
    }
    if (EFI_ERROR(Status)) {
      Print (L"ERROR: Did not find initrd image.\n");
      goto EXIT_FREE_LINUX;
    }

    // Check if the initrd is a uInitrd
    if (*(UINT32*)((UINTN)InitrdImageBase) == LINUX_UIMAGE_SIGNATURE) {
      // Skip the 64-byte image header
      InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImageBase + 64);
      InitrdImageSize = InitrdImageBaseSize - 64;
    } else {
      InitrdImage = InitrdImageBase;
      InitrdImageSize = InitrdImageBaseSize;
    }
  }

  //
  // Get the FDT from the Configuration Table.
  // The FDT will be reloaded in PrepareFdt() to a more appropriate
  // location for the Linux Kernel.
  //
  Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &InstalledFdtBase);
  if (EFI_ERROR (Status)) {
    Print (L"ERROR: Did not get the Device Tree blob (%r).\n", Status);
    goto EXIT_FREE_INITRD;
  }
  FdtBlobBase = (EFI_PHYSICAL_ADDRESS)(UINTN)InstalledFdtBase;
  FdtBlobSize = fdt_totalsize (InstalledFdtBase);

  // Update the Fdt with the Initrd information. The FDT will increase in size.
  // By setting address=0 we leave the memory allocation to the function
  Status = PrepareFdt (CommandLineArguments, InitrdImage, InitrdImageSize, &FdtBlobBase, &FdtBlobSize);
  if (EFI_ERROR(Status)) {
    Print(L"ERROR: Can not load kernel with FDT. Status=%r\n", Status);
    goto EXIT_FREE_FDT;
  }

  return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize, ARM_FDT_MACHINE_TYPE);

EXIT_FREE_FDT:
  gBS->FreePages (FdtBlobBase, EFI_SIZE_TO_PAGES (FdtBlobSize));

EXIT_FREE_INITRD:
  if (InitrdDevicePath) {
    gBS->FreePages (InitrdImageBase, EFI_SIZE_TO_PAGES (InitrdImageBaseSize));
  }

EXIT_FREE_LINUX:
  gBS->FreePages (LinuxImage, EFI_SIZE_TO_PAGES (LinuxImageSize));

  return Status;
}
示例#26
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);
}
示例#27
0
EFI_STATUS
RebuildHeap (
  IN OUT   HEAP_MANAGER                 **HeapManagerPtr
  )
{
  EFI_STATUS                  Status;
  AGESA_STATUS                AgesaStatus;
  UINTN                       AlignTo16ByteInDxeMem;
  UINTN                       TotalAlignTo16ByteInHob;
  EFI_PEI_HOB_POINTERS        Hob;
  VOID                        *HobList;
  VOID                        *HeapBufferInHob;
  HEAP_MANAGER                *HeapManagerInHob;
  BUFFER_NODE                 *HeapHeaderNodeInHob;
  BUFFER_NODE                 *HeapCurrentNodeInHob;
  BUFFER_NODE                 *HeapPreNodeInHob;

  HEAP_MANAGER                *HeapManagerInDxeMem;
  BUFFER_NODE                 *HeapHeaderNodeInDxeMem;
  BUFFER_NODE                 *HeapCurrentNodeInDxeMem;
  BUFFER_NODE                 *HeapPreNodeInDxeMem;
  UINT32                      OffsetOfHeapCurrentNodeInDxeMem;
  EFI_HOB_GUID_TYPE           *GuidHob;

  AGESA_BUFFER_PARAMS         AllocParams;

  Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
  ASSERT_EFI_ERROR (Status);

  Hob.Raw = HobList;
  HeapBufferInHob = NULL;

  while (!END_OF_HOB_LIST (Hob)) {
    GuidHob = GetNextGuidHob (&gAmdHeapHobGuid, HobList);
    HeapBufferInHob = GET_GUID_HOB_DATA (GuidHob);

    if (HeapBufferInHob != NULL) {
      HeapManagerInHob = (HEAP_MANAGER *) HeapBufferInHob;
      HeapHeaderNodeInHob = (BUFFER_NODE *) ((UINT8 *) HeapManagerInHob + HeapManagerInHob->FirstActiveBufferOffset);
      HeapCurrentNodeInHob = HeapHeaderNodeInHob;
      //
      // 1. Analyse heap buffer from HOB data to calculate the final size for recreating the heap buffers
      //    Reserve maximum pad size for each heap node.
      // 2. Allocate memory for heap buffers
      // 3. Copying heap manager data from HOB include extracing 1-byte alignment to 16-byte alignment
      //

      //
      // 1. Analyse heap buffer from HOB data to calculate the final size for recreating the heap buffers.
      //    Reserve maximum pad size for each heap node.
      //
      TotalAlignTo16ByteInHob = 0;
      do {
        HeapPreNodeInHob = HeapCurrentNodeInHob;
        TotalAlignTo16ByteInHob += 0xF;
        HeapCurrentNodeInHob = (BUFFER_NODE *) ((UINT8 *) HeapBufferInHob + HeapCurrentNodeInHob->OffsetOfNextNode);
      } while (HeapPreNodeInHob->OffsetOfNextNode != AMD_HEAP_INVALID_HEAP_OFFSET);

      //
      // 2. Allocate memory for heap buffers
      //
      AllocParams.BufferLength = (UINT32) (HeapManagerInHob->UsedSize + TotalAlignTo16ByteInHob + 0x0F);
      AllocParams.BufferHandle = AMD_HEAP_IN_MAIN_MEMORY_HANDLE;
      if ((AgesaStatus = AgesaAllocateBuffer (0, &AllocParams)) != AGESA_SUCCESS) {
        if (AGESA_ERROR > AgesaStatus) {
          return EFI_OUT_OF_RESOURCES;
        }
      }
      ZeroMem (AllocParams.BufferPointer, AllocParams.BufferLength);
      *HeapManagerPtr = AllocParams.BufferPointer;

      //
      // 3. Copying heap manager data from HOB include extracing 1-byte alignment to 16-byte alignment
      //
      HeapManagerInDxeMem = *HeapManagerPtr;
      HeapManagerInDxeMem->FirstActiveBufferOffset = sizeof (HEAP_MANAGER);
      HeapManagerInDxeMem->UsedSize = sizeof (HEAP_MANAGER);
      HeapHeaderNodeInDxeMem = (BUFFER_NODE *) ((UINT8 *) HeapManagerInDxeMem + HeapManagerInDxeMem->FirstActiveBufferOffset);
      OffsetOfHeapCurrentNodeInDxeMem = HeapManagerInDxeMem->FirstActiveBufferOffset;
      HeapCurrentNodeInDxeMem = HeapHeaderNodeInDxeMem;
      HeapCurrentNodeInHob = HeapHeaderNodeInHob;

      HeapPreNodeInHob = NULL;
      do {
        // Create BUFFER_NODE with 16-byte alignment padding considered.
        // The beginning of data buffer is on 16-byte boundary address.
        // The structure of a heap buffer would be looked like below.
        //
        // +---------------------------------------------------------------------------------+
        // | BUFFER_NODE | Pad | IDS SENTINEL ("Head") | Data buffer | IDS SENTINEL ("Tail") |
        // +---------------------------------------------------------------------------------+
        //
        AlignTo16ByteInDxeMem = ((0x10 - (((UINTN) (VOID *) HeapCurrentNodeInDxeMem + sizeof (BUFFER_NODE) + SIZE_OF_SENTINEL) & 0xF)) & 0xF);
        HeapCurrentNodeInDxeMem->BufferHandle = HeapCurrentNodeInHob->BufferHandle;
        HeapCurrentNodeInDxeMem->BufferSize = (UINT32) (HeapCurrentNodeInHob->BufferSize + AlignTo16ByteInDxeMem);
        HeapCurrentNodeInDxeMem->Persist = HeapCurrentNodeInHob->Persist;
        HeapCurrentNodeInDxeMem->PadSize = (UINT8) AlignTo16ByteInDxeMem;
        HeapCurrentNodeInDxeMem->OffsetOfNextNode = OffsetOfHeapCurrentNodeInDxeMem + sizeof (BUFFER_NODE) + HeapCurrentNodeInDxeMem->BufferSize;
        // Copy buffer data
        gBS->CopyMem (
          (UINT8 *) ((UINT8 *) HeapCurrentNodeInDxeMem + sizeof (BUFFER_NODE) + AlignTo16ByteInDxeMem),
          (UINT8 *) ((UINT8 *) HeapCurrentNodeInHob + sizeof (BUFFER_NODE)),
          HeapCurrentNodeInHob->BufferSize
          );
        // Point to the next heap node
        HeapPreNodeInHob = HeapCurrentNodeInHob;
        HeapPreNodeInDxeMem = HeapCurrentNodeInDxeMem;
        HeapCurrentNodeInHob = (BUFFER_NODE *) ((UINT8 *) HeapBufferInHob + HeapCurrentNodeInHob->OffsetOfNextNode);
        HeapCurrentNodeInDxeMem = (BUFFER_NODE *) ((UINT8 *) HeapManagerInDxeMem + HeapCurrentNodeInDxeMem->OffsetOfNextNode);
        OffsetOfHeapCurrentNodeInDxeMem = (UINT32) ((UINTN) HeapCurrentNodeInDxeMem - (UINTN) HeapManagerInDxeMem);

      } while (HeapPreNodeInHob->OffsetOfNextNode != AMD_HEAP_INVALID_HEAP_OFFSET);
      //
      // Finalize the last heap node
      //
      HeapManagerInDxeMem->UsedSize = (UINT32) HeapPreNodeInDxeMem->OffsetOfNextNode;
      HeapPreNodeInDxeMem->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET;

      //
      // Finalize Heap Manager pointer
      // No free buffer node is provide after heap recreation.
      //
      *HeapManagerPtr = HeapManagerInDxeMem;
      HeapManagerInDxeMem->FirstActiveBufferOffset = (UINT32) ((UINT8 *) HeapHeaderNodeInDxeMem - (UINT8 *) HeapManagerInDxeMem);
      HeapManagerInDxeMem->FirstFreeSpaceOffset = AMD_HEAP_INVALID_HEAP_OFFSET;
      HeapManagerInDxeMem->Signature = HeapManagerInHob->Signature;

      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}
示例#28
0
/**
  Initialize debug agent.

  This function is used to set up debug enviroment for source level debug
  in SMM code.

  If InitFlag is DEBUG_AGENT_INIT_SMM, it will overirde IDT table entries
  and initialize debug port. It will get debug agent Mailbox from GUIDed HOB,
  it it exists, debug agent wiil copied it into the local Mailbox in SMM space.
  it will overirde IDT table entries and initialize debug port. Context will be
  NULL.
  If InitFlag is DEBUG_AGENT_INIT_ENTER_SMI, debug agent will save Debug
  Registers and get local Mailbox in SMM space. Context will be NULL.
  If InitFlag is DEBUG_AGENT_INIT_EXIT_SMI, debug agent will restore Debug
  Registers. Context will be NULL.

  @param[in] InitFlag     Init flag is used to decide initialize process.
  @param[in] Context      Context needed according to InitFlag.
  @param[in] Function     Continue function called by debug agent library; it was
                          optional.

**/
VOID
EFIAPI
InitializeDebugAgent (
  IN UINT32                InitFlag,
  IN VOID                  *Context, OPTIONAL
  IN DEBUG_AGENT_CONTINUE  Function  OPTIONAL
  )
{
  EFI_STATUS                    Status;
  UINT64                        DebugPortHandle;
  IA32_IDT_GATE_DESCRIPTOR      IdtEntry[33];
  IA32_DESCRIPTOR               IdtDescriptor;
  IA32_DESCRIPTOR               *Ia32Idtr;
  IA32_IDT_ENTRY                *Ia32IdtEntry;
  IA32_DESCRIPTOR               Idtr;
  UINT16                        IdtEntryCount;
  DEBUG_AGENT_MAILBOX           *Mailbox;
  UINT64                        *MailboxLocation;
  UINT32                        DebugTimerFrequency;
  BOOLEAN                       PeriodicMode;
  UINTN                         TimerCycle;

  switch (InitFlag) {
  case DEBUG_AGENT_INIT_SMM:
    //
    // Install configuration table for persisted vector handoff info
    //
    Status = gSmst->SmmInstallConfigurationTable (
                      gSmst,
                      &gEfiVectorHandoffTableGuid,
                      (VOID *) &mVectorHandoffInfoDebugAgent[0],
                      sizeof (EFI_VECTOR_HANDOFF_INFO) * mVectorHandoffInfoCount
                      );
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "DebugAgent: Cannot install configuration table for persisted vector handoff info!\n"));
      CpuDeadLoop ();
    }
    //
    // Check if Debug Agent initialized in DXE phase
    //
    Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **) &Mailbox);
    if (Status == EFI_SUCCESS && Mailbox != NULL) {
      VerifyMailboxChecksum (Mailbox);
      mMailboxPointer = Mailbox;
      break;
    }
    //
    // Check if Debug Agent initialized in SEC/PEI phase
    //
    Mailbox = GetMailboxFromHob (); 
    if (Mailbox != NULL) {
      mMailboxPointer = Mailbox;
      break;
    }
    //
    // Debug Agent was not initialized before, use the local mailbox.
    //
    ZeroMem (&mLocalMailbox, sizeof (DEBUG_AGENT_MAILBOX));
    Mailbox = &mLocalMailbox;
    //
    // Save original IDT entries
    //
    AsmReadIdtr (&IdtDescriptor);      
    CopyMem (&IdtEntry, (VOID *)IdtDescriptor.Base, 33 * sizeof(IA32_IDT_GATE_DESCRIPTOR));
    //
    // Initialized Debug Agent
    //
    InitializeDebugIdt ();
    //
    // Initialize Debug Timer hardware and save its frequency
    //
    InitializeDebugTimer (&DebugTimerFrequency, TRUE);
    UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY, DebugTimerFrequency);

    DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((DEBUG_PORT_HANDLE) (UINTN)Mailbox->DebugPortHandle, NULL);
    UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
    mMailboxPointer = Mailbox;
    //
    // Trigger one software interrupt to inform HOST
    //
    TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE);

    SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);
    //
    // Memory has been ready
    //
    if (IsHostAttached ()) {
      //
      // Trigger one software interrupt to inform HOST
      //
      TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
    }
    //
    // Find and report PE/COFF image info to HOST
    //  
    FindAndReportModuleImageInfo (SIZE_4KB);
    //
    // Restore saved IDT entries
    //     
    CopyMem ((VOID *)IdtDescriptor.Base, &IdtEntry, 33 * sizeof(IA32_IDT_GATE_DESCRIPTOR));

    break;

  case DEBUG_AGENT_INIT_ENTER_SMI:
    SaveDebugRegister ();
    if (!mSmmDebugIdtInitFlag) {
      //
      // We only need to initialize Debug IDT table at first SMI entry
      // after SMM relocation.
      //
      InitializeDebugIdt ();
      mSmmDebugIdtInitFlag = TRUE;
    }
    //
    // Check if CPU APIC Timer is working, otherwise initialize it.
    //
    InitializeLocalApicSoftwareEnable (TRUE);
    GetApicTimerState (NULL, &PeriodicMode, NULL);
    TimerCycle = GetApicTimerInitCount ();
    if (!PeriodicMode || TimerCycle == 0) {
      InitializeDebugTimer (NULL, FALSE);
    }
    Mailbox = GetMailboxPointer ();
    if (GetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS) == 1) {
      //
      // If Debug Agent has been communicaton state with HOST, we need skip
      // any break points set in SMM, set Skip Breakpoint flag
      //
      mSkipBreakpoint = TRUE;
    }
    if (GetDebugFlag (DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI) == 1) {
      if (mSkipBreakpoint) {
        //
        // Print warning message if ignore smm entry break
        //
        DebugPortWriteBuffer ((DEBUG_PORT_HANDLE) (UINTN)Mailbox->DebugPortHandle,
                               (UINT8 *)mWarningMsgIgnoreSmmEntryBreak,
                               AsciiStrLen (mWarningMsgIgnoreSmmEntryBreak)
                               );
      } else {
        //
        // If SMM entry break is set, SMM code will be break at here.
        //
        CpuBreakpoint ();
      }
    }
    break;

  case DEBUG_AGENT_INIT_EXIT_SMI:
    Mailbox = GetMailboxPointer ();
    //
    // Clear Skip Breakpoint flag
    //
    mSkipBreakpoint = FALSE;
    RestoreDebugRegister ();
    break;

  case DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64:
    if (Context == NULL) {
      DEBUG ((EFI_D_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n"));
      CpuDeadLoop ();
    } else {
      Ia32Idtr =  (IA32_DESCRIPTOR *) Context;
      Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base);
      MailboxLocation = (UINT64 *) (UINTN) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow + 
                                  (UINT32) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16));
      mMailboxPointer = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);
      VerifyMailboxChecksum (mMailboxPointer);
      //
      // Get original IDT address and size.
      //
      AsmReadIdtr ((IA32_DESCRIPTOR *) &Idtr);
      IdtEntryCount = (UINT16) ((Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR));
      if (IdtEntryCount < 33) {
        Idtr.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 33 - 1);
        Idtr.Base  = (UINTN) &mIdtEntryTable;
        ZeroMem (&mIdtEntryTable, Idtr.Limit + 1);
        AsmWriteIdtr ((IA32_DESCRIPTOR *) &Idtr);
      }

      InitializeDebugIdt ();
      //
      // Initialize Debug Timer hardware and save its frequency
      //
      InitializeDebugTimer (&DebugTimerFrequency, TRUE);
      UpdateMailboxContent (mMailboxPointer, DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY, DebugTimerFrequency);
      //
      // Enable Debug Timer interrupt and CPU interrupt
      //
      SaveAndSetDebugTimerInterrupt (TRUE);
      EnableInterrupts ();

      FindAndReportModuleImageInfo (SIZE_4KB);
    }
    break;

  default:
    //
    // Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this 
    // Debug Agent library instance.
    //
    DEBUG ((EFI_D_ERROR, "Debug Agent: The InitFlag value is not allowed!\n"));
    CpuDeadLoop ();
    break;    
  }
}
示例#29
0
/**
  Measure and log EFI handoff tables, and extend the measurement result into PCR[1].

  @retval EFI_SUCCESS         Operation completed successfully.
  @retval EFI_DEVICE_ERROR    The operation was unsuccessful.

**/
EFI_STATUS
EFIAPI
MeasureHandoffTables (
    VOID
)
{
    EFI_STATUS                        Status;
    SMBIOS_TABLE_ENTRY_POINT          *SmbiosTable;
    TCG_PCR_EVENT_HDR                 TcgEvent;
    EFI_HANDOFF_TABLE_POINTERS        HandoffTables;
    UINTN                             ProcessorNum;
    EFI_CPU_PHYSICAL_LOCATION         *ProcessorLocBuf;

    //
    // Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1]
    //
    Status = EfiGetSystemConfigurationTable (
                 &gEfiSmbiosTableGuid,
                 (VOID **) &SmbiosTable
             );

    if (!EFI_ERROR (Status)) {
        ASSERT (SmbiosTable != NULL);

        TcgEvent.PCRIndex  = 1;
        TcgEvent.EventType = EV_EFI_HANDOFF_TABLES;
        TcgEvent.EventSize = sizeof (HandoffTables);

        HandoffTables.NumberOfTables = 1;
        HandoffTables.TableEntry[0].VendorGuid  = gEfiSmbiosTableGuid;
        HandoffTables.TableEntry[0].VendorTable = SmbiosTable;

        DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTable->TableAddress));
        DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", SmbiosTable->TableLength));

        Status = TcgDxeHashLogExtendEventI (
                     &mTcgDxeData,
                     (UINT8*)(UINTN)SmbiosTable->TableAddress,
                     SmbiosTable->TableLength,
                     &TcgEvent,
                     (UINT8*)&HandoffTables
                 );
    }

    if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {
        //
        // Tcg Server spec.
        // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
        //
        Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);

        if (!EFI_ERROR(Status)) {
            TcgEvent.PCRIndex  = 1;
            TcgEvent.EventType = EV_TABLE_OF_DEVICES;
            TcgEvent.EventSize = sizeof (HandoffTables);

            HandoffTables.NumberOfTables = 1;
            HandoffTables.TableEntry[0].VendorGuid  = gEfiMpServiceProtocolGuid;
            HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;

            Status = TcgDxeHashLogExtendEventI (
                         &mTcgDxeData,
                         (UINT8*)(UINTN)ProcessorLocBuf,
                         sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
                         &TcgEvent,
                         (UINT8*)&HandoffTables
                     );

            FreePool(ProcessorLocBuf);
        }
    }

    return Status;
}
示例#30
0
/**
  Internal constructor worker function.

  It will register one callback function on EFI PCD Protocol.
  It will allocate the NVS memory to store Mailbox and install configuration table
  in system table to store its pointer.

**/
VOID
InternalConstructorWorker (
  VOID
  )
{
  EFI_STATUS                  Status;
  EFI_PHYSICAL_ADDRESS        Address;
  BOOLEAN                     DebugTimerInterruptState;
  DEBUG_AGENT_MAILBOX         *Mailbox;
  DEBUG_AGENT_MAILBOX         *NewMailbox;
  EFI_HOB_GUID_TYPE           *GuidHob;
  EFI_VECTOR_HANDOFF_INFO     *VectorHandoffInfo;

  //
  // Check persisted vector handoff info
  //
  Status = EFI_SUCCESS;
  GuidHob = GetFirstGuidHob (&gEfiVectorHandoffInfoPpiGuid);
  if (GuidHob != NULL && !mDxeCoreFlag) {
    //
    // Check if configuration table is installed or not if GUIDed HOB existed,
    // only when Debug Agent is not linked by DXE Core
    //
    Status = EfiGetSystemConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID **) &VectorHandoffInfo);
  }
  if (GuidHob == NULL || Status != EFI_SUCCESS) {
    //
    // Install configuration table for persisted vector handoff info if GUIDed HOB cannot be found or
    // configuration table does not exist
    //
    Status = gBS->InstallConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID *) &mVectorHandoffInfoDebugAgent[0]);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "DebugAgent: Cannot install configuration table for persisted vector handoff info!\n"));
      CpuDeadLoop ();
    }
  }

  //
  // Install EFI Serial IO protocol on debug port
  //
  InstallSerialIo ();

  Address = 0;
  Status = gBS->AllocatePages (
                  AllocateAnyPages,
                  EfiACPIMemoryNVS,
                  EFI_SIZE_TO_PAGES (sizeof(DEBUG_AGENT_MAILBOX) + PcdGet16(PcdDebugPortHandleBufferSize)),
                  &Address
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "DebugAgent: Cannot install configuration table for mailbox!\n"));
    CpuDeadLoop ();
  }

  DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE);

  NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Address;
  //
  // Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox
  // and Debug Port Handle buffer may be free at runtime, SMM debug agent needs to access them
  //
  Mailbox = GetMailboxPointer ();
  CopyMem (NewMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
  CopyMem (NewMailbox + 1, (VOID *)(UINTN)Mailbox->DebugPortHandle, PcdGet16(PcdDebugPortHandleBufferSize));
  //
  // Update Debug Port Handle in new Mailbox
  //
  UpdateMailboxContent (NewMailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, (UINT64)(UINTN)(NewMailbox + 1));
  mMailboxPointer = NewMailbox;

  DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState);

  Status = gBS->InstallConfigurationTable (&gEfiDebugAgentGuid, (VOID *) mMailboxPointer);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to install configuration for mailbox!\n"));
    CpuDeadLoop ();
  }
}