summaryrefslogtreecommitdiffstats
path: root/src/usr/ipmi
diff options
context:
space:
mode:
authorNick Bofferding <bofferdn@us.ibm.com>2014-11-26 15:21:57 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-12-13 11:31:28 -0600
commit96205b6f33afcef886784a3ad1362e58127aa284 (patch)
tree2d623b9757999b8fe0df719fc67822e8dcfc5f85 /src/usr/ipmi
parentb5fa2d654e3c321f039a88a51afffce76d4a94a9 (diff)
downloadtalos-hostboot-96205b6f33afcef886784a3ad1362e58127aa284.tar.gz
talos-hostboot-96205b6f33afcef886784a3ad1362e58127aa284.zip
Support simple clock callouts
- Added new simple fault sensor to report clock faults - Updated MRW parser to generate clock fault sensors - Updated attribute definition to support clock fault sensors - Initialize clock fault sensors when Hostboot starts - Report clock fault to BMC when clock is called out - Terminate system (config option) when clock is deconfigured Change-Id: I5e4de8a7c509a45feaad948a565f4f614f821786 RTC: 117344 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/14643 Tested-by: Jenkins Server Reviewed-by: Andrew J. Geissler <andrewg@us.ibm.com> Reviewed-by: Brian H. Horton <brianh@linux.ibm.com> Reviewed-by: Richard J. Knight <rjknight@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/ipmi')
-rw-r--r--src/usr/ipmi/ipmisensor.C212
1 files changed, 212 insertions, 0 deletions
diff --git a/src/usr/ipmi/ipmisensor.C b/src/usr/ipmi/ipmisensor.C
index c6b118850..6f61e21e0 100644
--- a/src/usr/ipmi/ipmisensor.C
+++ b/src/usr/ipmi/ipmisensor.C
@@ -48,6 +48,8 @@ namespace SENSOR
TARGETING::Target * i_target)
:iv_name(i_name) ,iv_target(i_target)
{
+ assert(i_target != NULL);
+
// allocate a new message structure to use with our sensors
// this will be the payload for the IPMI send/sendrecv sensor message.
iv_msg = new setSensorReadingRequest;
@@ -321,6 +323,78 @@ namespace SENSOR
return a[0] < key;
};
+ /**
+ * @brief Returns major type of input sensor name
+ *
+ * @param[in] i_sensorName
+ * Name of the sensor
+ *
+ * @return Major type of input sensor name
+ */
+ static inline uint16_t getMajorType(
+ const uint16_t i_sensorName)
+ {
+ return (i_sensorName & SENSOR_NAME_MAJOR_MASK);
+ }
+
+ /**
+ * @brief Returns minor type of input sensor name
+ *
+ * @param[in] i_sensorName
+ * Name of the sensor
+ *
+ * @return Minor type of input sensor name
+ */
+ static inline uint16_t getMinorType(
+ const uint16_t i_sensorName)
+ {
+ return (i_sensorName & SENSOR_NAME_MINOR_MASK);
+ }
+
+ /**
+ * @brief Returns whether the supplied sensor record's major type is less
+ * than the major type of the supplied sensor name
+ *
+ * @param[in] i_sensorRecord
+ * Sensor record to compare
+ *
+ * @param[in] i_sensorName
+ * Name of the sensor to compare
+ *
+ * @retval true Major type of sensor record is less than major type of
+ * sensor name
+ * @retval false Major type of sensor record is not less than major type of
+ * sensor name
+ */
+ static inline bool compare_major(
+ const uint16_t (&i_sensorRecord)[2],
+ const uint16_t i_sensorName)
+ {
+ return getMajorType(i_sensorRecord[0]) < getMajorType(i_sensorName);
+ }
+
+ /**
+ * @brief Returns whether the supplied sensor record's major type equals
+ * the major type of the supplied sensor name
+ *
+ * @param[in] i_sensorRecord
+ * Sensor record to compare
+ *
+ * @param[in] i_sensorName
+ * Name of the sensor to compare
+ *
+ * @retval true Major type of sensor record equals major type of
+ * sensor name
+ * @retval false Major type of sensor record does not equal major type of
+ * sensor name
+ */
+ static inline bool equals_major(
+ const uint16_t (&i_sensorRecord)[2],
+ const uint16_t i_sensorName)
+ {
+ return getMajorType(i_sensorRecord[0]) == getMajorType(i_sensorName);
+ }
+
//
// Helper function to search the sensor data for the correct sensor number
// based on the sensor name.
@@ -551,6 +625,72 @@ namespace SENSOR
};
+ //**************************************************************************
+ // FaultSensor constructor
+ //**************************************************************************
+
+ FaultSensor::FaultSensor(
+ TARGETING::Target* i_pTarget)
+ : SensorBase(TARGETING::SENSOR_NAME_FAULT, i_pTarget)
+ {
+ }
+
+ //**************************************************************************
+ // FaultSensor constructor for associated targets
+ //**************************************************************************
+
+ FaultSensor::FaultSensor(
+ TARGETING::Target* i_pTarget,
+ const TARGETING::TYPE i_associatedType)
+ : SensorBase(
+ static_cast<TARGETING::SENSOR_NAME>(
+ TARGETING::SENSOR_NAME_FAULT | i_associatedType),
+ i_pTarget)
+ {
+ }
+
+ //**************************************************************************
+ // FaultSensor destructor
+ //**************************************************************************
+
+ FaultSensor::~FaultSensor()
+ {
+ }
+
+ //**************************************************************************
+ // FaultSensor::setStatus
+ //**************************************************************************
+
+ errlHndl_t FaultSensor::setStatus(
+ const FAULT_STATE i_faultState)
+ {
+ errlHndl_t pError = NULL;
+
+ switch(i_faultState)
+ {
+ case FAULT_STATE_ASSERTED:
+ iv_msg->iv_deassertion_mask = setMask(FAULT_DEASSERTED_OFFSET);
+ iv_msg->iv_assertion_mask = setMask(FAULT_ASSERTED_OFFSET);
+ break;
+ case FAULT_STATE_DEASSERTED:
+ iv_msg->iv_deassertion_mask = setMask(FAULT_ASSERTED_OFFSET);
+ iv_msg->iv_assertion_mask = setMask(FAULT_DEASSERTED_OFFSET);
+ break;
+ default:
+ assert(0,"Caller passed unsupported fault state of 0x%X",
+ i_faultState);
+ }
+
+ pError = writeSensorData();
+ if(pError)
+ {
+ TRACFCOMP(g_trac_ipmi, ERR_MRK " "
+ "Failed to write sensor data for sensor name 0x%X",
+ iv_name);
+ }
+
+ return pError;
+ }
//
// HostStausSensor constructor - uses system target
@@ -652,6 +792,76 @@ namespace SENSOR
}
+ void updateBMCFaultSensorStatus(void)
+ {
+ TARGETING::ATTR_IPMI_SENSORS_type noSensors = {{0}};
+
+ // No sensor attribute is all 0's; therefore if a sensor attribute is
+ // found and is not all zeros (using the predicate value inversion
+ // feature) then the sensor attribute has potential
+ // sensors to iterate through
+ TARGETING::PredicateAttrVal<TARGETING::ATTR_IPMI_SENSORS>
+ hasSensors(noSensors,true);
+ TARGETING::TargetRangeFilter targetsWithSensorsItr(
+ TARGETING::targetService().begin(),
+ TARGETING::targetService().end(),
+ &hasSensors);
+ for (; targetsWithSensorsItr; ++targetsWithSensorsItr)
+ {
+ // Cache the target for ease of reading/usage
+ TARGETING::TargetHandle_t pTarget = *targetsWithSensorsItr;
+
+ TARGETING::ATTR_IPMI_SENSORS_type sensors = {{0}};
+ assert(pTarget->tryGetAttr<TARGETING::ATTR_IPMI_SENSORS>(sensors));
+
+ // Derive number of sensor records by dividing attribute size by
+ // size of each sensor record
+ uint16_t sensorRows = (sizeof(sensors)/sizeof(sensors[0]));
+
+ // Ceate an iterator pointing to the first element of the array
+ uint16_t (*begin)[2] = &sensors[0];
+
+ // Using the number entries as the index into the array will set the
+ // end iterator to the correct position (one entry past the last
+ // element of the array)
+ uint16_t (*end)[2] = &sensors[sensorRows];
+
+ // Locate the first record that could possibly match the criteria
+ uint16_t (*ptr)[2] =
+ std::lower_bound(begin, end,
+ TARGETING::SENSOR_NAME_FAULT, &compare_major);
+
+ // Process any match, and all remaining matches after that, until
+ // there is no additional match. Here we are matching the major
+ // sensor type only
+ while( (ptr != end)
+ && ( getMajorType((*ptr)[0])
+ == TARGETING::SENSOR_NAME_FAULT ))
+ {
+ TRACFCOMP(g_trac_ipmi, INFO_MRK " "
+ "Found fault sensor name 0x%X and ID 0x%X for HUID 0x%X",
+ (*ptr)[0], (*ptr)[1], TARGETING::get_huid(pTarget));
+
+ FaultSensor faultSensor(pTarget,
+ static_cast<TARGETING::TYPE>(
+ (*ptr)[0]));
+
+ errlHndl_t pError = faultSensor.setStatus(
+ FaultSensor::FAULT_STATE_DEASSERTED);
+ if(pError)
+ {
+ TRACFCOMP(g_trac_ipmi, ERR_MRK " "
+ "Failed setting fault sensor name 0x%X and ID 0x%X for "
+ "HUID 0x%X",
+ (*ptr)[0], (*ptr)[1], TARGETING::get_huid(pTarget));
+ errlCommit(pError, IPMI_COMP_ID);
+ }
+
+ ++ptr;
+ }
+ }
+ }
+
void updateBMCSensorStatus()
{
// send status of all DIMM targets
@@ -662,6 +872,8 @@ namespace SENSOR
updateBMCSensorStatus(TARGETING::TYPE_CORE);
+ // Send status for all simple fault sensors in the system
+ updateBMCFaultSensorStatus();
};
}; // end name space
OpenPOWER on IntegriCloud