summaryrefslogtreecommitdiff
path: root/Silicon/Intel/PurleyRcPkg/Library/UsraAccessLib/UsraAccessLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'Silicon/Intel/PurleyRcPkg/Library/UsraAccessLib/UsraAccessLib.c')
-rw-r--r--Silicon/Intel/PurleyRcPkg/Library/UsraAccessLib/UsraAccessLib.c241
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);
+};