Various IPs on NXP/FSL SoCs having ARM64 cores have big-endian MMIO interfaces.
This implies that a byte-swap operation is needed to read/write such BE MMIO registers from the LE ARM64 cores. This patch adds the support for the same. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Meenakshi Aggarwal <meenakshi.aggar...@nxp.com> Signed-off-by: Bhupesh Sharma <bhupesh.sha...@nxp.com> --- MdePkg/Include/Library/IoLib.h | 364 ++++++++++++++++++++ MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.c | 479 +++++++++++++++++++++++++++ 2 files changed, 843 insertions(+) diff --git a/MdePkg/Include/Library/IoLib.h b/MdePkg/Include/Library/IoLib.h index a0dd16b..f5842e6 100644 --- a/MdePkg/Include/Library/IoLib.h +++ b/MdePkg/Include/Library/IoLib.h @@ -2658,6 +2658,370 @@ MmioWriteBuffer64 ( IN CONST UINT64 *Buffer ); +/** + Reads a 16-bit MMIO register in Big Endian format. + + Reads the 16-bit MMIO register specified by Address. The 16-bit read value is + returned. This function must guarantee that all MMIO read and write + operations are serialized. + + If 16-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT16 +EFIAPI +MmioReadBe16 ( + IN UINTN Address + ); + +/** + Writes a 16-bit MMIO register in Big Endian format. + + Writes the 16-bit MMIO register specified by Address with the value specified + by Value and returns Value. This function must guarantee that all MMIO read + and write operations are serialized. + + If 16-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + +**/ +UINT16 +EFIAPI +MmioWriteBe16 ( + IN UINTN Address, + IN UINT16 Value + ); + +/** + Reads a 32-bit MMIO register in Big Endian format. + + Reads the 32-bit MMIO register specified by Address. The 32-bit read value is + returned. This function must guarantee that all MMIO read and write + operations are serialized. + + If 32-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT32 +EFIAPI +MmioReadBe32 ( + IN UINTN Address + ); + +/** + Writes a 32-bit MMIO register in Big Endian format. + + Writes the 32-bit MMIO register specified by Address with the value specified + by Value and returns Value. This function must guarantee that all MMIO read + and write operations are serialized. + + If 32-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + +**/ +UINT32 +EFIAPI +MmioWriteBe32 ( + IN UINTN Address, + IN UINT32 Value + ); + + +/** + Reads a 64-bit MMIO register in Big Endian format. + + Reads the 64-bit MMIO register specified by Address. The 64-bit read value is + returned. This function must guarantee that all MMIO read and write + operations are serialized. + + If 64-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT64 +EFIAPI +MmioReadBe64 ( + IN UINTN Address + ); + + +/** + Writes a 64-bit MMIO register in Big Endian format. + + Writes the 64-bit MMIO register specified by Address with the value specified + by Value and returns Value. This function must guarantee that all MMIO read + and write operations are serialized. + + If 64-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + +**/ +UINT64 +EFIAPI +MmioWriteBe64 ( + IN UINTN Address, + IN UINT64 Value + ); + +/** + Clear and set a 8-bit MMIO register. + + Mask the 8-bit MMIO register specified by Address with the mask specified + by Mask and then Writes the 8-bit MMIO register specified by Address with + the value specified by Value and returns current value on register. This + function must guarantee that all MMIO read and write operations are serialized. + + @param Address The MMIO register to write. + @param Mask The Mask to clear the MMIO register. + @param Value The value to write to the MMIO register. + +**/ +UINT8 +EFIAPI +MmioClearSet8 ( + IN UINTN Address, + IN UINT8 Mask, + IN UINT8 Value + ); + +/** + Clear and set a 16-bit MMIO register in Big Endian format. + + Mask the 16-bit MMIO register specified by Address with the mask specified + by Mask and then Writes the 16-bit MMIO register specified by Address with + the value specified by Value and returns current value on register. This + function must guarantee that all MMIO read and write operations are serialized. + + If 16-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Mask The Mask to clear the MMIO register. + @param Value The value to write to the MMIO register. + +**/ +UINT16 +EFIAPI +MmioClearSetBe16 ( + IN UINTN Address, + IN UINT16 Mask, + IN UINT16 Value + ); + +/** + Clear and set a 32-bit MMIO register in Big Endian format. + + Mask the 32-bit MMIO register specified by Address with the mask specified + by Mask and then Writes the 32-bit MMIO register specified by Address with + the value specified by Value and returns current value on register. This + function must guarantee that all MMIO read and write operations are serialized. + + + If 32-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Mask The Mask to clear the MMIO register. + @param Value The value to write to the MMIO register. + +**/ +UINT32 +EFIAPI +MmioClearSetBe32 ( + IN UINTN Address, + IN UINT32 Mask, + IN UINT32 Value + ); + +/** + Clear and set a 64-bit MMIO register in Big Endian format. + + Mask the 64-bit MMIO register specified by Address with the mask specified + by Mask and then Writes the 64-bit MMIO register specified by Address with + the value specified by Value and returns current value on register. This + function must guarantee that all MMIO read and write operations are serialized. + + If 64-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Mask The Mask to clear the MMIO register. + @param Value The value to write to the MMIO register. + +**/ +UINT64 +EFIAPI +MmioClearSetBe64 ( + IN UINTN Address, + IN UINT64 Mask, + IN UINT64 Value + ); + +/** + Set a 8-bit MMIO register in Big Endian format. + + Set bits of the 8-bit MMIO register specified by Address with the Bits + specified by Bits and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 8-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Bits The Bits to set in MMIO register. + +**/ +UINT8 +EFIAPI +MmioSetBits8 ( + IN UINTN Address, + IN UINT8 Bits + ); + +/** + Set a 16-bit MMIO register in Big Endian format. + + Set bits of the 16-bit MMIO register specified by Address with the Bits + specified by Bits and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 16-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Bits The Bits to set in MMIO register. + +**/ +UINT16 +EFIAPI +MmioSetBitsBe16 ( + IN UINTN Address, + IN UINT16 Bits + ); + +/** + Set a 32-bit MMIO register in Big Endian format. + + Set bits of the 32-bit MMIO register specified by Address with the Bits + specified by Bits and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 32-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Bits The Bits to set in MMIO register. + +**/ +UINT32 +EFIAPI +MmioSetBitsBe32 ( + IN UINTN Address, + IN UINT32 Bits + ); + +/** + Set a 64-bit MMIO register in Big Endian format. + + Set bits of the 64-bit MMIO register specified by Address with the Bits + specified by Bits and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 64-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Bits The Bits to set in MMIO register. + +**/ +UINT64 +EFIAPI +MmioSetBitsBe64 ( + IN UINTN Address, + IN UINT64 Bits + ); + +/** + Clear bits of the 8-bit MMIO register specified by Address with the Mask + specified by Mask and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 8-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Mask The Bits to clear in MMIO register. + +**/ +UINT8 +EFIAPI +MmioClearBits8 ( + IN UINTN Address, + IN UINT8 Mask + ); + +/** + Clear bits of the 16-bit MMIO register specified by Address with the Mask + specified by Mask and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 16-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Mask The Bits to clear in MMIO register. + +**/ +UINT16 +EFIAPI +MmioClearBitsBe16 ( + IN UINTN Address, + IN UINT16 Mask + ); + +/** + Clear bits of the 32-bit MMIO register specified by Address with the Mask + specified by Mask and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 32-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Mask The Bits to clear in MMIO register. + +**/ +UINT32 +EFIAPI +MmioClearBitsBe32 ( + IN UINTN Address, + IN UINT32 Mask + ); + +/** + Clear bits of the 64-bit MMIO register specified by Address with the Mask + specified by Mask and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 64-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Mask The Bits to clear in MMIO register. + +**/ +UINT64 +EFIAPI +MmioClearBitsBe64 ( + IN UINTN Address, + IN UINT64 Mask + ); #endif diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.c b/MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.c index b9f4c5e..f2179d1 100644 --- a/MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.c +++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.c @@ -19,6 +19,26 @@ // #include "BaseIoLibIntrinsicInternal.h" + +#define Uswap16(X) \ + ((((X) & 0xff00) >> 8) | \ + (((X) & 0x00ff) << 8)) +#define Uswap32(X) \ + ((((X) & 0xff000000) >> 24) | \ + (((X) & 0x00ff0000) >> 8) | \ + (((X) & 0x0000ff00) << 8) | \ + (((X) & 0x000000ff) << 24)) +#define Uswap64(X) \ + ((((X) & 0xff00000000000000) >> 56) | \ + (((X) & 0x00ff000000000000) >> 40) | \ + (((X) & 0x0000ff0000000000) >> 24) | \ + (((X) & 0x000000ff00000000) >> 8) | \ + (((X) & 0x00000000ff000000) << 8) | \ + (((X) & 0x0000000000ff0000) << 24) | \ + (((X) & 0x000000000000ff00) << 40) | \ + (((X) & 0x00000000000000ff) << 56)) + + /** Reads an 8-bit I/O port. @@ -428,3 +448,462 @@ MmioWrite64 ( return Value; } + +/** + Reads a 16-bit MMIO register in Big Endian format. + + Reads the 16-bit MMIO register specified by Address. The 16-bit read value is + returned. This function must guarantee that all MMIO read and write + operations are serialized. + + If 16-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT16 +EFIAPI +MmioReadBe16 ( + IN UINTN Address + ) +{ + UINT16 Value; + + ASSERT ((Address & 1) == 0); + Value = *(volatile UINT16*)Address; + return Uswap16(Value); +} + +/** + Writes a 16-bit MMIO register in Big Endian format. + + Writes the 16-bit MMIO register specified by Address with the value specified + by Value and returns Value. This function must guarantee that all MMIO read + and write operations are serialized. + + If 16-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + +**/ +UINT16 +EFIAPI +MmioWriteBe16 ( + IN UINTN Address, + IN UINT16 Value + ) +{ + ASSERT ((Address & 1) == 0); + *(volatile UINT16*)Address = Uswap16(Value); + return Value; +} + +/** + Reads a 32-bit MMIO register in Big Endian format. + + Reads the 32-bit MMIO register specified by Address. The 32-bit read value is + returned. This function must guarantee that all MMIO read and write + operations are serialized. + + If 32-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT32 +EFIAPI +MmioReadBe32 ( + IN UINTN Address + ) +{ + UINT32 Value; + + ASSERT ((Address & 3) == 0); + Value = *(volatile UINT32*)Address; + return Uswap32(Value); +} + +/** + Writes a 32-bit MMIO register in Big Endian format. + + Writes the 32-bit MMIO register specified by Address with the value specified + by Value and returns Value. This function must guarantee that all MMIO read + and write operations are serialized. + + If 32-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + +**/ +UINT32 +EFIAPI +MmioWriteBe32 ( + IN UINTN Address, + IN UINT32 Value + ) +{ + ASSERT ((Address & 3) == 0); + *(volatile UINT32*)Address = Uswap32(Value); + return Value; +} + +/** + Reads a 64-bit MMIO register in Big Endian format. + + Reads the 64-bit MMIO register specified by Address. The 64-bit read value is + returned. This function must guarantee that all MMIO read and write + operations are serialized. + + If 64-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT64 +EFIAPI +MmioReadBe64 ( + IN UINTN Address + ) +{ + UINT64 Value; + + ASSERT ((Address & 7) == 0); + Value = *(volatile UINT64*)Address; + return Uswap64(Value); +} + +/** + Writes a 64-bit MMIO register in Big Endian format. + + Writes the 64-bit MMIO register specified by Address with the value specified + by Value and returns Value. This function must guarantee that all MMIO read + and write operations are serialized. + + If 64-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + +**/ +UINT64 +EFIAPI +MmioWriteBe64 ( + IN UINTN Address, + IN UINT64 Value + ) +{ + ASSERT ((Address & 7) == 0); + *(volatile UINT64*)Address = Uswap64(Value); + return Value; +} + +/** + Clear and set a 8-bit MMIO register. + + Mask the 8-bit MMIO register specified by Address with the mask specified + by Mask and then Writes the 8-bit MMIO register specified by Address with + the value specified by Value and returns current value on register. This + function must guarantee that all MMIO read and write operations are serialized. + + @param Address The MMIO register to write. + @param Mask The Mask to clear the MMIO register. + @param Value The value to write to the MMIO register. + +**/ +UINT8 +EFIAPI +MmioClearSet8 ( + IN UINTN Address, + IN UINT8 Mask, + IN UINT8 Value + ) +{ + *(volatile UINT8*)Address = (*(volatile UINT8*)Address & ~Mask) | Value; + return *(volatile UINT8*)Address; +} + +/** + Clear and set a 16-bit MMIO register in Big Endian format. + + Mask the 16-bit MMIO register specified by Address with the mask specified + by Mask and then Writes the 16-bit MMIO register specified by Address with + the value specified by Value and returns current value on register. This + function must guarantee that all MMIO read and write operations are serialized. + + If 16-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Mask The Mask to clear the MMIO register. + @param Value The value to write to the MMIO register. + +**/ +UINT16 +EFIAPI +MmioClearSetBe16 ( + IN UINTN Address, + IN UINT16 Mask, + IN UINT16 Value + ) +{ + ASSERT ((Address & 1) == 0); + *(volatile UINT16*)Address = (*(volatile UINT16*)Address & Uswap16(~Mask)) + | Uswap16(Value); + return *(volatile UINT16*)Address; +} + +/** + Clear and set a 32-bit MMIO register in Big Endian format. + + Mask the 32-bit MMIO register specified by Address with the mask specified + by Mask and then Writes the 32-bit MMIO register specified by Address with + the value specified by Value and returns current value on register. This + function must guarantee that all MMIO read and write operations are serialized. + + + If 32-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Mask The Mask to clear the MMIO register. + @param Value The value to write to the MMIO register. + +**/ +UINT32 +EFIAPI +MmioClearSetBe32 ( + IN UINTN Address, + IN UINT32 Mask, + IN UINT32 Value + ) +{ + ASSERT ((Address & 3) == 0); + *(volatile UINT32*)Address = (*(volatile UINT32*)Address & Uswap32(~Mask)) + | Uswap32(Value); + return *(volatile UINT32*)Address; +} + +/** + Clear and set a 64-bit MMIO register in Big Endian format. + + Mask the 64-bit MMIO register specified by Address with the mask specified + by Mask and then Writes the 64-bit MMIO register specified by Address with + the value specified by Value and returns current value on register. This + function must guarantee that all MMIO read and write operations are serialized. + + If 64-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Mask The Mask to clear the MMIO register. + @param Value The value to write to the MMIO register. + +**/ +UINT64 +EFIAPI +MmioClearSetBe64 ( + IN UINTN Address, + IN UINT64 Mask, + IN UINT64 Value + ) +{ + ASSERT ((Address & 7) == 0); + *(volatile UINT64*)Address = (*(volatile UINT64*)Address & Uswap64(~Mask)) + | Uswap64(Value); + return *(volatile UINT64*)Address; +} + +/** + Set a 8-bit MMIO register in Big Endian format. + + Set bits of the 8-bit MMIO register specified by Address with the Bits + specified by Bits and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 8-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Bits The Bits to set in MMIO register. + +**/ +UINT8 +EFIAPI +MmioSetBits8 ( + IN UINTN Address, + IN UINT8 Bits + ) +{ + *(volatile UINT8*)Address = *(volatile UINT8*)Address | Bits; + return *(volatile UINT8*)Address; +} + +/** + Set a 16-bit MMIO register in Big Endian format. + + Set bits of the 16-bit MMIO register specified by Address with the Bits + specified by Bits and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 16-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Bits The Bits to set in MMIO register. + +**/ +UINT16 +EFIAPI +MmioSetBitsBe16 ( + IN UINTN Address, + IN UINT16 Bits + ) +{ + ASSERT ((Address & 1) == 0); + *(volatile UINT16*)Address = *(volatile UINT16*)Address | Uswap16(Bits); + return *(volatile UINT16*)Address; +} + +/** + Set a 32-bit MMIO register in Big Endian format. + + Set bits of the 32-bit MMIO register specified by Address with the Bits + specified by Bits and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 32-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Bits The Bits to set in MMIO register. + +**/ +UINT32 +EFIAPI +MmioSetBitsBe32 ( + IN UINTN Address, + IN UINT32 Bits + ) +{ + ASSERT ((Address & 3) == 0); + *(volatile UINT32*)Address = *(volatile UINT32*)Address | Uswap32(Bits); + return *(volatile UINT32*)Address; +} + +/** + Set a 64-bit MMIO register in Big Endian format. + + Set bits of the 64-bit MMIO register specified by Address with the Bits + specified by Bits and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 64-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Bits The Bits to set in MMIO register. + +**/ +UINT64 +EFIAPI +MmioSetBitsBe64 ( + IN UINTN Address, + IN UINT64 Bits + ) +{ + ASSERT ((Address & 7) == 0); + *(volatile UINT64*)Address = *(volatile UINT64*)Address | Uswap64(Bits); + return *(volatile UINT64*)Address; +} + +/** + Clear bits of the 8-bit MMIO register specified by Address with the Mask + specified by Mask and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 8-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Mask The Bits to clear in MMIO register. + +**/ +UINT8 +EFIAPI +MmioClearBits8 ( + IN UINTN Address, + IN UINT8 Mask + ) +{ + *(volatile UINT8*)Address = *(volatile UINT8*)Address & (~Mask); + return *(volatile UINT8*)Address; +} + +/** + Clear bits of the 16-bit MMIO register specified by Address with the Mask + specified by Mask and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 16-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Mask The Bits to clear in MMIO register. + +**/ +UINT16 +EFIAPI +MmioClearBitsBe16 ( + IN UINTN Address, + IN UINT16 Mask + ) +{ + ASSERT ((Address & 1) == 0); + *(volatile UINT16*)Address = *(volatile UINT16*)Address & Uswap16(~Mask); + return *(volatile UINT16*)Address; +} + +/** + Clear bits of the 32-bit MMIO register specified by Address with the Mask + specified by Mask and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 32-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Mask The Bits to clear in MMIO register. + +**/ +UINT32 +EFIAPI +MmioClearBitsBe32 ( + IN UINTN Address, + IN UINT32 Mask + ) +{ + ASSERT ((Address & 3) == 0); + *(volatile UINT32*)Address = *(volatile UINT32*)Address & Uswap32(~Mask); + return *(volatile UINT32*)Address; +} + +/** + Clear bits of the 64-bit MMIO register specified by Address with the Mask + specified by Mask and returns register content. This function must + guarantee that all MMIO read and write operations are serialized. + + If 64-bit MMIO register operations are not supported, then ASSERT(). + + @param Address The MMIO register to write. + @param Mask The Bits to clear in MMIO register. + +**/ +UINT64 +EFIAPI +MmioClearBitsBe64 ( + IN UINTN Address, + IN UINT64 Mask + ) +{ + ASSERT ((Address & 7) == 0); + *(volatile UINT64*)Address = *(volatile UINT64*)Address & Uswap64(~Mask); + return *(volatile UINT64*)Address; +} -- 1.9.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel