From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: eric.dong@intel.com) Received: from mga12.intel.com (mga12.intel.com []) by groups.io with SMTP; Wed, 14 Aug 2019 19:50:41 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Aug 2019 19:50:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,387,1559545200"; d="scan'208";a="176753289" Received: from ydong10-win10.ccr.corp.intel.com ([10.239.158.133]) by fmsmga008.fm.intel.com with ESMTP; 14 Aug 2019 19:50:39 -0700 From: "Dong, Eric" To: devel@edk2.groups.io Cc: Ray Ni , Laszlo Ersek , Star Zeng Subject: [Patch v3 1/6] UefiCpuPkg/RegisterCpuFeaturesLib: Add "Test Then Write" Macros. Date: Thu, 15 Aug 2019 10:50:31 +0800 Message-Id: <20190815025036.6780-2-eric.dong@intel.com> X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: <20190815025036.6780-1-eric.dong@intel.com> References: <20190815025036.6780-1-eric.dong@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2040 Add below new micros which test the current value before write the new value. Only write new value when current value not same as new value. CPU_REGISTER_TABLE_TEST_THEN_WRITE32 CPU_REGISTER_TABLE_TEST_THEN_WRITE64 CPU_REGISTER_TABLE_TEST_THEN_WRITE_FIELD Also add below API: CpuRegisterTableTestThenWrite Signed-off-by: Eric Dong Cc: Ray Ni Cc: Laszlo Ersek Cc: Star Zeng --- UefiCpuPkg/Include/AcpiCpuData.h | 1 + .../Include/Library/RegisterCpuFeaturesLib.h | 91 +++++++++++++++++++ .../RegisterCpuFeaturesLib.c | 45 ++++++++- 3 files changed, 134 insertions(+), 3 deletions(-) diff --git a/UefiCpuPkg/Include/AcpiCpuData.h b/UefiCpuPkg/Include/AcpiCpuData.h index b963a2f592..472a1a8070 100644 --- a/UefiCpuPkg/Include/AcpiCpuData.h +++ b/UefiCpuPkg/Include/AcpiCpuData.h @@ -81,6 +81,7 @@ typedef struct { UINT16 Reserved; // offset 10 - 11 UINT32 HighIndex; // offset 12-15, only valid for MemoryMapped UINT64 Value; // offset 16-23 + UINT8 TestThenWrite; // 0ffset 24 } CPU_REGISTER_TABLE_ENTRY; // diff --git a/UefiCpuPkg/Include/Library/RegisterCpuFeaturesLib.h b/UefiCpuPkg/Include/Library/RegisterCpuFeaturesLib.h index e420e7f075..5bd464b32e 100644 --- a/UefiCpuPkg/Include/Library/RegisterCpuFeaturesLib.h +++ b/UefiCpuPkg/Include/Library/RegisterCpuFeaturesLib.h @@ -348,6 +348,32 @@ CpuRegisterTableWrite ( IN UINT64 Value ); +/** + Adds an entry in specified register table. + + This function adds an entry in specified register table, with given register type, + register index, bit section and value. + + Driver will test the current value before setting new value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] ValueMask Mask of bits in register to write + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuRegisterTableTestThenWrite ( + IN UINTN ProcessorNumber, + IN REGISTER_TYPE RegisterType, + IN UINT64 Index, + IN UINT64 ValueMask, + IN UINT64 Value + ); + /** Adds an entry in specified Pre-SMM register table. @@ -390,6 +416,26 @@ PreSmmCpuRegisterTableWrite ( CpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, MAX_UINT32, Value); \ } while(FALSE); +/** + Adds a 32-bit register write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, and value. + + Driver will test the current value before setting new value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_TEST_THEN_WRITE32(ProcessorNumber, RegisterType, Index, Value) \ + do { \ + CpuRegisterTableTestThenWrite (ProcessorNumber, RegisterType, Index, MAX_UINT32, Value); \ + } while(FALSE); + /** Adds a 64-bit register write entry in specified register table. @@ -408,6 +454,26 @@ PreSmmCpuRegisterTableWrite ( CpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, MAX_UINT64, Value); \ } while(FALSE); +/** + Adds a 64-bit register write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, and value. + + Driver will test the current value before setting new value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] Value Value to write + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_TEST_THEN_WRITE64(ProcessorNumber, RegisterType, Index, Value) \ + do { \ + CpuRegisterTableTestThenWrite (ProcessorNumber, RegisterType, Index, MAX_UINT64, Value); \ + } while(FALSE); + /** Adds a bit field write entry in specified register table. @@ -431,6 +497,31 @@ PreSmmCpuRegisterTableWrite ( CpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, ~ValueMask, Value); \ } while(FALSE); +/** + Adds a bit field write entry in specified register table. + + This macro adds an entry in specified register table, with given register type, + register index, bit field section, and value. + + Driver will test the current value before setting new value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry. + @param[in] RegisterType Type of the register to program. + @param[in] Index Index of the register to program. + @param[in] Type The data type name of a register structure. + @param[in] Field The bit fiel name in register structure to write. + @param[in] Value Value to write to the bit field. + + @note This service could be called by BSP only. +**/ +#define CPU_REGISTER_TABLE_TEST_THEN_WRITE_FIELD(ProcessorNumber, RegisterType, Index, Type, Field, Value) \ + do { \ + UINT64 ValueMask; \ + ValueMask = MAX_UINT64; \ + ((Type *)(&ValueMask))->Field = 0; \ + CpuRegisterTableTestThenWrite (ProcessorNumber, RegisterType, Index, ~ValueMask, Value); \ + } while(FALSE); + /** Adds a 32-bit register write entry in specified register table. diff --git a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.c b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.c index 67885bf69b..e9769882b9 100644 --- a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.c +++ b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.c @@ -1025,6 +1025,8 @@ EnlargeRegisterTable ( @param[in] ValidBitStart Start of the bit section @param[in] ValidBitLength Length of the bit section @param[in] Value Value to write + @param[in] TestThenWrite Whether need to test current Value before writing. + **/ VOID CpuRegisterTableWriteWorker ( @@ -1034,7 +1036,8 @@ CpuRegisterTableWriteWorker ( IN UINT64 Index, IN UINT8 ValidBitStart, IN UINT8 ValidBitLength, - IN UINT64 Value + IN UINT64 Value, + IN UINT8 TestThenWrite ) { CPU_FEATURES_DATA *CpuFeaturesData; @@ -1070,6 +1073,7 @@ CpuRegisterTableWriteWorker ( RegisterTableEntry[RegisterTable->TableLength].ValidBitStart = ValidBitStart; RegisterTableEntry[RegisterTable->TableLength].ValidBitLength = ValidBitLength; RegisterTableEntry[RegisterTable->TableLength].Value = Value; + RegisterTableEntry[RegisterTable->TableLength].TestThenWrite = TestThenWrite; RegisterTable->TableLength++; } @@ -1105,7 +1109,42 @@ CpuRegisterTableWrite ( Start = (UINT8)LowBitSet64 (ValueMask); End = (UINT8)HighBitSet64 (ValueMask); Length = End - Start + 1; - CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value); + CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value, FALSE); +} + +/** + Adds an entry in specified register table. + + This function adds an entry in specified register table, with given register type, + register index, bit section and value. + + @param[in] ProcessorNumber The index of the CPU to add a register table entry + @param[in] RegisterType Type of the register to program + @param[in] Index Index of the register to program + @param[in] ValueMask Mask of bits in register to write + @param[in] Value Value to write + @param[in] TestThenWrite Whether need to test current Value before writing. + + @note This service could be called by BSP only. +**/ +VOID +EFIAPI +CpuRegisterTableTestThenWrite ( + IN UINTN ProcessorNumber, + IN REGISTER_TYPE RegisterType, + IN UINT64 Index, + IN UINT64 ValueMask, + IN UINT64 Value + ) +{ + UINT8 Start; + UINT8 End; + UINT8 Length; + + Start = (UINT8)LowBitSet64 (ValueMask); + End = (UINT8)HighBitSet64 (ValueMask); + Length = End - Start + 1; + CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value, TRUE); } /** @@ -1139,7 +1178,7 @@ PreSmmCpuRegisterTableWrite ( Start = (UINT8)LowBitSet64 (ValueMask); End = (UINT8)HighBitSet64 (ValueMask); Length = End - Start + 1; - CpuRegisterTableWriteWorker (TRUE, ProcessorNumber, RegisterType, Index, Start, Length, Value); + CpuRegisterTableWriteWorker (TRUE, ProcessorNumber, RegisterType, Index, Start, Length, Value, FALSE); } /** -- 2.21.0.windows.1