/**
Communicates with a registered handler.
This function provides a service to send and receive messages from a registered UEFI service.
@param[in] This The EFI_PEI_SMM_COMMUNICATION_PPI instance.
@param[in, out] CommBuffer A pointer to the buffer to convey into SMRAM.
@param[in, out] CommSize The size of the data buffer being passed in.On exit, the size of data
being returned. Zero if the handler does not wish to reply with any data.
@retval EFI_SUCCESS The message was successfully posted.
@retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
@retval EFI_NOT_STARTED The service is NOT started.
**/
EFI_STATUS
EFIAPI
Communicate (
IN CONST EFI_PEI_SMM_COMMUNICATION_PPI *This,
IN OUT VOID *CommBuffer,
IN OUT UINTN *CommSize
)
{
EFI_STATUS Status;
PEI_SMM_CONTROL_PPI *SmmControl;
PEI_SMM_ACCESS_PPI *SmmAccess;
UINT8 SmiCommand;
UINTN Size;
EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext;
DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei Communicate Enter\n"));
if (CommBuffer == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Get needed resource
//
Status = PeiServicesLocatePpi (
&gPeiSmmControlPpiGuid,
0,
NULL,
(VOID **)&SmmControl
);
if (EFI_ERROR (Status)) {
return EFI_NOT_STARTED;
}
Status = PeiServicesLocatePpi (
&gPeiSmmAccessPpiGuid,
0,
NULL,
(VOID **)&SmmAccess
);
if (EFI_ERROR (Status)) {
return EFI_NOT_STARTED;
}
//
// Check SMRAM locked, it should be done after SMRAM lock.
//
if (!SmmAccess->LockState) {
DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei LockState - %x\n", (UINTN)SmmAccess->LockState));
return EFI_NOT_STARTED;
}
SmmCommunicationContext = GetCommunicationContext ();
DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei BufferPtrAddress - 0x%016lx, BufferPtr: 0x%016lx\n", SmmCommunicationContext->BufferPtrAddress, *(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress));
//
// No need to check if BufferPtr is 0, because it is in PEI phase.
//
*(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer;
DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei CommBuffer - %x\n", (UINTN)CommBuffer));
//
// Send command
//
SmiCommand = (UINT8)SmmCommunicationContext->SwSmiNumber;
Size = sizeof(SmiCommand);
Status = SmmControl->Trigger (
(EFI_PEI_SERVICES **)GetPeiServicesTablePointer (),
SmmControl,
(INT8 *)&SmiCommand,
&Size,
FALSE,
0
);
ASSERT_EFI_ERROR (Status);
//
// Setting BufferPtr to 0 means this transaction is done.
//
*(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress = 0;
DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei Communicate Exit\n"));
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
WinNtTimerDriverInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Initialize the Timer Architectural Protocol driver
Arguments:
ImageHandle - ImageHandle of the loaded driver
SystemTable - Pointer to the System Table
Returns:
EFI_SUCCESS - Timer Architectural Protocol created
EFI_OUT_OF_RESOURCES - Not enough resources available to initialize driver.
EFI_DEVICE_ERROR - A device error occured attempting to initialize the driver.
--*/
{
EFI_STATUS Status;
UINTN Result;
EFI_HANDLE Handle;
EFI_HANDLE hSourceProcessHandle;
EFI_HANDLE hSourceHandle;
EFI_HANDLE hTargetProcessHandle;
//
// Make sure the Timer Architectural Protocol is not already installed in the system
//
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid);
//
// Get the CPU Architectural Protocol instance
//
Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID**)&mCpu);
ASSERT_EFI_ERROR (Status);
//
// Get our handle so the timer tick thread can suspend
//
hSourceProcessHandle = gWinNt->GetCurrentProcess ();
hSourceHandle = gWinNt->GetCurrentThread ();
hTargetProcessHandle = gWinNt->GetCurrentProcess ();
Result = gWinNt->DuplicateHandle (
hSourceProcessHandle,
hSourceHandle,
hTargetProcessHandle,
&mNtMainThreadHandle,
0,
FALSE,
DUPLICATE_SAME_ACCESS
);
if (Result == 0) {
return EFI_DEVICE_ERROR;
}
//
// Initialize Critical Section used to update variables shared between the main
// thread and the timer interrupt thread.
//
gWinNt->InitializeCriticalSection (&mNtCriticalSection);
//
// Start the timer thread at the default timer period
//
Status = mTimer.SetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION);
if (EFI_ERROR (Status)) {
gWinNt->DeleteCriticalSection (&mNtCriticalSection);
return Status;
}
//
// Install the Timer Architectural Protocol onto a new handle
//
Handle = NULL;
Status = gBS->InstallProtocolInterface (
&Handle,
&gEfiTimerArchProtocolGuid,
EFI_NATIVE_INTERFACE,
&mTimer
);
if (EFI_ERROR (Status)) {
//
// Cancel the timer
//
mTimer.SetTimerPeriod (&mTimer, 0);
gWinNt->DeleteCriticalSection (&mNtCriticalSection);
return Status;
}
return EFI_SUCCESS;
}
/**
Dispatch initialization request to sub status code devices based on
customized feature flags.
**/
VOID
InitializationDispatcherWorker (
VOID
)
{
EFI_PEI_HOB_POINTERS Hob;
EFI_STATUS Status;
MEMORY_STATUSCODE_PACKET_HEADER *PacketHeader;
MEMORY_STATUSCODE_RECORD *Record;
UINTN Index;
UINTN MaxRecordNumber;
//
// If enable UseSerial, then initialize serial port.
// if enable UseRuntimeMemory, then initialize runtime memory status code worker.
//
if (FeaturePcdGet (PcdStatusCodeUseSerial)) {
//
// Call Serial Port Lib API to initialize serial port.
//
Status = SerialPortInitialize ();
ASSERT_EFI_ERROR (Status);
}
if (FeaturePcdGet (PcdStatusCodeUseMemory)) {
Status = RtMemoryStatusCodeInitializeWorker ();
ASSERT_EFI_ERROR (Status);
}
//
// Replay Status code which saved in GUID'ed HOB to all supported devices.
//
if (FeaturePcdGet (PcdStatusCodeReplayIn)) {
//
// Journal GUID'ed HOBs to find all record entry, if found,
// then output record to support replay device.
//
Hob.Raw = GetFirstGuidHob (&gMemoryStatusCodeRecordGuid);
if (Hob.Raw != NULL) {
PacketHeader = (MEMORY_STATUSCODE_PACKET_HEADER *) GET_GUID_HOB_DATA (Hob.Guid);
Record = (MEMORY_STATUSCODE_RECORD *) (PacketHeader + 1);
MaxRecordNumber = (UINTN) PacketHeader->RecordIndex;
if (PacketHeader->PacketIndex > 0) {
//
// Record has been wrapped around. So, record number has arrived at max number.
//
MaxRecordNumber = (UINTN) PacketHeader->MaxRecordsNumber;
}
for (Index = 0; Index < MaxRecordNumber; Index++) {
//
// Dispatch records to devices based on feature flag.
//
if (FeaturePcdGet (PcdStatusCodeUseSerial)) {
SerialStatusCodeReportWorker (
Record[Index].CodeType,
Record[Index].Value,
Record[Index].Instance,
NULL,
NULL
);
}
if (FeaturePcdGet (PcdStatusCodeUseMemory)) {
RtMemoryStatusCodeReportWorker (
Record[Index].CodeType,
Record[Index].Value,
Record[Index].Instance,
NULL,
NULL
);
}
}
}
}
}
//.........这里部分代码省略.........
}
if (BltOperation == EfiBltBufferToVideo || BltOperation == EfiBltVideoToVideo || BltOperation == EfiBltVideoFill) {
if (DestinationY + Height > ScreenHeight) {
return EFI_INVALID_PARAMETER;
}
if (DestinationX + Width > ScreenWidth) {
return EFI_INVALID_PARAMETER;
}
}
//
// We have to raise to TPL Notify, so we make an atomic write the frame buffer.
// We would not want a timer based event (Cursor, ...) to come in while we are
// doing this operation.
//
OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
switch (BltOperation) {
case EfiBltVideoToBltBuffer:
//
// Video to BltBuffer: Source is Video, destination is BltBuffer
//
for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY) && BltBuffer; SrcY++, DstY++) {
/// @todo assumes that color depth is 32 (*4, EfiPciIoWidthUint32) and format matches EFI_GRAPHICS_OUTPUT_BLT_PIXEL
Status = Private->PciIo->Mem.Read (
Private->PciIo,
EfiPciIoWidthUint32,
Private->BarIndexFB,
((SrcY * ScreenWidth) + SourceX) * 4,
Width,
BltBuffer + (DstY * Delta) + DestinationX
);
ASSERT_EFI_ERROR((Status));
}
break;
case EfiBltBufferToVideo:
//
// BltBuffer to Video: Source is BltBuffer, destination is Video
//
for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
/// @todo assumes that color depth is 32 (*4, EfiPciIoWidthUint32) and format matches EFI_GRAPHICS_OUTPUT_BLT_PIXEL
Status = Private->PciIo->Mem.Write (
Private->PciIo,
EfiPciIoWidthUint32,
Private->BarIndexFB,
((DstY * ScreenWidth) + DestinationX) * 4,
Width,
BltBuffer + (SrcY * Delta) + SourceX
);
ASSERT_EFI_ERROR((Status));
}
break;
case EfiBltVideoToVideo:
//
// Video to Video: Source is Video, destination is Video
//
if (DestinationY <= SourceY) {
// forward copy
for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
/// @todo assumes that color depth is 32 (*4, EfiPciIoWidthUint32) and format matches EFI_GRAPHICS_OUTPUT_BLT_PIXEL
Status = Private->PciIo->CopyMem (
Private->PciIo,
EfiPciIoWidthUint32,
/**
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;
//
// 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);
//
// Create legacy boot event to log OsLoaderStartImageStart for legacy boot.
//
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
FpdtLegacyBootEventNotify,
NULL,
&gEfiEventLegacyBootGuid,
&mLegacyBootEvent
);
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"));
}
return EFI_SUCCESS;
}
/**
Variable Driver main entry point. The Variable driver places the 4 EFI
runtime services in the EFI System Table and installs arch protocols
for variable read and write services being availible. It also registers
a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS Variable service successfully initialized.
**/
EFI_STATUS
EFIAPI
VariableServiceInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_EVENT ReadyToBootEvent;
Status = VariableCommonInitialize ();
ASSERT_EFI_ERROR (Status);
SystemTable->RuntimeServices->GetVariable = VariableServiceGetVariable;
SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;
SystemTable->RuntimeServices->SetVariable = VariableServiceSetVariable;
SystemTable->RuntimeServices->QueryVariableInfo = VariableServiceQueryVariableInfo;
//
// Now install the Variable Runtime Architectural protocol on a new handle.
//
Status = gBS->InstallProtocolInterface (
&mHandle,
&gEfiVariableArchProtocolGuid,
EFI_NATIVE_INTERFACE,
NULL
);
ASSERT_EFI_ERROR (Status);
//
// Register FtwNotificationEvent () notify function.
//
EfiCreateProtocolNotifyEvent (
&gEfiFaultTolerantWriteProtocolGuid,
TPL_CALLBACK,
FtwNotificationEvent,
(VOID *)SystemTable,
&mFtwRegistration
);
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
VariableClassAddressChangeEvent,
NULL,
&gEfiEventVirtualAddressChangeGuid,
&mVirtualAddressChangeEvent
);
ASSERT_EFI_ERROR (Status);
//
// Register the event handling function to reclaim variable for OS usage.
//
Status = EfiCreateEventReadyToBootEx (
TPL_NOTIFY,
OnReadyToBoot,
NULL,
&ReadyToBootEvent
);
return EFI_SUCCESS;
}
开发者ID:Cutty,项目名称:edk2,代码行数:74,代码来源:VariableDxe.c
示例14: line
/**
Function to read a single line (up to but not including the \n) from a file.
If the position upon start is 0, then the Ascii Boolean will be set. This should be
maintained and not changed for all operations with the same file.
The function will not return the \r and \n character in buffer. When an empty line is
read a CHAR_NULL character will be returned in buffer.
@param[in] Handle FileHandle to read from.
@param[in, out] Buffer The pointer to buffer to read into.
@param[in, out] Size The pointer to number of bytes in Buffer.
@param[in] Truncate If the buffer is large enough, this has no effect.
If the buffer is is too small and Truncate is TRUE,
the line will be truncated.
If the buffer is is too small and Truncate is FALSE,
then no read will occur.
@param[in, out] Ascii Boolean value for indicating whether the file is
Ascii (TRUE) or UCS2 (FALSE).
@retval EFI_SUCCESS The operation was successful. The line is stored in
Buffer.
@retval EFI_INVALID_PARAMETER Handle was NULL.
@retval EFI_INVALID_PARAMETER Size was NULL.
@retval EFI_BUFFER_TOO_SMALL Size was not large enough to store the line.
Size was updated to the minimum space required.
@sa FileHandleRead
**/
EFI_STATUS
EFIAPI
FileHandleReadLine(
IN EFI_FILE_HANDLE Handle,
IN OUT CHAR16 *Buffer,
IN OUT UINTN *Size,
IN BOOLEAN Truncate,
IN OUT BOOLEAN *Ascii
)
{
EFI_STATUS Status;
CHAR16 CharBuffer;
UINT64 FileSize;
UINTN CharSize;
UINTN CountSoFar;
UINTN CrCount;
UINT64 OriginalFilePosition;
if (Handle == NULL
||Size == NULL
||(Buffer==NULL&&*Size!=0)
){
return (EFI_INVALID_PARAMETER);
}
if (Buffer != NULL && *Size != 0) {
*Buffer = CHAR_NULL;
}
Status = FileHandleGetSize (Handle, &FileSize);
if (EFI_ERROR (Status)) {
return Status;
} else if (FileSize == 0) {
*Ascii = TRUE;
return EFI_SUCCESS;
}
FileHandleGetPosition(Handle, &OriginalFilePosition);
if (OriginalFilePosition == 0) {
CharSize = sizeof(CHAR16);
Status = FileHandleRead(Handle, &CharSize, &CharBuffer);
ASSERT_EFI_ERROR(Status);
if (CharBuffer == gUnicodeFileTag) {
*Ascii = FALSE;
} else {
*Ascii = TRUE;
FileHandleSetPosition(Handle, OriginalFilePosition);
}
}
CrCount = 0;
for (CountSoFar = 0;;CountSoFar++){
CharBuffer = 0;
if (*Ascii) {
CharSize = sizeof(CHAR8);
} else {
CharSize = sizeof(CHAR16);
}
Status = FileHandleRead(Handle, &CharSize, &CharBuffer);
if ( EFI_ERROR(Status)
|| CharSize == 0
|| (CharBuffer == L'\n' && !(*Ascii))
|| (CharBuffer == '\n' && *Ascii)
){
break;
} else if (
(CharBuffer == L'\r' && !(*Ascii)) ||
(CharBuffer == '\r' && *Ascii)
) {
CrCount++;
continue;
}
//.........这里部分代码省略.........
/**
This function attempts to boot for the boot order specified
by platform policy.
**/
VOID
BdsBootDeviceSelect (
VOID
)
{
EFI_STATUS Status;
LIST_ENTRY *Link;
BDS_COMMON_OPTION *BootOption;
UINTN ExitDataSize;
CHAR16 *ExitData;
UINT16 Timeout;
LIST_ENTRY BootLists;
CHAR16 Buffer[20];
BOOLEAN BootNextExist;
LIST_ENTRY *LinkBootNext;
EFI_EVENT ConnectConInEvent;
//
// Got the latest boot option
//
BootNextExist = FALSE;
LinkBootNext = NULL;
ConnectConInEvent = NULL;
InitializeListHead (&BootLists);
//
// First check the boot next option
//
ZeroMem (Buffer, sizeof (Buffer));
//
// Create Event to signal ConIn connection request
//
if (PcdGetBool (PcdConInConnectOnDemand)) {
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
BdsEmptyCallbackFunction,
NULL,
&gConnectConInEventGuid,
&ConnectConInEvent
);
if (EFI_ERROR(Status)) {
ConnectConInEvent = NULL;
}
}
if (mBootNext != NULL) {
//
// Indicate we have the boot next variable, so this time
// boot will always have this boot option
//
BootNextExist = TRUE;
//
// Clear the this variable so it's only exist in this time boot
//
Status = gRT->SetVariable (
L"BootNext",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
NULL
);
//
// Deleting variable with current variable implementation shouldn't fail.
//
ASSERT_EFI_ERROR (Status);
//
// Add the boot next boot option
//
UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *mBootNext);
BootOption = BdsLibVariableToOption (&BootLists, Buffer);
//
// If fail to get boot option from variable, just return and do nothing.
//
if (BootOption == NULL) {
return;
}
BootOption->BootCurrent = *mBootNext;
}
//
// Parse the boot order to get boot option
//
BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");
//
// When we didn't have chance to build boot option variables in the first
// full configuration boot (e.g.: Reset in the first page or in Device Manager),
// we have no boot options in the following mini configuration boot.
// Give the last chance to enumerate the boot options.
//.........这里部分代码省略.........
请发表评论