/**
Initialize the system (or sometimes called permanent) memory
This memory is generally represented by the DRAM.
This function is called from InitializeMemory() in MemoryInitPeim, in the PEI
phase.
**/
VOID
ArmPlatformInitializeSystemMemory (
VOID
)
{
VOID *DeviceTreeBase;
INT32 Node, Prev;
UINT64 NewBase;
UINT64 NewSize;
CONST CHAR8 *Type;
INT32 Len;
CONST UINT64 *RegProp;
NewBase = 0;
NewSize = 0;
DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
ASSERT (DeviceTreeBase != NULL);
//
// Make sure we have a valid device tree blob
//
ASSERT (fdt_check_header (DeviceTreeBase) == 0);
//
// Look for a memory node
//
for (Prev = 0;; Prev = Node) {
Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
if (Node < 0) {
break;
}
//
// Check for memory node
//
Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {
//
// Get the 'reg' property of this node. For now, we will assume
// two 8 byte quantities for base and size, respectively.
//
RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
if (RegProp != 0 && Len == (2 * sizeof (UINT64))) {
NewBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
NewSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));
//
// Make sure the start of DRAM matches our expectation
//
ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase);
PcdSet64 (PcdSystemMemorySize, NewSize);
DEBUG ((EFI_D_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n",
__FUNCTION__, NewBase, NewBase + NewSize - 1));
} else {
DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n",
__FUNCTION__));
}
break;
}
}
//
// We need to make sure that the machine we are running on has at least
// 128 MB of memory configured, and is currently executing this binary from
// NOR flash. This prevents a device tree image in DRAM from getting
// clobbered when our caller installs permanent PEI RAM, before we have a
// chance of marking its location as reserved or copy it to a freshly
// allocated block in the permanent PEI RAM in the platform PEIM.
//
ASSERT (NewSize >= SIZE_128MB);
ASSERT (
(((UINT64)PcdGet64 (PcdFdBaseAddress) +
(UINT64)PcdGet32 (PcdFdSize)) <= NewBase) ||
((UINT64)PcdGet64 (PcdFdBaseAddress) >= (NewBase + NewSize)));
}
/**
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
InitializeUserInterface (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_HII_HANDLE HiiHandle;
EFI_STATUS Status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
UINTN BootTextColumn;
UINTN BootTextRow;
if (!mModeInitialized) {
//
// After the console is ready, get current video resolution
// and text mode before launching setup at first time.
//
Status = gBS->HandleProtocol (
gST->ConsoleOutHandle,
&gEfiGraphicsOutputProtocolGuid,
(VOID**)&GraphicsOutput
);
if (EFI_ERROR (Status)) {
GraphicsOutput = NULL;
}
Status = gBS->HandleProtocol (
gST->ConsoleOutHandle,
&gEfiSimpleTextOutProtocolGuid,
(VOID**)&SimpleTextOut
);
if (EFI_ERROR (Status)) {
SimpleTextOut = NULL;
}
if (GraphicsOutput != NULL) {
//
// Get current video resolution and text mode.
//
mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
}
if (SimpleTextOut != NULL) {
Status = SimpleTextOut->QueryMode (
SimpleTextOut,
SimpleTextOut->Mode->Mode,
&BootTextColumn,
&BootTextRow
);
mBootTextModeColumn = (UINT32)BootTextColumn;
mBootTextModeRow = (UINT32)BootTextRow;
}
//
// Get user defined text mode for setup.
//
mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);
mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);
mModeInitialized = TRUE;
}
gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
gST->ConOut->ClearScreen (gST->ConOut);
//
// Install customized fonts needed by Front Page
//
HiiHandle = ExportFonts ();
ASSERT (HiiHandle != NULL);
InitializeStringSupport ();
BdsSetConsoleMode (TRUE);
UiEntry (FALSE);
BdsSetConsoleMode (FALSE);
UninitializeStringSupport ();
HiiRemovePackages (HiiHandle);
return EFI_SUCCESS;
}
/**
Initialize the state information for the CPU Architectural Protocol
@param ImageHandle of the loaded driver
@param SystemTable Pointer to the System Table
@retval EFI_SUCCESS Protocol registered
@retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
@retval EFI_DEVICE_ERROR Hardware problems
**/
EFI_STATUS
GicV2DxeInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
UINTN Index;
UINT32 RegOffset;
UINTN RegShift;
UINT32 CpuTarget;
// Make sure the Interrupt Controller Protocol is not already installed in the system.
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
mGicInterruptInterfaceBase = PcdGet32 (PcdGicInterruptInterfaceBase);
mGicDistributorBase = PcdGet32 (PcdGicDistributorBase);
mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);
for (Index = 0; Index < mGicNumInterrupts; Index++) {
GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index);
// Set Priority
RegOffset = Index / 4;
RegShift = (Index % 4) * 8;
MmioAndThenOr32 (
mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
~(0xff << RegShift),
ARM_GIC_DEFAULT_PRIORITY << RegShift
);
}
//
// Targets the interrupts to the Primary Cpu
//
// Only Primary CPU will run this code. We can identify our GIC CPU ID by reading
// the GIC Distributor Target register. The 8 first GICD_ITARGETSRn are banked to each
// connected CPU. These 8 registers hold the CPU targets fields for interrupts 0-31.
// More Info in the GIC Specification about "Interrupt Processor Targets Registers"
//
// Read the first Interrupt Processor Targets Register (that corresponds to the 4
// first SGIs)
CpuTarget = MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR);
// The CPU target is a bit field mapping each CPU to a GIC CPU Interface. This value
// is 0 when we run on a uniprocessor platform.
if (CpuTarget != 0) {
// The 8 first Interrupt Processor Targets Registers are read-only
for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) {
MmioWrite32 (mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4), CpuTarget);
}
}
// Set binary point reg to 0x7 (no preemption)
MmioWrite32 (mGicInterruptInterfaceBase + ARM_GIC_ICCBPR, 0x7);
// Set priority mask reg to 0xff to allow all priorities through
MmioWrite32 (mGicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0xff);
// Enable gic cpu interface
ArmGicEnableInterruptInterface (mGicInterruptInterfaceBase);
// Enable gic distributor
ArmGicEnableDistributor (mGicDistributorBase);
Status = InstallAndRegisterInterruptService (
&gHardwareInterruptV2Protocol, GicV2IrqInterruptHandler, GicV2ExitBootServicesEvent);
return Status;
}
/**
Get the PCD entry pointer in PCD database.
This routine will visit PCD database to find the PCD entry according to given
token number. The given token number is autogened by build tools and it will be
translated to local token number. Local token number contains PCD's type and
offset of PCD entry in PCD database.
@param TokenNumber Token's number, it is autogened by build tools
@param GetSize The size of token's value
@return PCD entry pointer in PCD database
**/
VOID *
GetWorker (
IN UINTN TokenNumber,
IN UINTN GetSize
)
{
UINT32 Offset;
EFI_GUID *Guid;
UINT16 *Name;
VARIABLE_HEAD *VariableHead;
EFI_STATUS Status;
UINTN DataSize;
VOID *Data;
UINT8 *StringTable;
STRING_HEAD StringTableIdx;
PEI_PCD_DATABASE *PeiPcdDb;
UINT32 LocalTokenNumber;
UINT32 LocalTokenCount;
UINT8 *VaraiableDefaultBuffer;
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
// We have to decrement TokenNumber by 1 to make it usable
// as the array index.
//
TokenNumber--;
PeiPcdDb = GetPcdDatabase ();
LocalTokenCount = PeiPcdDb->LocalTokenCount;
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));
ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0));
LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);
Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
StringTable = (UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset;
switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
case PCD_TYPE_VPD:
{
VPD_HEAD *VpdHead;
VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset);
return (VOID *) (UINTN) (PcdGet32 (PcdVpdBaseAddress) + VpdHead->Offset);
}
case PCD_TYPE_HII|PCD_TYPE_STRING:
case PCD_TYPE_HII:
{
VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset);
Guid = (EFI_GUID *) ((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset) + VariableHead->GuidTableIndex;
Name = (UINT16*)&StringTable[VariableHead->StringIndex];
if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) {
//
// If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of
// string array in string table.
//
VaraiableDefaultBuffer = (UINT8 *) &StringTable[*(STRING_HEAD*)((UINT8*) PeiPcdDb + VariableHead->DefaultValueOffset)];
} else {
VaraiableDefaultBuffer = (UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset;
}
Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
if ((Status == EFI_SUCCESS) && (DataSize >= (VariableHead->Offset + GetSize))) {
if (GetSize == 0) {
//
// It is a pointer type. So get the MaxSize reserved for
// this PCD entry.
//
GetPtrTypeSize (TokenNumber, &GetSize, PeiPcdDb);
if (GetSize > (DataSize - VariableHead->Offset)) {
//
// Use actual valid size.
//
GetSize = DataSize - VariableHead->Offset;
}
}
//
// If the operation is successful, we copy the data
// to the default value buffer in the PCD Database.
//
//.........这里部分代码省略.........
/**
The function registers the CallBackOnSet fucntion
according to TokenNumber and EFI_GUID space.
@param ExTokenNumber The token number.
@param Guid The GUID space.
@param CallBackFunction The Callback function to be registered.
@param Register To register or unregister the callback function.
@retval EFI_SUCCESS If the Callback function is registered.
@retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.
@retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free
slot left in the CallbackFnTable.
@retval EFI_INVALID_PARAMETER If the callback function want to be de-registered can not be found.
**/
EFI_STATUS
PeiRegisterCallBackWorker (
IN UINTN ExTokenNumber,
IN CONST EFI_GUID *Guid, OPTIONAL
IN PCD_PPI_CALLBACK CallBackFunction,
IN BOOLEAN Register
)
{
EFI_HOB_GUID_TYPE *GuidHob;
PCD_PPI_CALLBACK *CallbackTable;
PCD_PPI_CALLBACK Compare;
PCD_PPI_CALLBACK Assign;
UINT32 LocalTokenNumber;
UINT32 LocalTokenCount;
UINTN PeiNexTokenNumber;
UINTN TokenNumber;
UINTN Idx;
PEI_PCD_DATABASE *PeiPcdDb;
PeiPcdDb = GetPcdDatabase();
LocalTokenCount = PeiPcdDb->LocalTokenCount;
PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;
if (Guid == NULL) {
TokenNumber = ExTokenNumber;
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
// We have to decrement TokenNumber by 1 to make it usable
// as the array index.
//
TokenNumber--;
ASSERT (TokenNumber + 1 < (PeiNexTokenNumber + 1));
} else {
TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);
if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
return EFI_NOT_FOUND;
}
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
// We have to decrement TokenNumber by 1 to make it usable
// as the array index.
//
TokenNumber--;
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
ASSERT ((TokenNumber + 1) < (LocalTokenCount + 1));
}
LocalTokenNumber = *((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTableOffset) + TokenNumber);
//
// We don't support SET for HII and VPD type PCD entry in PEI phase.
// So we will assert if any register callback for such PCD entry.
//
ASSERT ((LocalTokenNumber & PCD_TYPE_HII) == 0);
ASSERT ((LocalTokenNumber & PCD_TYPE_VPD) == 0);
GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid);
ASSERT (GuidHob != NULL);
CallbackTable = GET_GUID_HOB_DATA (GuidHob);
CallbackTable = CallbackTable + (TokenNumber * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry));
Compare = Register? NULL: CallBackFunction;
Assign = Register? CallBackFunction: NULL;
for (Idx = 0; Idx < PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {
if (CallbackTable[Idx] == Compare) {
CallbackTable[Idx] = Assign;
return EFI_SUCCESS;
}
}
return Register? EFI_OUT_OF_RESOURCES : EFI_INVALID_PARAMETER;
}
开发者ID:M1cha,项目名称:edk2,代码行数:94,代码来源:Service.c
示例13: CopySingleFile
/**
Function to Copy one file to another location
If the destination exists the user will be prompted and the result put into *resp
@param[in] Source pointer to source file name
@param[in] Dest pointer to destination file name
@param[out] Resp pointer to response from question. Pass back on looped calling
@param[in] SilentMode whether to run in quiet mode or not
@param[in] CmdName Source command name requesting single file copy
@retval SHELL_SUCCESS The source file was copied to the destination
**/
SHELL_STATUS
CopySingleFile(
IN CONST CHAR16 *Source,
IN CONST CHAR16 *Dest,
OUT VOID **Resp,
IN BOOLEAN SilentMode,
IN CONST CHAR16 *CmdName
)
{
VOID *Response;
UINTN ReadSize;
SHELL_FILE_HANDLE SourceHandle;
SHELL_FILE_HANDLE DestHandle;
EFI_STATUS Status;
VOID *Buffer;
CHAR16 *TempName;
UINTN Size;
EFI_SHELL_FILE_INFO *List;
SHELL_STATUS ShellStatus;
UINT64 SourceFileSize;
UINT64 DestFileSize;
EFI_FILE_PROTOCOL *DestVolumeFP;
EFI_FILE_SYSTEM_INFO *DestVolumeInfo;
UINTN DestVolumeInfoSize;
ASSERT(Resp != NULL);
SourceHandle = NULL;
DestHandle = NULL;
Response = *Resp;
List = NULL;
DestVolumeInfo = NULL;
ShellStatus = SHELL_SUCCESS;
ReadSize = PcdGet32(PcdShellFileOperationSize);
// Why bother copying a file to itself
if (StrCmp(Source, Dest) == 0) {
return (SHELL_SUCCESS);
}
//
// if the destination file existed check response and possibly prompt user
//
if (ShellFileExists(Dest) == EFI_SUCCESS) {
if (Response == NULL && !SilentMode) {
Status = ShellPromptForResponseHii(ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response);
}
//
// possibly return based on response
//
if (!SilentMode) {
switch (*(SHELL_PROMPT_RESPONSE*)Response) {
case ShellPromptResponseNo:
//
// return success here so we dont stop the process
//
return (SHELL_SUCCESS);
case ShellPromptResponseCancel:
*Resp = Response;
//
// indicate to stop everything
//
return (SHELL_ABORTED);
case ShellPromptResponseAll:
*Resp = Response;
case ShellPromptResponseYes:
break;
default:
return SHELL_ABORTED;
}
}
}
if (ShellIsDirectory(Source) == EFI_SUCCESS) {
Status = ShellCreateDirectory(Dest, &DestHandle);
if (EFI_ERROR(Status)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_DIR_FAIL), gShellLevel2HiiHandle, CmdName, Dest);
return (SHELL_ACCESS_DENIED);
}
//
// Now copy all the files under the directory...
//
TempName = NULL;
Size = 0;
StrnCatGrow(&TempName, &Size, Source, 0);
StrnCatGrow(&TempName, &Size, L"\\*", 0);
//.........这里部分代码省略.........
开发者ID:EvanLloyd,项目名称:tianocore,代码行数:101,代码来源:Cp.c
示例14: FirmwarePerformanceDxeEntryPoint
/**
The module Entry Point of the Firmware Performance Data Table DXE driver.
@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
FirmwarePerformanceDxeEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_HOB_GUID_TYPE *GuidHob;
FIRMWARE_SEC_PERFORMANCE *Performance;
VOID *Registration;
UINT64 OemTableId;
CopyMem (
mFirmwarePerformanceTableTemplate.Header.OemId,
PcdGetPtr (PcdAcpiDefaultOemId),
sizeof (mFirmwarePerformanceTableTemplate.Header.OemId)
);
OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
CopyMem (&mFirmwarePerformanceTableTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
mFirmwarePerformanceTableTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
mFirmwarePerformanceTableTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
mFirmwarePerformanceTableTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
//
// Get Report Status Code Handler Protocol.
//
Status = gBS->LocateProtocol (&gEfiRscHandlerProtocolGuid, NULL, (VOID **) &mRscHandlerProtocol);
ASSERT_EFI_ERROR (Status);
//
// Register report status code listener for OS Loader load and start.
//
Status = mRscHandlerProtocol->Register (FpdtStatusCodeListenerDxe, TPL_HIGH_LEVEL);
ASSERT_EFI_ERROR (Status);
//
// Register the notify function to update FPDT on ExitBootServices Event.
//
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
FpdtExitBootServicesEventNotify,
NULL,
&gEfiEventExitBootServicesGuid,
&mExitBootServicesEvent
);
ASSERT_EFI_ERROR (Status);
//
// Create ready to boot event to install ACPI FPDT table.
//
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
FpdtReadyToBootEventNotify,
NULL,
&gEfiEventReadyToBootGuid,
&mReadyToBootEvent
);
ASSERT_EFI_ERROR (Status);
//
// Retrieve GUID HOB data that contains the ResetEnd.
//
GuidHob = GetFirstGuidHob (&gEfiFirmwarePerformanceGuid);
if (GuidHob != NULL) {
Performance = (FIRMWARE_SEC_PERFORMANCE *) GET_GUID_HOB_DATA (GuidHob);
mBootPerformanceTableTemplate.BasicBoot.ResetEnd = Performance->ResetEnd;
} else {
//
// SEC Performance Data Hob not found, ResetEnd in ACPI FPDT table will be 0.
//
DEBUG ((EFI_D_ERROR, "FPDT: WARNING: SEC Performance Data Hob not found, ResetEnd will be set to 0!\n"));
}
if (FeaturePcdGet (PcdFirmwarePerformanceDataTableS3Support)) {
//
// Register callback function upon VariableArchProtocol and LockBoxProtocol
// to allocate S3 performance table memory and save the pointer to LockBox.
//
EfiCreateProtocolNotifyEvent (
&gEfiVariableArchProtocolGuid,
TPL_CALLBACK,
FpdtAllocateS3PerformanceTableMemory,
NULL,
&Registration
);
EfiCreateProtocolNotifyEvent (
&gEfiLockBoxProtocolGuid,
//.........这里部分代码省略.........
EFI_STATUS
EFIAPI
PeimInitializeWinNtFwh (
IN EFI_FFS_FILE_HEADER *FfsHeader,
IN EFI_PEI_SERVICES **PeiServices
)
/*++
Routine Description:
Perform a call-back into the SEC simulator to get address of the Firmware Hub
Arguments:
FfsHeader - Ffs Header available to every PEIM
PeiServices - General purpose services available to every PEIM.
Returns:
None
--*/
{
EFI_STATUS Status;
EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor;
NT_FWH_PPI *FwhPpi;
EFI_PHYSICAL_ADDRESS FdBase;
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
UINT64 FdSize;
UINTN Index;
DEBUG ((EFI_D_ERROR, "NT 32 Firmware Volume PEIM Loaded\n"));
//
// Get the Fwh Information PPI
//
Status = (**PeiServices).LocatePpi (
(const EFI_PEI_SERVICES **)PeiServices,
&gNtFwhPpiGuid, // GUID
0, // INSTANCE
&PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR
(VOID**)&FwhPpi // PPI
);
ASSERT_EFI_ERROR (Status);
Index = 0;
do {
//
// Get information about all the FD's in the system
//
Status = FwhPpi->NtFwh (Index, &FdBase, &FdSize);
if (!EFI_ERROR (Status)) {
//
// Assume the FD starts with an FV header
//
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FdBase;
//
// Make an FV Hob for the first FV in the FD
//
BuildFvHob (FdBase, FvHeader->FvLength);
if (Index == 0) {
//
// Assume the first FD was produced by the NT32.DSC
// All these strange offests are needed to keep in
// sync with the FlashMap and NT32.dsc file
//
BuildResourceDescriptorHob (
EFI_RESOURCE_FIRMWARE_DEVICE,
(EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
FdBase,
(
FvHeader->FvLength +
PcdGet32 (PcdFlashNvStorageVariableSize) +
PcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
PcdGet32 (PcdFlashNvStorageFtwSpareSize) +
PcdGet32 (PcdWinNtFlashNvStorageEventLogSize)
)
);
//
// Hard code the address of the spare block and variable services.
// Assume it's a hard coded offset from FV0 in FD0.
//
FdSize =
PcdGet32 (PcdFlashNvStorageVariableSize) +
PcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
PcdGet32 (PcdFlashNvStorageFtwSpareSize) +
PcdGet32 (PcdWinNtFlashNvStorageEventLogSize);
BuildFvHob (FdBase + PcdGet32 (PcdWinNtFlashNvStorageVariableBase), FdSize);
} else {
//
// For other FD's just map them in.
//
BuildResourceDescriptorHob (
EFI_RESOURCE_FIRMWARE_DEVICE,
(EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
FdBase,
FdSize
);
}
}
//.........这里部分代码省略.........
请发表评论