// 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
) != 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
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
// 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
ASSERT (mCpuFlags.PackageSemaphoreCount != NULL);\r
}\r
InitializeSpinLock((SPIN_LOCK*) &mCpuFlags.MemoryMappedLock);\r
- InitializeSpinLock((SPIN_LOCK*) &mCpuFlags.ConsoleLogLock);\r
}\r
\r
/**\r