aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbUraLibV1/GnbUraLibV1.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbUraLibV1/GnbUraLibV1.c')
-rw-r--r--src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbUraLibV1/GnbUraLibV1.c388
1 files changed, 388 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbUraLibV1/GnbUraLibV1.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbUraLibV1/GnbUraLibV1.c
new file mode 100644
index 0000000000..7156f7e52d
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbUraLibV1/GnbUraLibV1.c
@@ -0,0 +1,388 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * Service procedure to access PCI config space registers
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: GNB
+ * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $
+ *
+ */
+/*
+*****************************************************************************
+*
+ * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+* ***************************************************************************
+*
+*/
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "Ids.h"
+#include "amdlib.h"
+#include "Gnb.h"
+#include "GnbLib.h"
+#include "GnbPcieConfig.h"
+#include "GnbCommonLib.h"
+#include "GnbUraServices.h"
+#include "Filecode.h"
+
+#define FILECODE PROC_GNB_MODULES_GNBURALIBV1_GNBURALIBV1_FILECODE
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+UINT8 RegisterDomainMap[] = {
+ 0x0, ///< Stub
+ 0x0, ///< Stub
+ 0x64, ///< 0x2
+ 0x98, ///< 0x3
+ 0xB8, ///< TYPE_D0F0xB8
+ 0xFD ///< End
+};
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Convert URA Token to register address and field location
+ *
+ * @param[in] UraToken Register of bit field identifier
+ * @param[in] UraTable Pointer to register token table
+ * @param[in, out] TokenInfo Pointer to URA_TOKEN_INFO structure
+ *
+ * @retval UraToken Token is defined
+ * @retval _UNUSED Token is undefined
+ *
+ */
+URA_TOKEN
+STATIC
+UraTranslateToken (
+ IN URA_TOKEN UraToken,
+ IN URA_ENTRY *UraTable,
+ IN OUT URA_TOKEN_INFO *TokenInfo
+ )
+{
+ URA_TOKEN_STRUCT Token;
+ URA_FIELD_16B_ENTRY *Field16;
+ URA_REGISTER_32B_ENTRY *Reg32;
+ URA_REGISTER_64B_ENTRY *Reg64;
+
+ Token.Encode = UraToken;
+ Reg32 = NULL;
+ Reg64 = NULL;
+ Field16 = NULL;
+
+ switch (Token.Parser.Type) {
+ //
+ // Parse 16 bit field encoding
+ //
+ case URA_TYPE_FIELD_16:
+ Field16 = (URA_FIELD_16B_ENTRY *) &(UraTable[Token.Parser.Index]);
+ TokenInfo->BfWidth = (UINT8) Field16->BfWidth;
+ TokenInfo->BfOffset = (UINT8) Field16->BfOffset;
+ while (Field16->Offset == 0) {
+ Token.Parser.Index -= 15;
+ Field16 = (URA_FIELD_16B_ENTRY *) &UraTable[Token.Parser.Index];
+ }
+
+ ASSERT (Field16->Offset != 0);
+
+ if (Token.Parser.ParentType == URA_TOKEN_PARENT_TYPE_32) {
+ Token.Parser.Index -= (Field16->Offset - 1) * 2 + 2;
+ Reg32 = (URA_REGISTER_32B_ENTRY *) &UraTable[Token.Parser.Index];
+ } else if (Token.Parser.ParentType == URA_TOKEN_PARENT_TYPE_64) {
+ Token.Parser.Index -= Field16->Offset + 3;
+ Reg64 = (URA_REGISTER_64B_ENTRY *) &(UraTable[Token.Parser.Index]);
+ } else {
+ ASSERT (FALSE);
+ return _UNUSED;
+ }
+
+ TokenInfo->WholeRegAccess = FALSE;
+ break;
+
+ //
+ // Parse 32 bit register encoding
+ //
+ case URA_TYPE_REGISTER_32:
+ Reg32 = (URA_REGISTER_32B_ENTRY *) &UraTable[Token.Parser.Index];
+ if (Reg32->Address == _UNUSED) {
+ return _UNUSED;
+ }
+ TokenInfo->WholeRegAccess = TRUE;
+ break;
+
+ //
+ // Parse 64 bit register encoding
+ //
+ case URA_TYPE_REGISTER_64:
+ Reg64 = (URA_REGISTER_64B_ENTRY *) &(UraTable[Token.Parser.Index]);
+ if (Reg64->DomainAddress == _UNUSED) {
+ return _UNUSED;
+ }
+ TokenInfo->WholeRegAccess = TRUE;
+ break;
+
+ default:
+ ASSERT (FALSE);
+ }
+
+ // Get register address
+ if ((Token.Parser.ParentType == URA_TOKEN_PARENT_TYPE_32) && (Reg32 != NULL)) {
+ TokenInfo->RegAddress = Reg32->Address;
+ TokenInfo->RegDomainType = 0;
+ } else if ((Token.Parser.ParentType == URA_TOKEN_PARENT_TYPE_64) && (Reg64 != NULL)) {
+ TokenInfo->RegAddress = (UINT32)Reg64->DomainAddress;
+ TokenInfo->RegDomainType = (UINT8)Reg64->DomainType;
+ } else {
+ ASSERT (FALSE);
+ return _UNUSED;
+ }
+
+ TokenInfo->MethodType = Token.Parser.Selector;
+
+ // Patch DomainType field
+ if (TokenInfo->MethodType == TYPE_GNB_INDIRECT_ACCESS) {
+ TokenInfo->RegDomainType = RegisterDomainMap[TokenInfo->RegDomainType];
+ }
+
+ TokenInfo->Flags = Token.Parser.S3Save;
+ TokenInfo->StreamSet = Token.Parser.StreamSet;
+
+ return Token.Encode;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Gnb Unified Register Access method
+ *
+ *
+ * @param[in] Device Standard configuration header
+ * @param[in] UraToken Context length
+ * @param[in, out] Value Pointer to Context
+ */
+VOID
+GnbUraGet (
+ IN DEV_OBJECT *Device,
+ IN URA_TOKEN UraToken,
+ IN OUT VOID *Value
+ )
+{
+ AGESA_STATUS Status;
+ GNB_URA_SERVICE *GnbUraProtocol;
+ URA_TOKEN_INFO TokenInfo;
+ URA_ENTRY *UraTable;
+ UINT32 UraTableAddress;
+
+ UraTable = NULL;
+ Status = GnbLibLocateService (GnbUraService, GnbGetSocketId (Device->GnbHandle), (VOID **)&GnbUraProtocol, Device->StdHeader);
+ ASSERT (Status == AGESA_SUCCESS);
+
+ GnbUraProtocol->GnbUraLocateRegTbl (Device, &UraTableAddress);
+ UraTable = (URA_ENTRY *) ((UINTN)UraTableAddress);
+ UraToken = UraTranslateToken (UraToken, UraTable, &TokenInfo);
+ if (UraToken == _UNUSED) {
+ return;
+ }
+
+ GnbUraProtocol->GnbUraGet (Device, &TokenInfo, Value);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Gnb Unified Register Access method
+ *
+ *
+ * @param[in] Device Standard configuration header
+ * @param[in] UraToken Ura token
+ * @param[in] Value Pointer to Context
+ */
+VOID
+GnbUraSet (
+ IN DEV_OBJECT *Device,
+ IN URA_TOKEN UraToken,
+ IN VOID *Value
+ )
+{
+ AGESA_STATUS Status;
+ GNB_URA_SERVICE *GnbUraProtocol;
+ URA_TOKEN_INFO TokenInfo;
+ URA_ENTRY *UraTable;
+ UINT32 UraTableAddress;
+
+ Status = GnbLibLocateService (GnbUraService, GnbGetSocketId (Device->GnbHandle), (VOID **)&GnbUraProtocol, Device->StdHeader);
+ ASSERT (Status == AGESA_SUCCESS);
+
+ GnbUraProtocol->GnbUraLocateRegTbl (Device, &UraTableAddress);
+ UraTable = (URA_ENTRY *) ((UINTN)UraTableAddress);
+ UraToken = UraTranslateToken (UraToken, UraTable, &TokenInfo);
+ if (UraToken == _UNUSED) {
+ return;
+ }
+
+ GnbUraProtocol->GnbUraSet (Device, &TokenInfo, Value);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Gnb Unified Register Access method
+ *
+ *
+ * @param[in] Device Standard configuration header
+ * @param[in, out] UraTokenRegister Register token
+ * @param[in] UraTuple Pointer to Context
+ * @param[in, out] CombinedCount Token count
+ */
+VOID
+GnbUraCombinedGet (
+ IN DEV_OBJECT *Device,
+ IN URA_TOKEN UraTokenRegister,
+ IN OUT URA_TUPLE *UraTuple,
+ IN UINT32 CombinedCount
+ )
+{
+ AGESA_STATUS Status;
+ GNB_URA_SERVICE *GnbUraProtocol;
+ URA_TOKEN_INFO TokenInfo;
+ URA_ENTRY *UraTable;
+ UINT32 UraTableAddress;
+ UINT32 RegValue;
+ UINT32 TempValue;
+ UINT32 FieldMask;
+ URA_TOKEN UraToken;
+ UINT32 Index;
+
+ Status = GnbLibLocateService (GnbUraService, GnbGetSocketId (Device->GnbHandle), (VOID **)&GnbUraProtocol, Device->StdHeader);
+ ASSERT (Status == AGESA_SUCCESS);
+
+ GnbUraProtocol->GnbUraLocateRegTbl (Device, &UraTableAddress);
+ UraTable = (URA_ENTRY *) ((UINTN)UraTableAddress);
+ UraTokenRegister = UraTranslateToken (UraTokenRegister, UraTable, &TokenInfo);
+ if (UraTokenRegister == _UNUSED) {
+ return;
+ }
+
+ GnbUraProtocol->GnbUraGet (Device, &TokenInfo, &RegValue);
+
+ Index = 0;
+ do {
+ UraToken = UraTuple[Index].Token;
+ UraToken = UraTranslateToken (UraToken, UraTable, &TokenInfo);
+ if (UraToken == _UNUSED) {
+ return;
+ }
+
+ TempValue = RegValue;
+ TempValue = TempValue >> TokenInfo.BfOffset;
+ FieldMask = (((UINT32)1 << TokenInfo.BfWidth) - 1);
+ UraTuple[Index].Value = TempValue & FieldMask;
+ Index++;
+ } while (Index < CombinedCount);
+
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Gnb Unified Register Access method
+ *
+ *
+ * @param[in] Device Standard configuration header
+ * @param[in, out] UraTokenRegister Register token
+ * @param[in] UraTuple Pointer to Context
+ * @param[in, out] CombinedCount Token count
+ */
+VOID
+GnbUraCombinedSet (
+ IN DEV_OBJECT *Device,
+ IN URA_TOKEN UraTokenRegister,
+ IN OUT URA_TUPLE *UraTuple,
+ IN UINT32 CombinedCount
+ )
+{
+ AGESA_STATUS Status;
+ GNB_URA_SERVICE *GnbUraProtocol;
+ URA_TOKEN_INFO TokenInfo;
+ URA_ENTRY *UraTable;
+ UINT32 UraTableAddress;
+ UINT32 RegValue;
+ UINT32 TempValue;
+ UINT32 FieldMask;
+ URA_TOKEN UraToken;
+ UINT32 Index;
+
+ Status = GnbLibLocateService (GnbUraService, GnbGetSocketId (Device->GnbHandle), (VOID **)&GnbUraProtocol, Device->StdHeader);
+ ASSERT (Status == AGESA_SUCCESS);
+
+ GnbUraProtocol->GnbUraLocateRegTbl (Device, &UraTableAddress);
+ UraTable = (URA_ENTRY *) ((UINTN)UraTableAddress);
+ UraTokenRegister = UraTranslateToken (UraTokenRegister, UraTable, &TokenInfo);
+ if (UraTokenRegister == _UNUSED) {
+ return;
+ }
+
+ if (TokenInfo.StreamSet == 1) {
+ GnbUraProtocol->GnbUraStreamSet (Device, &TokenInfo, UraTuple, CombinedCount);
+ } else {
+ GnbUraProtocol->GnbUraGet (Device, &TokenInfo, &RegValue);
+
+ Index = 0;
+ do {
+ UraToken = UraTuple[Index].Token;
+ UraToken = UraTranslateToken (UraToken, UraTable, &TokenInfo);
+ if (UraToken == _UNUSED) {
+ return;
+ }
+ FieldMask = (((UINT32)1 << TokenInfo.BfWidth) - 1);
+ TempValue = UraTuple[Index].Value & FieldMask;
+ RegValue &= ~(FieldMask << TokenInfo.BfOffset);
+ RegValue |= TempValue << TokenInfo.BfOffset;
+ Index++;
+ } while (Index < CombinedCount);
+
+ UraTokenRegister = UraTranslateToken (UraTokenRegister, UraTable, &TokenInfo);
+ GnbUraProtocol->GnbUraSet (Device, &TokenInfo, &RegValue);
+ }
+}