summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorJaymes Wilks <mjwilks@us.ibm.com>2018-08-17 11:24:21 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-11-12 09:00:37 -0600
commit87adeec286402eb648f14d274382fb8b84351467 (patch)
tree62f3c86906eac47753f862e8147af53a469e5d3f /src/usr
parentd83a4ee8495c5ad4b823c26b1a09a3c886882494 (diff)
downloadtalos-hostboot-87adeec286402eb648f14d274382fb8b84351467.tar.gz
talos-hostboot-87adeec286402eb648f14d274382fb8b84351467.zip
Support openpower-specific I2C device callouts
This change supports the openpower path for adding I2C device callouts to error logs. The process works as follows: - Create an I2C device lookup table on first use of I2C callout - Use that table to map I2C info to the actual device to callout - Callout any other I2C devices on the bus with lesser priority - If no I2C match found, callout the I2C master instead - If an I2C device was found, callout the I2C master as low Change-Id: Ib7b248ae60e7e834d6165bbdf4bd9b776ea2421b RTC:94872 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/64833 Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/errl/errl.mk1
-rw-r--r--src/usr/errl/errlentry.C7
-rw-r--r--src/usr/errl/errli2c.C279
-rw-r--r--src/usr/errl/errlmanager_common.C8
-rw-r--r--src/usr/errl/plugins/errludcallout.H4
-rw-r--r--src/usr/errldisplay/errldisplay.C7
-rw-r--r--src/usr/hwas/common/hwasCallout.C2
-rw-r--r--src/usr/hwas/hwasPlatCallout.C7
-rwxr-xr-xsrc/usr/i2c/eepromdd.H11
-rwxr-xr-xsrc/usr/i2c/i2c.C99
10 files changed, 350 insertions, 75 deletions
diff --git a/src/usr/errl/errl.mk b/src/usr/errl/errl.mk
index ce1c5c0e8..8cab37324 100644
--- a/src/usr/errl/errl.mk
+++ b/src/usr/errl/errl.mk
@@ -40,3 +40,4 @@ OBJS += errludcallout.o
OBJS += errludsensor.o
OBJS += errludstate.o
OBJS += errlmanager_common.o
+OBJS += errli2c.o
diff --git a/src/usr/errl/errlentry.C b/src/usr/errl/errlentry.C
index ad95bc4dd..7f7c9a5b0 100644
--- a/src/usr/errl/errlentry.C
+++ b/src/usr/errl/errlentry.C
@@ -47,6 +47,7 @@
#include <errl/errluserdetails.H>
#include <errl/errludattribute.H>
#include <errl/errludstate.H>
+#include <errl/errli2c.H>
#include <trace/interface.H>
#include <config.h>
@@ -64,10 +65,12 @@
#include <attributeenums.H>
#include "errlentry_consts.H"
#include <util/misc.H>
+
#ifdef CONFIG_BMC_IPMI
#include <ipmi/ipmisensor.H>
#include <errl/errludsensor.H>
#endif
+
// Hostboot Image ID string
extern char hbi_ImageId;
@@ -2203,10 +2206,12 @@ void ErrlEntry::addI2cDeviceCallout(const TARGETING::Target *i_i2cMaster,
ep = nullptr;
}
- } while (0);
+ handleI2cDeviceCalloutWithinHostboot(this, i_i2cMaster, i_engine, i_port, i_address, i_priority);
+ } while (0);
} // addI2cDeviceCallout
+
} // End namespace
diff --git a/src/usr/errl/errli2c.C b/src/usr/errl/errli2c.C
new file mode 100644
index 000000000..92229a65a
--- /dev/null
+++ b/src/usr/errl/errli2c.C
@@ -0,0 +1,279 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/errl/errli2c.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2018 */
+/* [+] 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 */
+/*****************************************************************************/
+// I n c l u d e s
+/*****************************************************************************/
+#include <stdio.h>
+#include <errl/errli2c.H>
+#include <errl/errlmanager.H>
+#include <trace/interface.H>
+#include <hwas/common/hwasCallout.H>
+#include <hwas/common/deconfigGard.H>
+#include <targeting/common/targetservice.H>
+#include <targeting/common/utilFilter.H>
+#include <config.h>
+#include <attributeenums.H>
+#include <i2c/eepromif.H>
+
+using namespace ERRORLOG;
+using namespace HWAS;
+
+namespace ERRORLOG
+{
+
+// Trace definition
+extern trace_desc_t* g_trac_errl;
+
+uint8_t I2cDevInfos::getDepth(const TARGETING::Target* i_target) const
+{
+ return i_target->getAttr<TARGETING::ATTR_PHYS_PATH>().size();
+}
+
+I2cDevInfos::I2cDevInfos()
+{
+ auto& tS = TARGETING::targetService();
+
+ TARGETING::TargetRangeFilter l_targetFilter(tS.begin(), tS.end(), nullptr);
+
+ // gather up all the matching info and store in the vector
+ for(;l_targetFilter; ++l_targetFilter)
+ {
+ const TARGETING::Target* l_tgt = (*l_targetFilter);
+ // Looking to see if we have any info about VPD or SBE Seeproms
+ {
+ TARGETING::ATTR_EEPROM_VPD_PRIMARY_INFO_type d; // local scope
+ if (l_tgt->tryGetAttr<TARGETING::ATTR_EEPROM_VPD_PRIMARY_INFO>(d))
+ {
+ iv_i2cdvs.push_back({d.i2cMasterPath, d.engine, d.port,
+ d.devAddr, d.chipCount, EEPROM::VPD_PRIMARY,
+ l_tgt, getDepth(l_tgt)});
+ }
+ }
+ {
+ TARGETING::ATTR_EEPROM_SBE_PRIMARY_INFO_type d; // local scope
+ if (l_tgt->tryGetAttr<TARGETING::ATTR_EEPROM_SBE_PRIMARY_INFO>(d))
+ {
+ // String literal is used for comparison below, must stay sync'd
+ iv_i2cdvs.push_back({d.i2cMasterPath, d.engine, d.port,
+ d.devAddr, d.chipCount, EEPROM::SBE_PRIMARY,
+ l_tgt, getDepth(l_tgt)});
+ }
+ }
+ {
+ TARGETING::ATTR_EEPROM_VPD_BACKUP_INFO_type d; // local scope
+ if (l_tgt->tryGetAttr<TARGETING::ATTR_EEPROM_VPD_BACKUP_INFO>(d))
+ {
+ // String literal is used for comparison below, must stay sync'd
+ iv_i2cdvs.push_back({d.i2cMasterPath, d.engine, d.port,
+ d.devAddr, d.chipCount, EEPROM::VPD_BACKUP,
+ l_tgt, getDepth(l_tgt)});
+ }
+ }
+ {
+ TARGETING::ATTR_EEPROM_SBE_BACKUP_INFO_type d; // local scope
+ if (l_tgt->tryGetAttr<TARGETING::ATTR_EEPROM_SBE_BACKUP_INFO>(d))
+ {
+ // String literal is used for comparison below, must stay sync'd
+ iv_i2cdvs.push_back({d.i2cMasterPath, d.engine, d.port,
+ d.devAddr, d.chipCount, EEPROM::SBE_BACKUP,
+ l_tgt, getDepth(l_tgt)});
+ }
+ }
+ // try for a TPM
+ {
+ TARGETING::ATTR_TPM_INFO_type t;
+ if (l_tgt->tryGetAttr<TARGETING::ATTR_TPM_INFO>(t))
+ {
+ // String literal is used for comparison below, must stay sync'd
+ iv_i2cdvs.push_back({t.i2cMasterPath, t.engine, t.port,
+ t.devAddrLocality0, 0,
+ EEPROM::INVALID_CHIP_TYPE, l_tgt,
+ getDepth(l_tgt)});
+ }
+ }
+ }
+}
+
+
+void handleI2cDeviceCalloutWithinHostboot(
+ errlHndl_t i_errl,
+ const TARGETING::Target *i_i2cMaster,
+ const uint8_t i_engine,
+ const uint8_t i_port,
+ const uint8_t i_address,
+ const HWAS::callOutPriority i_priority)
+{
+ do {
+
+ assert(i_errl != nullptr, "Bug! Error log handle pointer passed is null");
+ assert(i_i2cMaster != nullptr, "Bug! I2C master target passed is null");
+ assert(i_priority >= HWAS::SRCI_PRIORITY_LOW &&
+ i_priority <= HWAS::SRCI_PRIORITY_HIGH, "Bug! Bad priority given");
+
+ auto& tS = TARGETING::targetService();
+
+ auto l_devFound = false;
+
+ const auto l_i2cmPhysPath = i_i2cMaster->getAttr<TARGETING::ATTR_PHYS_PATH>();
+
+ // determine default priority to be one below what was passed in, or if
+ // LOW was passed in, then LOW. Its use is described below.
+ auto l_defaultPriority = HWAS::SRCI_PRIORITY_LOW;
+ if (i_priority == HWAS::SRCI_PRIORITY_HIGH)
+ {
+ l_defaultPriority = HWAS::SRCI_PRIORITY_MED;
+ }
+
+ // list of devices to search from
+ auto i2cdvs = I2cDevInfos::getInstance().getDevList();
+
+ // we delay adding hardware callouts until the end so that we
+ // can eliminate duplicate targets representing the same device
+ std::vector<I2cMatchingInfo_t> i2chwcos;
+
+ // try to find a device match in the list of matching infos
+ for (auto& i2cd : i2cdvs)
+ {
+ TRACDCOMP(g_trac_errl, "handleI2cDeviceCalloutWithinHostboot: chipType %d Engine=%d, Port=%d, addr=0x%X, i2cMasterHuid=0x%X huid=0x%X w/ %d chips ...", i2cd.chipType, i2cd.engine, i2cd.port, i2cd.devAddr, TARGETING::get_huid(tS.toTarget(i2cd.i2cMasterPath)), TARGETING::get_huid(i2cd.tgt), i2cd.chipCount);
+
+ // match the master path, engine and port
+ if (l_i2cmPhysPath == i2cd.i2cMasterPath &&
+ i_engine == i2cd.engine &&
+ i_port == i2cd.port)
+ {
+ // all devices on the bus default to one notch below the passed
+ // in priority unless LOW was passed in (see calculation above)
+ auto l_priority = l_defaultPriority;
+
+ // if the device is its own i2c master
+ if (i_i2cMaster == i2cd.tgt)
+ {
+ // go the part callout route
+
+ // set to the passed in priority if the address is in range
+ // otherwise leave as default priority
+ const auto maxAddr = i2cd.devAddr +
+ (i2cd.chipCount * EEPROM::EEPROM_DEVADDR_INC);
+ if (i_address >= i2cd.devAddr && i_address < maxAddr)
+ {
+ l_priority = i_priority; // priority passed in
+ l_devFound = true;
+ }
+ TRACDCOMP(g_trac_errl, "handleI2cDeviceCalloutWithinHostboot: Match found! Adding part callout for chipType %d Engine=%d, Port=%d, addr=0x%X, i2cMasterHuid=0x%X w/ %d chips", i2cd.chipType, i2cd.engine, i2cd.port, i2cd.devAddr, TARGETING::get_huid(i2cd.tgt), i2cd.chipCount);
+
+ // add VPD or SBE part callout depending on chip type
+ i_errl->addPartCallout(i2cd.tgt,
+ (i2cd.chipType==EEPROM::VPD_PRIMARY ||
+ i2cd.chipType==EEPROM::VPD_BACKUP)?
+ HWAS::VPD_PART_TYPE:
+ HWAS::SBE_SEEPROM_PART_TYPE,
+ l_priority,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+ }
+ else
+ {
+ // go the HW callout route
+
+ // first check to see if the device is a duplicate
+ auto dupItr = std::find_if(i2chwcos.begin(),i2chwcos.end(),
+ [&i2cd](const I2cMatchingInfo_t & matchedBefore)
+ {
+ // return true if the current device matches something we
+ // have matched previously
+ return i2cd.i2cMasterPath == matchedBefore.i2cMasterPath &&
+ i2cd.engine == matchedBefore.engine &&
+ i2cd.port == matchedBefore.port &&
+ i2cd.devAddr == matchedBefore.devAddr;
+ });
+
+ TRACDCOMP(g_trac_errl, "handleI2cDeviceCalloutWithinHostboot: i2cdev chipType=%d Engine=%d, Port=%d, addr=0x%X, i2cHuid=0x%X, i2cd.targetAncestryDepth=%d", i2cd.chipType, i2cd.engine, i2cd.port, i2cd.devAddr, TARGETING::get_huid(i2cd.tgt), i2cd.targetAncestryDepth);
+
+ if(dupItr == i2chwcos.end())
+ {
+ // not there so add the match
+ i2chwcos.push_back(i2cd);
+ }
+ else
+ {
+ // dereference the duplicate device from its iterator
+ auto dupDev = *dupItr;
+
+ TRACDCOMP(g_trac_errl, "handleI2cDeviceCalloutWithinHostboot: dupdev chipType=%d Engine=%d, Port=%d, addr=0x%X, i2cHuid=0x%X, dupDev.targetAncestryDepth=%d", dupDev.chipType, dupDev.engine, dupDev.port, dupDev.devAddr, TARGETING::get_huid(dupDev.tgt), dupDev.targetAncestryDepth);
+
+ // we need to replace it if we found a device with more
+ // seniority (in other words less depth) than the duplicate
+ if (dupDev.targetAncestryDepth > i2cd.targetAncestryDepth)
+ {
+ i2chwcos.erase(dupItr); // remove the old
+ i2chwcos.push_back(i2cd); // add the new
+ }
+ }
+ }
+ }
+ }
+
+ // now that we know there are no duplicates add the HW callouts in 2nd pass
+ for (auto& i2cd : i2chwcos)
+ {
+ // all devices on the bus default to one notch below the passed
+ // in priority unless LOW was passed in (see calculation above)
+ auto l_priority = l_defaultPriority;
+
+ // set to the passed in priority for exact device address matches
+ // otherwise leave as default priority
+
+ if (i_address == i2cd.devAddr)
+ {
+ l_priority = i_priority;
+ l_devFound = true;
+ }
+ TRACDCOMP(g_trac_errl, "handleI2cDeviceCalloutWithinHostboot: Match found! Adding Hw callout for huid 0x%X", TARGETING::get_huid(i2cd.tgt));
+ i_errl->addHwCallout(i2cd.tgt,
+ l_priority,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ }
+
+ // callout i2c master as the priorty passed in if nothing else was found
+ // otherwise callout as low to let the device found to take precedence
+ i_errl->addHwCallout( i_i2cMaster,
+ l_devFound? HWAS::SRCI_PRIORITY_LOW:
+ i_priority,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL );
+
+ } while ( 0 );
+}
+
+
+I2cDevInfos& I2cDevInfos::getInstance()
+{
+ return Singleton<I2cDevInfos>::instance();
+}
+
+} // End namespace
+
diff --git a/src/usr/errl/errlmanager_common.C b/src/usr/errl/errlmanager_common.C
index 77cd5594a..e1e965e5a 100644
--- a/src/usr/errl/errlmanager_common.C
+++ b/src/usr/errl/errlmanager_common.C
@@ -657,6 +657,14 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
l_calloutToAdd.procedure = HWAS::EPUB_PRC_EIBUS_ERROR;
}
+ // I2C device callouts don't map to anything useful in the
+ // IPMI world. They do come with a more IPMI-friendly
+ // callout that follows after, so we can skip to the next.
+ if (l_ud->type == HWAS::I2C_DEVICE_CALLOUT)
+ {
+ continue;
+ }
+
// if this callout is higher than any previous callout
if (l_ud->priority > l_priority)
{
diff --git a/src/usr/errl/plugins/errludcallout.H b/src/usr/errl/plugins/errludcallout.H
index f5ef563b7..e8bb364e9 100644
--- a/src/usr/errl/plugins/errludcallout.H
+++ b/src/usr/errl/plugins/errludcallout.H
@@ -222,13 +222,13 @@ case HWAS::_type: i_parser.PrintString( "Bus Type", #_type); break;
}
case HWAS::I2C_DEVICE_CALLOUT:
{
- i_parser.PrintString( "Callout type", "I2c Device Callout");
+ i_parser.PrintString( "Callout type", "I2C Device Callout");
i_parser.PrintNumber( "Engine","0x%.2x", pData->engine );
i_parser.PrintNumber( "Port","0x%.2x", pData->port );
i_parser.PrintNumber( "DevAddr","0x%.2x", pData->address );
uint8_t *l_ptr = reinterpret_cast<uint8_t *>(pData+1);
- printEntityPath(l_ptr, i_parser, "Target");
+ printEntityPath(l_ptr, i_parser, "I2C Master");
break; // I2C_DEVICE_CALLOUT
}
diff --git a/src/usr/errldisplay/errldisplay.C b/src/usr/errldisplay/errldisplay.C
index 768c45b73..bfae1d1f3 100644
--- a/src/usr/errldisplay/errldisplay.C
+++ b/src/usr/errldisplay/errldisplay.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2018 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -400,6 +400,11 @@ case HWAS::_type: CONSOLE::displayf(NULL, " Sensor Type : %s", #
#undef case_SENSOR_TYPE
break;
+ case HWAS::I2C_DEVICE_CALLOUT:
+ CONSOLE::displayf(nullptr, " Callout type : I2C Device Callout");
+
+ break;
+
default:
CONSOLE::displayf(NULL, " Callout type : UNKNOWN: 0x%X",
callout->type);
diff --git a/src/usr/hwas/common/hwasCallout.C b/src/usr/hwas/common/hwasCallout.C
index 83f168a29..48f91415a 100644
--- a/src/usr/hwas/common/hwasCallout.C
+++ b/src/usr/hwas/common/hwasCallout.C
@@ -259,7 +259,7 @@ void processCallout(errlHndl_t &io_errl,
// TODO RTC 94872 - Uncomment this later after the FSP team
// implements it.
//
- // errlHndl_t errl = platHandleI2cDeviceCallout(
+ // errl = platHandleI2cDeviceCallout(
// i2cMaster,
// pCalloutUD->engine,
// pCalloutUD->port,
diff --git a/src/usr/hwas/hwasPlatCallout.C b/src/usr/hwas/hwasPlatCallout.C
index ce1ec18b6..c7e34edb6 100644
--- a/src/usr/hwas/hwasPlatCallout.C
+++ b/src/usr/hwas/hwasPlatCallout.C
@@ -202,14 +202,9 @@ errlHndl_t platHandleI2cDeviceCallout(
callOutPriority i_priority,
errlHndl_t &io_errl)
{
- // WARNING:
- // this hostboot code should not change io_errl, unless the caller of the
- // processCallouts() function also changes, as today it (errlentry.C) calls
- // from the errlEntry object
-
errlHndl_t errl = nullptr;
- // hostboot does not yet handle or do any action for i2c callouts
+ // hostboot handling is done in ERRORLOG::addI2cDeviceCallout function
return errl;
}
diff --git a/src/usr/i2c/eepromdd.H b/src/usr/i2c/eepromdd.H
index b184f2b38..cfff8f679 100755
--- a/src/usr/i2c/eepromdd.H
+++ b/src/usr/i2c/eepromdd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2016 */
+/* Contributors Listed Below - COPYRIGHT 2011,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -72,15 +72,6 @@ typedef struct
uint64_t writeCycleTime; // in milliseconds
} eeprom_addr_t;
-/*
- * @brief Miscellaneous enums for EEPROM
- */
-enum
-{
- EEPROM_PAGE_SIZE = 0x100,
- EEPROM_DEVADDR_INC = 2
-};
-
/**
*
* @brief Perform an EEPROM access operation.
diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C
index 05c3e40ea..9d2e1d620 100755
--- a/src/usr/i2c/i2c.C
+++ b/src/usr/i2c/i2c.C
@@ -4455,53 +4455,7 @@ void addHwCalloutsI2c(errlHndl_t i_err,
assert(i_err != nullptr, "Bug! The supplied error log is nullptr.");
assert(i_target != nullptr, "Bug! The supplied target is nullptr.");
- // Attempt to find a target representing the device that
- // failed to respond, and call it out as the most likely
- // problem. For now, we only support TPM reverse lookup;
- // TODO RTC 94872 will implement generic support for other
- // devices.
-
- // Loop thru TPMs in the system and match physical path,
- // engine, and port to the i2c master
- auto l_devFound = false;
- const auto l_physPath = i_target->getAttr<
- TARGETING::ATTR_PHYS_PATH>();
- TARGETING::TargetHandleList allTpms;
- TARGETING::getAllChips( allTpms, TARGETING::TYPE_TPM, false );
- for(const auto &tpm: allTpms)
- {
- const auto l_tpmInfo = tpm->getAttr<
- TARGETING::ATTR_TPM_INFO>();
-
- if (l_tpmInfo.i2cMasterPath == l_physPath &&
- l_tpmInfo.engine == i_args.engine &&
- l_tpmInfo.port == i_args.port &&
- l_tpmInfo.devAddrLocality0 == i_args.devAddr)
- {
- TRACFCOMP(g_trac_i2c,
- "Unresponsive TPM found: "
- "Engine=%d, masterPort=%d "
- "huid for its i2c master is 0x%.8X",
- l_tpmInfo.engine,
- l_tpmInfo.port,
- TARGETING::get_huid(i_target));
- i_err->addHwCallout(tpm,
- HWAS::SRCI_PRIORITY_HIGH,
- HWAS::NO_DECONFIG,
- HWAS::GARD_NULL);
- l_devFound = true;
- break;
- }
- }
- // For the FSP, non-TPM case add an I2c Device callout.
- // TODO RTC 94872 In a future commit, we will want FSP to handle
- // the TPM case also, but we won't add it here until FSP fully
- // supports the new i2c callout type. The reasoning is that we still need
- // TPMs to be called out as before in the interim. The other i2c devices
- // (that were never called out to begin with) are the only ones being added
- // as the new type, because FSP will treat the new type as unknown until
- // support for the new type is added.
- if (l_devFound == false && INITSERVICE::spBaseServicesEnabled())
+ if (!INITSERVICE::spBaseServicesEnabled())
{
i_err->addI2cDeviceCallout(i_target,
i_args.engine,
@@ -4509,15 +4463,52 @@ void addHwCalloutsI2c(errlHndl_t i_err,
i_args.devAddr,
HWAS::SRCI_PRIORITY_HIGH);
}
+ // For FSP systems which don't yet have special handling for
+ // i2c device callouts we still need to handle the TPM search
+ // to avoid regression back to the "non TPM aware" behavior.
+ else
+ {
+ // Loop thru TPMs in the system and match physical path,
+ // engine, and port to the i2c master
+ auto l_devFound = false;
+ const auto l_physPath = i_target->getAttr<
+ TARGETING::ATTR_PHYS_PATH>();
+ TARGETING::TargetHandleList allTpms;
+ TARGETING::getAllChips( allTpms, TARGETING::TYPE_TPM, false );
+ for(const auto &tpm: allTpms)
+ {
+ const auto l_tpmInfo = tpm->getAttr<
+ TARGETING::ATTR_TPM_INFO>();
- // Could also be an issue with Processor or its bus
- // -- both on the same FRU
- i_err->addHwCallout( i_target,
- l_devFound? HWAS::SRCI_PRIORITY_MED:
- HWAS::SRCI_PRIORITY_HIGH,
- HWAS::NO_DECONFIG,
- HWAS::GARD_NULL );
+ if (l_tpmInfo.i2cMasterPath == l_physPath &&
+ l_tpmInfo.engine == i_args.engine &&
+ l_tpmInfo.port == i_args.port &&
+ l_tpmInfo.devAddrLocality0 == i_args.devAddr)
+ {
+ TRACFCOMP(g_trac_i2c,
+ "Unresponsive TPM found: "
+ "Engine=%d, masterPort=%d "
+ "huid for its i2c master is 0x%.8X",
+ l_tpmInfo.engine,
+ l_tpmInfo.port,
+ TARGETING::get_huid(i_target));
+ i_err->addHwCallout(tpm,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+ l_devFound = true;
+ break;
+ }
+ }
+ // Could also be an issue with Processor or its bus
+ // -- both on the same FRU
+ i_err->addHwCallout( i_target,
+ l_devFound? HWAS::SRCI_PRIORITY_MED:
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL );
+ }
}
}; // end namespace I2C
OpenPOWER on IntegriCloud