summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCamVan Nguyen <ctnguyen@us.ibm.com>2011-10-24 16:11:42 -0500
committerCAMVAN T. NGUYEN <ctnguyen@us.ibm.com>2011-10-27 16:58:16 -0500
commit7e2d025969d46a4f6fe1dab6e4c40061ce8e6fec (patch)
tree392ebe5669c1e7e1b7d93be212693f5fae88de4d
parent9e86b070a4429e7db34a5438611a67098ab92dfb (diff)
downloadtalos-hostboot-7e2d025969d46a4f6fe1dab6e4c40061ce8e6fec.tar.gz
talos-hostboot-7e2d025969d46a4f6fe1dab6e4c40061ce8e6fec.zip
Added Hwp to execute initfiles
Change-Id: Ie597c23eadc51b7463487eff9316a30ad04d88e5 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/455 Tested-by: Jenkins Server Reviewed-by: Andrew J. Geissler <andrewg@us.ibm.com>
-rw-r--r--src/include/usr/hwpf/fapi/fapiAttributeService.H4
-rw-r--r--src/include/usr/hwpf/fapi/fapiUtil.H38
-rw-r--r--src/include/usr/hwpf/hwp/fapiHwpExecInitFile.H113
-rwxr-xr-xsrc/usr/hwpf/fapi/fapiParseAttributeInfo.pl3
-rwxr-xr-xsrc/usr/hwpf/fapi/fapiParseErrorInfo.pl4
-rw-r--r--src/usr/hwpf/hwp/fapiHwpErrorInfo.xml24
-rw-r--r--src/usr/hwpf/hwp/fapiHwpExecInitFile.C1814
-rw-r--r--src/usr/hwpf/hwp/fapiTestHwp.C228
-rwxr-xr-xsrc/usr/hwpf/hwp/initfiles/sample.initfile151
-rw-r--r--src/usr/hwpf/hwp/makefile3
-rw-r--r--src/usr/hwpf/plat/fapiPlatUtil.C72
11 files changed, 2444 insertions, 10 deletions
diff --git a/src/include/usr/hwpf/fapi/fapiAttributeService.H b/src/include/usr/hwpf/fapi/fapiAttributeService.H
index e623a2e8a..bffe0341b 100644
--- a/src/include/usr/hwpf/fapi/fapiAttributeService.H
+++ b/src/include/usr/hwpf/fapi/fapiAttributeService.H
@@ -37,6 +37,8 @@
* mjjones 09/06/2011 Remove support for strings
* mjjones 09/22/2011 Fixed example
* mjjones 10/13/2011 Added fapiGetInitFileAttr
+ * camvanng 10/20/2011 Changed i_pTarget to "const"
+ * ptr
*/
#ifndef FAPIATTRIBUTESERVICE_H_
@@ -102,7 +104,7 @@ namespace fapi
* @return ReturnCode. Zero if success
*/
ReturnCode fapiGetInitFileAttr(const AttributeId i_id,
- Target * i_pTarget,
+ const Target * i_pTarget,
uint64_t & o_val,
const uint32_t i_arrayIndex1 = 0,
const uint32_t i_arrayIndex2 = 0,
diff --git a/src/include/usr/hwpf/fapi/fapiUtil.H b/src/include/usr/hwpf/fapi/fapiUtil.H
index e3a3b9f3a..e3033dc9a 100644
--- a/src/include/usr/hwpf/fapi/fapiUtil.H
+++ b/src/include/usr/hwpf/fapi/fapiUtil.H
@@ -38,6 +38,8 @@
* mjjones 09/14/2011 Prepended fapi to delay
* mjjones 10/05/2011 Added fapiCheckType
* mjjones 10/13/2011 Added extern "C" to functions
+ * camvanng 10/14/2011 Added fapiLoadInitFile &
+ * fapiUnloadInitFile
*/
#ifndef FAPIUTIL_H_
@@ -128,6 +130,42 @@ bool platIsScanTraceEnabled();
*/
void platSetScanTrace(bool i_enable);
+/** @brief Load the initfile
+ *
+ * This function can be called by a HWP to load an initfile.
+ *
+ * @note Implemented by platform code. Platform code is
+ * responsible for allocating any memory needed to load
+ * the initfile.
+ *
+ * @param[in] the .if filename: <initfile>.if
+ * @param[out] address in memory where initfile is loaded
+ * @param[out] size of memory allocated for initfile
+ *
+ * @return ReturnCode. Zero on success, else platform specified error.
+ */
+
+fapi::ReturnCode fapiLoadInitFile(const char * i_file, const char *& o_addr,
+ size_t & o_size);
+
+/** @brief Unload the initfile
+ *
+ * This function can be called by a HWP to unload an initfile.
+ *
+ * @note Implemented by platform code. Platform code is
+ * responsible for deleting any allocated memory.
+ *
+ * @param[in] the .if filename: <initfile>.if
+ * @param[in,out] address in memory where initfile is loaded
+ * set to NULL on exit
+ * @param[in,out] size of memory allocated for initfile
+ * set to 0 on exit
+ *
+ * @return ReturnCode. Zero on success, else platform specified error.
+ */
+fapi::ReturnCode fapiUnloadInitFile(const char * i_file, const char *& io_addr,
+ size_t & io_size);
+
}
namespace fapi
diff --git a/src/include/usr/hwpf/hwp/fapiHwpExecInitFile.H b/src/include/usr/hwpf/hwp/fapiHwpExecInitFile.H
new file mode 100644
index 000000000..7954f15cf
--- /dev/null
+++ b/src/include/usr/hwpf/hwp/fapiHwpExecInitFile.H
@@ -0,0 +1,113 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/include/usr/hwpf/hwp/fapiTestHwp.H $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+/**
+ * @file fapiHwpExecInitFile.H
+ *
+ * @brief Defines for Hardware Procedure initfile execution
+ */
+
+/*
+ * Change Log ******************************************************************
+ * Flag Defect/Feature User Date Description
+ * ------ -------------- ---------- ----------- ----------------------------
+ * camvanng 09/29/2011 Created.
+ *
+ */
+
+#ifndef FAPIHWPEXECINITFILE_H_
+#define FAPIHWPEXECINITFILE_H_
+
+#include <fapi.H>
+
+// HWPs are defined as C functions because platforms may wish to package them
+// in linux shared libraries which are DL-Opened
+extern "C"
+{
+
+/**
+ * @brief Enumeration of RPN ops
+ */
+enum IfRpnOp
+{
+ AND = 0x00000001,
+ OR = 0x00000002,
+ NOT = 0x00000003,
+ EQ = 0x00000004,
+ NE = 0x00000005,
+ GT = 0x00000006,
+ GE = 0x00000007,
+ LT = 0x00000008,
+ LE = 0x00000009,
+ PLUS = 0x0000000A,
+ MINUS = 0x0000000B,
+ MULT = 0x0000000C,
+ DIVIDE = 0x0000000D,
+ MOD = 0x0000000E,
+ LIST = 0x0000000F,
+ SHIFTLEFT = 0x00000010,
+ SHIFTRIGHT = 0x00000011,
+ FALSE_OP = 0x00000012,
+ TRUE_OP = 0x00000013,
+ PUSH_MASK = 0x000000C0,
+ OP_MASK = 0x000000FF
+};
+
+/**
+ * @brief Enumeration of Type Mask
+ */
+enum IfTypeMask
+{
+ IF_LIT_TYPE = 0x4000,
+ IF_VAR_TYPE = 0x8000,
+ IF_NUM_TYPE = 0xC000,
+ IF_TYPE_MASK = 0xC000,
+};
+
+/**
+ * @brief Enumeration of Attribute types
+ */
+enum IfAttrType
+{
+ SYM_ATTR_UINT8_TYPE = 0x00,
+ SYM_ATTR_UINT32_TYPE = 0x01,
+ SYM_ATTR_UINT64_TYPE = 0x02,
+ SYM_ATTR_UINT8_ARRAY_TYPE = 0x03,
+ SYM_ATTR_UINT32_ARRAY_TYPE = 0x04,
+ SYM_ATTR_UINT64_ARRAY_TYPE = 0x05,
+};
+
+
+
+/**
+* @brief HWP to execute an initfile.
+*
+* @param[in] i_chip Reference to target chip
+* @param[in] i_file filename of binary initfile
+*
+* @return ReturnCode
+*/
+fapi::ReturnCode hwpExecInitFile(const fapi::Target & i_chip, const char * i_file);
+
+} // extern "C"
+
+#endif // FAPIHWPEXECINITFILE_H_
diff --git a/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl b/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl
index b432f1fa7..34d08ef54 100755
--- a/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl
+++ b/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl
@@ -44,6 +44,7 @@
# mjjones 10/17/11 Support enums with values
# mjjones 10/18/11 Support multiple attr files and
# multi-line descriptions
+# camvanng 10/20/11 Changed i_pTarget to "const" ptr
#
# End Change Log ******************************************************
@@ -110,7 +111,7 @@ print ASFILE "#include <fapiAttributeService.H>\n\n";
print ASFILE "namespace fapi\n";
print ASFILE "{\n\n";
print ASFILE "ReturnCode fapiGetInitFileAttr(const AttributeId i_id,\n";
-print ASFILE " Target * i_pTarget,\n";
+print ASFILE " const Target * i_pTarget,\n";
print ASFILE " uint64_t & o_val,\n";
print ASFILE " const uint32_t i_arrayIndex1,\n";
print ASFILE " const uint32_t i_arrayIndex2,\n";
diff --git a/src/usr/hwpf/fapi/fapiParseErrorInfo.pl b/src/usr/hwpf/fapi/fapiParseErrorInfo.pl
index b17940e64..e51e0a24e 100755
--- a/src/usr/hwpf/fapi/fapiParseErrorInfo.pl
+++ b/src/usr/hwpf/fapi/fapiParseErrorInfo.pl
@@ -42,6 +42,7 @@
# mjjones 08/08/11 Large update to create more code
# mjjones 08/24/11 Parse GARD info
# mjjones 09/22/11 New Error Info Design
+# camvanng 10/20/11 Fix bug
#
# End Change Log ******************************************************
@@ -362,8 +363,9 @@ foreach my $argnum (1 .. $#ARGV)
if ($eiEntryCount > 0)
{
print EIFILE "{$eiObjectStr $eiEntryStr ";
- print EIFILE "RC.addErrorInfo(l_objects, l_entries, $eiEntryCount);}\n\n";
+ print EIFILE "RC.addErrorInfo(l_objects, l_entries, $eiEntryCount);}";
}
+ print EIFILE "\n\n";
}
}
diff --git a/src/usr/hwpf/hwp/fapiHwpErrorInfo.xml b/src/usr/hwpf/hwp/fapiHwpErrorInfo.xml
index 62cd3badd..df40e1010 100644
--- a/src/usr/hwpf/hwp/fapiHwpErrorInfo.xml
+++ b/src/usr/hwpf/hwp/fapiHwpErrorInfo.xml
@@ -53,4 +53,28 @@
<!-- Call hwpTestAnalyzeError on MASTER_CHIP to analyze the error -->
<callFunc>hwpTestAnalyzeError, MASTER_CHIP</callFunc>
</hwpError>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <rc>RC_INITFILE_INCORRECT_VER</rc>
+ <description>InitFile has incorrect version</description>
+ <!-- Collect local FFDC FFDC_IF_VER -->
+ <ffdc>FFDC_IF_VER</ffdc>
+ </hwpError>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <rc>RC_INITFILE_ATTR_ID_OUT_OF_RANGE</rc>
+ <description>InitFile's attribute id is out of range </description>
+ <!-- Collect local FFDC FFDC_IF_ATTR_ID_OUT_OF_RANGE -->
+ <ffdc>FFDC_IF_ATTR_ID_OUT_OF_RANGE</ffdc>
+ </hwpError>
+ <hwpError>
+ <rc>RC_INITFILE_LIT_ID_OUT_OF_RANGE</rc>
+ <description>InitFile's literal id is out of range </description>
+ <!-- Collect local FFDC FFDC_IF_LIT_ID_OUT_OF_RANGE -->
+ <ffdc>FFDC_IF_LIT_ID_OUT_OF_RANGE</ffdc>
+ </hwpError>
+ <hwpError>
+ <rc>RC_HWP_EXEC_INITFILE_TEST_FAILED</rc>
+ <description>HWP Exec InitFile test case failed </description>
+ </hwpError>
</hwpErrors>
diff --git a/src/usr/hwpf/hwp/fapiHwpExecInitFile.C b/src/usr/hwpf/hwp/fapiHwpExecInitFile.C
new file mode 100644
index 000000000..2019c8ed2
--- /dev/null
+++ b/src/usr/hwpf/hwp/fapiHwpExecInitFile.C
@@ -0,0 +1,1814 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/hwpf/hwp/fapiTestHwp.C $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+/**
+ * @file fapiHwpExecInitFile.C
+ *
+ * @brief Implements a Hardware Procedure to execute an initfile.
+ */
+
+/*
+ * Change Log ******************************************************************
+ * Flag Defect/Feature User Date Description
+ * ------ -------------- ---------- ----------- ----------------------------
+ * camvanng 09/29/2011 Created.
+ */
+
+#include <fapiHwpExecInitFile.H>
+#include <fapiUtil.H>
+#include <fapiAttributeService.H>
+#include <string.h>
+#include <vector>
+
+extern "C"
+{
+
+//******************************************************************************
+// Enumerations
+//******************************************************************************
+
+//Flag indicating ANY operand
+enum IfAnyFlags
+{
+ IF_NOT_ANY = 0,
+ IF_ANY = 1,
+ IF_ONE_SIDED_ANY = 2
+};
+
+//Special variables & literals
+enum IfSpecialIds
+{
+ IF_VAL_ANY = 0x4000,
+ IF_EXPR = 0x8000
+};
+
+/**
+* Offsets of certain elements in the initfile.
+*/
+enum IfHeader
+{
+ // Initfile Header
+ //-----------------
+ IF_VERSION_LOC = 0,
+ IF_CVS_VERSION_LOC = 4,
+ IF_ATTR_TABLE_OFFSET_LOC = 12,
+ IF_LIT_TABLE_OFFSET_LOC = 16,
+ IF_SCOM_SECTION_OFFSET_LOC= 20,
+ IF_SCOM_NUM_LOC = 24,
+
+ IF_VERSION_SIZE = 4,
+ IF_CVS_VERSION_SIZE = 8,
+
+ IF_ATTR_TABLE_OFFSET_SIZE = 4,
+ IF_LIT_TABLE_OFFSET_SIZE = 4,
+ IF_SCOM_SECTION_OFFSET_SIZE= 4,
+ IF_SCOM_NUM_SIZE = 4,
+
+ // Supported Syntax Version
+ IF_SYNTAX_VERSION = 1,
+
+ // Header size
+ IF_HEADER_SIZE = IF_VERSION_SIZE + IF_CVS_VERSION_SIZE +
+ IF_ATTR_TABLE_OFFSET_SIZE + IF_LIT_TABLE_OFFSET_SIZE +
+ IF_SCOM_SECTION_OFFSET_SIZE + IF_SCOM_NUM_SIZE,
+};
+
+//******************************************************************************
+// typedefs and structs
+//******************************************************************************
+
+//RPN stack
+typedef std::vector<uint64_t> rpnStack_t;
+
+//InitFile address, size and current offset
+typedef struct ifInfo
+{
+ const char * addr;
+ size_t size;
+ size_t offset;
+}ifInfo_t;
+
+//Attribute Symbol Table entry
+typedef struct attrTableEntry
+{
+ uint8_t type;
+ uint32_t attrId;
+}attrTableEntry_t;
+
+//Scom Section Data entry
+typedef struct scomData
+{
+ uint16_t len;
+ uint16_t offset;
+ uint16_t addrId; //numeric literal
+ uint16_t numCols;
+ uint16_t numRows;
+ uint16_t * dataId; //numeric literal
+ bool hasExpr;
+ uint16_t * colId; //expr or an attribute
+ char ** rowData;
+}scomData_t;
+
+//Init File Data
+typedef struct ifData
+{
+ const fapi::Target * pTarget;
+ uint16_t numAttrs;
+ uint16_t numLits;
+ uint32_t numScoms;
+ attrTableEntry_t * attrs;
+ uint64_t * numericLits;
+ scomData_t * scoms;
+ rpnStack_t * rpnStack;
+}ifData_t;
+
+
+//******************************************************************************
+// Forward Declarations
+//******************************************************************************
+attrTableEntry_t * loadAttrSymbolTable(ifInfo_t & io_ifInfo,
+ uint16_t & o_numAttrs);
+
+void unloadAttrSymbolTable(attrTableEntry_t *& io_attrs);
+
+fapi::ReturnCode getAttr(const ifData_t & i_ifData,
+ const uint16_t i_id,
+ uint64_t & o_val,
+ const uint32_t i_arrayIndex1 = 0,
+ const uint32_t i_arrayIndex2 = 0,
+ const uint32_t i_arrayIndex3 = 0,
+ const uint32_t i_arrayIndex4 = 0);
+
+uint64_t * loadLitSymbolTable(ifInfo_t & io_ifInfo,
+ uint16_t & o_numLits);
+
+void unloadLitSymbolTable(uint64_t *& io_numericLits);
+
+fapi::ReturnCode getLit(const ifData_t & i_ifData,
+ const uint16_t i_id,
+ uint64_t & o_val);
+
+scomData_t * loadScomSection(ifInfo_t & io_ifInfo,
+ uint32_t & o_numScoms);
+
+void unloadScomSection(scomData_t *& io_scoms, uint32_t i_numScoms);
+
+fapi::ReturnCode executeScoms(ifData_t & io_ifData);
+
+fapi::ReturnCode writeScom(const ifData_t & i_ifData, const uint32_t i_scomNum,
+ const uint16_t i_row);
+
+void rpnPush(rpnStack_t * io_rpnStack, uint64_t i_val);
+
+uint64_t rpnPop(rpnStack_t * io_rpnStack);
+
+void rpnDumpStack(rpnStack_t * i_rpnStack);
+
+uint64_t rpnUnaryOp(IfRpnOp i_op, uint64_t i_val, uint32_t i_any);
+
+uint64_t rpnBinaryOp(IfRpnOp i_op, uint64_t i_val1, uint64_t i_val2,
+ uint32_t i_any);
+
+fapi::ReturnCode rpnDoPush(ifData_t & io_ifData, const uint16_t i_id,
+ uint32_t & io_any, const uint16_t i_arrayIndex1 = 0);
+
+fapi::ReturnCode rpnDoOp(rpnStack_t * io_rpnStack, IfRpnOp i_op,
+ uint32_t i_any);
+
+fapi::ReturnCode evalRpn(ifData_t & i_ifData, char * i_expr, uint32_t i_len,
+ bool i_hasExpr = false);
+
+
+//******************************************************************************
+// hwpExecInitFile function
+//******************************************************************************
+
+/** @brief Execute the initfile
+ *
+ * This HWP can be called to execute a binary initfile.
+ *
+ * @param[in] i_Target Reference to fapi::Target
+ * @param[in] i_file The binary if filename: <initfile>.if
+ *
+ * @return ReturnCode. Zero on success.
+ */
+fapi::ReturnCode hwpExecInitFile(const fapi::Target & i_Target,
+ const char * i_file)
+{
+ FAPI_INF(">> hwpExecInitFile: Performing HWP for %s", i_file);
+
+ // Print the ecmd string of the chip
+ char l_string[fapi::MAX_ECMD_STRING_LEN] = {0};
+ i_Target.toString(l_string);
+ FAPI_INF("HwpExecInitFile: Target: %s", l_string);
+
+ fapi::ReturnCode l_rc = fapi::FAPI_RC_SUCCESS;
+ fapi::ReturnCode l_tmpRc = fapi::FAPI_RC_SUCCESS;
+ size_t l_ifSize = 0;
+ const char * l_ifAddr = NULL;
+ const char * l_offset = NULL;
+
+ // Load the binary initfile
+ l_rc = fapiLoadInitFile(i_file, l_ifAddr, l_ifSize);
+
+ if (l_rc.ok())
+ {
+ FAPI_DBG("hwpExecInitFile: data module addr = %p, size = %ld",
+ l_ifAddr, l_ifSize);
+
+ //Expect binary file size to be greater than header size
+ if(l_ifSize <= IF_HEADER_SIZE)
+ {
+ FAPI_ERR("hwpExecInitFile: if file size %ld <= if header size %u",
+ l_ifSize, IF_HEADER_SIZE);
+ fapiAssert(false);
+ }
+
+ //Check the version
+ l_offset = l_ifAddr + IF_VERSION_LOC;
+
+ if (IF_SYNTAX_VERSION != *(reinterpret_cast<const uint32_t *>(l_offset)))
+ {
+ FAPI_ERR("hwpExecInitFile: Syntax version 0x%x Expected version 0x%x",
+ *(const uint32_t *)l_offset, IF_SYNTAX_VERSION);
+
+ uint32_t l_ffdc = *(const uint32_t *)l_offset;
+ uint32_t & FFDC_IF_VER = l_ffdc; // GENERIC IDENTIFIER
+ FAPI_SET_HWP_ERROR(l_rc, RC_INITFILE_INCORRECT_VER);
+
+ // Unload the initfile, disregard this rc
+ l_tmpRc = fapiUnloadInitFile(i_file, l_ifAddr, l_ifSize);
+ if (!l_tmpRc.ok())
+ {
+ //Log error
+ fapiLogError(l_tmpRc);
+ }
+ }
+ else
+ {
+ //Save the data
+ ifInfo_t l_ifInfo;
+ memset(&l_ifInfo, 0, sizeof(ifInfo_t));
+ l_ifInfo.addr = l_ifAddr;
+ l_ifInfo.size = l_ifSize;
+ l_ifInfo.offset = IF_VERSION_LOC;
+
+ ifData_t l_ifData;
+ memset(&l_ifData, 0, sizeof(ifData_t));
+
+ //--------------------------------
+ // Load the Attribute Symbol Table
+ //--------------------------------
+ attrTableEntry_t * l_attrs = NULL;
+ uint16_t l_numAttrs = 0;
+
+ l_attrs = loadAttrSymbolTable(l_ifInfo, l_numAttrs);
+ FAPI_DBG("hwpExecInitFile: Addr of attribute struct %p, "
+ "num attrs %u", l_attrs, l_numAttrs);
+
+ l_ifData.attrs = l_attrs;
+ l_ifData.numAttrs = l_numAttrs;
+
+ //--------------------------------
+ // Load the Literal Symbol Table
+ //--------------------------------
+ uint64_t * l_numericLits = NULL;
+ uint16_t l_numLits = 0;
+
+ l_numericLits = loadLitSymbolTable(l_ifInfo, l_numLits);
+ FAPI_DBG("hwpExecInitFile: Addr of literal struct %p, "
+ "num lits %u", l_numericLits, l_numLits);
+
+ l_ifData.numericLits = l_numericLits;
+ l_ifData.numLits = l_numLits;
+
+ //--------------------------------
+ // Load the SCOM Section
+ //--------------------------------
+ scomData_t * l_scoms = NULL;
+ uint32_t l_numScoms = 0;
+
+ l_scoms = loadScomSection(l_ifInfo, l_numScoms);
+ FAPI_DBG("hwpExecInitFile: Addr of scom struct %p, "
+ "num scoms %u", l_scoms, l_numScoms);
+
+ l_ifData.scoms = l_scoms;
+ l_ifData.numScoms = l_numScoms;
+
+ //--------------------------------
+ // Execute SCOMs
+ //--------------------------------
+ l_ifData.pTarget = &i_Target;
+
+ l_rc = executeScoms(l_ifData);
+
+ //--------------------------------
+ // Unload
+ //--------------------------------
+
+ // Unload the Attribute Symbol Table
+ unloadAttrSymbolTable(l_attrs);
+
+ // Unload the Literal Symbol Table
+ unloadLitSymbolTable(l_numericLits);
+
+ // Unload the Literal Symbol Table
+ unloadScomSection(l_scoms, l_numScoms);
+ }
+
+ // Unload the initfile
+ l_tmpRc = fapiUnloadInitFile(i_file, l_ifAddr, l_ifSize);
+
+ // return code from executeScoms takes precedence
+ if (l_rc.ok())
+ {
+ l_rc = l_tmpRc;
+ }
+ else if (!l_tmpRc.ok())
+ {
+ //Log error
+ fapiLogError(l_tmpRc);
+ }
+ }
+
+ FAPI_INF("<< hwpExecInitFile: Performing HWP for %s", i_file);
+ return l_rc;
+}
+
+
+//******************************************************************************
+// Helper functions to read initfiles
+//******************************************************************************
+
+/** @brief Seek to the specified offset in the binary initfile
+ *
+ * Seeks from the start of the file to the position passed in.
+ *
+ * @param[in,out] io_ifInfo Reference to ifInfo_t which contains addr, size,
+ * and current offset of the initfile
+ * @param[in] i_offset Position to seek to.
+ */
+void ifSeek(ifInfo_t & io_ifInfo, size_t i_offset)
+{
+ if (i_offset > io_ifInfo.size)
+ {
+ FAPI_ERR("hwpExecInitFile: ifSeek: offset out of range 0x%X", i_offset);
+
+ fapiAssert(false);
+ }
+
+ //Advance the offset
+ io_ifInfo.offset = i_offset;
+}
+
+/** @brief Reads the initfile
+ *
+ * Reads the binary initfile at the current offset.
+ *
+ * @param[in,out] io_ifInfo Reference to ifInfo_t which contains addr, size,
+ * and current offset of the initfile
+ * @param[out] o_data Ptr to buffer where data read will be stored
+ * @param[in] i_size number of bytes to read
+ */
+void ifRead(ifInfo_t & io_ifInfo, void * o_data, uint32_t i_size)
+{
+ if ((io_ifInfo.offset + i_size) > io_ifInfo.size)
+ {
+ FAPI_ERR("hwpExecInitFile: ifRead: offset 0x%X +size 0x%X out of range",
+ io_ifInfo.offset, i_size);
+
+ fapiAssert(false);
+ }
+
+ //Copy the data
+ memcpy(o_data, io_ifInfo.addr + io_ifInfo.offset, i_size);
+
+ //Advance the offset
+ io_ifInfo.offset += i_size;
+}
+
+//******************************************************************************
+// Helper functions for Attributes
+//******************************************************************************
+
+/** @brief Loads the Attribute Symbol Table
+ *
+ * Loads the Attribute Symbol Table from the binary initfile.
+ *
+ * @param[in,out] io_ifInfo Reference to ifInfo_t which contains addr, size,
+ * and current offset of the initfile
+ * @param[out] o_numAttrs Number of Attribute entries read
+ *
+ * @return attrTableEntry_t * ptr to the Attribute Symbol Table
+ */
+attrTableEntry_t * loadAttrSymbolTable(ifInfo_t & io_ifInfo,
+ uint16_t & o_numAttrs)
+{
+ FAPI_DBG(">> hwpExecInitFile: loadAttrSymbolTable");
+
+ attrTableEntry_t * l_attrs = NULL;
+ uint32_t l_attrTableOffset = 0;
+
+ //Seek to the Attribute Symbol Table offset
+ ifSeek(io_ifInfo, IF_ATTR_TABLE_OFFSET_LOC);
+
+ //Read the offset to the Attribute Symbol Table
+ ifRead(io_ifInfo, &l_attrTableOffset, IF_ATTR_TABLE_OFFSET_SIZE);
+
+ //Seek to the Attribute Symbol Table
+ ifSeek(io_ifInfo, l_attrTableOffset);
+
+ //Read the number of attributes
+ ifRead(io_ifInfo, &o_numAttrs, sizeof(o_numAttrs));
+ FAPI_DBG("loadAttrSymbolTable: Offset of Attr Symbol Table 0x%X "
+ "num attrs %u", l_attrTableOffset, o_numAttrs);
+
+ //Now read the individual attribute entry
+ if (0 < o_numAttrs)
+ {
+ //Allocate memory to hold the attribute data
+ l_attrs = reinterpret_cast<attrTableEntry_t *>
+ (malloc(o_numAttrs * sizeof(attrTableEntry_t)));
+ memset(l_attrs, 0, o_numAttrs * sizeof(attrTableEntry_t));
+
+ for (uint16_t i = 0; i < o_numAttrs; i++)
+ {
+ //Read the attribute type
+ ifRead(io_ifInfo, &(l_attrs[i].type), sizeof(l_attrs[i].type));
+
+ //Read the attribute id
+ ifRead(io_ifInfo, &(l_attrs[i].attrId), sizeof(l_attrs[i].attrId));
+
+ FAPI_DBG("loadAttrSymbolTable: attr[%u]: type 0x%x, id 0x%x",
+ i, l_attrs[i].type, l_attrs[i].attrId);
+ }
+ }
+
+ FAPI_DBG("<< hwpExecInitFile: loadAttrSymbolTable");
+ return l_attrs;
+}
+
+/** @brief Unloads the Attribue Symbol Table from memory
+ *
+ * Unloads the Attribute Symbol Table from memory
+ *
+ * @param[in,out] io_attrs Reference to ptr to the Attribute Symbol Table
+ */
+void unloadAttrSymbolTable(attrTableEntry_t *& io_attrs)
+{
+ FAPI_DBG("hwpExecInitFile: unloadAttrSymbolTable");
+ // Deallocate memory
+ free(io_attrs);
+ io_attrs = NULL;
+}
+
+/** @brief Get an InitFile attribute value
+ *
+ * This function gets a copy of an attribute. In the case of an array attribute,
+ * The value in the specified index is retrieved.
+ *
+ * If there are ever attributes with more than 4 dimensions then this function
+ * will need to be updated.
+ *
+ * @param[in] i_ifData Reference to ifData_t which contains initfile data
+ * @param[in] i_id AttributeID
+ * @param[out] o_val Reference to uint64_t where attribute value is set
+ * @param[in] i_arrayIndex1 If array attribute then index1
+ * @param[in] i_arrayIndex2 If at least 2D array attribute then index2
+ * @param[in] i_arrayIndex3 If at least 3D array attribute then index3
+ * @param[in] i_arrayIndex4 If at least 4D array attribute then index4
+ *
+ * @return ReturnCode. Zero if success.
+ */
+//******************************************************************************
+fapi::ReturnCode getAttr(const ifData_t & i_ifData,
+ const uint16_t i_id,
+ uint64_t & o_val,
+ const uint32_t i_arrayIndex1,
+ const uint32_t i_arrayIndex2,
+ const uint32_t i_arrayIndex3,
+ const uint32_t i_arrayIndex4)
+{
+ FAPI_DBG(">> hwpExecInitFile: getAttr: id 0x%x index %d",
+ i_id, i_arrayIndex1);
+
+ fapi::ReturnCode l_rc = fapi::FAPI_RC_SUCCESS;
+
+ //Mask out the types bits and zero-base
+ uint16_t l_id = (i_id & (~IF_TYPE_MASK)) - 1;
+ FAPI_DBG("hwpExecInitFile: getAttr: id %u", l_id);
+
+ if ((0 <= l_id) && (l_id < i_ifData.numAttrs))
+ {
+ const fapi::Target * l_pTarget = NULL;
+ bool l_systemAttr = true;
+
+ //@todo - check if system attribute once info is encoded in the binary
+ //initfile
+ if (!l_systemAttr)
+ {
+ l_pTarget = i_ifData.pTarget;
+ }
+
+ fapi::AttributeId l_attrId =
+ static_cast<fapi::AttributeId>(i_ifData.attrs[l_id].attrId);
+ FAPI_DBG("hwpExecInitFile: getAttr: attrId %u", l_attrId);
+
+ l_rc = fapi::fapiGetInitFileAttr(l_attrId, l_pTarget, o_val,
+ i_arrayIndex1, i_arrayIndex2,
+ i_arrayIndex3, i_arrayIndex4);
+
+ if (l_rc)
+ {
+ FAPI_ERR("hwpExecInitFile: getAttr: GetInitFileAttr failed rc 0x%x",
+ static_cast<uint32_t>(l_rc));
+ }
+ else
+ {
+ FAPI_DBG("hwpExecInitFile: getAttr: val 0x%.16x", o_val);
+ }
+ }
+ else
+ {
+ FAPI_ERR("hwpExecInitFile: getAttr: id out of range");
+
+ uint32_t l_ffdc = i_id;
+ uint32_t & FFDC_IF_ATTR_ID_OUT_OF_RANGE = l_ffdc; // GENERIC IDENTIFIER
+ FAPI_SET_HWP_ERROR(l_rc, RC_INITFILE_ATTR_ID_OUT_OF_RANGE);
+ }
+
+ FAPI_DBG("<< hwpExecInitFile: getAttr");
+ return l_rc;
+}
+
+
+//******************************************************************************
+// Helper functions for Literals
+//******************************************************************************
+
+/** @brief Loads the Literal Symbol Table
+ *
+ * Loads the Literal Symbol Table from the binary initfile.
+ *
+ * @param[in,out] io_ifInfo Reference to ifInfo_t which contains addr, size,
+ * and current offset of the initfile
+ * @param[out] o_numLits Reference to number of Literal entries read
+ *
+ * @return uint64_t * Ptr to the Literal Symbol Table
+ */
+uint64_t * loadLitSymbolTable(ifInfo_t & io_ifInfo,
+ uint16_t & o_numLits)
+{
+ FAPI_DBG(">> hwpExecInitFile: loadLitSymbolTable");
+
+ uint64_t * l_numericLits = NULL;
+ uint32_t l_litTableOffset = 0;
+
+ //Seek to the Literal Symbol Table offset
+ ifSeek(io_ifInfo, IF_LIT_TABLE_OFFSET_LOC);
+
+ //Read the offset to the Literal Symbol Table
+ ifRead(io_ifInfo, &l_litTableOffset, IF_LIT_TABLE_OFFSET_SIZE);
+
+ //Seek to the Literal Symbol Table
+ ifSeek(io_ifInfo, l_litTableOffset);
+
+ //Read the number of literals
+ ifRead(io_ifInfo, &o_numLits, sizeof(o_numLits));
+ FAPI_DBG("loadLitSymbolTable: Offset of Literal Symbol Table 0x%X "
+ "num literals %u", l_litTableOffset, o_numLits);
+
+ if (0 < o_numLits)
+ {
+ //Now read the individual literal entry
+
+ uint8_t l_litSize = 0;
+
+ l_numericLits =
+ reinterpret_cast<uint64_t *>(malloc(o_numLits * sizeof(uint64_t)));
+ memset(l_numericLits, 0, o_numLits * sizeof(uint64_t));
+
+ for (uint16_t i = 0; i < o_numLits; i++)
+ {
+ //Read the literal size in bytes
+ ifRead(io_ifInfo, &l_litSize, sizeof(l_litSize));
+
+ if ((l_litSize > 0) && (l_litSize <= sizeof(uint64_t)))
+ {
+ //Read the literal value
+ ifRead(io_ifInfo, &(l_numericLits[i]), l_litSize);
+
+ //Right justify
+ l_numericLits[i] >>= (64 - (l_litSize * 8));
+
+ FAPI_DBG("loadLitSymbolTable: lit[%u]: size 0x%x, value 0x%016x",
+ i, l_litSize, l_numericLits[i]);
+ }
+ else
+ {
+ //Expect nonzero literal size of 1 to 8 bytes
+ FAPI_ERR("loadLitSymbolTable: lit[%u]: invalid size %u",
+ i, l_litSize);
+ fapiAssert(false);
+ }
+ }
+ }
+
+ FAPI_DBG("<< hwpExecInitFile: loadLitSymbolTable");
+ return l_numericLits;
+}
+
+/** @brief Unloads the Literal Symbol Table from memory
+ *
+ * Unloads the Literal Symbol Table from memory
+ *
+ * @param[in,out] io_numericLits Reference to ptr to the Literal Symbol Table
+ */
+void unloadLitSymbolTable(uint64_t *& io_numericLits)
+{
+ FAPI_DBG("hwpExecInitFile: unloadLitSymbolTable");
+
+ // Deallocate memory
+ free(io_numericLits);
+ io_numericLits = NULL;
+}
+
+/** @brief Get an InitFile numeric literal value
+ *
+ * This function gets a copy of a numeric literal.
+ *
+ * @param[in] i_ifData Reference to ifData_t which contains initfile data
+ * @param[in] i_id Numeric Literal id
+ * @param[out] o_val Reference to uint64_t where literal value is set
+ *
+ * @return ReturnCode. Zero if success.
+ */
+//******************************************************************************
+fapi::ReturnCode getLit(const ifData_t & i_ifData,
+ const uint16_t i_id,
+ uint64_t & o_val)
+{
+ FAPI_DBG(">> hwpExecInitFile: getLit: id 0x%X", i_id);
+
+ fapi::ReturnCode l_rc = fapi::FAPI_RC_SUCCESS;
+
+ //Mask out the type bits and zero-base
+ uint16_t l_id = (i_id & (~IF_TYPE_MASK)) - 1;
+
+ if ((0 <= l_id) && (l_id < i_ifData.numLits))
+ {
+ o_val = i_ifData.numericLits[l_id];
+ FAPI_DBG("hwpExecInitFile: getLit: val 0x%.16X", o_val);
+ }
+ else
+ {
+ FAPI_ERR("hwpExecInitFile: getLit: id out of range");
+
+ uint32_t l_ffdc = i_id;
+ uint32_t & FFDC_IF_LIT_ID_OUT_OF_RANGE = l_ffdc; // GENERIC IDENTIFIER
+ FAPI_SET_HWP_ERROR(l_rc, RC_INITFILE_LIT_ID_OUT_OF_RANGE);
+ }
+
+ return l_rc;
+}
+
+
+//******************************************************************************
+// Helper functions for Scoms
+//******************************************************************************
+
+/** @brief Loads the Scom Section
+ *
+ * Loads the Scom Section from the binary initfile.
+ *
+ * @param[in,out] io_ifInfo Reference to ifInfo_t which contains addr, size,
+ * and current offset of the initfile
+ * @param[out] o_numScoms Reference to number of Scom entries read
+ *
+ * @return scomData_t * Ptr to the Scom Section
+ */
+scomData_t * loadScomSection(ifInfo_t & io_ifInfo,
+ uint32_t & o_numScoms)
+{
+ FAPI_DBG(">> hwpExecInitFile: loadScomSection");
+
+ scomData_t * l_scoms = NULL;
+ uint32_t l_scomSectionOffset = 0;
+
+ //Seek to the Scom Section offset
+ ifSeek(io_ifInfo, IF_SCOM_SECTION_OFFSET_LOC);
+
+ //Read the offset to the Scom Section
+ ifRead(io_ifInfo, &l_scomSectionOffset, IF_SCOM_SECTION_OFFSET_SIZE);
+
+ //Read the number of Scoms
+ ifRead(io_ifInfo, &o_numScoms, sizeof(o_numScoms));
+ FAPI_DBG("loadScomSection: Offset of Scom Section 0x%X "
+ "num scoms %u", l_scomSectionOffset, o_numScoms);
+
+ //Seek to the Scom Section
+ ifSeek(io_ifInfo, l_scomSectionOffset);
+
+ if (0 < o_numScoms)
+ {
+ //------------------------------------
+ //Now read the individual SCOM entry
+ //------------------------------------
+
+ //Allocate memory to hold the data
+ l_scoms = reinterpret_cast<scomData_t *>(malloc(o_numScoms * sizeof(scomData_t)));
+ memset(l_scoms, 0, o_numScoms * sizeof(scomData_t));
+
+ for (uint32_t i = 0; i < o_numScoms; i++)
+ {
+ //Read the SCOM len
+ ifRead(io_ifInfo, &(l_scoms[i].len), sizeof(l_scoms[i].len));
+
+ //Read the SCOM offset
+ ifRead(io_ifInfo, &(l_scoms[i].offset), sizeof(l_scoms[i].offset));
+
+ //Read the SCOM address id
+ ifRead(io_ifInfo, &(l_scoms[i].addrId), sizeof(l_scoms[i].addrId));
+
+ //Expect numeric literal id, 1-based
+ if ( ! ((IF_NUM_TYPE == (l_scoms[i].addrId & IF_TYPE_MASK)) &&
+ (IF_NUM_TYPE < l_scoms[i].addrId)) )
+ {
+ FAPI_ERR("loadScomSection: scom[%u]: addrId not a numeric "
+ "literal");
+ fapiAssert(false);
+ }
+
+ //Read the number of columns
+ ifRead(io_ifInfo, &(l_scoms[i].numCols), sizeof(l_scoms[i].numCols));
+
+ //Read the number of rows
+ ifRead(io_ifInfo, &(l_scoms[i].numRows), sizeof(l_scoms[i].numRows));
+
+ FAPI_DBG("loadScomSection: scom[%u]: len %u, offset %u",
+ i, l_scoms[i].len, l_scoms[i].offset);
+ FAPI_DBG("loadScomSection: addr id 0x%x, #cols %u, #rows %u",
+ l_scoms[i].addrId, l_scoms[i].numCols,
+ l_scoms[i].numRows);
+
+ //Expect at least one row
+ if (0 >= l_scoms[i].numRows)
+ {
+ FAPI_ERR("loadScomSection: scom[%u]: num rows %u <= 0",
+ l_scoms[i].numRows);
+ fapiAssert(false);
+ }
+
+ //-----------------------------------
+ //Read the scom data ids
+ //-----------------------------------
+
+ //Allocate memory to hold the data ids; i.e. numeric literal ids
+ l_scoms[i].dataId =
+ reinterpret_cast<uint16_t*>(malloc(l_scoms[i].numRows * sizeof(uint16_t*)));
+ memset(l_scoms[i].dataId, 0,
+ l_scoms[i].numRows * sizeof(uint16_t*));
+
+ //Read the data ids
+ for (uint16_t j = 0; j < l_scoms[i].numRows; j++)
+ {
+ ifRead(io_ifInfo, &(l_scoms[i].dataId[j]),
+ sizeof(l_scoms[i].dataId[j]));
+
+ FAPI_DBG("loadScomSection: scom[%u]: dataId[%u] 0x%02x",
+ i, j, l_scoms[i].dataId[j]);
+ }
+
+ // Set to default
+ l_scoms[i].hasExpr = false;
+
+ //-----------------------------------
+ //Load the column data
+ //-----------------------------------
+ if (0 < l_scoms[i].numCols)
+ {
+ //Allocate memory to hold the column data
+ l_scoms[i].colId =
+ reinterpret_cast<uint16_t *>(malloc(l_scoms[i].numCols * sizeof(uint16_t)));
+ memset(l_scoms[i].colId, 0,
+ l_scoms[i].numCols * sizeof(uint16_t));
+
+ //Read Column Id
+ uint16_t j;
+ for (j = 0; j < l_scoms[i].numCols; j++)
+ {
+ ifRead(io_ifInfo, &(l_scoms[i].colId[j]),
+ sizeof(l_scoms[i].colId[j]));
+
+ FAPI_DBG("loadScomSection: scom[%u]: colId[%u] "
+ "0x%02x", i, j, l_scoms[i].colId[j]);
+ }
+
+ //Is the last column an EXPR column
+ if (IF_EXPR == l_scoms[i].colId[j-1])
+ {
+ l_scoms[i].hasExpr = true;
+ }
+ }
+
+ //-----------------------------------
+ //Load the row data for each columns
+ //-----------------------------------
+ if (0 == l_scoms[i].numCols)
+ {
+ // Set the row data ptr to NULL & discard 1-byte row size
+ l_scoms[i].rowData = NULL;
+ ifSeek(io_ifInfo, io_ifInfo.offset + 1);
+ }
+ else
+ {
+ //Allocate memory to hold the row data
+ l_scoms[i].rowData =
+ reinterpret_cast<char**>(malloc(l_scoms[i].numRows * sizeof(char**)));
+ memset(l_scoms[i].rowData, 0,
+ l_scoms[i].numRows * sizeof(char**));
+
+ // Determine the number of simple columns (not an expr columns)
+ uint16_t l_numSimpleCols = l_scoms[i].numCols;
+ if (l_scoms[i].hasExpr)
+ {
+ l_numSimpleCols--;
+ }
+
+ //Read the row data for each row
+ uint8_t l_rowSize = 0;
+ char * l_rowPtr = NULL;
+ uint32_t c;
+
+ for (uint16_t j = 0; j < l_scoms[i].numRows; j++)
+ {
+ //Read the row size; i.e. # of bytes
+ ifRead(io_ifInfo, &l_rowSize, sizeof(l_rowSize));
+
+ //Expect non-zero row size
+ if (0 >= l_rowSize)
+ {
+ FAPI_ERR("loadScomSection: scom[%u]: row size %u",
+ l_rowSize);
+ fapiAssert(false);
+ }
+
+ //If have expr column, need another byte to store its length
+ if (l_scoms[i].hasExpr)
+ {
+ l_rowSize++;
+ }
+
+ //Allocate the space
+ l_scoms[i].rowData[j] = reinterpret_cast<char *>(malloc(l_rowSize));
+ l_rowPtr = l_scoms[i].rowData[j];
+
+ //Read in the simple column entries in the rows
+ for (uint16_t k = 0; k < l_numSimpleCols; k++)
+ {
+ //Keep reading in data until we hit a non push, which
+ //would be an operator
+ while (1)
+ {
+ //Read the first byte of the Push, or an operator
+ ifRead(io_ifInfo, l_rowPtr, sizeof(char));
+ FAPI_DBG("loadScomSection: scom[%u]: rowData[%u] "
+ "0x%02x", i, j, *l_rowPtr);
+
+ c = *l_rowPtr++;
+ l_rowSize--;
+
+ //If it's not a push, then it must be an operator,
+ //so we're done
+ if (!(c & PUSH_MASK))
+ {
+ break;
+ }
+
+ //It was a push, so read in the 2nd byte of it
+ ifRead(io_ifInfo, l_rowPtr, sizeof(char));
+ FAPI_DBG("loadScomSection: scom[%u]: rowData[%u] "
+ "0x%02x", i, j, *l_rowPtr);
+ l_rowPtr++;
+ l_rowSize--;
+ }
+ }
+
+ //After the simple columns comes the expression column,
+ //if present
+ if (l_scoms[i].hasExpr)
+ {
+ l_rowSize--;
+ *l_rowPtr = l_rowSize; //Save the length of the expr
+ FAPI_DBG("loadScomSection: scom[%u]: rowData[%u] "
+ "expr len 0x%02x", i, j, *l_rowPtr);
+ l_rowPtr++;
+
+ //Read in the rest of the expression, which goes to the
+ //end of the row
+ while (l_rowSize--)
+ {
+ ifRead(io_ifInfo, l_rowPtr, sizeof(char));
+ FAPI_DBG("loadScomSection: scom[%u]: rowData[%u] "
+ "0x%02x", i, j, *l_rowPtr);
+ l_rowPtr++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ FAPI_DBG("<< hwpExecInitFile: loadScomSection");
+ return l_scoms;
+}
+
+/** @brief Unloads the Scom Section from memory
+ *
+ * @param[in, out] io_scoms Reference to ptr to the Scom Section
+ * @param[in] i_numScoms Number of Scom entries
+ */
+void unloadScomSection(scomData_t *& io_scoms, uint32_t i_numScoms)
+{
+ FAPI_DBG(">> hwpExecInitFile: unloadScomSection");
+
+ //Deallocate memory
+ for (uint32_t i = 0; i < i_numScoms; i++)
+ {
+ free(io_scoms[i].dataId);
+ io_scoms[i].dataId = NULL;
+
+ free(io_scoms[i].colId);
+ io_scoms[i].colId = NULL;
+
+ if (NULL != io_scoms[i].rowData)
+ {
+ for (uint16_t j = 0; j < io_scoms[i].numRows; j++)
+ {
+ free(io_scoms[i].rowData[j]);
+ io_scoms[i].rowData[j] = NULL;
+ }
+
+ free(io_scoms[i].rowData);
+ io_scoms[i].rowData = NULL;
+ }
+ }
+
+ free(io_scoms);
+ io_scoms = NULL;
+
+ FAPI_DBG("<< hwpExecInitFile: unloadScomSection");
+}
+
+/** @brief Execute the Scom Section
+ *
+ * @param[in] i_ifData Reference to ifData_t which contains initfile data
+ *
+ * @return ReturnCode. Zero if success.
+ */
+fapi::ReturnCode executeScoms(ifData_t & i_ifData)
+{
+ FAPI_INF(">> hwpExecInitFile: executeScoms");
+
+ fapi::ReturnCode l_rc;
+ uint16_t l_numSimpleCols = 0;
+ uint8_t l_len = 0;
+ char * l_rowExpr = NULL;
+ uint16_t * l_colExpr = NULL;
+ uint16_t l_row;
+ bool l_goToNextRow = false;
+ rpnStack_t l_rpnStack;
+ uint64_t result = 0;
+
+ //Create RPN stack
+ l_rpnStack.reserve(128);
+
+ i_ifData.rpnStack = &l_rpnStack;
+
+ for (uint32_t i = 0; i < i_ifData.numScoms; i++)
+ {
+ //Get the number of simple columns
+ l_numSimpleCols = i_ifData.scoms[i].numCols;
+ if (i_ifData.scoms[i].hasExpr)
+ {
+ l_numSimpleCols--;
+ }
+
+ FAPI_DBG("hwpExecInitFile: executeScoms: #simple cols %u",
+ l_numSimpleCols);
+
+ for (l_row = 0; l_row < i_ifData.scoms[i].numRows; l_row++)
+ {
+ //Nothing to check if there are no columns
+ //We found a row match
+ if ((0 == i_ifData.scoms[i].numCols) ||
+ (NULL == i_ifData.scoms[i].rowData))
+ {
+ FAPI_DBG("hwpExecInitFile: executeScoms: no cols");
+ break;
+ }
+
+ //Get a pointer to the row expressions
+ l_rowExpr = i_ifData.scoms[i].rowData[l_row];
+
+ //Get a pointer to the column expressions
+ if (l_numSimpleCols > 0)
+ {
+ l_colExpr = i_ifData.scoms[i].colId;
+ }
+
+ //Evaluate the simple columns (not the 'expr' column)
+ for (uint16_t col= 0; col < l_numSimpleCols; col++)
+ {
+ //This will always be a push
+ l_rc = evalRpn(i_ifData, (char *)l_colExpr, 2);
+
+ if (l_rc)
+ {
+ FAPI_ERR("hwpExecInitFile: Simple Column evalRpn failed");
+ break;
+ }
+
+ l_colExpr++; //advance past calculation
+
+ //This might be several pushes or just a push and an operator,
+ //so loop to read in the pushes
+ //An OP marks the end of a simple column RPN
+ while (static_cast<uint32_t>(*l_rowExpr) & PUSH_MASK)
+ {
+ // PUSH (SYMBOL) always 2 bytes
+ l_rc = evalRpn(i_ifData, l_rowExpr, 2);
+
+ if (l_rc)
+ {
+ FAPI_ERR("hwpExecInitFile: Simple Column evalRpn failed"
+ " on scom 0x%X", i_ifData.scoms[i].addrId);
+ break;
+ }
+
+ l_rowExpr += 2; //advance past the calculation
+ }
+
+ if (l_rc)
+ {
+ break;
+ }
+
+ //If the op is TRUE_OP or FALSE_OP then pop the extra column
+ //symbol off the Rpn stack since it won't be consumed by the OP
+ if((*l_rowExpr == FALSE_OP) || (*l_rowExpr == TRUE_OP))
+ {
+ //Unconditional OP; throw pushed COL symbol away
+ rpnPop(i_ifData.rpnStack);
+ FAPI_DBG("hwpExecInitFile: executeScoms: True or False op");
+ }
+
+ l_rc = evalRpn(i_ifData, l_rowExpr, 1);
+ l_rowExpr++;
+
+ if (l_rc)
+ {
+ FAPI_ERR("hwpExecInitFile: Simple Column evalRpn failed on "
+ "scom 0x%X", i_ifData.scoms[i].addrId);
+ break;
+ }
+
+ result = rpnPop(i_ifData.rpnStack);
+ FAPI_DBG("hwpExecInitFile: executeScoms: Simple Col: result 0x%X",
+ result);
+
+ //If zero, continue on to the next row.
+ if (0 == result)
+ {
+ l_goToNextRow = true;
+ break; //break out of simple column for loop
+ }
+
+ } //End looping on simple columns
+
+ if (l_rc)
+ {
+ break;
+ }
+
+ //Skip over to the next row
+ if (l_goToNextRow)
+ {
+ FAPI_DBG("hwpExecInitFile: executeScoms: check next row");
+ l_goToNextRow = false;
+ continue;
+ }
+
+ //Now evaluate the expression, if there is one
+ if (i_ifData.scoms[i].hasExpr)
+ {
+ FAPI_DBG("hwpExecInitFile: Evaluate expr");
+
+ l_len = *((uint8_t*)l_rowExpr);
+ l_rowExpr++;
+ //l_len--; //remove the length value from the length left
+
+ l_rc = evalRpn(i_ifData, l_rowExpr, l_len, true);
+
+ if (l_rc)
+ {
+ FAPI_ERR("hwpExecInitFile: Row expression evalRpn failed on "
+ "scom 0x%X", i_ifData.scoms[i].addrId);
+ break;
+ }
+
+ result = rpnPop(i_ifData.rpnStack);
+ FAPI_DBG("hwpExecInitFile: executeScoms: Expr: result 0x%X",
+ result);
+
+ //If nonzero, we're done so break out of row loop, otherwise
+ //let it go down to the next row
+ if (0 != result)
+ {
+ FAPI_DBG("hwpExecInitFile: executeScoms: Expr: found valid row");
+ break;
+ }
+ }
+ else
+ {
+ //No expression, and we're at the end, so we must
+ //have found a match in the columns
+ FAPI_DBG("hwpExecInitFile: executeScoms: found valid row");
+ break;
+ }
+
+ } // end looping for all rows
+
+ if (l_rc)
+ {
+ break;
+ }
+
+ FAPI_DBG("hwpExecInitFile: executeScoms: row %u", l_row);
+
+ //Can tell we found a match by checking if we broke out of the
+ //for loop early
+ if (l_row < i_ifData.scoms[i].numRows)
+ {
+ FAPI_DBG("hwpExecInitFile: executeScoms: found valid row %u", l_row);
+ // Perform a scom operation on the chip
+ l_rc = writeScom(i_ifData, i, l_row);
+
+ if (l_rc)
+ {
+ break;
+ }
+ }
+
+ } // end looping for all scoms
+
+ //Clear the stack
+ l_rpnStack.clear();
+
+ FAPI_INF("<< hwpExecInitFile: executeScoms");
+ return l_rc;
+}
+
+/** @brief Write Scom
+ *
+ * @param[in] i_ifData Reference to ifData_t which contains initfile data
+ * @param[in] i_scomNum Scom entry number
+ * @param[in] i_row Scom entry row number
+ *
+ * @return ReturnCode. Zero if success.
+ */
+fapi::ReturnCode writeScom(const ifData_t & i_ifData, const uint32_t i_scomNum,
+ const uint16_t i_row)
+{
+ FAPI_DBG(">> hwpExecInitFile: writeScom");
+
+ fapi::ReturnCode l_rc = fapi::FAPI_RC_SUCCESS;
+ uint32_t l_ecmdRc = ECMD_DBUF_SUCCESS;
+
+ const fapi::Target l_target = *(i_ifData.pTarget);
+
+ do
+ {
+ //Get the the scom address
+ uint64_t l_addr = 0;
+ uint64_t l_id = i_ifData.scoms[i_scomNum].addrId;
+ l_rc = getLit(i_ifData, l_id, l_addr);
+
+ if (l_rc)
+ {
+ break;
+ }
+
+ //Get the scom data
+ uint64_t l_data = 0;
+ l_id = i_ifData.scoms[i_scomNum].dataId[i_row];
+ l_rc = getLit(i_ifData, l_id, l_data);
+
+ if (l_rc)
+ {
+ break;
+ }
+
+ FAPI_DBG("hwpExecInitFile: writeScom: addr 0x%.16llX, data 0x%.16llX",
+ l_addr, l_data);
+
+ //Create a 64 bit data buffer
+ ecmdDataBufferBase l_scomData(64);
+
+ //Check if this is a bit operation
+ if (i_ifData.scoms[i_scomNum].len)
+ {
+ //Perform a PutScomUnderMask operation on the target
+
+ #ifdef HOSTBOOT_DEBUG
+ l_rc = fapiGetScom(l_target, l_addr, l_scomData);
+ FAPI_DBG("hwpExecInitFile: writeScom: Data read 0x%.16llX",
+ l_scomData.getDoubleWord(0));
+ #endif
+
+ //Create a 64 bit data buffer
+ ecmdDataBufferBase l_scomMask(64);
+
+ //Get offset and len
+ uint16_t l_offset = i_ifData.scoms[i_scomNum].offset;
+ uint16_t l_len = i_ifData.scoms[i_scomNum].len;
+
+ //Shift data to the right offset
+ l_data >>= l_offset;
+
+ //Create mask
+ uint64_t l_mask = 0;
+ for (uint64_t i = l_offset; i < (l_offset + l_len); i++)
+ {
+ l_mask |= (0x8000000000000000 >> i);
+ }
+
+ FAPI_DBG("hwpExecInitFile: writeScom: data 0x%.16llX mask 0x%.16llX"
+ " len %u offset %u", l_data, l_mask, l_len, l_offset);
+
+ l_ecmdRc = l_scomData.setDoubleWord(0, l_data);
+ l_ecmdRc |= l_scomMask.setDoubleWord(0, l_mask);
+
+ if (l_ecmdRc != ECMD_DBUF_SUCCESS)
+ {
+ FAPI_ERR("hwpExecInitFile: writeScom: error from "
+ "ecmdDataBuffer setDoubleWord() - rc 0x%.8X",
+ l_ecmdRc);
+
+ l_rc = l_ecmdRc;
+ break;
+ }
+
+ FAPI_DBG("hwpExecInitFile: writeScom: PutScomUnderMask: "
+ "0x%.16llX = 0x%.16llX mask 0x%.16llX",
+ l_addr, l_scomData.getDoubleWord(0),
+ l_scomMask.getDoubleWord(0));
+
+ l_rc = fapiPutScomUnderMask(l_target, l_addr, l_scomData,
+ l_scomMask);
+
+ if (l_rc)
+ {
+ FAPI_ERR("hwpExecInitFile: Error from fapiPutScomUnderMask");
+ break;
+ }
+ #ifdef HOSTBOOT_DEBUG
+ else
+ {
+ l_rc = fapiGetScom(l_target, l_addr, l_scomData);
+ FAPI_DBG("hwpExecInitFile: writeScom: Data read 0x%.16llX",
+ l_scomData.getDoubleWord(0));
+ }
+ #endif
+ }
+ else
+ {
+ //Perform a PutScom operation on the target
+
+ #ifdef HOSTBOOT_DEBUG
+ l_rc = fapiGetScom(l_target, l_addr, l_scomData);
+ FAPI_DBG("hwpExecInitFile: writeScom: Data read 0x%.16llX",
+ l_scomData.getDoubleWord(0));
+ #endif
+
+ l_ecmdRc = l_scomData.setDoubleWord(0, l_data);
+
+ if (l_ecmdRc != ECMD_DBUF_SUCCESS)
+ {
+ FAPI_ERR("hwpExecInitFile: writeScom: error from "
+ "ecmdDataBuffer setDoubleWord() - rc 0x%.8llX",
+ l_ecmdRc);
+
+ l_rc = fapi::FAPI_RC_ECMD_MASK;
+ break;
+ }
+
+ FAPI_DBG("hwpExecInitFile: writeScom: PutScom: 0x%.16llX = 0x%.16llX",
+ l_addr, l_scomData.getDoubleWord(0));
+
+ l_rc = fapiPutScom(l_target, l_addr, l_scomData);
+
+ if (l_rc)
+ {
+ FAPI_ERR("hwpExecInitFile: Error from fapiPutScom");
+ }
+ #ifdef HOSTBOOT_DEBUG
+ else
+ {
+ l_rc = fapiGetScom(l_target, l_addr, l_scomData);
+ FAPI_DBG("hwpExecInitFile: writeScom: Data read 0x%.16llX",
+ l_scomData.getDoubleWord(0));
+ }
+ #endif
+ }
+
+ } while(0);
+
+ FAPI_DBG("<< hwpExecInitFile: writeScom");
+ return l_rc;
+}
+
+//******************************************************************************
+// RPN Calculator functions
+//******************************************************************************
+
+/** @brief Pushes a value onto the RPN stack.
+ *
+ * @param[in,out] io_rpnStack Ptr to RPN stack
+ * @param[in] i_val Value to push
+ */
+void rpnPush(rpnStack_t * io_rpnStack, uint64_t i_val)
+{
+ FAPI_DBG("hwpExecInitFile: rpnPush");
+
+ io_rpnStack->push_back(i_val);
+}
+
+/** @brief Pops the top value off of the RPN stack.
+ *
+ * @param[in,out] io_rpnStack Ptr to RPN stack
+ * @return uint64_t Value from top of stack
+ */
+uint64_t rpnPop(rpnStack_t * io_rpnStack)
+{
+ FAPI_DBG("hwpExecInitFile: rpnPop");
+
+ uint64_t l_val = 0;
+
+ if (io_rpnStack->size() != 0)
+ {
+ l_val = io_rpnStack->back();
+ io_rpnStack->pop_back();
+ }
+
+ return l_val;
+}
+
+/** @brief Dumps out the RPN stack
+ *
+ * @param[in] i_rpnStack Ptr to RPN stack
+ */
+void rpnDumpStack(rpnStack_t * i_rpnStack)
+{
+ #ifdef HOSTBOOT_DEBUG
+
+ FAPI_DBG(">> hwpExecInitFile: rpnDumpStack: stack size = %d",
+ i_rpnStack->size());
+
+ uint64_t l_val = 0;
+
+ for (ssize_t i = i_rpnStack->size() - 1; i >= 0; i--)
+ {
+ l_val = i_rpnStack->at(i);
+ FAPI_DBG("Stack: Value = 0x%llX", l_val);
+ }
+
+ FAPI_DBG("<< hwpExecInitFile: rpnDumpStack");
+
+ #endif
+}
+
+/** @brief Executes the unary operations - the ones with 1 operand.
+ *
+ * @param[in] i_op Operation to perform
+ * @param[in] i_val Value to perform it on
+ * @param[in] i_any Flag indicating if this is an ANY op
+ * @return uint64_t The result
+ */
+uint64_t rpnUnaryOp(IfRpnOp i_op, uint64_t i_val, uint32_t i_any)
+{
+ FAPI_DBG("hwpExecInitFile: rpnUnaryOp");
+ uint64_t result = 0;
+
+ if (i_op == NOT)
+ {
+ if (i_any & IF_ANY) //everything returns true
+ {
+ result = 1;
+ }
+ else
+ {
+ result = (i_val == 0) ? 1 : 0;
+ }
+ }
+ else
+ {
+ FAPI_ERR("hwpExecInitFile: rpnUnaryOp: Invalid Op %u", i_op);
+ fapiAssert(false);
+ }
+
+ return result;
+}
+
+/** @brief Executes the binary operations - the ones with 2 operands.
+ *
+ * @param[in] IfRpnOp i_op Operation to perform
+ * @param[in] uint64_t i_val1 The first operand
+ * @param[in] uint64_t i_val2 The second operand
+ * @return uint64_t The result
+ */
+uint64_t rpnBinaryOp(IfRpnOp i_op, uint64_t i_val1, uint64_t i_val2,
+ uint32_t i_any)
+{
+ FAPI_DBG(">> hwpExecInitFile: rpnBinaryOp 0x%X", i_op);
+
+ uint64_t result = 0;
+
+ //If either of these are ANY, then just return nonzero/true
+ if (i_any & IF_ANY)
+ {
+ result = 1;
+ FAPI_DBG("hwpExecInitFile: rpnBinaryOp: ANY");
+ }
+ else
+ {
+ switch (i_op)
+ {
+ case (AND):
+ result = i_val1 && i_val2;
+ break;
+
+ case (OR):
+ result = i_val1 || i_val2;
+ break;
+
+ case (EQ):
+ result = i_val1 == i_val2;
+ break;
+
+ case (NE):
+ result = i_val1 != i_val2;
+ break;
+
+ case (GT):
+ result = i_val1 > i_val2;
+ break;
+
+ case (GE):
+ result = i_val1 >= i_val2;
+ break;
+
+ case (LT):
+ result = i_val1 < i_val2;
+ break;
+
+ case (LE):
+ result = i_val1 <= i_val2;
+ break;
+
+ case (PLUS):
+ result = i_val1 + i_val2;
+ break;
+
+ case (MINUS):
+ result = i_val1 - i_val2;
+ break;
+
+ case (MULT):
+ result = i_val1 * i_val2;
+ break;
+
+ case (DIVIDE):
+ if (0 == i_val2)
+ {
+ FAPI_ERR("hwpExecInitFile: rpnBinaryOp: "
+ "Division by zero, i_val1 = 0x%x", i_val1);
+ fapiAssert(false);
+ }
+
+ result = i_val1 / i_val2;
+ break;
+
+ case (MOD):
+ if (0 == i_val2)
+ {
+ FAPI_ERR("hwpExecInitFile: rpnBinaryOp: "
+ "Mod by zero, i_val1 = 0x%x", i_val1);
+ fapiAssert(false);
+ }
+
+ result = i_val1 % i_val2;
+ break;
+
+ case (SHIFTLEFT):
+ result = i_val1 << i_val2;
+ break;
+
+ case (SHIFTRIGHT):
+ result = i_val1 >> i_val2;
+ break;
+
+ default:
+ FAPI_ERR("hwpExecInitFile: rpnBinaryOp, invalid operator %d",
+ i_op);
+ fapiAssert(false);
+ break;
+ }
+ }
+
+ FAPI_DBG("<< hwpExecInitFile: rpnBinaryOp: result 0x%X", result);
+ return result;
+}
+
+/** @brief Pushes an attribute or literal value onto the RPN stack.
+ *
+ * Pushes the attribute or literal value specified by i_id onto the RPN stack.
+ * It uses the appropriate symbol table to resolve the value first.
+ *
+ * @param[in,out] io_ifData Reference to ifData_t which contains initfile data
+ * @param[in] i_id Id of element to push
+ * @param[in,out] io_any Set if ANY op
+ * @param[in] i_arrayIndexId Set to array index if this is an array attribute,
+ * support for 1-dimensional array only
+ * @return fapi::ReturnCode Zero on success
+ */
+fapi::ReturnCode rpnDoPush(ifData_t & io_ifData, const uint16_t i_id,
+ uint32_t & io_any, const uint16_t i_arrayIndexId)
+{
+ FAPI_DBG(">> HwpInitFile: rpnDoPush: id 0x%X", i_id);
+
+ fapi::ReturnCode l_rc = fapi::FAPI_RC_SUCCESS;
+ uint64_t l_val = 0;
+ uint64_t l_idx = 0;
+
+ do
+ {
+
+ if ((i_id & IF_TYPE_MASK) == IF_VAR_TYPE) //It's an attribute
+ {
+ if (i_arrayIndexId)
+ {
+ l_rc = getLit(io_ifData, i_arrayIndexId, l_idx);
+
+ if (l_rc)
+ {
+ break;
+ }
+ }
+
+ l_rc = getAttr(io_ifData, i_id, l_val, l_idx);
+
+ if (l_rc)
+ {
+ break;
+ }
+
+ FAPI_DBG("hwpExecInitFile: rpnDoPush: getAttr: id = 0x%X, "
+ "value = 0x%llX idx = %u", i_id, l_val, l_idx);
+
+ rpnPush(io_ifData.rpnStack, l_val);
+ }
+ else //It's a literal
+ {
+ //If it's not 'ANY'
+ if (i_id != IF_VAL_ANY)
+ {
+ l_rc = getLit(io_ifData, i_id, l_val);
+ if (l_rc)
+ {
+ FAPI_ERR("hwpExecInitFile: rpnDoPush: getLit: id 0x%X failed",
+ i_id);
+ break;
+ }
+
+ FAPI_DBG("hwpExecInitFile: rpnDoPush: Literal lookup: "
+ "id = 0x%X, value = 0x%llX", i_id, l_val);
+
+ rpnPush(io_ifData.rpnStack, l_val);
+ }
+ else //It's 'ANY', which will always return true
+ {
+ io_any |= IF_ANY;
+
+ l_val = 1;
+ rpnPush(io_ifData.rpnStack, l_val);
+
+ //If this is set, then we will see a PUSH ANY on the stack
+ //without the 2nd operand for the binary operator EQ. This
+ //happens when parsing the expression column
+ if (io_any & IF_ONE_SIDED_ANY)
+ {
+ //To get the second operand, push a fake one on the stack
+ uint64_t l_temp = 0;
+ rpnPush(io_ifData.rpnStack, l_temp);
+ }
+
+ FAPI_DBG("hwpExecInitFile: rpnDoPush: Literal ANY pushed on "
+ "stack");
+ }
+ }
+
+ } while(0);
+
+ FAPI_DBG("<< HwpInitFile: rpnDoPush");
+ return l_rc;
+}
+
+/** @brief Execute the operation
+ *
+ * Executes the operation passed in, and places the result onto
+ *
+ * @param[in,out] io_rpnStack Ptr to RPN stack
+ * @param[in,out] i_op Operation to perform
+ * @param[in] i_any Set if ANY op
+ * @return fapi::ReturnCode Zero on success
+ */
+fapi::ReturnCode rpnDoOp(rpnStack_t * io_rpnStack, IfRpnOp i_op, uint32_t i_any)
+{
+ FAPI_DBG(">> hwpExecInitFile: rpnDoOp 0x%X", i_op);
+
+ rpnDumpStack(io_rpnStack);
+
+ fapi::ReturnCode l_rc = fapi::FAPI_RC_SUCCESS;
+ uint64_t val1 = 0;
+ uint64_t val2 = 0;
+ uint64_t result = 0;
+
+ switch (i_op)
+ {
+ //Do all of the binary ops
+ case (AND):
+ case (OR):
+ case (GT):
+ case (GE):
+ case (LT):
+ case (LE):
+ case (EQ):
+ case (NE):
+ case (PLUS):
+ case (MINUS):
+ case (MULT):
+ case (DIVIDE):
+ case (MOD):
+ case (SHIFTLEFT):
+ case (SHIFTRIGHT):
+
+ //pop the first value
+ val2 = rpnPop(io_rpnStack);
+
+ //pop the second value
+ val1 = rpnPop(io_rpnStack);
+
+ //Calculate the result
+ result = rpnBinaryOp(i_op, val1, val2, i_any);
+
+ //Push the result onto the stack
+ rpnPush(io_rpnStack, result);
+
+ break;
+
+ case (NOT):
+
+ //Pop the value
+ val1 = rpnPop(io_rpnStack);
+
+ //Calculate the result
+ result = rpnUnaryOp(i_op, val1, i_any);
+
+ //Push the result onto the stack
+ rpnPush(io_rpnStack, result);
+
+ break;
+
+ case (FALSE_OP):
+
+ result = 0;
+ rpnPush(io_rpnStack, result);
+ break;
+
+ case (TRUE_OP):
+
+ result = 1;
+ rpnPush(io_rpnStack, result);
+ break;
+
+ default:
+ FAPI_DBG("hwpExecInitFile: rpnDoOp: invalid op 0x%X", i_op);
+ fapiAssert(false);
+ break;
+ }
+
+ FAPI_DBG("<< hwpExecInitFile: rpnDoOp: result %u", result);
+ return l_rc;
+}
+
+/** @brief Evaluates the RPN expression
+ *
+ * Evaluates the expression passed in and places the result on the RPN stack.
+ *
+ * @param[in,out] io_ifData Reference to ifData_t which contains initfile data
+ * @param[in] i_expr Expression to evaluate
+ * @param[in] i_len Length of expression
+ * @param[in] i_hasExpr True if EXPR column
+ *
+ * @return fapi::ReturnCode Zero on success
+ */
+fapi::ReturnCode evalRpn(ifData_t & io_ifData, char * i_expr,
+ uint32_t i_len, const bool i_hasExpr)
+{
+ FAPI_DBG(">> hwpExecInitFile: evalRpn");
+
+ fapi::ReturnCode l_rc;
+ IfRpnOp l_op;
+ uint16_t l_id;
+ uint32_t l_any = IF_NOT_ANY;
+
+ FAPI_DBG("hwpExecInitFile: evalRpn: len %u", i_len);
+
+ //If we're in an expression column, then an 'ANY' will just be one sided,
+ //and won't have the 2nd operand needed for the upcoming EQ operator
+ if (i_hasExpr)
+ {
+ FAPI_DBG("hwpExecInitFile: evalRpn: this is an expr");
+ l_any = IF_ONE_SIDED_ANY;
+ }
+
+ while (i_len--)
+ {
+ l_op = static_cast<IfRpnOp>((*i_expr++) & OP_MASK);
+ FAPI_DBG("hwpExecInitFile: evalRpn: op? 0x%.2X", l_op);
+
+ if (l_op & PUSH_MASK) //Push
+ {
+ l_id = static_cast<uint16_t>((l_op << 8) | ((*i_expr++) & OP_MASK));
+ --i_len;
+
+ FAPI_DBG("hwpExecInitFile: evalRpn: id 0x%.2X", l_id);
+
+ //Check for attribute of array type
+ //1 dimensional support only
+ uint16_t l_arrayIndexId = 0;
+ if ((l_id & IF_TYPE_MASK) == IF_VAR_TYPE)
+ {
+ //Mask out the type bits and zero-based
+ uint16_t i = (l_id & ~IF_TYPE_MASK) - 1;
+
+ if (SYM_ATTR_UINT8_ARRAY_TYPE <= io_ifData.attrs[i].type)
+ {
+ l_arrayIndexId = *(const uint16_t *)i_expr;
+ i_expr += 2;
+ i_len -= 2;
+ FAPI_DBG("hwpExecInitFile: evalRpn: array index id 0x%.2X",
+ l_arrayIndexId);
+ }
+ }
+
+ l_rc = rpnDoPush(io_ifData, l_id, l_any, l_arrayIndexId);
+ }
+ else
+ {
+ l_rc = rpnDoOp(io_ifData.rpnStack, l_op, l_any);
+ }
+
+ if (l_rc)
+ {
+ break;
+ }
+ }
+
+ FAPI_DBG("<< hwpExecInitFile: evalRpn");
+ return l_rc;
+}
+
+
+
+} // extern "C"
diff --git a/src/usr/hwpf/hwp/fapiTestHwp.C b/src/usr/hwpf/hwp/fapiTestHwp.C
index 347c18291..3a340f9fa 100644
--- a/src/usr/hwpf/hwp/fapiTestHwp.C
+++ b/src/usr/hwpf/hwp/fapiTestHwp.C
@@ -37,15 +37,22 @@
* mjjones 08/10/2011 Removed clock HWP
* mjjones 09/01/2011 Call toString in InitialTest
* mjjones 09/14/2011 Update to scom function name
+ * camvanng 09/28/2011 Added test for initfile
*
*/
#include <fapiTestHwp.H>
#include <fapiHwAccess.H>
+#include <fapiHwpExecInitFile.H>
extern "C"
{
//******************************************************************************
+// Forward Declaration
+//******************************************************************************
+fapi::ReturnCode testExecInitFile(const fapi::Target & i_chip);
+
+//******************************************************************************
// hwpInitialTest function - Override with whatever you want here
//******************************************************************************
fapi::ReturnCode hwpInitialTest(const fapi::Target & i_chip)
@@ -91,7 +98,7 @@ fapi::ReturnCode hwpInitialTest(const fapi::Target & i_chip)
if (l_ecmdRc != ECMD_DBUF_SUCCESS)
{
FAPI_ERR("hwpInitialTest: fapiPutScom test, error from ecmdDataBuffer setDoubleWord() - rc 0x%.8X", l_ecmdRc);
- l_rc = fapi::FAPI_RC_ECMD_MASK;
+ l_rc = l_ecmdRc;
break;
}
@@ -118,7 +125,7 @@ fapi::ReturnCode hwpInitialTest(const fapi::Target & i_chip)
if (l_ecmdRc != ECMD_DBUF_SUCCESS)
{
FAPI_ERR("hwpInitialTest: fapiPutScomUnderMask test, error from ecmdDataBuffer setDoubleWord() - rc 0x%.8X", l_ecmdRc);
- l_rc = fapi::FAPI_RC_ECMD_MASK;
+ l_rc = l_ecmdRc;
break;
}
@@ -142,7 +149,7 @@ fapi::ReturnCode hwpInitialTest(const fapi::Target & i_chip)
if (l_ecmdRc != ECMD_DBUF_SUCCESS)
{
FAPI_ERR("hwpInitialTest: fapiPutScom to restore, error from ecmdDataBuffer setDoubleWord() - rc 0x%.8X", l_ecmdRc);
- l_rc = fapi::FAPI_RC_ECMD_MASK;
+ l_rc = l_ecmdRc;
break;
}
@@ -196,7 +203,7 @@ fapi::ReturnCode hwpInitialTest(const fapi::Target & i_chip)
if (l_ecmdRc != ECMD_DBUF_SUCCESS)
{
FAPI_ERR("hwpInitialTest: fapiPutCfamRegister test, error from ecmdDataBuffer setWord() - rc 0x%.8X", l_ecmdRc);
- l_rc = fapi::FAPI_RC_ECMD_MASK;
+ l_rc = l_ecmdRc;
break;
}
@@ -221,7 +228,7 @@ fapi::ReturnCode hwpInitialTest(const fapi::Target & i_chip)
if (l_ecmdRc != ECMD_DBUF_SUCCESS)
{
FAPI_ERR("hwpInitialTest: fapiModifyCfamRegister test, error from ecmdDataBuffer setWord() - rc 0x%.8X", l_ecmdRc);
- l_rc = fapi::FAPI_RC_ECMD_MASK;
+ l_rc = l_ecmdRc;
break;
}
@@ -245,7 +252,7 @@ fapi::ReturnCode hwpInitialTest(const fapi::Target & i_chip)
if (l_ecmdRc != ECMD_DBUF_SUCCESS)
{
FAPI_ERR("hwpInitialTest: fapiPutCfamRegister to restore, error from ecmdDataBuffer setWord() - rc 0x%.8X", l_ecmdRc);
- l_rc = fapi::FAPI_RC_ECMD_MASK;
+ l_rc = l_ecmdRc;
break;
}
@@ -263,9 +270,218 @@ fapi::ReturnCode hwpInitialTest(const fapi::Target & i_chip)
#endif
+ // --------------------------------------------------------
+ // 9. hwpExecInitFile test
+ // --------------------------------------------------------
+
+ l_rc = testExecInitFile(i_chip);
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ FAPI_ERR("hwpInitialTest: Error from testExecInitFile");
+ break;
+ }
+ else
+ {
+ FAPI_INF("hwpInitialTest: Test testExecInitFile passed");
+ }
+
+ } while (0);
+
+ return l_rc;
+}
+
+
+//******************************************************************************
+// testExecInitFile function - function to test sample initfile
+//******************************************************************************
+fapi::ReturnCode testExecInitFile(const fapi::Target & i_chip)
+{
+ typedef struct ifScom {
+ uint64_t addr;
+ uint64_t origData;
+ uint64_t writtenData;
+ }ifScom_t;
+
+ //Note: this data is based on the sample.initfile.
+ //If the initfile changes, this data will also need to be changed.
+ ifScom_t l_ifScomData[] =
+ {
+ {0x000000000006002b, 0, 0x0000000000000183},
+ {0x000000000006002c, 0, 0x0000000000000183},
+ {0x000000000006800b, 0, 0},
+ {0x000000000006800c, 0, 0x8000000000000000 >> 0x17},
+ {0x0000000013010002, 0, 0x0000000000000181},
+ {0x0000000013013283, 0, 0x3c90000000000000 |
+ 0x8000000000000000 >> 0x0c |
+ 0x8000000000000000 >> 0x0d |
+ 0x0306400412000000 >> 0x0e},
+ {0x0000000013013284, 0, 0x3c90000000000000},
+ {0x0000000013013285, 0, 0x8000000000000000 >> 0x0f |
+ 0x8000000000000000 >> 0x10 |
+ 0x8000000000000000 >> 0x13 |
+ 0x0306400412000000 >> 0x15 },
+ {0x0000000013013286, 0, 0},
+ {0x0000000013013287, 0, 0x0000000000000182},
+ {0x0000000013013288, 0, 0x0000000000000192},
+ {0x0000000013013289, 0, 0x8000000000000000 >> 0x17},
+ {0x0000000013030007, 0, 0x0000000000000182}
+ };
+
+ fapi::ReturnCode l_rc = fapi::FAPI_RC_SUCCESS;
+ uint32_t l_ecmdRc = ECMD_DBUF_SUCCESS;
+ ecmdDataBufferBase l_ScomData(64);
+
+ do {
+ // Set up some attributes for testing
+ uint8_t l_uint8 = 1;
+ l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_1, NULL, l_uint8);
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ FAPI_ERR("hwpInitialTest: testExecInitFile: "
+ "ATTR_SCRATCH_UINT8_1. Error from SET");
+ break;
+ }
+
+ l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_2, NULL, l_uint8);
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ FAPI_ERR("hwpInitialTest: testExecInitFile: "
+ "ATTR_SCRATCH_UINT8_2. Error from SET");
+ break;
+ }
+
+ uint32_t l_uint32 = 3;
+ l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_1, NULL, l_uint32);
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ FAPI_ERR("hwpInitialTest: testExecInitFile: "
+ "ATTR_SCRATCH_UINT32_1. Error from SET");
+ break;
+ }
+
+ uint64_t l_uint64 = 2;
+ l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_1, NULL, l_uint64);
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ FAPI_ERR("hwpInitialTest: testExecInitFile: "
+ "ATTR_SCRATCH_UINT64_1. Error from SET");
+ break;
+ }
+
+ uint8_t l_uint8array1[32];
+ l_uint8array1[2] = 1;
+ l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_ARRAY_1, NULL, l_uint8array1);
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ FAPI_ERR("hwpInitialTest: testExecInitFile: "
+ "ATTR_SCRATCH_UINT8_ARRAY_1. Error from SET");
+ break;
+ }
+
+ // Save original scom data to restore at end of test
+ for (uint32_t i = 0; i < sizeof(l_ifScomData)/sizeof(ifScom_t); i++)
+ {
+ l_rc = fapiGetScom(i_chip, l_ifScomData[i].addr, l_ScomData);
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ FAPI_ERR("hwpInitialTest: testExecInitFile: Error from "
+ "fapiGetScom");
+ break;
+ }
+
+ l_ifScomData[i].origData = l_ScomData.getDoubleWord(0);
+ }
+
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ break;
+ }
+
+ // Set scom data to 0 to start from known state for bit ops
+ l_ScomData.setDoubleWord(0, 0ll);
+ for (uint32_t i = 0; i < sizeof(l_ifScomData)/sizeof(ifScom_t); i++)
+ {
+ l_rc = fapiPutScom(i_chip, l_ifScomData[i].addr, l_ScomData);
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ FAPI_ERR("hwpInitialTest: testExecInitFile: Error from "
+ "fapiPutScom");
+ break;
+ }
+ }
+
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ break;
+ }
+
+ //Call Hwp to execute the initfile
+ FAPI_EXEC_HWP(l_rc, hwpExecInitFile, i_chip, "sample.if");
+
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ FAPI_ERR("hwpInitialTest: Error from hwpExecInitFile");
+ break;
+ }
+
+ //Verify the data written
+ for (uint32_t i = 0; i < sizeof(l_ifScomData)/sizeof(ifScom_t); i++)
+ {
+ l_rc = fapiGetScom(i_chip, l_ifScomData[i].addr, l_ScomData);
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ FAPI_ERR("hwpInitialTest: testExecInitFile: Error from "
+ "fapiGetScom");
+ break;
+ }
+
+ if (l_ScomData.getDoubleWord(0) != l_ifScomData[i].writtenData)
+ {
+ FAPI_ERR("hwpInitialTest: testExecInitFile: GetScom addr "
+ "0x%.16llX data read 0x%.16llX data expected 0x%.16llX",
+ l_ifScomData[i].addr, l_ScomData.getDoubleWord(0),
+ l_ifScomData[i].writtenData);
+ l_rc = fapi::RC_HWP_EXEC_INITFILE_TEST_FAILED;
+ break;
+ }
+ }
+
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ break;
+ }
+
+ // Restore the original Scom data
+ for (uint32_t i = 0; i < sizeof(l_ifScomData)/sizeof(ifScom_t); i++)
+ {
+ l_ecmdRc = l_ScomData.setDoubleWord(0, l_ifScomData[i].origData);
+ if (l_ecmdRc != ECMD_DBUF_SUCCESS)
+ {
+ FAPI_ERR("hwpInitialTest: testExecInitFile: fapiPutScom to "
+ "restore, error from ecmdDataBuffer setDoubleWord() - "
+ "rc 0x%.8X", l_ecmdRc);
+ l_rc = l_ecmdRc;
+ break;
+ }
+
+ l_rc = fapiPutScom(i_chip, l_ifScomData[i].addr, l_ScomData);
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ FAPI_ERR("hwpInitialTest: testExecInitFile: Error from "
+ "fapiGetScom");
+ break;
+ }
+ }
+
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ break;
+ }
+
} while (0);
return l_rc;
}
+
} // extern "C"
diff --git a/src/usr/hwpf/hwp/initfiles/sample.initfile b/src/usr/hwpf/hwp/initfiles/sample.initfile
new file mode 100755
index 000000000..17ee552a5
--- /dev/null
+++ b/src/usr/hwpf/hwp/initfiles/sample.initfile
@@ -0,0 +1,151 @@
+#-- $Id: sample.initfile,v 1.1 2011/07/13 16:03:44 andrewg Exp $
+#-- CHANGE HISTORY:
+#--------------------------------------------------------------------------------
+#-- Version:|Author: | Date: | Comment:
+#-- --------|--------|--------|--------------------------------------------------
+#-- 0.01|andrewg |05/24/11|Created sample file
+#-- --------|--------|--------|--------------------------------------------------
+#--------------------------------------------------------------------------------
+# End of revision history
+#--------------------------------------------------------------------------------
+
+#--Master list of variables that can be used in this file is at:
+#--<Attribute Definition Location>
+
+SyntaxVersion = 1
+
+#-- -----------------------------------------------------------------------------
+#--******************************************************************************
+#-- -----------------------------------------------------------------------------
+#--
+#-- Defines
+#--
+#-- -----------------------------------------------------------------------------
+#--******************************************************************************
+#-- -----------------------------------------------------------------------------
+
+define def_equal_test = (ATTR_SCRATCH_UINT32_1 == ATTR_SCRATCH_UINT32_2);
+define def_not_equal_test = (ATTR_SCRATCH_UINT64_1 != ATTR_SCRATCH_UINT64_2);
+
+
+#--******************************************************************************
+#-- Basic SCOM
+#--******************************************************************************
+scom 0x0000000013010002 {
+ scom_data ;
+ 0x0000000000000181 ;
+}
+
+#--******************************************************************************
+#-- Basic SCOM with Expression and Attribute
+#--******************************************************************************
+
+scom 0x0000000013030007 {
+ scom_data, expr ;
+ 0x0000000000000182, ATTR_SCRATCH_UINT8_1 == ATTR_SCRATCH_UINT8_2 ;
+}
+
+#--******************************************************************************
+#-- Basic SCOM with Array In Middle
+#--******************************************************************************
+
+scom 0x000000000006002(B,C) {
+ scom_data ;
+ 0x0000000000000183 ;
+}
+
+#--******************************************************************************
+#-- Basic SCOM with define used
+#--******************************************************************************
+
+scom 0x000000000006800b {
+ scom_data, expr ;
+ 0x0000000000000184, def_equal_test ;
+}
+
+#--******************************************************************************
+#-- Basic SCOM with a single bit set
+#--******************************************************************************
+
+scom 0x000000000006800c {
+ bits , scom_data ;
+ 23 , 0b1 ;
+}
+
+#--******************************************************************************
+#-- Basic SCOM with bits
+#--******************************************************************************
+
+scom 0x0000000013013283 {
+ bits , scom_data ;
+ 0:11 , 0b001111001001 ;
+ 12 , 0b1 ;
+ 13 , 0b1 ;
+ 14:59, 0b0000001100000110010000000000010000010010000000 ;
+}
+
+#--******************************************************************************
+#-- Complext SCOM with Bit Support, define, and attributes
+#--******************************************************************************
+
+scom 0x0000000013013284 {
+ bits , scom_data, expr ;
+ 0:11 , 0b001111001001, any ;
+ 12 , 0b1, def_equal_test ;
+ 12 , 0b0, def_not_equal_test ;
+ 13 , 0b1, ATTR_SCRATCH_UINT8_1 > ATTR_SCRATCH_UINT8_2 ;
+ 14:59, 0b0000001100000110010000000000010000010010000000, ATTR_SCRATCH_UINT64_1 == ATTR_SCRATCH_UINT64_2 ;
+}
+
+#--******************************************************************************
+#-- Complex SCOM with Bit Support, and logical operators
+#--******************************************************************************
+
+scom 0x0000000013013285 {
+ bits , scom_data, expr ;
+ 12 , 0b1, def_equal_test && def_not_equal_test ;
+ 12 , 0b0, def_equal_test || def_not_equal_test ;
+ 14 , 0b1, ATTR_SCRATCH_UINT32_1 < ATTR_SCRATCH_UINT32_2 ;
+ 15 , 0b1, ATTR_SCRATCH_UINT32_1 > ATTR_SCRATCH_UINT32_2 ;
+ 16 , 0b1, ATTR_SCRATCH_UINT32_1 >= ATTR_SCRATCH_UINT32_2 ;
+ 17 , 0b1, ATTR_SCRATCH_UINT32_1 <= ATTR_SCRATCH_UINT32_2 ;
+ 18 , 0b1, ATTR_SCRATCH_UINT32_1 == ATTR_SCRATCH_UINT32_2 ;
+ 19 , 0b1, ATTR_SCRATCH_UINT32_1 != ATTR_SCRATCH_UINT32_2 ;
+ 20 , 0b1, (ATTR_SCRATCH_UINT32_1 + ATTR_SCRATCH_UINT32_2) == 4 ;
+ 21:59, 0b000000110000011001000000000001000001001, ATTR_SCRATCH_UINT8_1 == ATTR_SCRATCH_UINT8_2 ;
+}
+
+#--******************************************************************************
+#-- SCOM with 'ec' column - Use scratch for now since all attributes work
+#--******************************************************************************
+
+scom 0x0000000013013286 {
+ scom_data, ATTR_SCRATCH_UINT32_1 ;
+ 0x0000000000000192, 1 ;
+}
+
+#--******************************************************************************
+#-- Basic SCOM with an array
+#--******************************************************************************
+scom 0x0000000013013287 {
+ scom_data, expr ;
+ 0x0000000000000182, ATTR_SCRATCH_UINT8_ARRAY_1[2] == ATTR_SCRATCH_UINT8_1 ;
+}
+
+#--******************************************************************************
+#-- SCOM with 'ec' & expr column - Use scratch for now since all attributes work
+#--******************************************************************************
+scom 0x0000000013013288 {
+ scom_data, ATTR_SCRATCH_UINT32_1 expr;
+ 0x0000000000000192, 3, ATTR_SCRATCH_UINT8_ARRAY_1[2] == ATTR_SCRATCH_UINT8_1;
+}
+
+#--******************************************************************************
+#-- Complex SCOM with Bit Support, logical operators and 'ec' column
+#--******************************************************************************
+scom 0x0000000013013289 {
+ bits , scom_data ATTR_SCRATCH_UINT32_1 expr;
+ 23 , 0b1, any, ATTR_SCRATCH_UINT8_ARRAY_1[2] == ATTR_SCRATCH_UINT8_1;
+ 23 , 0b0, 1, any;
+}
+
diff --git a/src/usr/hwpf/hwp/makefile b/src/usr/hwpf/hwp/makefile
index f2401f2d5..cc6d32303 100644
--- a/src/usr/hwpf/hwp/makefile
+++ b/src/usr/hwpf/hwp/makefile
@@ -33,6 +33,7 @@ OBJS = fapiTestHwp.o \
fapiTestHwpAnalyzeError.o \
fapiTestHwpFfdc.o \
fapiTestHwpConfig.o \
- fapiTestHwpAttr.o
+ fapiTestHwpAttr.o \
+ fapiHwpExecInitFile.o
include ${ROOTPATH}/config.mk
diff --git a/src/usr/hwpf/plat/fapiPlatUtil.C b/src/usr/hwpf/plat/fapiPlatUtil.C
index fd989e398..667e4dffe 100644
--- a/src/usr/hwpf/plat/fapiPlatUtil.C
+++ b/src/usr/hwpf/plat/fapiPlatUtil.C
@@ -34,6 +34,7 @@
#include <sys/time.h>
#include <errl/errlmanager.H>
#include <fapiPlatHwpInvoker.H>
+#include <vfs/vfs.H>
//******************************************************************************
@@ -128,4 +129,75 @@ void platSetScanTrace(bool i_enable)
return;
}
+//******************************************************************************
+// fapiLoadInitFile
+//******************************************************************************
+fapi::ReturnCode fapiLoadInitFile(const char * i_file, const char *& o_addr,
+ size_t & o_size)
+{
+ fapi::ReturnCode l_rc = fapi::FAPI_RC_SUCCESS;
+ errlHndl_t l_pError = NULL;
+ o_size = 0;
+ o_addr = NULL;
+
+ FAPI_INF("fapiLoadInitFile: %s", i_file);
+
+ l_pError = VFS::module_load(i_file);
+ if(l_pError)
+ {
+ // Add the error log pointer as data to the ReturnCode
+ FAPI_ERR("fapiLoadInitFile: module_load failed");
+ l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA;
+ l_rc.setPlatData(reinterpret_cast<void *> (l_pError));
+ }
+ else
+ {
+ l_pError = VFS::module_address(i_file, o_addr, o_size);
+ if(l_pError)
+ {
+ // Add the error log pointer as data to the ReturnCode
+ FAPI_ERR("fapiLoadInitFile: module_address failed");
+ l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA;
+ l_rc.setPlatData(reinterpret_cast<void *> (l_pError));
+ }
+ else
+ {
+ FAPI_DBG("fapiLoadInitFile: data module addr = %p, size = %ld",
+ o_addr, o_size);
+ FAPI_DBG("fapiLoadInitFile: *addr = 0x%llX",
+ *(reinterpret_cast<const uint64_t*>(o_addr)));
+ }
+ }
+
+ return l_rc;
+}
+
+//******************************************************************************
+// fapiUnloadInitFile
+//******************************************************************************
+fapi::ReturnCode fapiUnloadInitFile(const char * i_file, const char *& io_addr,
+ size_t & io_size)
+{
+ fapi::ReturnCode l_rc = fapi::FAPI_RC_SUCCESS;
+ errlHndl_t l_pError = NULL;
+
+ FAPI_INF("fapiUnloadInitFile: %s", i_file);
+
+ l_pError = VFS::module_unload(i_file);
+ if(l_pError)
+ {
+ // Add the error log pointer as data to the ReturnCode
+ FAPI_ERR("fapiUnloadInitFile: module_unload failed %s", i_file);
+ l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA;
+ l_rc.setPlatData(reinterpret_cast<void *> (l_pError));
+ }
+ else
+ {
+ io_addr = NULL;
+ io_size = 0;
+ }
+
+ return l_rc;
+}
+
}
OpenPOWER on IntegriCloud