mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-03 07:25:03 +00:00 
			
		
		
		
	Signed-off-by: Liming Gao <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14497 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			923 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			923 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Bit field functions of BaseLib.
 | 
						|
 | 
						|
  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
 | 
						|
  This program and the accompanying materials
 | 
						|
  are licensed and made available under the terms and conditions of the BSD License
 | 
						|
  which accompanies this distribution.  The full text of the license may be found at
 | 
						|
  http://opensource.org/licenses/bsd-license.php.
 | 
						|
 | 
						|
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "BaseLibInternals.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Worker function that returns a bit field from Operand.
 | 
						|
 | 
						|
  Returns the bitfield specified by the StartBit and the EndBit from Operand.
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
 | 
						|
  @return The bit field read.
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
EFIAPI
 | 
						|
InternalBaseLibBitFieldReadUint (
 | 
						|
  IN      UINTN                     Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]
 | 
						|
  // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.
 | 
						|
  //
 | 
						|
  return (Operand & ~((UINTN)-2 << EndBit)) >> StartBit;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Worker function that reads a bit field from Operand, performs a bitwise OR,
 | 
						|
  and returns the result.
 | 
						|
 | 
						|
  Performs a bitwise OR between the bit field specified by StartBit and EndBit
 | 
						|
  in Operand and the value specified by AndData. All other bits in Operand are
 | 
						|
  preserved. The new value is returned.
 | 
						|
 | 
						|
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
  @param  OrData    The value to OR with the read value from the value.
 | 
						|
 | 
						|
  @return The new value.
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
EFIAPI
 | 
						|
