EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

MdeModulePkg/Core/PiSmmCore/PiSmmCore.c

Go to the documentation of this file.
00001 
00015 #include "PiSmmCore.h"
00016 
00017 //
00018 // Physical pointer to private structure shared between SMM IPL and the SMM Core
00019 //
00020 SMM_CORE_PRIVATE_DATA  *gSmmCorePrivate;
00021 
00022 //
00023 // SMM Core global variable for SMM System Table.  Only accessed as a physical structure in SMRAM.
00024 //
00025 EFI_SMM_SYSTEM_TABLE2  gSmmCoreSmst = {
00026   {
00027     SMM_SMST_SIGNATURE,
00028     EFI_SMM_SYSTEM_TABLE2_REVISION,
00029     sizeof (gSmmCoreSmst.Hdr)
00030   },
00031   NULL,                          // SmmFirmwareVendor
00032   0,                             // SmmFirmwareRevision
00033   SmmInstallConfigurationTable,
00034   {
00035     {
00036       (EFI_SMM_CPU_IO2) SmmEfiNotAvailableYetArg5,       // SmmMemRead
00037       (EFI_SMM_CPU_IO2) SmmEfiNotAvailableYetArg5        // SmmMemWrite
00038     },
00039     {
00040       (EFI_SMM_CPU_IO2) SmmEfiNotAvailableYetArg5,       // SmmIoRead
00041       (EFI_SMM_CPU_IO2) SmmEfiNotAvailableYetArg5        // SmmIoWrite
00042     }
00043   },
00044   SmmAllocatePool,
00045   SmmFreePool,
00046   SmmAllocatePages,
00047   SmmFreePages,
00048   NULL,                          // SmmStartupThisAp
00049   0,                             // CurrentlyExecutingCpu
00050   0,                             // NumberOfCpus
00051   NULL,                          // CpuSaveStateSize
00052   NULL,                          // CpuSaveState
00053   0,                             // NumberOfTableEntries
00054   NULL,                          // SmmConfigurationTable
00055   SmmInstallProtocolInterface,
00056   SmmUninstallProtocolInterface,
00057   SmmHandleProtocol,
00058   SmmRegisterProtocolNotify,
00059   SmmLocateHandle,
00060   SmmLocateProtocol,
00061   SmiManage,
00062   SmiHandlerRegister,
00063   SmiHandlerUnRegister
00064 };
00065 
00066 //
00067 // Flag to determine if the platform has performed a legacy boot.
00068 // If this flag is TRUE, then the runtime code and runtime data associated with the 
00069 // SMM IPL are converted to free memory, so the SMM COre must guarantee that is
00070 // does not touch of the code/data associated with the SMM IPL if this flag is TRUE.
00071 //
00072 BOOLEAN  mInLegacyBoot = FALSE;
00073 
00074 //
00075 // Table of SMI Handlers that are registered by the SMM Core when it is initialized
00076 //
00077 SMM_CORE_SMI_HANDLERS  mSmmCoreSmiHandlers[] = {
00078   { SmmDriverDispatchHandler, &gEfiEventDxeDispatchGuid,          NULL, TRUE  },
00079   { SmmReadyToLockHandler,    &gEfiDxeSmmReadyToLockProtocolGuid, NULL, FALSE }, 
00080   { SmmLegacyBootHandler,     &gEfiEventLegacyBootGuid,           NULL, FALSE },
00081   { NULL,                     NULL,                               NULL, FALSE }
00082 };
00083 
00098 EFI_STATUS
00099 EFIAPI
00100 SmmEfiNotAvailableYetArg5 (
00101   UINTN Arg1,
00102   UINTN Arg2,
00103   UINTN Arg3,
00104   UINTN Arg4,
00105   UINTN Arg5
00106   )
00107 {
00108   //
00109   // This function should never be executed.  If it does, then the architectural protocols
00110   // have not been designed correctly.
00111   //
00112   return EFI_NOT_AVAILABLE_YET;
00113 }
00114 
00131 EFI_STATUS
00132 EFIAPI
00133 SmmLegacyBootHandler (
00134   IN     EFI_HANDLE  DispatchHandle,
00135   IN     CONST VOID  *Context,        OPTIONAL
00136   IN OUT VOID        *CommBuffer,     OPTIONAL
00137   IN OUT UINTN       *CommBufferSize  OPTIONAL
00138   )
00139 {
00140   mInLegacyBoot = TRUE;
00141   return EFI_SUCCESS;
00142 }
00143 
00161 EFI_STATUS
00162 EFIAPI
00163 SmmReadyToLockHandler (
00164   IN     EFI_HANDLE  DispatchHandle,
00165   IN     CONST VOID  *Context,        OPTIONAL
00166   IN OUT VOID        *CommBuffer,     OPTIONAL
00167   IN OUT UINTN       *CommBufferSize  OPTIONAL
00168   )
00169 {
00170   EFI_STATUS  Status;
00171   UINTN       Index;
00172   EFI_HANDLE  SmmHandle;
00173   VOID        *Interface;
00174 
00175   //
00176   // Unregister SMI Handlers that are no required after the SMM driver dispatch is stopped
00177   //
00178   for (Index = 0; mSmmCoreSmiHandlers[Index].HandlerType != NULL; Index++) {
00179     if (mSmmCoreSmiHandlers[Index].UnRegister) {
00180       SmiHandlerUnRegister (mSmmCoreSmiHandlers[Index].DispatchHandle);
00181     }
00182   }
00183 
00184   //
00185   // Install SMM Ready to lock protocol
00186   //
00187   SmmHandle = NULL;
00188   Status = SmmInstallProtocolInterface (
00189              &SmmHandle,
00190              &gEfiSmmReadyToLockProtocolGuid,
00191              EFI_NATIVE_INTERFACE,
00192              NULL
00193              );
00194 
00195   //
00196   // Make sure SMM CPU I/O 2 Procol has been installed into the handle database
00197   //
00198   Status = SmmLocateProtocol (&gEfiSmmCpuIo2ProtocolGuid, NULL, &Interface);
00199 
00200   //
00201   // Print a message on a debug build if the SMM CPU I/O 2 Protocol is not installed
00202   //
00203   DEBUG_CODE_BEGIN ();
00204     if (EFI_ERROR (Status)) {
00205       DEBUG ((DEBUG_ERROR, "\nSMM: SmmCpuIo Arch Protocol not present!!\n"));
00206     }
00207   DEBUG_CODE_END ();
00208 
00209   //
00210   // Assert if the CPU I/O 2 Protocol is not installed
00211   //
00212   ASSERT_EFI_ERROR (Status);
00213 
00214   //
00215   // Display any drivers that were not dispatched because dependency expression
00216   // evaluated to false if this is a debug build
00217   //
00218   DEBUG_CODE_BEGIN ();
00219     SmmDisplayDiscoveredNotDispatched ();
00220   DEBUG_CODE_END ();
00221 
00222   //
00223   // Not allowed to use gST or gBS after lock
00224   //
00225   gST = NULL;
00226   gBS = NULL;
00227 
00228   return Status;
00229 }
00230 
00240 VOID
00241 EFIAPI
00242 SmmEntryPoint (
00243   IN CONST EFI_SMM_ENTRY_CONTEXT  *SmmEntryContext
00244 )
00245 {
00246   EFI_STATUS                  Status;
00247   EFI_SMM_COMMUNICATE_HEADER  *CommunicateHeader;
00248 
00249   PERF_START (NULL, "SMM", NULL, 0) ;
00250 
00251   //
00252   // Update SMST using the context
00253   //
00254   CopyMem (&gSmmCoreSmst.SmmStartupThisAp, SmmEntryContext, sizeof (EFI_SMM_ENTRY_CONTEXT));
00255 
00256   //
00257   // Call platform hook before Smm Dispatch
00258   //
00259   PlatformHookBeforeSmmDispatch ();
00260 
00261   //
00262   // If a legacy boot has occured, then make sure gSmmCorePrivate is not accessed
00263   //
00264   if (mInLegacyBoot) {
00265     //
00266     // Asynchronous SMI
00267     //
00268     SmiManage (NULL, NULL, NULL, NULL);
00269     return;
00270   }
00271 
00272   //
00273   // Mark the InSmm flag as TRUE, it will be used by SmmBase2 protocol
00274   //
00275   gSmmCorePrivate->InSmm = TRUE;
00276 
00277   //
00278   // Check to see if this is a Synchronous SMI sent through the SMM Communication 
00279   // Protocol or an Asynchronous SMI
00280   //
00281   if (gSmmCorePrivate->CommunicationBuffer != NULL) {
00282     //
00283     // Synchronous SMI for SMM Core or request from Communicate protocol
00284     //
00285     CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)gSmmCorePrivate->CommunicationBuffer;
00286     gSmmCorePrivate->BufferSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
00287     Status = SmiManage (
00288                &CommunicateHeader->HeaderGuid, 
00289                NULL, 
00290                CommunicateHeader->Data, 
00291                &gSmmCorePrivate->BufferSize
00292                );
00293 
00294     //
00295     // Update CommunicationBuffer, BufferSize and ReturnStatus
00296     // Communicate service finished, reset the pointer to CommBuffer to NULL
00297     //
00298     gSmmCorePrivate->BufferSize += OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
00299     gSmmCorePrivate->CommunicationBuffer = NULL;
00300     gSmmCorePrivate->ReturnStatus = (Status == EFI_WARN_INTERRUPT_SOURCE_QUIESCED) ? EFI_SUCCESS : EFI_NOT_FOUND;
00301   } else {
00302     //
00303     // Asynchronous SMI
00304     //
00305     SmiManage (NULL, NULL, NULL, NULL);
00306   }
00307   
00308   //
00309   // Call platform hook after Smm Dispatch
00310   //
00311   PlatformHookAfterSmmDispatch ();
00312 
00313   //
00314   // Clear the InSmm flag as we are going to leave SMM
00315   //
00316   gSmmCorePrivate->InSmm = FALSE;
00317 
00318   PERF_END (NULL, "SMM", NULL, 0) ;
00319 }
00320 
00336 EFI_STATUS
00337 EFIAPI
00338 SmmMain (
00339   IN EFI_HANDLE        ImageHandle,
00340   IN EFI_SYSTEM_TABLE  *SystemTable
00341   )
00342 {
00343   EFI_STATUS  Status;
00344   UINTN       Index;
00345 
00346   //
00347   // Get SMM Core Private context passed in from SMM IPL in ImageHandle.
00348   //
00349   gSmmCorePrivate = (SMM_CORE_PRIVATE_DATA *)ImageHandle;
00350 
00351   //
00352   // Fill in SMRAM physical address for the SMM Services Table and the SMM Entry Point.
00353   //
00354   gSmmCorePrivate->Smst          = &gSmmCoreSmst;
00355   gSmmCorePrivate->SmmEntryPoint = SmmEntryPoint;
00356   
00357   //
00358   // Initialize memory service using free SMRAM
00359   //
00360   SmmInitializeMemoryServices (gSmmCorePrivate->SmramRangeCount, gSmmCorePrivate->SmramRanges);
00361 
00362   //
00363   // Register all SMI Handlers required by the SMM Core
00364   //
00365   for (Index = 0; mSmmCoreSmiHandlers[Index].HandlerType != NULL; Index++) {
00366     Status = SmiHandlerRegister (
00367                mSmmCoreSmiHandlers[Index].Handler,
00368                mSmmCoreSmiHandlers[Index].HandlerType,
00369                &mSmmCoreSmiHandlers[Index].DispatchHandle
00370                );
00371     ASSERT_EFI_ERROR (Status);
00372   }
00373   
00374   return EFI_SUCCESS;
00375 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines