]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
UefiCpuPkg: Explain relationship between several SMM PCDs
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / CpuS3.c
index d20bc4aae6c8f9b6f3f15cab0052e527f00cd138..ba5cc0194c2d2121e1efdc1a3cb0a424e3349e1e 100644 (file)
@@ -35,7 +35,6 @@ typedef struct {
 // Flags used when program the register.\r
 //\r
 typedef struct {\r
-  volatile UINTN           ConsoleLogLock;          // Spinlock used to control console.\r
   volatile UINTN           MemoryMappedLock;        // Spinlock used to program mmio\r
   volatile UINT32          *CoreSemaphoreCount;     // Semaphore container used to program\r
                                                     // core level semaphore.\r
@@ -160,6 +159,58 @@ S3WaitForSemaphore (
              ) != Value);\r
 }\r
 \r
+/**\r
+  Read / write CR value.\r
+\r
+  @param[in]      CrIndex         The CR index which need to read/write.\r
+  @param[in]      Read            Read or write. TRUE is read.\r
+  @param[in,out]  CrValue         CR value.\r
+\r
+  @retval    EFI_SUCCESS means read/write success, else return EFI_UNSUPPORTED.\r
+**/\r
+UINTN\r
+ReadWriteCr (\r
+  IN     UINT32       CrIndex,\r
+  IN     BOOLEAN      Read,\r
+  IN OUT UINTN        *CrValue\r
+  )\r
+{\r
+  switch (CrIndex) {\r
+  case 0:\r
+    if (Read) {\r
+      *CrValue = AsmReadCr0 ();\r
+    } else {\r
+      AsmWriteCr0 (*CrValue);\r
+    }\r
+    break;\r
+  case 2:\r
+    if (Read) {\r
+      *CrValue = AsmReadCr2 ();\r
+    } else {\r
+      AsmWriteCr2 (*CrValue);\r
+    }\r
+    break;\r
+  case 3:\r
+    if (Read) {\r
+      *CrValue = AsmReadCr3 ();\r
+    } else {\r
+      AsmWriteCr3 (*CrValue);\r
+    }\r
+    break;\r
+  case 4:\r
+    if (Read) {\r
+      *CrValue = AsmReadCr4 ();\r
+    } else {\r
+      AsmWriteCr4 (*CrValue);\r
+    }\r
+    break;\r
+  default:\r
+    return EFI_UNSUPPORTED;;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Initialize the CPU registers from a register table.\r
 \r
@@ -189,6 +240,8 @@ ProgramProcessorRegister (
   UINTN                     ProcessorIndex;\r
   UINTN                     ValidThreadCount;\r
   UINT32                    *ValidCoreCountPerPackage;\r
+  EFI_STATUS                Status;\r
+  UINT64                    CurrentValue;\r
 \r
   //\r
   // Traverse Register Table of this logical processor\r
@@ -207,55 +260,50 @@ ProgramProcessorRegister (
     // The specified register is Control Register\r
     //\r
     case ControlRegister:\r
-      switch (RegisterTableEntry->Index) {\r
-      case 0:\r
-        Value = AsmReadCr0 ();\r
-        Value = (UINTN) BitFieldWrite64 (\r
-                          Value,\r
-                          RegisterTableEntry->ValidBitStart,\r
-                          RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,\r
-                          (UINTN) RegisterTableEntry->Value\r
-                          );\r
-        AsmWriteCr0 (Value);\r
-        break;\r
-      case 2:\r
-        Value = AsmReadCr2 ();\r
-        Value = (UINTN) BitFieldWrite64 (\r
-                          Value,\r
-                          RegisterTableEntry->ValidBitStart,\r
-                          RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,\r
-                          (UINTN) RegisterTableEntry->Value\r
-                          );\r
-        AsmWriteCr2 (Value);\r
-        break;\r
-      case 3:\r
-        Value = AsmReadCr3 ();\r
-        Value = (UINTN) BitFieldWrite64 (\r
-                          Value,\r
-                          RegisterTableEntry->ValidBitStart,\r
-                          RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,\r
-                          (UINTN) RegisterTableEntry->Value\r
-                          );\r
-        AsmWriteCr3 (Value);\r
-        break;\r
-      case 4:\r
-        Value = AsmReadCr4 ();\r
-        Value = (UINTN) BitFieldWrite64 (\r
-                          Value,\r
-                          RegisterTableEntry->ValidBitStart,\r
-                          RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,\r
-                          (UINTN) RegisterTableEntry->Value\r
-                          );\r
-        AsmWriteCr4 (Value);\r
-        break;\r
-      default:\r
+      Status = ReadWriteCr (RegisterTableEntry->Index, TRUE, &Value);\r
+      if (EFI_ERROR (Status)) {\r
         break;\r
       }\r
+      if (RegisterTableEntry->TestThenWrite) {\r
+        CurrentValue = BitFieldRead64 (\r
+                         Value,\r
+                         RegisterTableEntry->ValidBitStart,\r
+                         RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1\r
+                         );\r
+        if (CurrentValue == RegisterTableEntry->Value) {\r
+          break;\r
+        }\r
+      }\r
+      Value = (UINTN) BitFieldWrite64 (\r
+                        Value,\r
+                        RegisterTableEntry->ValidBitStart,\r
+                        RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,\r
+                        RegisterTableEntry->Value\r
+                        );\r
+      ReadWriteCr (RegisterTableEntry->Index, FALSE, &Value);\r
       break;\r
     //\r
     // The specified register is Model Specific Register\r
     //\r
     case Msr:\r
+      if (RegisterTableEntry->TestThenWrite) {\r
+        Value = (UINTN)AsmReadMsr64 (RegisterTableEntry->Index);\r
+        if (RegisterTableEntry->ValidBitLength >= 64) {\r
+          if (Value == RegisterTableEntry->Value) {\r
+            break;\r
+          }\r
+        } else {\r
+          CurrentValue = BitFieldRead64 (\r
+                           Value,\r
+                           RegisterTableEntry->ValidBitStart,\r
+                           RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1\r
+                           );\r
+          if (CurrentValue == RegisterTableEntry->Value) {\r
+            break;\r
+          }\r
+        }\r
+      }\r
+\r
       //\r
       // If this function is called to restore register setting after INIT signal,\r
       // there is no need to restore MSRs in register table.\r
@@ -1028,7 +1076,6 @@ GetAcpiCpuData (
     ASSERT (mCpuFlags.PackageSemaphoreCount != NULL);\r
   }\r
   InitializeSpinLock((SPIN_LOCK*) &mCpuFlags.MemoryMappedLock);\r
-  InitializeSpinLock((SPIN_LOCK*) &mCpuFlags.ConsoleLogLock);\r
 }\r
 \r
 /**\r