summaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Control/IdsNvToCmos.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/f15tn/Proc/IDS/Control/IdsNvToCmos.c')
-rw-r--r--src/vendorcode/amd/agesa/f15tn/Proc/IDS/Control/IdsNvToCmos.c442
1 files changed, 442 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Control/IdsNvToCmos.c b/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Control/IdsNvToCmos.c
new file mode 100644
index 0000000000..b9a69b7863
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Control/IdsNvToCmos.c
@@ -0,0 +1,442 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD Integrated Debug library Routines
+ *
+ * Contains AMD AGESA debug macros and library functions
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: IDS
+ * @e \$Revision: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $
+ */
+/*****************************************************************************
+ * Copyright 2008 - 2012 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
+ *
+ * AMD is granting you permission to use this software (the Materials)
+ * pursuant to the terms and conditions of your Software License Agreement
+ * with AMD. This header does *NOT* give you permission to use the Materials
+ * or any rights under AMD's intellectual property. Your use of any portion
+ * of these Materials shall constitute your acceptance of those terms and
+ * conditions. If you do not agree to the terms and conditions of the Software
+ * License Agreement, please do not use any portion of these Materials.
+ *
+ * CONFIDENTIALITY: The Materials and all other information, identified as
+ * confidential and provided to you by AMD shall be kept confidential in
+ * accordance with the terms and conditions of the Software License Agreement.
+ *
+ * LIMITATION OF LIABILITY: THE MATERIALS AND ANY OTHER RELATED INFORMATION
+ * PROVIDED TO YOU BY AMD ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+ * MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE,
+ * OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR USAGE OF TRADE.
+ * IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER
+ * (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS
+ * INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF AMD'S NEGLIGENCE,
+ * GROSS NEGLIGENCE, THE USE OF OR INABILITY TO USE THE MATERIALS OR ANY OTHER
+ * RELATED INFORMATION PROVIDED TO YOU BY AMD, EVEN IF AMD HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE
+ * EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES,
+ * THE ABOVE LIMITATION MAY NOT APPLY TO YOU.
+ *
+ * AMD does not assume any responsibility for any errors which may appear in
+ * the Materials or any other related information provided to you by AMD, or
+ * result from use of the Materials or any related information.
+ *
+ * You agree that you will not reverse engineer or decompile the Materials.
+ *
+ * NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any
+ * further information, software, technical information, know-how, or show-how
+ * available to you. Additionally, AMD retains the right to modify the
+ * Materials at any time, without notice, and is not obligated to provide such
+ * modified Materials to you.
+ *
+ * U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with
+ * "RESTRICTED RIGHTS." Use, duplication, or disclosure by the Government is
+ * subject to the restrictions as set forth in FAR 52.227-14 and
+ * DFAR252.227-7013, et seq., or its successor. Use of the Materials by the
+ * Government constitutes acknowledgement of AMD's proprietary rights in them.
+ *
+ * EXPORT ASSURANCE: You agree and certify that neither the Materials, nor any
+ * direct product thereof will be exported directly or indirectly, into any
+ * country prohibited by the United States Export Administration Act and the
+ * regulations thereunder, without the required authorization from the U.S.
+ * government nor will be used for any purpose prohibited by the same.
+ ******************************************************************************
+ */
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "AGESA.h"
+#include "Ids.h"
+#include "IdsLib.h"
+#include "amdlib.h"
+#include "heapManager.h"
+#include "IdsNvToCmos.h"
+#include "Filecode.h"
+CODE_GROUP (G1_PEICC)
+RDATA_GROUP (G1_PEICC)
+
+#define FILECODE PROC_IDS_CONTROL_IDSNVTOCMOS_FILECODE
+
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+extern IDS_NV_TO_CMOS gIdsNVToCmos[];
+
+/**
+ *
+ * Read CMOS
+ *
+ * @param[in] IndexPort Index port of access CMOS
+ * @param[in] DataPort Data port of access CMOS
+ * @param[in] Index Index of CMOS
+ * @param[in,out] Value Point to Value
+ * @param[in,out] StdHeader The Pointer of Standard Header.
+ *
+ **/
+VOID
+IdsReadCmos (
+ IN UINT16 IndexPort,
+ IN UINT16 DataPort,
+ IN UINT16 Index,
+ IN OUT UINT8 *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ LibAmdIoWrite (AccessWidth8, IndexPort, &Index, StdHeader);
+ LibAmdIoRead (AccessWidth8, DataPort, Value, StdHeader);
+}
+/**
+ *
+ * Write CMOS
+ *
+ * @param[in] IndexPort Index port of access CMOS
+ * @param[in] DataPort Data port of access CMOS
+ * @param[in] Index Index of CMOS
+ * @param[in,out] Value Point to Value
+ * @param[in,out] StdHeader The Pointer of Standard Header.
+ *
+ **/
+VOID
+IdsWriteCmos (
+ IN UINT16 IndexPort,
+ IN UINT16 DataPort,
+ IN UINT16 Index,
+ IN OUT UINT8 *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ LibAmdIoWrite (AccessWidth8, IndexPort, &Index, StdHeader);
+ LibAmdIoWrite (AccessWidth8, DataPort, Value, StdHeader);
+}
+/**
+ *
+ * Get IDS CMOS save region in the AGESA Heap.
+ *
+ * @param[in,out] IdsCmosRegion The Pointer of IDS CMOS save address in heap.
+ * @param[in,out] StdHeader The Pointer of Standard Header.
+ *
+ * @retval AGESA_SUCCESS Success to get the pointer of NV Table.
+ * @retval AGESA_ERROR Fail to get the pointer of NV Table.
+ **/
+AGESA_STATUS
+AmdGetIdsCmosSaveRegion (
+ IN OUT VOID **IdsCmosRegion,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ AGESA_STATUS status;
+ LOCATE_HEAP_PTR LocateHeapStructPtr;
+ ALLOCATE_HEAP_PARAMS AllocHeapParams;
+
+ LocateHeapStructPtr.BufferHandle = IDS_NV_TO_CMOS_HANDLE;
+ LocateHeapStructPtr.BufferPtr = NULL;
+ status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader);
+ if (status == AGESA_SUCCESS) {
+ *IdsCmosRegion = LocateHeapStructPtr.BufferPtr;
+ } else {
+ //Allocated the heap when can't located
+ AllocHeapParams.RequestedBufferSize = IDS_CMOS_REGION_END - IDS_CMOS_REGION_START + 1;
+ AllocHeapParams.BufferHandle = IDS_NV_TO_CMOS_HANDLE;
+ AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
+ status = HeapAllocateBuffer (&AllocHeapParams, (AMD_CONFIG_PARAMS *) StdHeader);
+ if (status == AGESA_SUCCESS) {
+ *IdsCmosRegion = AllocHeapParams.BufferPtr;
+ }
+ }
+ return status;
+}
+
+
+/**
+ * IDS Backend Function for save BSP's NV heap to CMOS
+ *
+ *
+ * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS.
+ *
+ * @retval IDS_SUCCESS Backend function is called successfully.
+ * @retval IDS_UNSUPPORTED No Backend function is found.
+ *
+ **/
+IDS_STATUS
+IdsCheckCmosValid (
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT8 CmosIndex;
+ UINT8 TmpValue;
+ UINT8 Len;
+ UINT8 Sum;
+ CmosIndex = IDS_CMOS_REGION_SIGNATURE_OFFSET;
+ //Validate the Signature
+ IdsReadCmos (IDS_CMOS_INDEX_PORT, IDS_CMOS_DATA_PORT, CmosIndex, &TmpValue, StdHeader);
+ if (TmpValue != 'N') {
+ return IDS_UNSUPPORTED;
+ }
+
+ CmosIndex++;
+ IdsReadCmos (IDS_CMOS_INDEX_PORT, IDS_CMOS_DATA_PORT, CmosIndex, &TmpValue, StdHeader);
+ if (TmpValue != 'V') {
+ return IDS_UNSUPPORTED;
+ }
+
+ CmosIndex = IDS_CMOS_REGION_LENGTH_OFFSET;
+ IdsReadCmos (IDS_CMOS_INDEX_PORT, IDS_CMOS_DATA_PORT, CmosIndex, &Len, StdHeader);
+ if (Len > (IDS_CMOS_REGION_END - IDS_CMOS_REGION_START - IDS_NV_TO_CMOS_HEADER_SIZE + 1)) {
+ return IDS_UNSUPPORTED;
+ }
+ Sum = 0;
+ CmosIndex = IDS_CMOS_REGION_CHECKSUM_OFFSET;
+ for (; CmosIndex < IDS_CMOS_REGION_DATA_OFFSET + Len; CmosIndex++) {
+ IdsReadCmos (IDS_CMOS_INDEX_PORT, IDS_CMOS_DATA_PORT, CmosIndex, &TmpValue, StdHeader);
+ Sum = (UINT8) (Sum + TmpValue);
+ }
+ if (Sum != 0) {
+ return IDS_UNSUPPORTED;
+ }
+ return IDS_SUCCESS;
+}
+
+/**
+ *
+ * AP get NV from CMOS
+ *
+ * If Ap Can't get Nv Data from Callout, Try to Create NV heap via the
+ * CMOS data area save by BSP previous
+
+ *
+ * @param[in,out] StdHeader The Pointer of IDS Initial Parameter
+ *
+ * @retval AGESA_SUCCESS Success to get the NV from CMOS
+ * @retval AGESA_ERROR Fail to get
+ *
+ **/
+AGESA_STATUS
+AmdIdsApGetNvFromCmos (
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ AGESA_STATUS status;
+ ALLOCATE_HEAP_PARAMS AllocHeapParams;
+ IDS_CONTROL_STRUCT *IdsCtrlPtr;
+ UINT8 CmosIndex;
+ UINT8 TmpValue;
+ UINT8 TmpU16Value;
+ UINT8 k;
+ UINT16 i;
+ IDS_NV_ITEM *NvPtr;
+ UINT8 Len;
+ status = AGESA_ERROR;
+ if (IdsCheckCmosValid (StdHeader) == IDS_SUCCESS) {
+ AllocHeapParams.RequestedBufferSize = sizeof (IDS_CONTROL_STRUCT);
+ AllocHeapParams.RequestedBufferSize += (IDS_CMOS_REGION_END - IDS_CMOS_REGION_START - IDS_NV_TO_CMOS_HEADER_SIZE + 2) * sizeof (IDS_NV_ITEM) ;
+ AllocHeapParams.BufferHandle = IDS_CONTROL_HANDLE;
+ AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
+
+ //
+ // Allocate data buffer in heap
+ //
+ status = HeapAllocateBuffer (&AllocHeapParams, (AMD_CONFIG_PARAMS *) StdHeader);
+ if (status == AGESA_SUCCESS) {
+ IdsCtrlPtr = (IDS_CONTROL_STRUCT *) AllocHeapParams.BufferPtr;
+ IdsCtrlPtr->IgnoreIdsDefault = TRUE;
+ IdsCtrlPtr->IdsHeapMemSize = AllocHeapParams.RequestedBufferSize;
+ IdsCtrlPtr->IdsNvTableOffset = sizeof (IDS_CONTROL_STRUCT);
+ NvPtr = (IDS_NV_ITEM *) (AllocHeapParams.BufferPtr + IdsCtrlPtr->IdsNvTableOffset);
+ i = 0;
+ CmosIndex = IDS_CMOS_REGION_LENGTH_OFFSET;
+ IdsReadCmos (IDS_CMOS_INDEX_PORT, IDS_CMOS_DATA_PORT, CmosIndex, &Len, StdHeader);
+ CmosIndex = IDS_CMOS_REGION_DATA_OFFSET;
+ while ((gIdsNVToCmos[i].Length != IDS_NV_TO_CMOS_LEN_END) &&
+ (gIdsNVToCmos[i].IDS_NV_ID != IDS_NV_TO_CMOS_ID_END) &&
+ (CmosIndex <= IDS_CMOS_REGION_END) &&
+ (Len-- > 0)) {
+ if (gIdsNVToCmos[i].Length == IDS_NV_TO_CMOS_LEN_BYTE || gIdsNVToCmos[i].Length == IDS_NV_TO_CMOS_LEN_WORD) {
+ TmpU16Value = 0;
+ for (k = 0; k < gIdsNVToCmos[i].Length; k++, CmosIndex++) {
+ IdsReadCmos (IDS_CMOS_INDEX_PORT, IDS_CMOS_DATA_PORT, CmosIndex, &TmpValue, StdHeader);
+ TmpU16Value |= (UINT16)TmpValue << (k * 8);
+ }
+ if ((TmpU16Value != IDS_NV_TO_CMOS_BYTE_IGNORED && (gIdsNVToCmos[i].Length == IDS_NV_TO_CMOS_LEN_BYTE)) ||
+ (TmpU16Value != IDS_NV_TO_CMOS_WORD_IGNORED && (gIdsNVToCmos[i].Length == IDS_NV_TO_CMOS_LEN_WORD))) {
+ NvPtr->IdsNvId = gIdsNVToCmos[i].IDS_NV_ID;
+ NvPtr->IdsNvValue = TmpU16Value;
+ NvPtr ++;
+ }
+ }
+ i++;
+ }
+ NvPtr->IdsNvId = AGESA_IDS_NV_END;
+ }
+ }
+ return status;
+}
+
+/**
+ * IDS Backend Function for Restore CMOS
+ *
+ *
+ * @param[in,out] DataPtr NULL
+ * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS.
+ * @param[in] IdsNvPtr The Pointer of NV Table.
+ *
+ * @retval IDS_SUCCESS Backend function is called successfully.
+ * @retval IDS_UNSUPPORTED No Backend function is found.
+ *
+ **/
+IDS_STATUS
+IdsSubRestoreCmos (
+ IN OUT VOID *DataPtr,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader,
+ IN IDS_NV_ITEM *IdsNvPtr
+ )
+{
+ UINT8 *PCmosSave;
+ UINT8 CmosIndex;
+
+ //Save CMOS to BSP heap
+ if (AmdGetIdsCmosSaveRegion ((VOID **) &PCmosSave, StdHeader) == AGESA_SUCCESS) {
+ for (CmosIndex = IDS_CMOS_REGION_START; CmosIndex <= IDS_CMOS_REGION_END; CmosIndex++, PCmosSave++) {
+ IdsWriteCmos (IDS_CMOS_INDEX_PORT, IDS_CMOS_DATA_PORT, CmosIndex, PCmosSave, StdHeader);
+ }
+ }
+ return IDS_SUCCESS;
+}
+/**
+ * IDS Backend Function for save BSP's NV heap to CMOS
+ *
+ *
+ * @param[in,out] DataPtr NULL
+ * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS.
+ * @param[in] IdsNvPtr The Pointer of NV Table.
+ *
+ * @retval IDS_SUCCESS Backend function is called successfully.
+ * @retval IDS_UNSUPPORTED No Backend function is found.
+ *
+ **/
+IDS_STATUS
+IdsSubSaveBspNvHeapToCmos (
+ IN OUT VOID *DataPtr,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader,
+ IN IDS_NV_ITEM *IdsNvPtr
+ )
+{
+ UINT8 i;
+ UINT8 k;
+ UINT8 CmosIndex;
+ UINT8 TmpValue;
+ UINT8 Sum;
+ UINT8 Len;
+ UINT8 *PCmosSave;
+ IDS_STATUS IdsNvValue;
+
+ //Save CMOS to BSP heap
+ if (AmdGetIdsCmosSaveRegion ((VOID **) &PCmosSave, StdHeader) == AGESA_SUCCESS) {
+ for (CmosIndex = IDS_CMOS_REGION_START; CmosIndex <= IDS_CMOS_REGION_END; CmosIndex++) {
+ IdsReadCmos (IDS_CMOS_INDEX_PORT, IDS_CMOS_DATA_PORT, CmosIndex, &TmpValue, StdHeader);
+ *(PCmosSave++) = TmpValue;
+ }
+ //The CMOS Region is saved to heap,Now we can save BSP NV to CMOS
+ i = 0;
+ CmosIndex = IDS_CMOS_REGION_SIGNATURE_OFFSET;
+ //CMOS Map
+ // **********************************************************************************
+ // Field | Offset | Description
+ // **********************************************************************************
+ // Signature | 0 | 'NV' specify the IDS Cmos save region
+ // **********************************************************************************
+ // Length | 2 | Actual Length of all save NV, may less than platform
+ // | | define
+ // **********************************************************************************
+ // CheckSum | 3 | CheckSum of all NV fields exclue Signature & Length
+ // **********************************************************************************
+ // NVSaveRegion | 4 | Nv Save Region
+ // **********************************************************************************
+ // Set Signature 'NV';
+ TmpValue = 'N';
+ IdsWriteCmos (IDS_CMOS_INDEX_PORT, IDS_CMOS_DATA_PORT, CmosIndex, &TmpValue, StdHeader);
+ CmosIndex++;
+ TmpValue = 'V';
+ IdsWriteCmos (IDS_CMOS_INDEX_PORT, IDS_CMOS_DATA_PORT, CmosIndex, &TmpValue, StdHeader);
+
+ CmosIndex = IDS_CMOS_REGION_DATA_OFFSET;
+ Sum = 0;
+ Len = 0;
+ while ((gIdsNVToCmos[i].Length != IDS_NV_TO_CMOS_LEN_END) &&
+ (gIdsNVToCmos[i].IDS_NV_ID != IDS_NV_TO_CMOS_ID_END) &&
+ (CmosIndex <= IDS_CMOS_REGION_END)) {
+ //Get NV Value length
+ if (gIdsNVToCmos[i].Length == IDS_NV_TO_CMOS_LEN_BYTE || gIdsNVToCmos[i].Length == IDS_NV_TO_CMOS_LEN_WORD) {
+ IdsNvValue = AmdIdsNvReader (gIdsNVToCmos[i].IDS_NV_ID, IdsNvPtr, StdHeader);
+ for (k = 0; k < gIdsNVToCmos[i].Length; k++) {
+ TmpValue = (UINT8) ((IdsNvValue >> (8 * k)) & 0xFF);
+ Sum = (UINT8) (Sum + TmpValue);
+ Len++;
+ IdsWriteCmos (IDS_CMOS_INDEX_PORT, IDS_CMOS_DATA_PORT, CmosIndex, &TmpValue, StdHeader);
+ CmosIndex++;
+ }
+ } else {
+ ASSERT (FALSE);
+ }
+ i++;
+ }
+ CmosIndex = IDS_CMOS_REGION_LENGTH_OFFSET;
+ IdsWriteCmos (IDS_CMOS_INDEX_PORT, IDS_CMOS_DATA_PORT, CmosIndex, &Len, StdHeader);
+ CmosIndex = IDS_CMOS_REGION_CHECKSUM_OFFSET;
+ TmpValue = (UINT8) (0x100 - Sum);
+ IdsWriteCmos (IDS_CMOS_INDEX_PORT, IDS_CMOS_DATA_PORT, CmosIndex, &TmpValue, StdHeader);
+ }
+ return IDS_SUCCESS;
+}
+
+CONST IDS_FAMILY_FEAT_STRUCT ROMDATA IdsFeatNvToCmosSaveBlock =
+{
+ IDS_FEAT_NV_TO_CMOS,
+ IDS_BSP_ONLY,
+ IDS_CPU_Early_Override,
+ IDS_FAMILY_ALL,
+ IdsSubSaveBspNvHeapToCmos
+};
+
+CONST IDS_FAMILY_FEAT_STRUCT ROMDATA IdsFeatNvToCmosRestoreBlock =
+{
+ IDS_FEAT_NV_TO_CMOS,
+ IDS_BSP_ONLY,
+ IDS_BEFORE_AP_EARLY_HALT,
+ IDS_FAMILY_ALL,
+ IdsSubRestoreCmos
+};
+
+