mirror of https://github.com/acidanthera/audk.git
Use linked list to replace the current array solution to store the periodic SMI handlers to support more than 8 periodic SMI handlers.
Signed-off-by: niruiyu Reviewed-by: xdu2 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12127 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
5672b88f6c
commit
569224f9de
|
@ -27,10 +27,8 @@
|
||||||
#include <Library/SmmPeriodicSmiLib.h>
|
#include <Library/SmmPeriodicSmiLib.h>
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Define the number of periodic SMI handler entries that should be allocated in
|
/// Define the number of periodic SMI handler entries that should be allocated to the list
|
||||||
/// the constructor for gPeriodicSmiLibraryHandlers and also use this value as the
|
/// of free periodic SMI handlers when the list of free periodic SMI handlers is empty.
|
||||||
/// number of entries to add to gPeriodicSmiLibraryHandlers when gPeriodicSmiLibraryHandlers
|
|
||||||
/// is full.
|
|
||||||
///
|
///
|
||||||
#define PERIODIC_SMI_LIBRARY_ALLOCATE_SIZE 0x08
|
#define PERIODIC_SMI_LIBRARY_ALLOCATE_SIZE 0x08
|
||||||
|
|
||||||
|
@ -48,6 +46,10 @@ typedef struct {
|
||||||
///
|
///
|
||||||
UINT32 Signature;
|
UINT32 Signature;
|
||||||
///
|
///
|
||||||
|
/// The link entry to be inserted to the list of periodic SMI handlers.
|
||||||
|
///
|
||||||
|
LIST_ENTRY Link;
|
||||||
|
///
|
||||||
/// The dispatch function to called to invoke an enabled periodic SMI handler.
|
/// The dispatch function to called to invoke an enabled periodic SMI handler.
|
||||||
///
|
///
|
||||||
PERIODIC_SMI_LIBRARY_HANDLER DispatchFunction;
|
PERIODIC_SMI_LIBRARY_HANDLER DispatchFunction;
|
||||||
|
@ -155,6 +157,19 @@ typedef struct {
|
||||||
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_SIGNATURE \
|
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_SIGNATURE \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Macro that returns a pointer to a PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT
|
||||||
|
structure based on a pointer to a Link field.
|
||||||
|
|
||||||
|
**/
|
||||||
|
#define PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_FROM_LINK(a) \
|
||||||
|
CR ( \
|
||||||
|
a, \
|
||||||
|
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT, \
|
||||||
|
Link, \
|
||||||
|
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_SIGNATURE \
|
||||||
|
)
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Pointer to the SMM Periodic Timer Disatch Protocol that was located in the constuctor.
|
/// Pointer to the SMM Periodic Timer Disatch Protocol that was located in the constuctor.
|
||||||
///
|
///
|
||||||
|
@ -170,21 +185,22 @@ EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL *gSmmPeriodicTimerDispatch2
|
||||||
UINT64 *gSmiTickPeriodTable = NULL;
|
UINT64 *gSmiTickPeriodTable = NULL;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The number entries in gPeriodicSmiLibraryHandlers
|
/// Linked list of free periodic SMI handlers that this library can use.
|
||||||
///
|
///
|
||||||
UINTN gNumberOfPeriodicSmiLibraryHandlers = 0;
|
LIST_ENTRY gFreePeriodicSmiLibraryHandlers =
|
||||||
|
INITIALIZE_LIST_HEAD_VARIABLE (gFreePeriodicSmiLibraryHandlers);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Table of periodic SMI handlers that this library is currently managing. This
|
/// Linked list of periodic SMI handlers that this library is currently managing.
|
||||||
/// table is allocated using AllocatePool()
|
|
||||||
///
|
///
|
||||||
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *gPeriodicSmiLibraryHandlers = NULL;
|
LIST_ENTRY gPeriodicSmiLibraryHandlers =
|
||||||
|
INITIALIZE_LIST_HEAD_VARIABLE (gPeriodicSmiLibraryHandlers);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The index of gPeriodicSmiLibraryHandlers that is currently being executed.
|
/// Pointer to the periodic SMI handler that is currently being executed.
|
||||||
/// Is set to -1 if no periodic SMI handler is currently being executed.
|
/// Is set to NULL if no periodic SMI handler is currently being executed.
|
||||||
///
|
///
|
||||||
INTN gActivePeriodicSmiLibraryHandlerIndex = -1;
|
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *gActivePeriodicSmiLibraryHandler = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Internal worker function that returns a pointer to the
|
Internal worker function that returns a pointer to the
|
||||||
|
@ -202,18 +218,7 @@ GetActivePeriodicSmiLibraryHandler (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (gActivePeriodicSmiLibraryHandlerIndex < 0) {
|
return gActivePeriodicSmiLibraryHandler;
|
||||||
//
|
|
||||||
// Return NULL if index is negative, which means that there is no active
|
|
||||||
// periodic SMI handler.
|
|
||||||
//
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return a pointer to the active periodic SMI handler context
|
|
||||||
//
|
|
||||||
return &gPeriodicSmiLibraryHandlers[gActivePeriodicSmiLibraryHandlerIndex];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -240,24 +245,30 @@ GetActivePeriodicSmiLibraryHandler (
|
||||||
**/
|
**/
|
||||||
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *
|
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *
|
||||||
LookupPeriodicSmiLibraryHandler (
|
LookupPeriodicSmiLibraryHandler (
|
||||||
IN EFI_HANDLE DispatchHandle OPTIONAL
|
IN EFI_HANDLE DispatchHandle OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN Index;
|
LIST_ENTRY *Link;
|
||||||
|
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *PeriodicSmiLibraryHandler;
|
||||||
|
|
||||||
//
|
//
|
||||||
// If DispatchHandle is NULL, then return the active periodic SMI handler
|
// If DispatchHandle is NULL, then return the active periodic SMI handler
|
||||||
//
|
//
|
||||||
if (DispatchHandle == NULL) {
|
if (DispatchHandle == NULL) {
|
||||||
return GetActivePeriodicSmiLibraryHandler ();
|
return GetActivePeriodicSmiLibraryHandler ();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Search the periodic SMI handler entries for a a matching DispatchHandle
|
// Search the periodic SMI handler entries for a a matching DispatchHandle
|
||||||
//
|
//
|
||||||
for (Index = 0; Index < gNumberOfPeriodicSmiLibraryHandlers; Index++) {
|
for ( Link = GetFirstNode (&gPeriodicSmiLibraryHandlers)
|
||||||
if (gPeriodicSmiLibraryHandlers[Index].DispatchHandle == DispatchHandle) {
|
; !IsNull (&gPeriodicSmiLibraryHandlers, Link)
|
||||||
return &gPeriodicSmiLibraryHandlers[Index];
|
; Link = GetNextNode (&gPeriodicSmiLibraryHandlers, Link)
|
||||||
|
) {
|
||||||
|
PeriodicSmiLibraryHandler = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_FROM_LINK (Link);
|
||||||
|
|
||||||
|
if (PeriodicSmiLibraryHandler->DispatchHandle == DispatchHandle) {
|
||||||
|
return PeriodicSmiLibraryHandler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,15 +296,88 @@ SetActivePeriodicSmiLibraryHandler (
|
||||||
IN CONST VOID *Context OPTIONAL
|
IN CONST VOID *Context OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *PeriodicSmiLibraryHandler;
|
|
||||||
|
|
||||||
if (Context == NULL) {
|
if (Context == NULL) {
|
||||||
gActivePeriodicSmiLibraryHandlerIndex = -1;
|
gActivePeriodicSmiLibraryHandler = NULL;
|
||||||
return NULL;
|
} else {
|
||||||
|
gActivePeriodicSmiLibraryHandler = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_FROM_REGISTER_CONTEXT (Context);
|
||||||
}
|
}
|
||||||
PeriodicSmiLibraryHandler = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_FROM_REGISTER_CONTEXT (Context);
|
return gActivePeriodicSmiLibraryHandler;
|
||||||
gActivePeriodicSmiLibraryHandlerIndex = PeriodicSmiLibraryHandler - gPeriodicSmiLibraryHandlers;
|
}
|
||||||
return PeriodicSmiLibraryHandler;
|
|
||||||
|
/**
|
||||||
|
Internal worker function that moves the specified periodic SMI handler from the
|
||||||
|
list of managed periodic SMI handlers to the list of free periodic SMI handlers.
|
||||||
|
|
||||||
|
@param[in] PeriodicSmiLibraryHandler Pointer to the periodic SMI handler to be reclaimed.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
ReclaimPeriodicSmiLibraryHandler (
|
||||||
|
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *PeriodicSmiLibraryHandler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LIST_ENTRY *Link;
|
||||||
|
|
||||||
|
ASSERT (PeriodicSmiLibraryHandler->DispatchHandle == NULL);
|
||||||
|
if (PeriodicSmiLibraryHandler->Stack != NULL) {
|
||||||
|
FreePages (
|
||||||
|
PeriodicSmiLibraryHandler->Stack,
|
||||||
|
EFI_SIZE_TO_PAGES (PeriodicSmiLibraryHandler->StackSize)
|
||||||
|
);
|
||||||
|
PeriodicSmiLibraryHandler->Stack = NULL;
|
||||||
|
}
|
||||||
|
RemoveEntryList (&PeriodicSmiLibraryHandler->Link);
|
||||||
|
//
|
||||||
|
// Insert to gFreePeriodicSmiLibraryHandlers in the reverse order of the address of PeriodicSmiLibraryHandler
|
||||||
|
//
|
||||||
|
for ( Link = GetFirstNode (&gFreePeriodicSmiLibraryHandlers)
|
||||||
|
; !IsNull (&gFreePeriodicSmiLibraryHandlers, Link)
|
||||||
|
; Link = GetNextNode (&gFreePeriodicSmiLibraryHandlers, Link)
|
||||||
|
) {
|
||||||
|
if (Link < &PeriodicSmiLibraryHandler->Link) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InsertTailList (Link, &PeriodicSmiLibraryHandler->Link);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Add the additional entries to the list of free periodic SMI handlers.
|
||||||
|
The function is assumed to be called only when the list of free periodic SMI
|
||||||
|
handlers is empty.
|
||||||
|
|
||||||
|
@retval TRUE The additional entries were added.
|
||||||
|
@retval FALSE There was no available resource for the additional entries.
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EnlargeFreePeriodicSmiLibraryHandlerList (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *PeriodicSmiLibraryHandlers;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The function is assumed to be called only when the list of free periodic SMI library
|
||||||
|
// handlers is empty.
|
||||||
|
//
|
||||||
|
ASSERT (IsListEmpty (&gFreePeriodicSmiLibraryHandlers));
|
||||||
|
|
||||||
|
PeriodicSmiLibraryHandlers = AllocatePool (
|
||||||
|
PERIODIC_SMI_LIBRARY_ALLOCATE_SIZE * sizeof (PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT)
|
||||||
|
);
|
||||||
|
if (PeriodicSmiLibraryHandlers == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add the entries to the list in the reverse order of the their memory address
|
||||||
|
//
|
||||||
|
for (Index = 0; Index < PERIODIC_SMI_LIBRARY_ALLOCATE_SIZE; Index++) {
|
||||||
|
PeriodicSmiLibraryHandlers[Index].Signature = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_SIGNATURE;
|
||||||
|
InsertHeadList (&gFreePeriodicSmiLibraryHandlers, &PeriodicSmiLibraryHandlers[Index].Link);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -310,40 +394,24 @@ FindFreePeriodicSmiLibraryHandler (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN Index;
|
|
||||||
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *PeriodicSmiLibraryHandler;
|
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *PeriodicSmiLibraryHandler;
|
||||||
|
|
||||||
//
|
if (IsListEmpty (&gFreePeriodicSmiLibraryHandlers)) {
|
||||||
// Search for a free entry in gPeriodicSmiLibraryHandlers
|
if (!EnlargeFreePeriodicSmiLibraryHandlerList ()) {
|
||||||
// A free entry must have a NULL DispatchHandle and a NULL Stack.
|
|
||||||
//
|
|
||||||
for (Index = 0; Index < gNumberOfPeriodicSmiLibraryHandlers; Index++) {
|
|
||||||
if (gPeriodicSmiLibraryHandlers[Index].DispatchHandle != NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (gPeriodicSmiLibraryHandlers[Index].Stack != NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return &gPeriodicSmiLibraryHandlers[Index];
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// If no free entries were found, then grow the table of periodic SMI handler entries
|
|
||||||
//
|
|
||||||
if (Index == gNumberOfPeriodicSmiLibraryHandlers) {
|
|
||||||
PeriodicSmiLibraryHandler = ReallocatePool (
|
|
||||||
gNumberOfPeriodicSmiLibraryHandlers * sizeof (PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT),
|
|
||||||
(gNumberOfPeriodicSmiLibraryHandlers + PERIODIC_SMI_LIBRARY_ALLOCATE_SIZE) * sizeof (PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT),
|
|
||||||
gPeriodicSmiLibraryHandlers
|
|
||||||
);
|
|
||||||
if (PeriodicSmiLibraryHandler == NULL) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
gPeriodicSmiLibraryHandlers = PeriodicSmiLibraryHandler;
|
|
||||||
gNumberOfPeriodicSmiLibraryHandlers += PERIODIC_SMI_LIBRARY_ALLOCATE_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &gPeriodicSmiLibraryHandlers[Index];
|
//
|
||||||
|
// Get one from the list of free periodic SMI handlers.
|
||||||
|
//
|
||||||
|
PeriodicSmiLibraryHandler = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_FROM_LINK (
|
||||||
|
GetFirstNode (&gFreePeriodicSmiLibraryHandlers)
|
||||||
|
);
|
||||||
|
RemoveEntryList (&PeriodicSmiLibraryHandler->Link);
|
||||||
|
InsertTailList (&gPeriodicSmiLibraryHandlers, &PeriodicSmiLibraryHandler->Link);
|
||||||
|
|
||||||
|
return PeriodicSmiLibraryHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -807,27 +875,12 @@ PeriodicSmiDispatchFunction (
|
||||||
//
|
//
|
||||||
ReleaseSpinLock (&PeriodicSmiLibraryHandler->DispatchLock);
|
ReleaseSpinLock (&PeriodicSmiLibraryHandler->DispatchLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Retrieve the active periodic SMI handler in case the entries were reallocated
|
// Reclaim the active periodic SMI handler if it was disabled during the current dispatch.
|
||||||
// when the active periodic SMI handler was dispatched.
|
|
||||||
//
|
//
|
||||||
PeriodicSmiLibraryHandler = GetActivePeriodicSmiLibraryHandler ();
|
if (PeriodicSmiLibraryHandler->DispatchHandle == NULL) {
|
||||||
if (PeriodicSmiLibraryHandler != NULL) {
|
ReclaimPeriodicSmiLibraryHandler (PeriodicSmiLibraryHandler);
|
||||||
//
|
|
||||||
// If the active periodic SMI handler was disabled during the current dispatch
|
|
||||||
// and the periodic SMI handler was allocated a stack when it was enabled, then
|
|
||||||
// free that stack here.
|
|
||||||
//
|
|
||||||
if (PeriodicSmiLibraryHandler->DispatchHandle == NULL) {
|
|
||||||
if (PeriodicSmiLibraryHandler->Stack != NULL) {
|
|
||||||
FreePages (
|
|
||||||
PeriodicSmiLibraryHandler->Stack,
|
|
||||||
EFI_SIZE_TO_PAGES (PeriodicSmiLibraryHandler->StackSize)
|
|
||||||
);
|
|
||||||
PeriodicSmiLibraryHandler->Stack = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -923,8 +976,7 @@ PeriodicSmiEnable (
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize a new periodic SMI handler entry
|
// Initialize a new periodic SMI handler entry
|
||||||
//
|
//
|
||||||
PeriodicSmiLibraryHandler->Signature = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_SIGNATURE;
|
|
||||||
PeriodicSmiLibraryHandler->YieldFlag = FALSE;
|
PeriodicSmiLibraryHandler->YieldFlag = FALSE;
|
||||||
PeriodicSmiLibraryHandler->DispatchHandle = NULL;
|
PeriodicSmiLibraryHandler->DispatchHandle = NULL;
|
||||||
PeriodicSmiLibraryHandler->DispatchFunction = DispatchFunction;
|
PeriodicSmiLibraryHandler->DispatchFunction = DispatchFunction;
|
||||||
|
@ -937,6 +989,8 @@ PeriodicSmiEnable (
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
ZeroMem (PeriodicSmiLibraryHandler->Stack, PeriodicSmiLibraryHandler->StackSize);
|
ZeroMem (PeriodicSmiLibraryHandler->Stack, PeriodicSmiLibraryHandler->StackSize);
|
||||||
|
} else {
|
||||||
|
PeriodicSmiLibraryHandler->Stack = NULL;
|
||||||
}
|
}
|
||||||
InitializeSpinLock (&PeriodicSmiLibraryHandler->DispatchLock);
|
InitializeSpinLock (&PeriodicSmiLibraryHandler->DispatchLock);
|
||||||
PeriodicSmiLibraryHandler->PerfomanceCounterRate = GetPerformanceCounterProperties (
|
PeriodicSmiLibraryHandler->PerfomanceCounterRate = GetPerformanceCounterProperties (
|
||||||
|
@ -951,18 +1005,9 @@ PeriodicSmiEnable (
|
||||||
&PeriodicSmiLibraryHandler->RegisterContext,
|
&PeriodicSmiLibraryHandler->RegisterContext,
|
||||||
&PeriodicSmiLibraryHandler->DispatchHandle
|
&PeriodicSmiLibraryHandler->DispatchHandle
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status) || PeriodicSmiLibraryHandler->DispatchHandle == NULL) {
|
if (EFI_ERROR (Status)) {
|
||||||
//
|
|
||||||
// If the registration failed or the handle is invalid, free the stack if one was allocated
|
|
||||||
//
|
|
||||||
if (PeriodicSmiLibraryHandler->Stack != NULL) {
|
|
||||||
FreePages (
|
|
||||||
PeriodicSmiLibraryHandler->Stack,
|
|
||||||
EFI_SIZE_TO_PAGES (PeriodicSmiLibraryHandler->StackSize)
|
|
||||||
);
|
|
||||||
PeriodicSmiLibraryHandler->Stack = NULL;
|
|
||||||
}
|
|
||||||
PeriodicSmiLibraryHandler->DispatchHandle = NULL;
|
PeriodicSmiLibraryHandler->DispatchHandle = NULL;
|
||||||
|
ReclaimPeriodicSmiLibraryHandler (PeriodicSmiLibraryHandler);
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1021,25 +1066,15 @@ PeriodicSmiDisable (
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// If active periodic SMI handler is not the periodic SMI handler being
|
// Mark the entry for the disabled periodic SMI handler as free, and
|
||||||
// disabled, and the periodic SMI handler being disabled was allocated a
|
// call ReclaimPeriodicSmiLibraryHandler to move it to the list of free
|
||||||
// stack when it was enabled, then free the stack.
|
// periodic SMI handlers.
|
||||||
//
|
|
||||||
if (PeriodicSmiLibraryHandler != GetActivePeriodicSmiLibraryHandler ()) {
|
|
||||||
if (PeriodicSmiLibraryHandler->Stack != NULL) {
|
|
||||||
FreePages (
|
|
||||||
PeriodicSmiLibraryHandler->Stack,
|
|
||||||
EFI_SIZE_TO_PAGES (PeriodicSmiLibraryHandler->StackSize)
|
|
||||||
);
|
|
||||||
PeriodicSmiLibraryHandler->Stack = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Mark the entry for the disabled periodic SMI handler as free
|
|
||||||
//
|
//
|
||||||
PeriodicSmiLibraryHandler->DispatchHandle = NULL;
|
PeriodicSmiLibraryHandler->DispatchHandle = NULL;
|
||||||
|
if (PeriodicSmiLibraryHandler != GetActivePeriodicSmiLibraryHandler ()) {
|
||||||
|
ReclaimPeriodicSmiLibraryHandler (PeriodicSmiLibraryHandler);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1111,12 +1146,12 @@ SmmPeriodicSmiLibConstructor (
|
||||||
gSmiTickPeriodTable[Count] = *SmiTickInterval;
|
gSmiTickPeriodTable[Count] = *SmiTickInterval;
|
||||||
}
|
}
|
||||||
Count++;
|
Count++;
|
||||||
} while (SmiTickInterval != NULL);
|
} while (SmiTickInterval != NULL);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate buffer for initial set of periodic SMI handlers
|
// Allocate buffer for initial set of periodic SMI handlers
|
||||||
//
|
//
|
||||||
FindFreePeriodicSmiLibraryHandler ();
|
EnlargeFreePeriodicSmiLibraryHandlerList ();
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1138,28 +1173,43 @@ SmmPeriodicSmiLibDestructor (
|
||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN Index;
|
LIST_ENTRY *Link;
|
||||||
|
PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *PeriodicSmiLibraryHandler;
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Free the table of supported periodic SMI tick rates
|
// Free the table of supported periodic SMI tick rates
|
||||||
//
|
//
|
||||||
if (gSmiTickPeriodTable != NULL) {
|
if (gSmiTickPeriodTable != NULL) {
|
||||||
FreePool (gSmiTickPeriodTable);
|
FreePool (gSmiTickPeriodTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disable all periodic SMI handlers
|
// Disable all periodic SMI handlers
|
||||||
//
|
//
|
||||||
for (Index = 0; Index < gNumberOfPeriodicSmiLibraryHandlers; Index++) {
|
for (Link = GetFirstNode (&gPeriodicSmiLibraryHandlers); !IsNull (&gPeriodicSmiLibraryHandlers, Link);) {
|
||||||
PeriodicSmiDisable (gPeriodicSmiLibraryHandlers[Index].DispatchHandle);
|
PeriodicSmiLibraryHandler = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_FROM_LINK (Link);
|
||||||
|
Link = GetNextNode (&gPeriodicSmiLibraryHandlers, Link);
|
||||||
|
PeriodicSmiDisable (PeriodicSmiLibraryHandler->DispatchHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Free all the periodic SMI handler entries
|
// Free all the periodic SMI handler entries
|
||||||
//
|
//
|
||||||
if (gPeriodicSmiLibraryHandlers != NULL) {
|
Index = 0;
|
||||||
FreePool (gPeriodicSmiLibraryHandlers);
|
for (Link = GetFirstNode (&gFreePeriodicSmiLibraryHandlers); !IsNull (&gFreePeriodicSmiLibraryHandlers, Link);) {
|
||||||
|
PeriodicSmiLibraryHandler = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_FROM_LINK (Link);
|
||||||
|
Link = RemoveEntryList (Link);
|
||||||
|
Index++;
|
||||||
|
//
|
||||||
|
// Because the entries in the list are in the reverse order of the address of PeriodicSmiLibraryHandler and
|
||||||
|
// every PERIODIC_SMI_LIBRARY_ALLOCATE_SIZE entries are in the same pool returned by AllocatePool(),
|
||||||
|
// every PERIODIC_SMI_LIBRARY_ALLOCATE_SIZE'th entry is the header of allocated pool.
|
||||||
|
//
|
||||||
|
if ((Index % PERIODIC_SMI_LIBRARY_ALLOCATE_SIZE) == 0) {
|
||||||
|
FreePool (PeriodicSmiLibraryHandler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue