UefiCpuPkg/PiSmmCpuDxeSmm: Add MemoryMapped in SetProcessorRegister()

REGISTER_TYPE in UefiCpuPkg/Include/AcpiCpuData.h defines a MemoryMapped
enum value.  However support for the MemoryMapped enum is missing from
the implementation of SetProcessorRegister().  This patch adds support
for MemoryMapped type SetProcessorRegister().

One spin lock is added to avoid potential conflict when multiple processor
update the same memory space.

Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Michael Kinney <michael.d.kinney@intel.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
index 5e63f8a..4c995ec 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
@@ -34,6 +34,11 @@
   UINTN LongJumpOffset;

 } MP_ASSEMBLY_ADDRESS_MAP;

 

+//

+// Spin lock used to serialize MemoryMapped operation

+//

+SPIN_LOCK                *mMemoryMappedLock = NULL;

+

 /**

   Get starting address and size of the rendezvous entry for APs.

   Information for fixing a jump instruction in the code is also returned.

@@ -284,6 +289,19 @@
       }

       break;

     //

+    // MemoryMapped operations

+    //

+    case MemoryMapped:

+      AcquireSpinLock (mMemoryMappedLock);

+      MmioBitFieldWrite32 (

+        RegisterTableEntry->Index,

+        RegisterTableEntry->ValidBitStart,

+        RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,

+        (UINT32)RegisterTableEntry->Value

+        );

+      ReleaseSpinLock (mMemoryMappedLock);

+      break;

+    //

     // Enable or disable cache

     //

     case CacheControl:

diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
index 62d037c..5ba0514 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
@@ -1239,6 +1239,10 @@
   SemaphoreAddr += SemaphoreSize;

   mSmmCpuSemaphores.SemaphoreGlobal.CodeAccessCheckLock

                                                   = (SPIN_LOCK *)SemaphoreAddr;

+  SemaphoreAddr += SemaphoreSize;

+  mSmmCpuSemaphores.SemaphoreGlobal.MemoryMappedLock

+                                                  = (SPIN_LOCK *)SemaphoreAddr;

+

   SemaphoreAddr = (UINTN)SemaphoreBlock + GlobalSemaphoresSize;

   mSmmCpuSemaphores.SemaphoreCpu.Busy    = (SPIN_LOCK *)SemaphoreAddr;

   SemaphoreAddr += ProcessorCount * SemaphoreSize;

@@ -1254,6 +1258,7 @@
 

   mPFLock                       = mSmmCpuSemaphores.SemaphoreGlobal.PFLock;

   mConfigSmmCodeAccessCheckLock = mSmmCpuSemaphores.SemaphoreGlobal.CodeAccessCheckLock;

+  mMemoryMappedLock             = mSmmCpuSemaphores.SemaphoreGlobal.MemoryMappedLock;

 

   mSemaphoreSize = SemaphoreSize;

 }

diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
index 8b3bb34..0858d8f 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
@@ -485,6 +485,8 @@
 

   DEBUG ((EFI_D_INFO, "SmmRestoreCpu()\n"));

 

+  InitializeSpinLock (mMemoryMappedLock);

+

   //

   // See if there is enough context to resume PEI Phase

   //

diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
index b6c57e3..bf31e9e 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
@@ -366,6 +366,7 @@
   volatile BOOLEAN     *AllCpusInSync;

   SPIN_LOCK            *PFLock;

   SPIN_LOCK            *CodeAccessCheckLock;

+  SPIN_LOCK            *MemoryMappedLock;

 } SMM_CPU_SEMAPHORE_GLOBAL;

 

 ///

@@ -413,6 +414,7 @@
 extern UINTN                               mSemaphoreSize;

 extern SPIN_LOCK                           *mPFLock;

 extern SPIN_LOCK                           *mConfigSmmCodeAccessCheckLock;

+extern SPIN_LOCK                           *mMemoryMappedLock;

 

 /**

   Create 4G PageTable in SMRAM.