diff options
Diffstat (limited to 'Silicon/Intel/PurleyRcPkg/Library/UsraAccessLib/UsraAccessLib.c')
-rw-r--r-- | Silicon/Intel/PurleyRcPkg/Library/UsraAccessLib/UsraAccessLib.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/Silicon/Intel/PurleyRcPkg/Library/UsraAccessLib/UsraAccessLib.c b/Silicon/Intel/PurleyRcPkg/Library/UsraAccessLib/UsraAccessLib.c new file mode 100644 index 0000000000..d01d69192f --- /dev/null +++ b/Silicon/Intel/PurleyRcPkg/Library/UsraAccessLib/UsraAccessLib.c @@ -0,0 +1,241 @@ +/** @file + +Copyright (c) 2018, 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 that 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 "UsraAccessLib.h" + +GET_ALLIGNED_ACCESS_ADDRESS mAccessAddrPtr[] = +{ + &GetPcieAccessAddress, // AddrTypePCIE + &GetPcieAccessAddress, // AddrTypePCIEBLK + &GetCsrAccessAddress, // AddrTypeCSR +}; + +REGISTER_READ mRegisterReadPtr[] = +{ + &PcieRegisterRead, // AddrTypePCIE + &PcieBlkRegisterRead, // AddrTypePCIEBLK + &CsrRegisterRead, // AddrTypeCSR +}; + +REGISTER_WRITE mRegisterWritePtr[] = +{ + &PcieRegisterWrite, // AddrTypePCIE + &PcieBlkRegisterWrite, // AddrTypePCIEBLK + &CsrRegisterWrite, // AddrTypeCSR +}; + +REGISTER_MODIFY mRegisterModifyPtr[] = +{ + &PcieRegisterModify, // AddrTypePCIE + &PcieRegisterModify, // AddrTypePCIEBLK + &CsrRegisterModify, // AddrTypeCSR +}; + +/** + Perform MMIO read + + @param[in] AccessWidth Access Width + @param[in] AlignedAddress An address to be read out + @param[in] Buffer A pointer of buffer contains the data to be read out + + @retval RETURN_SUCCESS The function completed successfully. +**/ +RETURN_STATUS +UsraRegAlignedRead ( + IN UINT32 AccessWidth, + IN UINTN AlignedAddress, + OUT VOID *Buffer + ) +{ + switch (AccessWidth) + { + case UsraWidth8: + *((UINT8*)Buffer) = MmioRead8 (AlignedAddress); + break; + case UsraWidth16: + *((UINT16*)Buffer) = MmioRead16 (AlignedAddress); + break; + case UsraWidth32: + *((UINT32*)Buffer) = MmioRead32 (AlignedAddress); + break; + default: + *((UINT64*)Buffer) = MmioRead64 (AlignedAddress); + break; + } + + return RETURN_SUCCESS; +}; + +/** + Perform MMIO write + + @param[in] AccessWidth Access Width + @param[in] AlignedAddress An address to be written + @param[in] Buffer A pointer of buffer contains the data to be written + + @retval RETURN_SUCCESS The function completed successfully. +**/ +RETURN_STATUS +UsraRegAlignedWrite ( + IN UINT32 AccessWidth, + IN UINTN AlignedAddress, + OUT VOID *Buffer + ) +{ + switch (AccessWidth) + { + case UsraWidth8: + MmioWrite8 (AlignedAddress,*((UINT8*)Buffer)); + break; + case UsraWidth16: + MmioWrite16 (AlignedAddress,*((UINT16*)Buffer)); + break; + case UsraWidth32: + MmioWrite32 (AlignedAddress,*((UINT32*)Buffer)); + break; + default: + MmioWrite64 (AlignedAddress, *((UINT64*)Buffer)); + break; + } + return RETURN_SUCCESS; +} + +/** + Perform AND then OR operations for a input data + + @param[in out] Data A pointer of the address of the register to be modified + @param[in] AndBuffer A pointer of buffer for the value used for AND operation + A NULL pointer means no AND operation. RegisterModify() equivalents to RegisterOr() + @param[in] OrBuffer A pointer of buffer for the value used for OR operation + A NULL pointer means no OR operation. RegisterModify() equivalents to RegisterAnd() + @param[in] NumOfByte NumOfByte Count of byte data to be performed + + @retval NONE +**/ +VOID +DataAndOr ( + IN UINT64 *Data, + IN VOID *AndBuffer, + IN VOID *OrBuffer, + IN UINT8 NumOfByte +) +{ + union{ + UINT64 QW; + UINT8 Byte[8]; + } Buffer; + UINT8 AndData[8], OrData[8], i; + + Buffer.QW = *Data; + for(i=0;i<NumOfByte;i++) + { + if (AndBuffer == NULL) + ((UINT8*)AndData)[i] = 0xff; + else + AndData[i] = ((UINT8*)AndBuffer)[i]; + if (OrBuffer == NULL) + ((UINT8*)OrData)[i] = 0; + else + OrData[i] = ((UINT8*)OrBuffer)[i]; + Buffer.Byte[i] = (Buffer.Byte[i] & AndData[i]) | OrData[i]; + } + + *Data = Buffer.QW; +} + +////////////////////////////////////////////////////////////////////////// +// +// USRA Hardware Access Library +// +////////////////////////////////////////////////////////////////////////// + +/** + This API gets the flat address from the given USRA Address. + + @param[in] Address A pointer of the address of the USRA Address Structure to be read out + + @retval The flat address +**/ +INTN +EFIAPI +GetRegisterAddress ( + IN USRA_ADDRESS *Address + ) +{ + UINTN AlignedAddress; + + mAccessAddrPtr[Address->Attribute.AddrType] (NULL, 0, Address, &AlignedAddress); + + return AlignedAddress; +}; + +/** + This API performs 8-bit, 16-bit, 32-bit or 64-bit silicon register read operations. + It transfers data from a register into a naturally aligned data buffer. + + @param[in] Address A pointer of the address of the USRA Address Structure to be read out + @param[in] Buffer A pointer of buffer for the value read from the register + + @retval RETURN_SUCCESS The function completed successfully. +**/ +RETURN_STATUS +EFIAPI +RegisterRead ( + IN USRA_ADDRESS *Address, + IN VOID *Buffer + ) +{ + return mRegisterReadPtr[Address->Attribute.AddrType] (Address, Buffer); +}; + +/** + This API performs 8-bit, 16-bit, 32-bit or 64-bit silicon register write operations. + It transfers data from a naturally aligned data buffer into a silicon register. + + @param[in] Address A pointer of the address of the USRA Address Structure to be written + @param[in] Buffer A pointer of buffer for the value write to the register + + @retval RETURN_SUCCESS The function completed successfully. +**/ +RETURN_STATUS +EFIAPI +RegisterWrite ( + IN USRA_ADDRESS *Address, + OUT VOID *Buffer + ) +{ + return mRegisterWritePtr[Address->Attribute.AddrType] (Address, Buffer); +}; + +/** + This API performs 8-bit, 16-bit, 32-bit or 64-bit silicon register AND then OR operations. It read data from a + register, And it with the AndBuffer, then Or it with the OrBuffer, and write the result back to the register + + @param[in] Address A pointer of the address of the silicon register to be written + @param[in] AndBuffer A pointer of buffer for the value used for AND operation + A NULL pointer means no AND operation. RegisterModify() equivalents to RegisterOr() + @param[in] OrBuffer A pointer of buffer for the value used for OR operation + A NULL pointer means no OR operation. RegisterModify() equivalents to RegisterAnd() + + @retval RETURN_SUCCESS The function completed successfully. +**/ +RETURN_STATUS +EFIAPI +RegisterModify ( + IN USRA_ADDRESS *Address, + IN VOID *AndBuffer, + IN VOID *OrBuffer + ) +{ + return mRegisterModifyPtr[Address->Attribute.AddrType] (Address, AndBuffer, OrBuffer); +}; |