Reviewed_by: Eric Dong <[email protected]>

> -----Original Message-----
> From: Fan, Jeff
> Sent: Monday, June 06, 2016 2:00 PM
> To: [email protected]
> Cc: Dong, Eric; Tian, Feng; Kinney, Michael D
> Subject: [Patch v2] UefiCpuPkg/MtrrLib: Fixed bug if length is less than 
> Fixed-MTRR range
> 
> Currently, if the memory length to be programmed is less than the remaining 
> size
> of one Fixed-MTRR supported, RETURN_UNSUPPORTED returned. This is not correct.
> This is one regression at 07e889209034ba94bfac9e765b8a50ef344daef2 when we
> updated ProgramFixedMtrr() to remove the loop of calculating Fixed-MTRR Mask.
> 
> This fix will calculate Right offset in Fixed-MTRR beside left offset. It
> supports small length (less than remaining size supported by Fixed-MTRR) to be
> programmed.
> 
> v2:
>  1) Remove unnecessary local variable OrMaskTemplate.
>  2) Exchange LeftByteShift and RightByteShift programm order and correct the
>     comments.
> 
> Cc: Eric Dong <[email protected]>
> Cc: Feng Tian <[email protected]>
> Cc: Michael Kinney <[email protected]>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jeff Fan <[email protected]>
> ---
>  UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 71 
> ++++++++++++++++++++++++------------
>  1 file changed, 48 insertions(+), 23 deletions(-)
> 
> diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c 
> b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
> index c4a39b5..6a6bf76 100644
> --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
> +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
> @@ -20,8 +20,8 @@
>  #include <Library/BaseMemoryLib.h>
>  #include <Library/DebugLib.h>
> 
> -#define OR_SEED      0x01010101
> -#define CLEAR_SEED   0xFFFFFFFF
> +#define OR_SEED      0x0101010101010101ull
> +#define CLEAR_SEED   0xFFFFFFFFFFFFFFFFull
> 
>  //
>  // Context to save and restore when MTRRs are programmed
> @@ -462,14 +462,15 @@ ProgramFixedMtrr (
>    )
>  {
>    UINT32  MsrNum;
> -  UINT32  ByteShift;
> -  UINT32  OrMask[2];
> -  UINT32  ClearMask[2];
> +  UINT32  LeftByteShift;
> +  UINT32  RightByteShift;
> +  UINT64  OrMask;
> +  UINT64  ClearMask;
>    UINT64  SubLength;
> 
> -  *(UINT64 *)OrMask    = 0;
> -  *(UINT64 *)ClearMask = 0;
> -
> +  //
> +  // Find the fixed MTRR index to be programmed
> +  //
>    for (MsrNum = *LastMsrNum + 1; MsrNum < MTRR_NUMBER_OF_FIXED_MTRR; 
> MsrNum++) {
>      if ((*Base >= mMtrrLibFixedMtrrTable[MsrNum].BaseAddress) &&
>          (*Base <
> @@ -488,36 +489,60 @@ ProgramFixedMtrr (
>    }
> 
>    //
> -  // We found the fixed MTRR to be programmed
> +  // Find the begin offset in fixed MTRR and calculate byte offset of left 
> shift
>    //
> -  ByteShift = ((UINT32)*Base - mMtrrLibFixedMtrrTable[MsrNum].BaseAddress)
> +  LeftByteShift = ((UINT32)*Base - 
> mMtrrLibFixedMtrrTable[MsrNum].BaseAddress)
>                 / mMtrrLibFixedMtrrTable[MsrNum].Length;
> 
> -  if (ByteShift >= 8) {
> +  if (LeftByteShift >= 8) {
>      return RETURN_UNSUPPORTED;
>    }
> 
> -  if (ByteShift < 4) {
> -    OrMask[0]    = OR_SEED * (UINT32)MemoryCacheType;
> -    ClearMask[0] = CLEAR_SEED;
> -    OrMask[1]    = (OR_SEED * (UINT32)MemoryCacheType) >> ((4 - ByteShift) * 
> 8);
> -    ClearMask[1] = CLEAR_SEED >> ((4 - ByteShift) * 8);
> +  //
> +  // Find the end offset in fixed MTRR and calculate byte offset of right 
> shift
> +  //
> +  SubLength = mMtrrLibFixedMtrrTable[MsrNum].Length * (8 - LeftByteShift);
> +  if (*Length >= SubLength) {
> +    RightByteShift = 0;
>    } else {
> -    OrMask[0]    = (OR_SEED * (UINT32)MemoryCacheType) >> ((8 - ByteShift) * 
> 8);
> -    ClearMask[0] = CLEAR_SEED >> ((8 - ByteShift) * 8);
> +    RightByteShift = 8 - LeftByteShift -
> +                (UINT32)(*Length) / mMtrrLibFixedMtrrTable[MsrNum].Length;
> +    if ((LeftByteShift >= 8) ||
> +        (((UINT32)(*Length) % mMtrrLibFixedMtrrTable[MsrNum].Length) != 0)
> +        ) {
> +      return RETURN_UNSUPPORTED;
> +    }
> +    //
> +    // Update SubLength by actual length
> +    //
> +    SubLength = *Length;
>    }
> 
> -  SubLength = mMtrrLibFixedMtrrTable[MsrNum].Length * (8 - ByteShift);
> -  if (*Length < SubLength) {
> -    return RETURN_UNSUPPORTED;
> +  ClearMask = CLEAR_SEED;
> +  OrMask    = MultU64x32 (OR_SEED, (UINT32)MemoryCacheType);
> +
> +  if (LeftByteShift != 0) {
> +    //
> +    // Clear the low bits by LeftByteShift
> +    //
> +    ClearMask &= LShiftU64 (ClearMask, LeftByteShift * 8);
> +    OrMask    &= LShiftU64 (OrMask, LeftByteShift * 8);
> +  }
> +
> +  if (RightByteShift != 0) {
> +    //
> +    // Clear the high bits by RightByteShift
> +    //
> +    ClearMask &= RShiftU64 (ClearMask, RightByteShift * 8);
> +    OrMask    &= RShiftU64 (OrMask, RightByteShift * 8);
>    }
> 
>    *Length -= SubLength;
>    *Base   += SubLength;
> 
>    *LastMsrNum      = MsrNum;
> -  *ReturnClearMask = *(UINT64 *)ClearMask;
> -  *ReturnOrMask    = *(UINT64 *)OrMask;
> +  *ReturnClearMask = ClearMask;
> +  *ReturnOrMask    = OrMask;
> 
>    return RETURN_SUCCESS;
>  }
> --
> 2.7.4.windows.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to