Check in DxeCore for Nt32 platform. Currently, it does not follow PI/UEFI2.1.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3045 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
260
MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
Normal file
260
MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
Normal file
@@ -0,0 +1,260 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
DebugImageInfo.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Support functions for managing debug image info table when loading and unloading
|
||||
images.
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
|
||||
static EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugInfoTableHeader = {
|
||||
0, // volatile UINT32 UpdateStatus;
|
||||
0, // UINT32 TableSize;
|
||||
NULL // EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable;
|
||||
};
|
||||
|
||||
static EFI_SYSTEM_TABLE_POINTER *mDebugTable = NULL;
|
||||
|
||||
|
||||
VOID
|
||||
CoreInitializeDebugImageInfoTable (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Creates and initializes the DebugImageInfo Table. Also creates the configuration
|
||||
table and registers it into the system table.
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
NA
|
||||
|
||||
Notes:
|
||||
This function allocates memory, frees it, and then allocates memory at an
|
||||
address within the initial allocation. Since this function is called early
|
||||
in DXE core initialization (before drivers are dispatched), this should not
|
||||
be a problem.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS Mem;
|
||||
UINTN NumberOfPages;
|
||||
|
||||
//
|
||||
// Allocate boot services memory for the structure. It's required to be aligned on
|
||||
// a 4M boundary, so allocate a 4M block (plus what we require), free it up, calculate
|
||||
// a 4M aligned address within the memory we just freed, and then allocate memory at that
|
||||
// address for our initial structure.
|
||||
//
|
||||
NumberOfPages = FOUR_MEG_PAGES + EFI_SIZE_TO_PAGES(sizeof (EFI_SYSTEM_TABLE_POINTER));
|
||||
|
||||
Status = CoreAllocatePages (AllocateAnyPages, EfiBootServicesData, NumberOfPages , &Mem);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return;
|
||||
}
|
||||
Status = CoreFreePages (Mem, NumberOfPages);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
// Now get a 4M aligned address within the memory range we were given.
|
||||
// Then allocate memory at that address
|
||||
//
|
||||
Mem = (Mem + FOUR_MEG_MASK) & (~FOUR_MEG_MASK);
|
||||
|
||||
Status = CoreAllocatePages (AllocateAddress, EfiBootServicesData, NumberOfPages - FOUR_MEG_PAGES, &Mem);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
// We now have a 4M aligned page allocated, so fill in the data structure.
|
||||
// Ideally we would update the CRC now as well, but the service may not yet be available.
|
||||
// See comments in the CoreUpdateDebugTableCrc32() function below for details.
|
||||
//
|
||||
mDebugTable = (EFI_SYSTEM_TABLE_POINTER *)(UINTN)Mem;
|
||||
mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE;
|
||||
mDebugTable->EfiSystemTableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) gDxeCoreST;
|
||||
mDebugTable->Crc32 = 0;
|
||||
Status = CoreInstallConfigurationTable (&gEfiDebugImageInfoTableGuid, &mDebugInfoTableHeader);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
VOID
|
||||
CoreUpdateDebugTableCrc32 (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Update the CRC32 in the Debug Table.
|
||||
Since the CRC32 service is made available by the Runtime driver, we have to
|
||||
wait for the Runtime Driver to be installed before the CRC32 can be computed.
|
||||
This function is called elsewhere by the core when the runtime architectural
|
||||
protocol is produced.
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
NA
|
||||
|
||||
--*/
|
||||
{
|
||||
ASSERT(mDebugTable != NULL);
|
||||
mDebugTable->Crc32 = 0;
|
||||
gDxeCoreBS->CalculateCrc32 ((VOID *)mDebugTable, sizeof (EFI_SYSTEM_TABLE_POINTER), &mDebugTable->Crc32);
|
||||
}
|
||||
|
||||
VOID
|
||||
CoreNewDebugImageInfoEntry (
|
||||
IN UINT32 ImageInfoType,
|
||||
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
|
||||
IN EFI_HANDLE ImageHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates
|
||||
the table if it's not large enough to accomidate another entry.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageInfoType - type of debug image information
|
||||
LoadedImage - pointer to the loaded image protocol for the image being loaded
|
||||
ImageHandle - image handle for the image being loaded
|
||||
|
||||
Returns:
|
||||
NA
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_DEBUG_IMAGE_INFO *Table;
|
||||
EFI_DEBUG_IMAGE_INFO *NewTable;
|
||||
UINTN Index;
|
||||
UINTN MaxTableIndex;
|
||||
UINTN TableSize;
|
||||
|
||||
//
|
||||
// Set the flag indicating that we're in the process of updating the table.
|
||||
//
|
||||
mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
|
||||
|
||||
Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
|
||||
MaxTableIndex = mDebugInfoTableHeader.TableSize;
|
||||
|
||||
for (Index = 0; Index < MaxTableIndex; Index++) {
|
||||
if (Table[Index].NormalImage == NULL) {
|
||||
//
|
||||
// We have found a free entry so exit the loop
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Index == MaxTableIndex) {
|
||||
//
|
||||
// Table is full, so re-allocate another page for a larger table...
|
||||
//
|
||||
TableSize = MaxTableIndex * EFI_DEBUG_TABLE_ENTRY_SIZE;
|
||||
NewTable = CoreAllocateZeroBootServicesPool (TableSize + EFI_PAGE_SIZE);
|
||||
if (NewTable == NULL) {
|
||||
mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
|
||||
return;
|
||||
}
|
||||
//
|
||||
// Copy the old table into the new one
|
||||
//
|
||||
CopyMem (NewTable, Table, TableSize);
|
||||
//
|
||||
// Free the old table
|
||||
//
|
||||
CoreFreePool (Table);
|
||||
//
|
||||
// Update the table header
|
||||
//
|
||||
Table = NewTable;
|
||||
mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable;
|
||||
mDebugInfoTableHeader.TableSize += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;
|
||||
}
|
||||
//
|
||||
// Allocate data for new entry
|
||||
//
|
||||
Table[Index].NormalImage = CoreAllocateZeroBootServicesPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));
|
||||
if (Table[Index].NormalImage != NULL) {
|
||||
//
|
||||
// Update the entry
|
||||
//
|
||||
Table[Index].NormalImage->ImageInfoType = (UINT32) ImageInfoType;
|
||||
Table[Index].NormalImage->LoadedImageProtocolInstance = LoadedImage;
|
||||
Table[Index].NormalImage->ImageHandle = ImageHandle;
|
||||
}
|
||||
mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CoreRemoveDebugImageInfoEntry (
|
||||
EFI_HANDLE ImageHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Removes and frees an entry from the DebugImageInfo Table.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle - image handle for the image being unloaded
|
||||
|
||||
Returns:
|
||||
|
||||
NA
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_DEBUG_IMAGE_INFO *Table;
|
||||
UINTN Index;
|
||||
|
||||
mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
|
||||
|
||||
Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
|
||||
|
||||
for (Index = 0; Index < mDebugInfoTableHeader.TableSize; Index++) {
|
||||
if (Table[Index].NormalImage != NULL && Table[Index].NormalImage->ImageHandle == ImageHandle) {
|
||||
//
|
||||
// Found a match. Free up the record, then NULL the pointer to indicate the slot
|
||||
// is free.
|
||||
//
|
||||
CoreFreePool (Table[Index].NormalImage);
|
||||
Table[Index].NormalImage = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
|
||||
}
|
||||
|
225
MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c
Normal file
225
MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c
Normal file
@@ -0,0 +1,225 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
InstallConfigurationTable.c
|
||||
|
||||
|
||||
Abstract:
|
||||
|
||||
Tiano Miscellaneous Services InstallConfigurationTable service
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
#define CONFIG_TABLE_SIZE_INCREASED 0x10
|
||||
|
||||
UINTN mSystemTableAllocateSize = 0;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
CoreGetConfigTable (
|
||||
IN EFI_GUID *Guid,
|
||||
OUT VOID **Table
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Find a config table by name in system table's ConfigurationTable.
|
||||
|
||||
Arguments:
|
||||
|
||||
Guid - The table name to look for
|
||||
|
||||
Table - Pointer of the config table
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_NOT_FOUND - Could not find the table in system table's ConfigurationTable.
|
||||
|
||||
EFI_SUCCESS - Table successfully found.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
for (Index = 0; Index < gDxeCoreST->NumberOfTableEntries; Index++) {
|
||||
if (CompareGuid (Guid, &(gDxeCoreST->ConfigurationTable[Index].VendorGuid))) {
|
||||
*Table = gDxeCoreST->ConfigurationTable[Index].VendorTable;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreInstallConfigurationTable (
|
||||
IN EFI_GUID *Guid,
|
||||
IN VOID *Table
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Boot Service called to add, modify, or remove a system configuration table from
|
||||
the EFI System Table.
|
||||
|
||||
Arguments:
|
||||
|
||||
Guid - Pointer to the GUID for the entry to add, update, or remove
|
||||
Table - Pointer to the configuration table for the entry to add, update, or
|
||||
remove, may be NULL.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS Guid, Table pair added, updated, or removed.
|
||||
EFI_INVALID_PARAMETER Input GUID not valid.
|
||||
EFI_NOT_FOUND Attempted to delete non-existant entry
|
||||
EFI_OUT_OF_RESOURCES Not enough memory available
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN Index;
|
||||
EFI_CONFIGURATION_TABLE *EfiConfigurationTable;
|
||||
|
||||
//
|
||||
// If Guid is NULL, then this operation cannot be performed
|
||||
//
|
||||
if (Guid == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
EfiConfigurationTable = gDxeCoreST->ConfigurationTable;
|
||||
|
||||
//
|
||||
// Search all the table for an entry that matches Guid
|
||||
//
|
||||
for (Index = 0; Index < gDxeCoreST->NumberOfTableEntries; Index++) {
|
||||
if (CompareGuid (Guid, &(gDxeCoreST->ConfigurationTable[Index].VendorGuid))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Index < gDxeCoreST->NumberOfTableEntries) {
|
||||
//
|
||||
// A match was found, so this is either a modify or a delete operation
|
||||
//
|
||||
if (Table != NULL) {
|
||||
//
|
||||
// If Table is not NULL, then this is a modify operation.
|
||||
// Modify the table enty and return.
|
||||
//
|
||||
gDxeCoreST->ConfigurationTable[Index].VendorTable = Table;
|
||||
|
||||
//
|
||||
// Signal Configuration Table change
|
||||
//
|
||||
CoreNotifySignalList (Guid);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// A match was found and Table is NULL, so this is a delete operation.
|
||||
//
|
||||
gDxeCoreST->NumberOfTableEntries--;
|
||||
|
||||
//
|
||||
// Copy over deleted entry
|
||||
//
|
||||
CopyMem (
|
||||
&(EfiConfigurationTable[Index]),
|
||||
&(gDxeCoreST->ConfigurationTable[Index + 1]),
|
||||
(gDxeCoreST->NumberOfTableEntries - Index) * sizeof (EFI_CONFIGURATION_TABLE)
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
//
|
||||
// No matching GUIDs were found, so this is an add operation.
|
||||
//
|
||||
|
||||
if (Table == NULL) {
|
||||
//
|
||||
// If Table is NULL on an add operation, then return an error.
|
||||
//
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Assume that Index == gDxeCoreST->NumberOfTableEntries
|
||||
//
|
||||
if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSystemTableAllocateSize) {
|
||||
//
|
||||
// Allocate a table with one additional entry.
|
||||
//
|
||||
mSystemTableAllocateSize += (CONFIG_TABLE_SIZE_INCREASED * sizeof (EFI_CONFIGURATION_TABLE));
|
||||
EfiConfigurationTable = CoreAllocateRuntimePool (mSystemTableAllocateSize);
|
||||
if (EfiConfigurationTable == NULL) {
|
||||
//
|
||||
// If a new table could not be allocated, then return an error.
|
||||
//
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
if (gDxeCoreST->ConfigurationTable != NULL) {
|
||||
//
|
||||
// Copy the old table to the new table.
|
||||
//
|
||||
CopyMem (
|
||||
EfiConfigurationTable,
|
||||
gDxeCoreST->ConfigurationTable,
|
||||
Index * sizeof (EFI_CONFIGURATION_TABLE)
|
||||
);
|
||||
|
||||
//
|
||||
// Free Old Table
|
||||
//
|
||||
CoreFreePool (gDxeCoreST->ConfigurationTable);
|
||||
}
|
||||
|
||||
//
|
||||
// Update System Table
|
||||
//
|
||||
gDxeCoreST->ConfigurationTable = EfiConfigurationTable;
|
||||
}
|
||||
|
||||
//
|
||||
// Fill in the new entry
|
||||
//
|
||||
CopyMem ((VOID *)&EfiConfigurationTable[Index].VendorGuid, Guid, sizeof (EFI_GUID));
|
||||
EfiConfigurationTable[Index].VendorTable = Table;
|
||||
|
||||
//
|
||||
// This is an add operation, so increment the number of table entries
|
||||
//
|
||||
gDxeCoreST->NumberOfTableEntries++;
|
||||
}
|
||||
|
||||
//
|
||||
// Fix up the CRC-32 in the EFI System Table
|
||||
//
|
||||
CalculateEfiHdrCrc (&gDxeCoreST->Hdr);
|
||||
|
||||
//
|
||||
// Signal Configuration Table change
|
||||
//
|
||||
CoreNotifySignalList (Guid);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
83
MdeModulePkg/Core/Dxe/Misc/SetWatchdogTimer.c
Normal file
83
MdeModulePkg/Core/Dxe/Misc/SetWatchdogTimer.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
SetWatchdogTimer.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Tiano Miscellaneous Services SetWatchdogTimer service implementation
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
#define WATCHDOG_TIMER_CALIBRATE_PER_SECOND 10000000
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreSetWatchdogTimer (
|
||||
IN UINTN Timeout,
|
||||
IN UINT64 WatchdogCode,
|
||||
IN UINTN DataSize,
|
||||
IN CHAR16 *WatchdogData OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Sets the system's watchdog timer.
|
||||
|
||||
Arguments:
|
||||
|
||||
Timeout The number of seconds. Zero disables the timer.
|
||||
|
||||
///////following three parameters are left for platform specific using
|
||||
|
||||
WatchdogCode The numberic code to log. 0x0 to 0xffff are firmware
|
||||
DataSize Size of the optional data
|
||||
WatchdogData Optional Null terminated unicode string followed by binary
|
||||
data.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS Timeout has been set
|
||||
EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet
|
||||
EFI_UNSUPPORTED System does not have a timer (currently not used)
|
||||
EFI_DEVICE_ERROR Could not complete due to hardware error
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Check our architectural protocol
|
||||
//
|
||||
if (gWatchdogTimer == NULL) {
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
//
|
||||
// Attempt to set the timeout
|
||||
//
|
||||
Status = gWatchdogTimer->SetTimerPeriod (gWatchdogTimer, MultU64x32 (Timeout, WATCHDOG_TIMER_CALIBRATE_PER_SECOND));
|
||||
|
||||
//
|
||||
// Check for errors
|
||||
//
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
82
MdeModulePkg/Core/Dxe/Misc/Stall.c
Normal file
82
MdeModulePkg/Core/Dxe/Misc/Stall.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
Stall.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Tiano Miscellaneous Services Stall service implementation
|
||||
|
||||
--*/
|
||||
|
||||
//
|
||||
// Include statements
|
||||
//
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreStall (
|
||||
IN UINTN Microseconds
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Introduces a fine-grained stall.
|
||||
|
||||
Arguments:
|
||||
|
||||
Microseconds The number of microseconds to stall execution
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Execution was stalled for at least the requested amount
|
||||
of microseconds.
|
||||
|
||||
EFI_NOT_AVAILABLE_YET - gMetronome is not available yet
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT32 Counter;
|
||||
UINT32 Remainder;
|
||||
|
||||
if (gMetronome == NULL) {
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate the number of ticks by dividing the number of microseconds by
|
||||
// the TickPeriod.
|
||||
// Calcullation is based on 100ns unit.
|
||||
//
|
||||
Counter = (UINT32) DivU64x32Remainder (
|
||||
Microseconds * 10,
|
||||
gMetronome->TickPeriod,
|
||||
&Remainder
|
||||
);
|
||||
|
||||
//
|
||||
// Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
|
||||
// periods, thus attempting to ensure Microseconds of stall time.
|
||||
//
|
||||
if (Remainder != 0) {
|
||||
Counter++;
|
||||
}
|
||||
|
||||
gMetronome->WaitForTick (gMetronome, Counter);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
Reference in New Issue
Block a user