summaryrefslogtreecommitdiffstats
path: root/src/usr/isteps/expupd
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/isteps/expupd')
-rw-r--r--src/usr/isteps/expupd/expupd.C393
-rw-r--r--src/usr/isteps/expupd/expupd.mk38
-rw-r--r--src/usr/isteps/expupd/expupd_trace.H40
-rw-r--r--src/usr/isteps/expupd/makefile35
-rw-r--r--src/usr/isteps/expupd/ocmbFwImage.C391
-rw-r--r--src/usr/isteps/expupd/ocmbFwImage.H68
-rw-r--r--src/usr/isteps/expupd/test/expupdatetest.H175
-rw-r--r--src/usr/isteps/expupd/test/makefile33
-rw-r--r--src/usr/isteps/expupd/test/test.mk35
9 files changed, 1208 insertions, 0 deletions
diff --git a/src/usr/isteps/expupd/expupd.C b/src/usr/isteps/expupd/expupd.C
new file mode 100644
index 000000000..3f63ac191
--- /dev/null
+++ b/src/usr/isteps/expupd/expupd.C
@@ -0,0 +1,393 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/isteps/expupd/expupd.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include <expupd/expupd_reasoncodes.H>
+#include <pnor/pnorif.H>
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/utilFilter.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <isteps/hwpisteperror.H>
+#include <isteps/hwpistepud.H>
+#include <fapi2.H>
+#include <fapi2/plat_hwp_invoker.H>
+#include <fapi2/hw_access.H>
+#include <chipids.H>
+#include <trace/interface.H>
+#include <hbotcompid.H>
+#include "ocmbFwImage.H"
+#include <exp_fw_update.H>
+#include <initservice/istepdispatcherif.H>
+
+using namespace ISTEP_ERROR;
+using namespace ERRORLOG;
+using namespace TARGETING;
+
+namespace expupd
+{
+
+// Initialize the trace buffer for this component
+trace_desc_t* g_trac_expupd = nullptr;
+TRAC_INIT(&g_trac_expupd, EXPUPD_COMP_NAME, 2*KILOBYTE);
+
+/**
+ * @brief Structure for retrieving the explorer SHA512 hash value
+ *
+ */
+typedef union sha512regs
+{
+ struct
+ {
+ uint32_t imageId;
+ uint8_t sha512Hash[HEADER_SHA512_SIZE];
+ };
+ uint8_t unformatted[sizeof(uint32_t) + HEADER_SHA512_SIZE];
+}sha512regs_t;
+
+/**
+ * @brief Retrieve the SHA512 hash for the currently flashed explorer
+ * firmware image.
+ *
+ * @param[in] i_target Target of the OCMB chip to retrieve the SHA512 hash
+ * @param[out] o_regs Structure for storing the retrieved SHA512 hash
+ *
+ * @return NULL on success. Non-null on failure.
+ */
+errlHndl_t getFlashedHash(TargetHandle_t i_target, sha512regs_t& o_regs)
+{
+ fapi2::buffer<uint64_t> l_scomBuffer;
+ uint8_t* l_scomPtr = reinterpret_cast<uint8_t*>(l_scomBuffer.pointer());
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>l_fapi2Target(i_target);
+ errlHndl_t l_err = nullptr;
+
+ //Start addres of hash register (a.k.a. RAM1 register)
+ const uint32_t HASH_REG_ADDR = 0x00002200;
+
+ // loop until we've filled the sha512regs_t struct
+ for(uint32_t l_bytesCopied = 0; l_bytesCopied < sizeof(sha512regs_t);
+ l_bytesCopied += sizeof(uint32_t))
+ {
+ // Use getScom, this knows internally whether to use i2c or inband
+ FAPI_INVOKE_HWP(l_err, getScom,
+ l_fapi2Target,
+ HASH_REG_ADDR + l_bytesCopied,
+ l_scomBuffer);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "getFlashedHash: Failed reading SHA512 hash from"
+ " ocmb[0x%08x]. bytesCopied[%u]",
+ TARGETING::get_huid(i_target), l_bytesCopied);
+
+ break;
+ }
+
+ // copy scom buffer into the unformatted uint8_t array.
+ // Even though the scom buffer is 8 bytes, only 4 bytes are read and
+ // copied into the least significant 4 bytes.
+ memcpy(&o_regs.unformatted[l_bytesCopied], l_scomPtr + sizeof(uint32_t),
+ sizeof(uint32_t));
+ }
+
+ return l_err;
+}
+
+/**
+ * @brief Check flash image SHA512 hash value of each explorer chip
+ * and update the flash if it does not match the SHA512 hash
+ * of the image in PNOR.
+ *
+ * @param[out] o_stepError Error handle for logging istep failures
+ *
+ */
+void updateAll(IStepError& o_stepError)
+{
+ bool l_imageLoaded = false;
+ errlHndl_t l_err = nullptr;
+ bool l_rebootRequired = false;
+
+ // Get a list of OCMB chips
+ TARGETING::TargetHandleList l_ocmbTargetList;
+ getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
+
+ Target* l_pTopLevel = nullptr;
+ targetService().getTopLevelTarget( l_pTopLevel );
+ assert(l_pTopLevel, "expupd::updateAll: no TopLevelTarget");
+
+ TRACFCOMP(g_trac_expupd, ENTER_MRK
+ "updateAll: %d ocmb chips found",
+ l_ocmbTargetList.size());
+
+ do
+ {
+ // If no OCMB chips exist, we're done.
+ if(l_ocmbTargetList.size() == 0)
+ {
+ break;
+ }
+
+ // Check if we have any overrides to force our behavior
+ auto l_forced_behavior =
+ l_pTopLevel->getAttr<TARGETING::ATTR_OCMB_FW_UPDATE_OVERRIDE>();
+
+ // Exit now if told to
+ if( TARGETING::OCMB_FW_UPDATE_BEHAVIOR_PREVENT_UPDATE
+ == l_forced_behavior )
+ {
+ TRACFCOMP(g_trac_expupd, INFO_MRK "Skipping update due to override (PREVENT_UPDATE)");
+ break;
+ }
+
+ // Read explorer fw image from pnor
+ PNOR::SectionInfo_t l_pnorSectionInfo;
+ rawImageInfo_t l_imageInfo;
+
+#ifdef CONFIG_SECUREBOOT
+ l_err = PNOR::loadSecureSection(PNOR::OCMBFW);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "updateAll: Failed to load OCMBFW section"
+ " from PNOR!");
+
+ l_err->collectTrace(EXPUPD_COMP_NAME);
+
+ // Create IStep error log and cross reference to error that occurred
+ o_stepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, EXPUPD_COMP_ID );
+
+ break;
+ }
+#endif //CONFIG_SECUREBOOT
+
+ l_imageLoaded = true;
+
+ // get address and size of packaged image
+ l_err = PNOR::getSectionInfo(PNOR::OCMBFW, l_pnorSectionInfo);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "updateAll: Failure in getSectionInfo()");
+
+ l_err->collectTrace(EXPUPD_COMP_NAME);
+
+ // Create IStep error log and cross reference to error that occurred
+ o_stepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, EXPUPD_COMP_ID );
+ break;
+ }
+
+ // Verify the header and retrieve address, size and
+ // SHA512 hash of unpackaged image
+ l_err = ocmbFwValidateImage(
+ l_pnorSectionInfo.vaddr,
+ l_pnorSectionInfo.secureProtectedPayloadSize,
+ l_imageInfo);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "updateAll: Failure in expupdValidateImage");
+
+ l_err->collectTrace(EXPUPD_COMP_NAME);
+
+ // Create IStep error log and cross reference to error that occurred
+ o_stepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, EXPUPD_COMP_ID );
+ break;
+ }
+
+ // For each explorer chip, compare flash hash with PNOR hash and
+ // create a list of explorer chips with differing hash values.
+ TARGETING::TargetHandleList l_flashUpdateList;
+ for(const auto & l_ocmbTarget : l_ocmbTargetList)
+ {
+ sha512regs_t l_regs;
+
+ //skip all gemini ocmb chips (not updateable)
+ if(l_ocmbTarget->getAttr<TARGETING::ATTR_CHIP_ID>() ==
+ POWER_CHIPID::GEMINI_16)
+ {
+ TRACFCOMP(g_trac_expupd,
+ "updateAll: skipping update of gemini OCMB 0x%08x",
+ TARGETING::get_huid(l_ocmbTarget));
+ continue;
+ }
+
+ //retrieve the SHA512 hash for the currently flashed image.
+ l_err = getFlashedHash(l_ocmbTarget, l_regs);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "updateAll: Failure in getFlashedHash(huid = 0x%08x)",
+ TARGETING::get_huid(l_ocmbTarget));
+
+ l_err->collectTrace(EXPUPD_COMP_NAME);
+
+ // Create IStep error log and cross reference to error
+ // that occurred
+ o_stepError.addErrorDetails(l_err);
+
+ errlCommit(l_err, EXPUPD_COMP_ID);
+
+ //Don't stop on error, go to next target.
+ continue;
+ }
+
+ // Trace the hash and image ID values
+ TRACFCOMP(g_trac_expupd,
+ "updateAll: OCMB 0x%08x image ID=0x%08x",
+ TARGETING::get_huid(l_ocmbTarget), l_regs.imageId);
+ TRACFBIN(g_trac_expupd, "SHA512 HASH FROM EXPLORER",
+ l_regs.sha512Hash, HEADER_SHA512_SIZE);
+
+ //Compare hashes. If different, add to list for update.
+ if(memcmp(l_regs.sha512Hash, l_imageInfo.imageSHA512HashPtr,
+ HEADER_SHA512_SIZE))
+ {
+ TRACFCOMP(g_trac_expupd,
+ "updateAll: SHA512 hash mismatch on ocmb[0x%08x]",
+ TARGETING::get_huid(l_ocmbTarget));
+
+ //add target to our list of targets needing an update
+ l_flashUpdateList.push_back(l_ocmbTarget);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_expupd,
+ "updateAll: SHA512 hash for ocmb[0x%08x]"
+ " matches SHA512 hash of PNOR image.",
+ TARGETING::get_huid(l_ocmbTarget));
+
+ // Add every OCMB to the update list if told to
+ if( TARGETING::OCMB_FW_UPDATE_BEHAVIOR_FORCE_UPDATE
+ == l_forced_behavior )
+ {
+ TRACFCOMP(g_trac_expupd, INFO_MRK "Forcing update due to override (FORCE_UPDATE)");
+ l_flashUpdateList.push_back(l_ocmbTarget);
+ }
+ }
+ }
+
+ TRACFCOMP(g_trac_expupd,
+ "updateAll: updating flash for %d OCMB chips",
+ l_flashUpdateList.size());
+
+ // Exit now if we were asked to only do the check portion
+ if( TARGETING::OCMB_FW_UPDATE_BEHAVIOR_CHECK_BUT_NO_UPDATE
+ == l_forced_behavior )
+ {
+ TRACFCOMP(g_trac_expupd, INFO_MRK "Skipping update due to override (CHECK_BUT_NO_UPDATE)");
+ break;
+ }
+
+ // update each explorer in the list of chips needing updates
+ for(const auto & l_ocmb : l_flashUpdateList)
+ {
+ TRACFCOMP(g_trac_expupd, "updateAll: updating OCMB 0x%08x",
+ TARGETING::get_huid(l_ocmb));
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>l_fapi2Target(l_ocmb);
+
+ // reset watchdog for each ocmb as this function can be very slow
+ INITSERVICE::sendProgressCode();
+
+ // Invoke procedure
+ FAPI_INVOKE_HWP(l_err, exp_fw_update, l_fapi2Target,
+ l_imageInfo.imagePtr, l_imageInfo.imageSize);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_expupd,
+ "Error from exp_fw_update for OCMB 0x%08x",
+ TARGETING::get_huid(l_ocmb));
+
+ l_err->collectTrace(EXPUPD_COMP_NAME);
+
+ // Create IStep error log and cross reference to error
+ // that occurred
+ o_stepError.addErrorDetails( l_err );
+
+ errlCommit(l_err, EXPUPD_COMP_ID);
+
+ // Don't stop on error, go to next target.
+ continue;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_expupd,
+ "updateAll: successfully updated OCMB 0x%08x",
+ TARGETING::get_huid(l_ocmb));
+
+ // Request reboot for new firmware to be used
+ l_rebootRequired = true;
+ }
+ }
+ }while(0);
+
+ // unload explorer fw image
+ if(l_imageLoaded)
+ {
+#ifdef CONFIG_SECUREBOOT
+ l_err = PNOR::unloadSecureSection(PNOR::OCMBFW);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "updateAll: Failed to unload OCMBFW");
+
+ l_err->collectTrace(EXPUPD_COMP_NAME);
+
+ // Create IStep error log and cross reference to error that occurred
+ o_stepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, EXPUPD_COMP_ID );
+ }
+#endif //CONFIG_SECUREBOOT
+ }
+
+ // force reboot if any updates were successful
+ if(l_rebootRequired)
+ {
+ TRACFCOMP(g_trac_expupd,
+ "updateAll: OCMB chip(s) was updated. Requesting reboot...");
+ auto l_reconfigAttr =
+ l_pTopLevel->getAttr<TARGETING::ATTR_RECONFIGURE_LOOP>();
+ l_reconfigAttr |= RECONFIGURE_LOOP_OCMB_FW_UPDATE;
+ l_pTopLevel->setAttr<TARGETING::ATTR_RECONFIGURE_LOOP>(l_reconfigAttr);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_expupd, "updateAll: No OCMB chips were updated");
+ }
+
+
+ TRACFCOMP(g_trac_expupd, EXIT_MRK"updateAll()");
+}
+
+}//namespace expupd
diff --git a/src/usr/isteps/expupd/expupd.mk b/src/usr/isteps/expupd/expupd.mk
new file mode 100644
index 000000000..b7b769e7a
--- /dev/null
+++ b/src/usr/isteps/expupd/expupd.mk
@@ -0,0 +1,38 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/isteps/expupd/expupd.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+EXTRAINCDIR += ${ROOTPATH}/src/import
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc/
+EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils
+
+OBJS += expupd.o
+OBJS += ocmbFwImage.o
+
+# Need to build exp_fw_update procedure
+OBJS += exp_fw_update.o
diff --git a/src/usr/isteps/expupd/expupd_trace.H b/src/usr/isteps/expupd/expupd_trace.H
new file mode 100644
index 000000000..a2da13a8f
--- /dev/null
+++ b/src/usr/isteps/expupd/expupd_trace.H
@@ -0,0 +1,40 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/isteps/expupd/expupd_trace.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __EXPUPD_TRACE_H
+#define __EXPUPD_TRACE_H
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <trace/interface.H>
+
+namespace expupd
+{
+
+extern trace_desc_t *g_trac_expupd;
+
+} // end namespace
+
+#endif
diff --git a/src/usr/isteps/expupd/makefile b/src/usr/isteps/expupd/makefile
new file mode 100644
index 000000000..2ee89f6e4
--- /dev/null
+++ b/src/usr/isteps/expupd/makefile
@@ -0,0 +1,35 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/isteps/expupd/makefile $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+ROOTPATH = ../../../..
+MODULE = expupd
+
+SUBDIRS += test.d
+
+include expupd.mk
+
+include ${ROOTPATH}/config.mk
+
+VPATH += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
diff --git a/src/usr/isteps/expupd/ocmbFwImage.C b/src/usr/isteps/expupd/ocmbFwImage.C
new file mode 100644
index 000000000..dee2affdd
--- /dev/null
+++ b/src/usr/isteps/expupd/ocmbFwImage.C
@@ -0,0 +1,391 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/isteps/expupd/ocmbFwImage.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include "ocmbFwImage.H"
+#include <expupd/ocmbFwImage_const.H>
+#include <expupd/expupd_reasoncodes.H>
+#include "expupd_trace.H"
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <hbotcompid.H>
+#include <algorithm>
+
+#define EXPUPD_8BYTE_ALIGNED(_SIZE) (!(_SIZE & 0x7))
+
+namespace expupd
+{
+
+/**
+ * @brief Validates a tagged data triplet
+ * @param[in] i_tripletPtr starting address of a tagged data triplet
+ * @param[in] i_endDataPtr ending address of the OCMB firmware header
+ * @param[out] o_imageInfo Structure will hold pointer to SHA512 hash (if found)
+ * @param[out] o_numBytes total number of bytes used by this tagged data triplet
+ * @return errlHndl_t indicating success or failure
+ *
+ */
+errlHndl_t parseTaggedDataTriplet(const uint8_t* i_tripletPtr,
+ const uint8_t* i_endDataPtr,
+ rawImageInfo_t& o_imageInfo,
+ uint32_t& o_numBytes)
+{
+ errlHndl_t l_err = nullptr;
+
+ // Determine start of the data for the tagged data triplet
+ const uint8_t* l_dataStartPtr = i_tripletPtr + sizeof(taggedTriplet_t);
+ const taggedTriplet_t* l_ttPtr =
+ reinterpret_cast<const taggedTriplet_t*>(i_tripletPtr);
+
+ // Assume failure and set number of bytes consumed to 0
+ o_numBytes = 0;
+
+ do
+ {
+ // Check that we have enough room for the triplet
+ if((l_dataStartPtr > i_endDataPtr) ||
+ ((l_dataStartPtr + l_ttPtr->dataSize) > i_endDataPtr) ||
+ !EXPUPD_8BYTE_ALIGNED(l_ttPtr->dataSize))
+ {
+ int64_t l_reqdSize = sizeof(taggedTriplet_t);
+ l_reqdSize += (l_dataStartPtr > i_endDataPtr)? 0: l_ttPtr->dataSize;
+
+ int64_t l_allocSize =
+ reinterpret_cast<int64_t>(i_endDataPtr - i_tripletPtr);
+
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "parseTaggedDataTriplet: Triplet does not fit or is"
+ " misaligned. bytesReqd[%d] bytesAllocated[%d]",
+ l_reqdSize,
+ l_allocSize);
+
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_PARSE_TAGGED_DATA_TRIPLET
+ * @reasoncode EXPUPD::INVALID_DATA_TRIPLET_SIZE
+ * @userdata1 allocated size
+ * @userdata2 required size
+ * @devdesc Tagged data triplet size is too big or misaligned
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_PARSE_TAGGED_DATA_TRIPLET,
+ EXPUPD::INVALID_DATA_TRIPLET_SIZE,
+ l_allocSize,
+ l_reqdSize,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ // Check for the SHA512 tag
+ if(l_ttPtr->tagId == TAG_SHA512)
+ {
+ // Check that hash data is complete
+ if(l_ttPtr->dataSize != HEADER_SHA512_SIZE)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "parseTaggedDataTriplet: Invalid hash triplet size."
+ " expected[%u] actual[%u]",
+ HEADER_SHA512_SIZE,
+ l_ttPtr->dataSize);
+
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_PARSE_TAGGED_DATA_TRIPLET
+ * @reasoncode EXPUPD::INVALID_HASH_TRIPLET_SIZE
+ * @userdata1 Expected Size
+ * @userdata2 Actual Size
+ * @devdesc Incorrect hash size in OCMB image header
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_PARSE_TAGGED_DATA_TRIPLET,
+ EXPUPD::INVALID_HASH_TRIPLET_SIZE,
+ HEADER_SHA512_SIZE,
+ l_ttPtr->dataSize,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ // Save off pointer to hash for later.
+ o_imageInfo.imageSHA512HashPtr = l_dataStartPtr;
+ }
+ else if(l_ttPtr->tagId == TAG_KEY_VALUE_PAIRS)
+ {
+ //trace up to MAX_BIN_TRACE bytes of the data in case it is useful
+ TRACFBIN(g_trac_expupd, "OCMB FW IMAGE KEY/VALUE DATA",
+ l_dataStartPtr,
+ std::min(l_ttPtr->dataSize, MAX_BIN_TRACE));
+ }
+ else
+ {
+ //unsupported tag id.
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "parseTaggedDataTriplet: Invalid tag id[%u].",
+ l_ttPtr->tagId);
+
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_PARSE_TAGGED_DATA_TRIPLET
+ * @reasoncode EXPUPD::INVALID_TAG_ID
+ * @userdata1 tag id
+ * @userdata2 <unused>
+ * @devdesc Invalid tag id found in OCMB image header
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_PARSE_TAGGED_DATA_TRIPLET,
+ EXPUPD::INVALID_TAG_ID,
+ l_ttPtr->tagId,
+ 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ //Parsing was successful. Set bytes consumed.
+ o_numBytes = sizeof(taggedTriplet_t) + l_ttPtr->dataSize;
+ }while(0);
+
+ return l_err;
+}
+
+/**
+ * @brief Validates OCMB firmware header of packaged image
+ *
+ * @param[in] i_imageStart Start address of packaged image
+ * @param[in] i_imageSize Size of packaged image
+ * @param[out] o_imageInfo Information pertaining to image after
+ * being stripped of OCMB firmware header
+ * @return errlHndl_t indicating success or failure
+ *
+ */
+errlHndl_t ocmbFwValidateImage(const uint64_t i_imageStart,
+ const uint64_t i_imageSize,
+ rawImageInfo_t& o_imageInfo)
+{
+ const uint8_t* l_imageStartPtr =
+ reinterpret_cast<const uint8_t*>(i_imageStart);
+ errlHndl_t l_err = nullptr;
+
+ TRACFCOMP(g_trac_expupd,
+ ENTER_MRK "ocmbFwValidateImage(): startAddr[0x%016x] size[%u]",
+ i_imageStart, i_imageSize);
+
+ //clear out o_imageInfo
+ memset(&o_imageInfo, 0, sizeof(o_imageInfo));
+
+ do
+ {
+ const uint64_t l_minHeaderSize =
+ sizeof(ocmbFwHeader_t) +
+ sizeof(taggedTriplet_t) + HEADER_SHA512_SIZE;
+
+ const uint64_t l_maxHeaderSize =
+ std::min(static_cast<const uint64_t>(HEADER_MAX_SIZE),
+ i_imageSize);
+
+ // Check input parameters
+ if((!l_imageStartPtr) || (i_imageSize < l_minHeaderSize))
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "ocmbFwValidateImage: Invalid image address[%p] or"
+ " size[%u]",
+ l_imageStartPtr, i_imageSize);
+
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE
+ * @reasoncode EXPUPD::INVALID_PARMS
+ * @userdata1 i_imageStart
+ * @userdata2 i_imageSize
+ * @devdesc Invalid size or address for OCMB Flash Image
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE,
+ EXPUPD::INVALID_PARMS,
+ i_imageStart,
+ i_imageSize,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ const ocmbFwHeader_t* l_header =
+ reinterpret_cast<const ocmbFwHeader_t*>(l_imageStartPtr);
+
+ // Check eye catcher value
+ if(l_header->eyeCatcher != EYE_CATCHER_VALUE)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "ocmbFwValidateImage: Invalid eye catcher value: "
+ "expected[0x%016llx] actual[0x%016llx]",
+ EYE_CATCHER_VALUE, l_header->eyeCatcher);
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE
+ * @reasoncode EXPUPD::INVALID_EYE_CATCHER
+ * @userdata1 Expected Value
+ * @userdata2 Actual Value
+ * @devdesc Invalid eye catcher value for OCMB Flash Image
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE,
+ EXPUPD::INVALID_EYE_CATCHER,
+ EYE_CATCHER_VALUE,
+ l_header->eyeCatcher,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ // Check header version
+ if((l_header->majorVersion != HEADER_VERSION_MAJOR) ||
+ (l_header->minorVersion != HEADER_VERSION_MINOR))
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "ocmbFwValidateImage: Unsupported header version: %u.%u",
+ l_header->majorVersion, l_header->minorVersion);
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE
+ * @reasoncode EXPUPD::INVALID_HEADER_VERSION
+ * @userdata1 majorVersion
+ * @userdata2 minorVersion
+ * @devdesc Invalid header version for OCMB Flash Image
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE,
+ EXPUPD::INVALID_HEADER_VERSION,
+ l_header->majorVersion,
+ l_header->minorVersion,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ //Check that header size is within min/max range and 8byte aligned
+ if((l_header->headerSize < l_minHeaderSize) ||
+ (l_header->headerSize > l_maxHeaderSize) ||
+ !EXPUPD_8BYTE_ALIGNED(l_header->headerSize))
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "ocmbFwValidateImage: Unsupported header size: %u bytes",
+ l_header->headerSize);
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE
+ * @reasoncode EXPUPD::INVALID_HEADER_SIZE
+ * @userdata1 header size
+ * @userdata2 maximum allowed size
+ * @devdesc Invalid header size for OCMB Flash Image
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE,
+ EXPUPD::INVALID_HEADER_SIZE,
+ l_header->headerSize,
+ l_maxHeaderSize,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ // Trace header information.
+ TRACFCOMP(g_trac_expupd, "OCMB HEADER: Version[%u.%u] size[%u]"
+ " triplets[%u]",
+ l_header->majorVersion,
+ l_header->minorVersion,
+ l_header->headerSize,
+ l_header->numTriplets);
+
+ // Parse all tagged triplet data
+ const uint8_t* l_curTripletPtr = l_imageStartPtr + sizeof(*l_header);
+ const uint8_t* l_endDataPtr = l_imageStartPtr + l_header->headerSize;
+ for(uint32_t l_curTriplet = 0;
+ l_curTriplet < l_header->numTriplets;
+ l_curTriplet++)
+ {
+ uint32_t l_numBytes = 0;
+
+ // This will set o_imageInfo.imageSHA512Ptr if
+ // SHA512 hash is found
+ l_err = parseTaggedDataTriplet(l_curTripletPtr,
+ l_endDataPtr,
+ o_imageInfo,
+ l_numBytes);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "ocmbFwValidateImage: Failed parsing tagged data"
+ " triplet %u of %u",
+ l_curTriplet + 1, l_header->numTriplets);
+ break;
+ }
+
+ // Advance to next triplet
+ l_curTripletPtr += l_numBytes;
+ }
+ if(l_err)
+ {
+ break;
+ }
+
+ // Check if we found a SHA512 hash in the header
+ if(!o_imageInfo.imageSHA512HashPtr)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "ocmbFwValidateImage: No SHA512 Hash found in header!");
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE
+ * @reasoncode EXPUPD::MISSING_SHA512_HASH
+ * @userdata1 <unused>
+ * @userdata2 <unused>
+ * @devdesc Missing SHA512 hash in OCMB Flash Image
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE,
+ EXPUPD::MISSING_SHA512_HASH,
+ 0, 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ //** Header is valid if we made it this far **
+
+ // Trace the SHA512 hash
+ TRACFBIN(g_trac_expupd, "OCMB FW IMAGE SHA512 HASH",
+ o_imageInfo.imageSHA512HashPtr, HEADER_SHA512_SIZE);
+
+ // Set the image start address and size and we are done here.
+ o_imageInfo.imagePtr = l_imageStartPtr + l_header->headerSize;
+ o_imageInfo.imageSize = i_imageSize - l_header->headerSize;
+
+ }while(0);
+
+ TRACFCOMP(g_trac_expupd, EXIT_MRK "ocmbFwValidateImage()");
+ return l_err;
+}
+
+} //namespace expupd
+
diff --git a/src/usr/isteps/expupd/ocmbFwImage.H b/src/usr/isteps/expupd/ocmbFwImage.H
new file mode 100644
index 000000000..5e5de2e64
--- /dev/null
+++ b/src/usr/isteps/expupd/ocmbFwImage.H
@@ -0,0 +1,68 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/isteps/expupd/ocmbFwImage.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __OCMBFWIMAGE_H
+#define __OCMBFWIMAGE_H
+
+/**
+ * @file ocmbFwImage.H
+ *
+ * Interface for validating the OCMB firmware image from PNOR
+ *
+ */
+
+#include <errl/errlentry.H>
+
+namespace expupd
+{
+
+constexpr uint32_t HEADER_SHA512_SIZE = 64;
+
+/**
+ * @brief Parameters pertaining to an unpackaged (raw) OCMB firmware image
+ */
+typedef struct rawImageInfo
+{
+ const uint8_t* imagePtr;
+ size_t imageSize;
+ const uint8_t* imageSHA512HashPtr;
+}rawImageInfo_t;
+
+/**
+ * @brief Validates OCMB firmware header of packaged image
+ *
+ * @param[in] i_imageStart Start address of packaged image
+ * @param[in] i_imageSize Size of packaged image
+ * @param[out] o_imageInfo Information pertaining to image after
+ * being stripped of OCMB firmware header
+ * @return errlHndl_t indicating success or failure
+ *
+ */
+errlHndl_t ocmbFwValidateImage(const uint64_t i_imageStart,
+ const uint64_t i_imageSize,
+ rawImageInfo_t& o_imageInfo);
+
+}//namespace expupd
+
+#endif
diff --git a/src/usr/isteps/expupd/test/expupdatetest.H b/src/usr/isteps/expupd/test/expupdatetest.H
new file mode 100644
index 000000000..1fed4813e
--- /dev/null
+++ b/src/usr/isteps/expupd/test/expupdatetest.H
@@ -0,0 +1,175 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/isteps/expupd/test/expupdatetest.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __EXPUPDATETEST_H
+#define __EXPUPDATETEST_H
+
+/**
+ * @file expupdatetest.H
+ *
+ * @brief Test cases for explorer chip firmware update
+ */
+
+#include <cxxtest/TestSuite.H>
+#include <errl/errlmanager.H>
+#include <errl/errlentry.H>
+#include <fapi2.H>
+#include <plat_hwp_invoker.H>
+#include <lib/inband/exp_inband.H>
+#include <exp_data_structs.H>
+#include <exp_fw_update.H>
+#include <generic/memory/lib/utils/endian_utils.H>
+#ifndef __HOSTBOOT_RUNTIME
+#include <vfs/vfs.H> // module_is_loaded & module_load
+#endif
+#include <test/exptest_utils.H>
+
+const char MSS_LIBRARY_NAME[] = "libisteps_mss.so";
+const char EXPUPD_LIBRARY_NAME[] = "libexpupd.so";
+
+/**
+ * @brief Generic function to load a module
+ * @param i_modName - module name to load
+ * @return error handle if module_load call fails
+ */
+errlHndl_t loadModule(const char * i_modName)
+{
+ errlHndl_t err = nullptr;
+
+// VFS functions only compilable in non-runtime environment
+#ifndef __HOSTBOOT_RUNTIME
+ if(!VFS::module_is_loaded(i_modName))
+ {
+ err = VFS::module_load(i_modName);
+ if(err)
+ {
+ TS_FAIL("loadModule() - %s load failed", i_modName );
+ }
+ else
+ {
+ TS_TRACE("loadModule: %s loaded", i_modName);
+ }
+ }
+#endif
+ return err;
+}
+
+
+class ExpUpdateTest: public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief Test the explorer firmware update procedure
+ */
+ void testExpFwUpdate( void )
+ {
+ errlHndl_t l_errl = nullptr;
+
+ uint8_t l_dataBuffer[4096] = {0};
+
+ // Create a vector of TARGETING::Target pointers
+ TARGETING::TargetHandleList l_chipList;
+
+ // Get a list of all of the functioning ocmb chips
+ TARGETING::getAllChips(l_chipList, TARGETING::TYPE_OCMB_CHIP, true);
+
+ TARGETING::HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR l_mutex = exptest::getTestMutex();
+ if (l_mutex == nullptr)
+ {
+ TS_FAIL("testExpFwUpdate: unable to get test mutex");
+ }
+ else
+ {
+ for (const auto & l_ocmb: l_chipList)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>l_fapi2_target(l_ocmb);
+
+ // Inband operations can't be run at the same time
+ // atomic section >>
+ mutex_lock(l_mutex);
+
+ // Invoke procedure
+ FAPI_INVOKE_HWP(l_errl, exp_fw_update, l_fapi2_target,
+ l_dataBuffer, sizeof(l_dataBuffer));
+
+ // << atomic section
+ mutex_unlock(l_mutex);
+ if (l_errl)
+ {
+#if 0 // skipping exp_fw_update error until simics is changed - @fixme:RTC-209865
+ TS_FAIL("Error from exp_fw_update for 0x%.8X target",
+ TARGETING::get_huid(l_ocmb));
+#endif
+ break;
+ }
+ }
+
+ if (l_errl)
+ {
+ errlCommit(l_errl, CXXTEST_COMP_ID);
+ }
+ }
+
+ TS_INFO("testExpFwUpdate: exiting");
+ };
+
+ /**
+ * @brief Constructor
+ */
+ ExpUpdateTest() : CxxTest::TestSuite()
+ {
+ // All modules are loaded by runtime,
+ // so testcase loading of modules is not required
+#ifndef __HOSTBOOT_RUNTIME
+ errlHndl_t err = nullptr;
+
+ err = loadModule(MSS_LIBRARY_NAME);
+ if(err)
+ {
+ TS_FAIL("ExpUpdateTest() - Constuctor: failed to load MSS module");
+ errlCommit( err, CXXTEST_COMP_ID );
+ }
+ err = loadModule(EXPUPD_LIBRARY_NAME);
+ if(err)
+ {
+ TS_FAIL("ExpUpdateTest() - Constuctor: failed to load EXPUPD module");
+ errlCommit( err, CXXTEST_COMP_ID );
+ }
+#endif
+ };
+
+
+ /**
+ * @brief Destructor
+ */
+ ~ExpUpdateTest()
+ {
+ };
+
+ private:
+};
+
+#endif
diff --git a/src/usr/isteps/expupd/test/makefile b/src/usr/isteps/expupd/test/makefile
new file mode 100644
index 000000000..d028105f9
--- /dev/null
+++ b/src/usr/isteps/expupd/test/makefile
@@ -0,0 +1,33 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/isteps/expupd/test/makefile $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+ROOTPATH = ../../../../..
+MODULE = testexpupd
+
+include test.mk
+
+TESTS = expupdatetest.H
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/isteps/expupd/test/test.mk b/src/usr/isteps/expupd/test/test.mk
new file mode 100644
index 000000000..aca30b7f4
--- /dev/null
+++ b/src/usr/isteps/expupd/test/test.mk
@@ -0,0 +1,35 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/isteps/expupd/test/test.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2
+EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include
+EXTRAINCDIR += ${ROOTPATH}/src/import
+EXTRAINCDIR += ${ROOTPATH}/src/usr/expaccess
+
OpenPOWER on IntegriCloud