InternalBaseLibBitFieldOrUint (
 | 
						|
  IN      UINTN                     Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINTN                     OrData
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // Higher bits in OrData those are not used must be zero. 
 | 
						|
  //
 | 
						|
  // EndBit - StartBit + 1 might be 32 while the result right shifting 32 on a 32bit integer is undefined,
 | 
						|
  // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
 | 
						|
  //
 | 
						|
  ASSERT ((OrData >> (EndBit - StartBit)) == ((OrData >> (EndBit - StartBit)) & 1));
 | 
						|
  
 | 
						|
  //
 | 
						|
  // ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]
 | 
						|
  // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.
 | 
						|
  //
 | 
						|
  return Operand | ((OrData << StartBit) & ~((UINTN) -2 << EndBit));
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Worker function that reads a bit field from Operand, performs a bitwise AND,
 | 
						|
  and returns the result.
 | 
						|
 | 
						|
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
 | 
						|
  in Operand and the value specified by AndData. All other bits in Operand are
 | 
						|
  preserved. The new value is returned.
 | 
						|
 | 
						|
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
  @param  AndData    The value to And with the read value from the value.
 | 
						|
 | 
						|
  @return The new value.
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
EFIAPI
 | 
						|
InternalBaseLibBitFieldAndUint (
 | 
						|
  IN      UINTN                     Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINTN                     AndData
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // Higher bits in AndData those are not used must be zero. 
 | 
						|
  //
 | 
						|
  // EndBit - StartBit + 1 might be 32 while the result right shifting 32 on a 32bit integer is undefined,
 | 
						|
  // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
 | 
						|
  //
 | 
						|
  ASSERT ((AndData >> (EndBit - StartBit)) == ((AndData >> (EndBit - StartBit)) & 1));
 | 
						|
 | 
						|
  //
 | 
						|
  // ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]
 | 
						|
  // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.
 | 
						|
  //
 | 
						|
  return Operand & ~((~AndData << StartBit) & ~((UINTN)-2 << EndBit));
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Returns a bit field from an 8-bit value.
 | 
						|
 | 
						|
  Returns the bitfield specified by the StartBit and the EndBit from Operand.
 | 
						|
 | 
						|
  If 8-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 7, then ASSERT().
 | 
						|
  If EndBit is greater than 7, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..7.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..7.
 | 
						|
 | 
						|
  @return The bit field read.
 | 
						|
 | 
						|
**/
 | 
						|
UINT8
 | 
						|
EFIAPI
 | 
						|
BitFieldRead8 (
 | 
						|
  IN      UINT8                     Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 8);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return (UINT8)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Writes a bit field to an 8-bit value, and returns the result.
 | 
						|
 | 
						|
  Writes Value to the bit field specified by the StartBit and the EndBit in
 | 
						|
  Operand. All other bits in Operand are preserved. The new 8-bit value is
 | 
						|
  returned.
 | 
						|
 | 
						|
  If 8-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 7, then ASSERT().
 | 
						|
  If EndBit is greater than 7, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..7.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..7.
 | 
						|
  @param  Value     The new value of the bit field.
 | 
						|
 | 
						|
  @return The new 8-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT8
 | 
						|
EFIAPI
 | 
						|
BitFieldWrite8 (
 | 
						|
  IN      UINT8                     Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT8                     Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 8);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return BitFieldAndThenOr8 (Operand, StartBit, EndBit, 0, Value);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Reads a bit field from an 8-bit value, performs a bitwise OR, and returns the
 | 
						|
  result.
 | 
						|
 | 
						|
  Performs a bitwise OR between the bit field specified by StartBit
 | 
						|
  and EndBit in Operand and the value specified by OrData. All other bits in
 | 
						|
  Operand are preserved. The new 8-bit value is returned.
 | 
						|
 | 
						|
  If 8-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 7, then ASSERT().
 | 
						|
  If EndBit is greater than 7, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..7.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..7.
 | 
						|
  @param  OrData    The value to OR with the read value from the value.
 | 
						|
 | 
						|
  @return The new 8-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT8
 | 
						|
EFIAPI
 | 
						|
BitFieldOr8 (
 | 
						|
  IN      UINT8                     Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT8                     OrData
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 8);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return (UINT8)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Reads a bit field from an 8-bit value, performs a bitwise AND, and returns
 | 
						|
  the result.
 | 
						|
 | 
						|
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
 | 
						|
  in Operand and the value specified by AndData. All other bits in Operand are
 | 
						|
  preserved. The new 8-bit value is returned.
 | 
						|
 | 
						|
  If 8-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 7, then ASSERT().
 | 
						|
  If EndBit is greater than 7, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..7.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..7.
 | 
						|
  @param  AndData   The value to AND with the read value from the value.
 | 
						|
 | 
						|
  @return The new 8-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT8
 | 
						|
EFIAPI
 | 
						|
BitFieldAnd8 (
 | 
						|
  IN      UINT8                     Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT8                     AndData
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 8);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return (UINT8)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Reads a bit field from an 8-bit value, performs a bitwise AND followed by a
 | 
						|
  bitwise OR, and returns the result.
 | 
						|
 | 
						|
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
 | 
						|
  in Operand and the value specified by AndData, followed by a bitwise 
 | 
						|
  OR with value specified by OrData. All other bits in Operand are
 | 
						|
  preserved. The new 8-bit value is returned.
 | 
						|
 | 
						|
  If 8-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 7, then ASSERT().
 | 
						|
  If EndBit is greater than 7, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..7.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..7.
 | 
						|
  @param  AndData   The value to AND with the read value from the value.
 | 
						|
  @param  OrData    The value to OR with the result of the AND operation.
 | 
						|
 | 
						|
  @return The new 8-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT8
 | 
						|
EFIAPI
 | 
						|
BitFieldAndThenOr8 (
 | 
						|
  IN      UINT8                     Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT8                     AndData,
 | 
						|
  IN      UINT8                     OrData
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 8);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return BitFieldOr8 (
 | 
						|
           BitFieldAnd8 (Operand, StartBit, EndBit, AndData),
 | 
						|
           StartBit,
 | 
						|
           EndBit,
 | 
						|
           OrData
 | 
						|
           );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Returns a bit field from a 16-bit value.
 | 
						|
 | 
						|
  Returns the bitfield specified by the StartBit and the EndBit from Operand.
 | 
						|
 | 
						|
  If 16-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 15, then ASSERT().
 | 
						|
  If EndBit is greater than 15, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..15.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..15.
 | 
						|
 | 
						|
  @return The bit field read.
 | 
						|
 | 
						|
**/
 | 
						|
UINT16
 | 
						|
EFIAPI
 | 
						|
BitFieldRead16 (
 | 
						|
  IN      UINT16                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 16);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return (UINT16)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Writes a bit field to a 16-bit value, and returns the result.
 | 
						|
 | 
						|
  Writes Value to the bit field specified by the StartBit and the EndBit in
 | 
						|
  Operand. All other bits in Operand are preserved. The new 16-bit value is
 | 
						|
  returned.
 | 
						|
 | 
						|
  If 16-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 15, then ASSERT().
 | 
						|
  If EndBit is greater than 15, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..15.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..15.
 | 
						|
  @param  Value     The new value of the bit field.
 | 
						|
 | 
						|
  @return The new 16-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT16
 | 
						|
EFIAPI
 | 
						|
BitFieldWrite16 (
 | 
						|
  IN      UINT16                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT16                    Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 16);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return BitFieldAndThenOr16 (Operand, StartBit, EndBit, 0, Value);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Reads a bit field from a 16-bit value, performs a bitwise OR, and returns the
 | 
						|
  result.
 | 
						|
 | 
						|
  Performs a bitwise OR between the bit field specified by StartBit
 | 
						|
  and EndBit in Operand and the value specified by OrData. All other bits in
 | 
						|
  Operand are preserved. The new 16-bit value is returned.
 | 
						|
 | 
						|
  If 16-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 15, then ASSERT().
 | 
						|
  If EndBit is greater than 15, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..15.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..15.
 | 
						|
  @param  OrData    The value to OR with the read value from the value.
 | 
						|
 | 
						|
  @return The new 16-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT16
 | 
						|
EFIAPI
 | 
						|
BitFieldOr16 (
 | 
						|
  IN      UINT16                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT16                    OrData
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 16);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return (UINT16)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Reads a bit field from a 16-bit value, performs a bitwise AND, and returns
 | 
						|
  the result.
 | 
						|
 | 
						|
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
 | 
						|
  in Operand and the value specified by AndData. All other bits in Operand are
 | 
						|
  preserved. The new 16-bit value is returned.
 | 
						|
 | 
						|
  If 16-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 15, then ASSERT().
 | 
						|
  If EndBit is greater than 15, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..15.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..15.
 | 
						|
  @param  AndData   The value to AND with the read value from the value.
 | 
						|
 | 
						|
  @return The new 16-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT16
 | 
						|
EFIAPI
 | 
						|
BitFieldAnd16 (
 | 
						|
  IN      UINT16                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT16                    AndData
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 16);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return (UINT16)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Reads a bit field from a 16-bit value, performs a bitwise AND followed by a
 | 
						|
  bitwise OR, and returns the result.
 | 
						|
 | 
						|
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
 | 
						|
  in Operand and the value specified by AndData, followed by a bitwise 
 | 
						|
  OR with value specified by OrData. All other bits in Operand are
 | 
						|
  preserved. The new 16-bit value is returned.
 | 
						|
 | 
						|
  If 16-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 15, then ASSERT().
 | 
						|
  If EndBit is greater than 15, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..15.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..15.
 | 
						|
  @param  AndData   The value to AND with the read value from the value.
 | 
						|
  @param  OrData    The value to OR with the result of the AND operation.
 | 
						|
 | 
						|
  @return The new 16-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT16
 | 
						|
EFIAPI
 | 
						|
BitFieldAndThenOr16 (
 | 
						|
  IN      UINT16                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT16                    AndData,
 | 
						|
  IN      UINT16                    OrData
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 16);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return BitFieldOr16 (
 | 
						|
           BitFieldAnd16 (Operand, StartBit, EndBit, AndData),
 | 
						|
           StartBit,
 | 
						|
           EndBit,
 | 
						|
           OrData
 | 
						|
           );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Returns a bit field from a 32-bit value.
 | 
						|
 | 
						|
  Returns the bitfield specified by the StartBit and the EndBit from Operand.
 | 
						|
 | 
						|
  If 32-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 31, then ASSERT().
 | 
						|
  If EndBit is greater than 31, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..31.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..31.
 | 
						|
 | 
						|
  @return The bit field read.
 | 
						|
 | 
						|
**/
 | 
						|
UINT32
 | 
						|
EFIAPI
 | 
						|
BitFieldRead32 (
 | 
						|
  IN      UINT32                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 32);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return (UINT32)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Writes a bit field to a 32-bit value, and returns the result.
 | 
						|
 | 
						|
  Writes Value to the bit field specified by the StartBit and the EndBit in
 | 
						|
  Operand. All other bits in Operand are preserved. The new 32-bit value is
 | 
						|
  returned.
 | 
						|
 | 
						|
  If 32-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 31, then ASSERT().
 | 
						|
  If EndBit is greater than 31, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..31.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..31.
 | 
						|
  @param  Value     The new value of the bit field.
 | 
						|
 | 
						|
  @return The new 32-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT32
 | 
						|
EFIAPI
 | 
						|
BitFieldWrite32 (
 | 
						|
  IN      UINT32                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT32                    Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 32);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return BitFieldAndThenOr32 (Operand, StartBit, EndBit, 0, Value);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Reads a bit field from a 32-bit value, performs a bitwise OR, and returns the
 | 
						|
  result.
 | 
						|
 | 
						|
  Performs a bitwise OR between the bit field specified by StartBit
 | 
						|
  and EndBit in Operand and the value specified by OrData. All other bits in
 | 
						|
  Operand are preserved. The new 32-bit value is returned.
 | 
						|
 | 
						|
  If 32-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 31, then ASSERT().
 | 
						|
  If EndBit is greater than 31, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..31.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..31.
 | 
						|
  @param  OrData    The value to OR with the read value from the value.
 | 
						|
 | 
						|
  @return The new 32-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT32
 | 
						|
EFIAPI
 | 
						|
BitFieldOr32 (
 | 
						|
  IN      UINT32                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT32                    OrData
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 32);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return (UINT32)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Reads a bit field from a 32-bit value, performs a bitwise AND, and returns
 | 
						|
  the result.
 | 
						|
 | 
						|
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
 | 
						|
  in Operand and the value specified by AndData. All other bits in Operand are
 | 
						|
  preserved. The new 32-bit value is returned.
 | 
						|
 | 
						|
  If 32-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 31, then ASSERT().
 | 
						|
  If EndBit is greater than 31, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..31.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..31.
 | 
						|
  @param  AndData   The value to AND with the read value from the value.
 | 
						|
 | 
						|
  @return The new 32-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT32
 | 
						|
EFIAPI
 | 
						|
BitFieldAnd32 (
 | 
						|
  IN      UINT32                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT32                    AndData
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 32);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return (UINT32)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Reads a bit field from a 32-bit value, performs a bitwise AND followed by a
 | 
						|
  bitwise OR, and returns the result.
 | 
						|
 | 
						|
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
 | 
						|
  in Operand and the value specified by AndData, followed by a bitwise 
 | 
						|
  OR with value specified by OrData. All other bits in Operand are
 | 
						|
  preserved. The new 32-bit value is returned.
 | 
						|
 | 
						|
  If 32-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 31, then ASSERT().
 | 
						|
  If EndBit is greater than 31, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..31.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..31.
 | 
						|
  @param  AndData   The value to AND with the read value from the value.
 | 
						|
  @param  OrData    The value to OR with the result of the AND operation.
 | 
						|
 | 
						|
  @return The new 32-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT32
 | 
						|
EFIAPI
 | 
						|
BitFieldAndThenOr32 (
 | 
						|
  IN      UINT32                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT32                    AndData,
 | 
						|
  IN      UINT32                    OrData
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 32);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return BitFieldOr32 (
 | 
						|
           BitFieldAnd32 (Operand, StartBit, EndBit, AndData),
 | 
						|
           StartBit,
 | 
						|
           EndBit,
 | 
						|
           OrData
 | 
						|
           );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Returns a bit field from a 64-bit value.
 | 
						|
 | 
						|
  Returns the bitfield specified by the StartBit and the EndBit from Operand.
 | 
						|
 | 
						|
  If 64-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 63, then ASSERT().
 | 
						|
  If EndBit is greater than 63, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..63.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..63.
 | 
						|
 | 
						|
  @return The bit field read.
 | 
						|
 | 
						|
**/
 | 
						|
UINT64
 | 
						|
EFIAPI
 | 
						|
BitFieldRead64 (
 | 
						|
  IN      UINT64                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 64);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return RShiftU64 (Operand & ~LShiftU64 ((UINT64)-2, EndBit), StartBit);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Writes a bit field to a 64-bit value, and returns the result.
 | 
						|
 | 
						|
  Writes Value to the bit field specified by the StartBit and the EndBit in
 | 
						|
  Operand. All other bits in Operand are preserved. The new 64-bit value is
 | 
						|
  returned.
 | 
						|
 | 
						|
  If 64-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 63, then ASSERT().
 | 
						|
  If EndBit is greater than 63, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..63.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..63.
 | 
						|
  @param  Value     The new value of the bit field.
 | 
						|
 | 
						|
  @return The new 64-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT64
 | 
						|
EFIAPI
 | 
						|
BitFieldWrite64 (
 | 
						|
  IN      UINT64                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT64                    Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 64);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return BitFieldAndThenOr64 (Operand, StartBit, EndBit, 0, Value);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Reads a bit field from a 64-bit value, performs a bitwise OR, and returns the
 | 
						|
  result.
 | 
						|
 | 
						|
  Performs a bitwise OR between the bit field specified by StartBit
 | 
						|
  and EndBit in Operand and the value specified by OrData. All other bits in
 | 
						|
  Operand are preserved. The new 64-bit value is returned.
 | 
						|
 | 
						|
  If 64-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 63, then ASSERT().
 | 
						|
  If EndBit is greater than 63, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..63.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..63.
 | 
						|
  @param  OrData    The value to OR with the read value from the value
 | 
						|
 | 
						|
  @return The new 64-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT64
 | 
						|
EFIAPI
 | 
						|
BitFieldOr64 (
 | 
						|
  IN      UINT64                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT64                    OrData
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT64  Value1;
 | 
						|
  UINT64  Value2;
 | 
						|
 | 
						|
  ASSERT (EndBit < 64);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  //
 | 
						|
  // Higher bits in OrData those are not used must be zero. 
 | 
						|
  //
 | 
						|
  // EndBit - StartBit + 1 might be 64 while the result right shifting 64 on RShiftU64() API is invalid,
 | 
						|
  // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
 | 
						|
  //
 | 
						|
  ASSERT (RShiftU64 (OrData, EndBit - StartBit) == (RShiftU64 (OrData, EndBit - StartBit) & 1));
 | 
						|
 | 
						|
  Value1 = LShiftU64 (OrData, StartBit);
 | 
						|
  Value2 = LShiftU64 ((UINT64) - 2, EndBit);
 | 
						|
 | 
						|
  return Operand | (Value1 & ~Value2);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Reads a bit field from a 64-bit value, performs a bitwise AND, and returns
 | 
						|
  the result.
 | 
						|
 | 
						|
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
 | 
						|
  in Operand and the value specified by AndData. All other bits in Operand are
 | 
						|
  preserved. The new 64-bit value is returned.
 | 
						|
 | 
						|
  If 64-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 63, then ASSERT().
 | 
						|
  If EndBit is greater than 63, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..63.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..63.
 | 
						|
  @param  AndData   The value to AND with the read value from the value.
 | 
						|
 | 
						|
  @return The new 64-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT64
 | 
						|
EFIAPI
 | 
						|
BitFieldAnd64 (
 | 
						|
  IN      UINT64                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT64                    AndData
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT64  Value1;
 | 
						|
  UINT64  Value2;
 | 
						|
  
 | 
						|
  ASSERT (EndBit < 64);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  //
 | 
						|
  // Higher bits in AndData those are not used must be zero. 
 | 
						|
  //
 | 
						|
  // EndBit - StartBit + 1 might be 64 while the right shifting 64 on RShiftU64() API is invalid,
 | 
						|
  // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
 | 
						|
  //
 | 
						|
  ASSERT (RShiftU64 (AndData, EndBit - StartBit) == (RShiftU64 (AndData, EndBit - StartBit) & 1));
 | 
						|
 | 
						|
  Value1 = LShiftU64 (~AndData, StartBit);
 | 
						|
  Value2 = LShiftU64 ((UINT64)-2, EndBit);
 | 
						|
 | 
						|
  return Operand & ~(Value1 & ~Value2);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Reads a bit field from a 64-bit value, performs a bitwise AND followed by a
 | 
						|
  bitwise OR, and returns the result.
 | 
						|
 | 
						|
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
 | 
						|
  in Operand and the value specified by AndData, followed by a bitwise 
 | 
						|
  OR with value specified by OrData. All other bits in Operand are
 | 
						|
  preserved. The new 64-bit value is returned.
 | 
						|
 | 
						|
  If 64-bit operations are not supported, then ASSERT().
 | 
						|
  If StartBit is greater than 63, then ASSERT().
 | 
						|
  If EndBit is greater than 63, then ASSERT().
 | 
						|
  If EndBit is less than StartBit, then ASSERT().
 | 
						|
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
 | 
						|
 | 
						|
  @param  Operand   Operand on which to perform the bitfield operation.
 | 
						|
  @param  StartBit  The ordinal of the least significant bit in the bit field.
 | 
						|
                    Range 0..63.
 | 
						|
  @param  EndBit    The ordinal of the most significant bit in the bit field.
 | 
						|
                    Range 0..63.
 | 
						|
  @param  AndData   The value to AND with the read value from the value.
 | 
						|
  @param  OrData    The value to OR with the result of the AND operation.
 | 
						|
 | 
						|
  @return The new 64-bit value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT64
 | 
						|
EFIAPI
 | 
						|
BitFieldAndThenOr64 (
 | 
						|
  IN      UINT64                    Operand,
 | 
						|
  IN      UINTN                     StartBit,
 | 
						|
  IN      UINTN                     EndBit,
 | 
						|
  IN      UINT64                    AndData,
 | 
						|
  IN      UINT64                    OrData
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (EndBit < 64);
 | 
						|
  ASSERT (StartBit <= EndBit);
 | 
						|
  return BitFieldOr64 (
 | 
						|
           BitFieldAnd64 (Operand, StartBit, EndBit, AndData),
 | 
						|
           StartBit,
 | 
						|
           EndBit,
 | 
						|
           OrData
 | 
						|
           );
 | 
						|
}
 |