Attn: Add support for raw pel symptom-id
Update raw pel symptom-id based on TI info data.
Signed-off-by: Ben Tyner <ben.tyner@ibm.com>
Change-Id: I501938e0fc9dba189999ab1491d23acd15628068
diff --git a/attn/attn_logging.cpp b/attn/attn_logging.cpp
index 3395c19..a9be924 100644
--- a/attn/attn_logging.cpp
+++ b/attn/attn_logging.cpp
@@ -235,6 +235,21 @@
std::min(srcString.size(), pel::asciiStringSize), 0);
tiPel->setAsciiString(srcChars); // pel object src is char array
+
+ // set symptom-id
+ auto symptomId = (i_additional["SrcAscii"].substr(0, 8) + '_');
+
+ symptomId += (i_additional["0x10 SRC Word 12"]);
+ symptomId += (i_additional["0x14 SRC Word 13"] + '_');
+ symptomId += (i_additional["0x18 SRC Word 14"]);
+ symptomId += (i_additional["0x1c SRC Word 15"] + '_');
+ symptomId += (i_additional["0x20 SRC Word 16"]);
+ symptomId += (i_additional["0x24 SRC Word 17"] + '_');
+ symptomId += (i_additional["0x28 SRC Word 18"]);
+ symptomId += (i_additional["0x2c SRC Word 19"]);
+
+ // setSymptomId will take care of required null-terminate and padding
+ tiPel->setSymptomId(symptomId);
}
else
{
@@ -265,6 +280,21 @@
std::min(srcString.size(), pel::asciiStringSize), 0);
tiPel->setAsciiString(srcChars); // pel object src is char array
+
+ // set symptom-id
+ auto symptomId = (i_additional["SrcAscii"].substr(0, 8) + '_');
+
+ symptomId += (i_additional["0x10 HB Word 0"]); // note: word 1
+ symptomId += (i_additional["0x14 HB Word 2"] + '_'); // does not exist
+ symptomId += (i_additional["0x18 HB Word 3"]);
+ symptomId += (i_additional["0x1c HB Word 4"] + '_');
+ symptomId += (i_additional["0x20 HB Word 5"]);
+ symptomId += (i_additional["0x24 HB Word 6"] + '_');
+ symptomId += (i_additional["0x28 HB Word 7"]);
+ symptomId += (i_additional["0x2c HB Word 8"]);
+
+ // setSymptomId will take care of required null-terminate and padding
+ tiPel->setSymptomId(symptomId);
}
// set severity, event type and action flags
diff --git a/attn/meson.build b/attn/meson.build
index f6fdd56..3b085af 100644
--- a/attn/meson.build
+++ b/attn/meson.build
@@ -40,6 +40,7 @@
# for custom/raw PEL creation
pel_src = files(
+ 'pel/extended_user_header.cpp',
'pel/pel_minimal.cpp',
'pel/private_header.cpp',
'pel/primary_src.cpp',
diff --git a/attn/pel/extended_user_header.cpp b/attn/pel/extended_user_header.cpp
new file mode 100644
index 0000000..117ca62
--- /dev/null
+++ b/attn/pel/extended_user_header.cpp
@@ -0,0 +1,59 @@
+#include "extended_user_header.hpp"
+
+namespace attn
+{
+namespace pel
+{
+
+ExtendedUserHeader::ExtendedUserHeader(Stream& pel)
+{
+ unflatten(pel);
+}
+
+void ExtendedUserHeader::flatten(Stream& pel) const
+{
+ pel << _header;
+ pel.write(_mtms, mtmsSize);
+ pel.write(_serverFWVersion.data(), _serverFWVersion.size());
+ pel.write(_subsystemFWVersion.data(), _subsystemFWVersion.size());
+ pel << _reserved4B << _refTime << _reserved1B1 << _reserved1B2
+ << _reserved1B3 << _symptomIdSize << _symptomId;
+}
+
+void ExtendedUserHeader::unflatten(Stream& pel)
+{
+ pel >> _header;
+ pel.read(_mtms, mtmsSize);
+ pel.read(_serverFWVersion.data(), _serverFWVersion.size());
+ pel.read(_subsystemFWVersion.data(), _subsystemFWVersion.size());
+ pel >> _reserved4B >> _refTime >> _reserved1B1 >> _reserved1B2 >>
+ _reserved1B3 >> _symptomIdSize >> _symptomId;
+
+ //_symptomId.resize(_symptomIdSize);
+ pel >> _symptomId;
+}
+
+void ExtendedUserHeader::setSymptomId(const std::string& symptomId)
+{
+ // set symptomId to new symptomId
+ std::copy(symptomId.begin(), symptomId.end(),
+ std::back_inserter(_symptomId));
+
+ // new symptom Id cannot be larger than existing symptom Id
+ if (_symptomId.size() > size_t((_symptomIdSize - 1)))
+ {
+ _symptomId.resize(_symptomIdSize - 1);
+ }
+
+ // null terminate new symptom Id (it may have been smaller)
+ _symptomId.push_back(0);
+
+ // pad if new symptom ID (it may have been smaller)
+ while ((_symptomId.size() != _symptomIdSize))
+ {
+ _symptomId.push_back(0);
+ }
+}
+
+} // namespace pel
+} // namespace attn
diff --git a/attn/pel/extended_user_header.hpp b/attn/pel/extended_user_header.hpp
new file mode 100644
index 0000000..d6486f1
--- /dev/null
+++ b/attn/pel/extended_user_header.hpp
@@ -0,0 +1,164 @@
+#pragma once
+
+#include "pel_common.hpp"
+#include "pel_section.hpp"
+#include "stream.hpp"
+
+namespace attn
+{
+namespace pel
+{
+
+constexpr uint8_t extendedUserHeaderVersion = 0x01;
+constexpr size_t firmwareVersionSize = 16;
+
+/**
+ * @class ExtendedUserHeader
+ *
+ * This represents the Extended User Header section in a PEL
+ *
+ * |----------+---------------------------+-------+-------+-------------------|
+ * | length | byte0 | byte1 | byte2 | byte3 |
+ * |----------+---------------------------+-------+-------+-------------------|
+ * | 8 | Section Header |
+ * |----------+---------------------------------------------------------------|
+ * | 20 | Machine Type/Model/Serial |
+ * |----------+---------------------------------------------------------------|
+ * | 16 | FW Released Version |
+ * |----------+---------------------------------------------------------------|
+ * | 16 | FW Sub-system driver ver. |
+ * |----------+---------------------------+-------+-------+-------------------|
+ * | 4 | Reserved | rsvd | rsvd | Symptom ID length |
+ * |----------+---------------------------+-------+-------+-------------------|
+ * | 8 | Event Common Reference Time |
+ * |----------+---------------------------------------------------------------|
+ * | 4 | Reserved |
+ * |----------+---------------------------------------------------------------|
+ * | variable | Symptom ID |
+ * |----------+---------------------------------------------------------------|
+ *
+ */
+class ExtendedUserHeader : public Section
+{
+ public:
+ ExtendedUserHeader() = delete;
+ ~ExtendedUserHeader() = default;
+ ExtendedUserHeader(const ExtendedUserHeader&) = default;
+ ExtendedUserHeader& operator=(const ExtendedUserHeader&) = default;
+ ExtendedUserHeader(ExtendedUserHeader&&) = default;
+ ExtendedUserHeader& operator=(ExtendedUserHeader&&) = default;
+
+ /**
+ * @brief Constructor
+ *
+ * Fills in this class's data fields from raw data.
+ *
+ * @param[in] pel - the PEL data stream
+ */
+ explicit ExtendedUserHeader(Stream& pel);
+
+ /**
+ * @brief Flatten the section into the stream
+ *
+ * @param[in] stream - The stream to write to
+ */
+ void flatten(Stream& stream) const override;
+
+ /**
+ * @brief Fills in the object from the stream data
+ *
+ * @param[in] stream - The stream to read from
+ */
+ void unflatten(Stream& stream);
+
+ /**
+ * @brief Returns the size of this section when flattened into a PEL
+ *
+ * @return size_t - the size of the section
+ */
+ size_t flattenedSize()
+ {
+ return Section::flattenedSize() + mtmsSize + _serverFWVersion.size() +
+ _subsystemFWVersion.size() + sizeof(_reserved4B) +
+ sizeof(_refTime) + sizeof(_reserved1B1) + sizeof(_reserved1B2) +
+ sizeof(_reserved1B3) + sizeof(_symptomIdSize) + _symptomIdSize;
+ }
+
+ /**
+ * @brief Set the symptom id field in extended user header
+ *
+ * @param[in] symptomId - The symptom ID to set
+ */
+ void setSymptomId(const std::string& symptomId);
+
+ private:
+ /**
+ * @brief The structure that holds the machine TM and SN fields.
+ */
+ uint8_t _mtms[mtmsSize];
+
+ /**
+ * @brief The server firmware version
+ *
+ * NULL terminated.
+ *
+ * The release version of the full firmware image.
+ */
+ std::array<uint8_t, firmwareVersionSize> _serverFWVersion;
+
+ /**
+ * @brief The subsystem firmware version
+ *
+ * NULL terminated.
+ *
+ * On PELs created on the BMC, this will be the BMC code version.
+ */
+ std::array<uint8_t, firmwareVersionSize> _subsystemFWVersion;
+
+ /**
+ * @brief Reserved
+ */
+ uint32_t _reserved4B = 0;
+
+ /**
+ * @brief Event Common Reference Time
+ *
+ * This is not used by PELs created on the BMC.
+ */
+ uint64_t _refTime;
+
+ /**
+ * @brief Reserved
+ */
+ uint8_t _reserved1B1 = 0;
+
+ /**
+ * @brief Reserved
+ */
+ uint8_t _reserved1B2 = 0;
+
+ /**
+ * @brief Reserved
+ */
+ uint8_t _reserved1B3 = 0;
+
+ /**
+ * @brief The size of the symptom ID field
+ */
+ uint8_t _symptomIdSize;
+
+ /**
+ * @brief The symptom ID field
+ *
+ * Describes a unique event signature for the log.
+ * Required for serviceable events, otherwise optional.
+ * When present, must start with the first 8 characters
+ * of the ASCII string field from the SRC.
+ *
+ * NULL terminated.
+ */
+ std::vector<uint8_t> _symptomId;
+};
+
+} // namespace pel
+} // namespace attn
diff --git a/attn/pel/pel_common.hpp b/attn/pel/pel_common.hpp
index d0f3e15..3dbce5c 100644
--- a/attn/pel/pel_common.hpp
+++ b/attn/pel/pel_common.hpp
@@ -9,9 +9,10 @@
enum class SectionID
{
- privateHeader = 0x5048, // 'PH'
- userHeader = 0x5548, // 'UH'
- primarySRC = 0x5053, // 'PS'
+ privateHeader = 0x5048, // 'PH'
+ userHeader = 0x5548, // 'UH'
+ primarySRC = 0x5053, // 'PS'
+ extendedHeader = 0x4548, // 'EH'
};
enum class ComponentID
@@ -64,6 +65,7 @@
constexpr size_t numSrcWords = 8; // number of SRC hex words
const size_t asciiStringSize = 32; // size of SRC ascii string
+const size_t mtmsSize = 20; // size of an mtms field
} // namespace pel
} // namespace attn
diff --git a/attn/pel/pel_minimal.cpp b/attn/pel/pel_minimal.cpp
index 9d7dfc1..11f589f 100644
--- a/attn/pel/pel_minimal.cpp
+++ b/attn/pel/pel_minimal.cpp
@@ -14,6 +14,7 @@
_ph = std::make_unique<PrivateHeader>(pelData);
_uh = std::make_unique<UserHeader>(pelData);
_ps = std::make_unique<PrimarySrc>(pelData);
+ _eh = std::make_unique<ExtendedUserHeader>(pelData);
}
void PelMinimal::raw(std::vector<uint8_t>& pelBuffer) const
@@ -24,6 +25,7 @@
_ph->flatten(pelData);
_uh->flatten(pelData);
_ps->flatten(pelData);
+ _eh->flatten(pelData);
}
size_t PelMinimal::size() const
@@ -48,6 +50,12 @@
size += _ph->header().size;
}
+ // size of extended user section
+ if (_eh)
+ {
+ size += _eh->header().size;
+ }
+
return ((size > _maxPELSize) ? _maxPELSize : size);
}
@@ -91,5 +99,10 @@
_ph->setSectionCount(sectionCount);
}
+void PelMinimal::setSymptomId(const std::string& symptomId)
+{
+ _eh->setSymptomId(symptomId);
+}
+
} // namespace pel
} // namespace attn
diff --git a/attn/pel/pel_minimal.hpp b/attn/pel/pel_minimal.hpp
index 79c0c11..ad07ab3 100644
--- a/attn/pel/pel_minimal.hpp
+++ b/attn/pel/pel_minimal.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include "extended_user_header.hpp"
#include "pel_common.hpp"
#include "primary_src.hpp"
#include "private_header.hpp"
@@ -30,6 +31,8 @@
* |----------+------------------------------|
* | 72 | Primary SRC Section |
* |----------+------------------------------|
+ * | 20 | Extended User Header |
+ * |----------+------------------------------|
*/
class PelMinimal
{
@@ -111,6 +114,13 @@
*/
void setSectionCount(uint8_t sectionCount);
+ /**
+ * @brief Set the symptom id field in extended user header
+ *
+ * @param[in] symptomId - The symptom ID to set
+ */
+ void setSymptomId(const std::string& symptomId);
+
private:
/**
* @brief Maximum PEL size
@@ -138,6 +148,11 @@
* @brief PEL Primary SRC
*/
std::unique_ptr<PrimarySrc> _ps;
+
+ /**
+ * @brief PEL Extended User Header
+ */
+ std::unique_ptr<ExtendedUserHeader> _eh;
};
} // namespace pel
diff --git a/attn/ti_handler.cpp b/attn/ti_handler.cpp
index 8b8fa7d..fc546c4 100644
--- a/attn/ti_handler.cpp
+++ b/attn/ti_handler.cpp
@@ -274,37 +274,66 @@
std::stringstream ss;
- ss << std::hex << std::showbase;
- ss << "0x00 TI Area Valid:" << (int)i_tiDataArea->tiAreaValid << ":";
- ss << "0x01 Command:" << (int)i_tiDataArea->command << ":";
- ss << "0x02 Num. Data Bytes:" << be16toh(i_tiDataArea->numDataBytes) << ":";
- ss << "0x04 Reserved:" << (int)i_tiDataArea->reserved1 << ":";
- ss << "0x06 HWDump Type:" << be16toh(i_tiDataArea->hardwareDumpType) << ":";
- ss << "0x08 SRC Format:" << (int)i_tiDataArea->srcFormat << ":";
- ss << "0x09 SRC Flags:" << (int)i_tiDataArea->srcFlags << ":";
- ss << "0x0a Num. ASCII Words:" << (int)i_tiDataArea->numAsciiWords << ":";
- ss << "0x0b Num. Hex Words:" << (int)i_tiDataArea->numHexWords << ":";
- ss << "0x0e Length of SRC:" << be16toh(i_tiDataArea->lenSrc) << ":";
- ss << "0x10 SRC Word 12:" << be32toh(i_tiDataArea->srcWord12HbWord0) << ":";
- ss << "0x14 SRC Word 13:" << be32toh(i_tiDataArea->srcWord13HbWord2) << ":";
- ss << "0x18 SRC Word 14:" << be32toh(i_tiDataArea->srcWord14HbWord3) << ":";
- ss << "0x1c SRC Word 15:" << be32toh(i_tiDataArea->srcWord15HbWord4) << ":";
- ss << "0x20 SRC Word 16:" << be32toh(i_tiDataArea->srcWord16HbWord5) << ":";
- ss << "0x24 SRC Word 17:" << be32toh(i_tiDataArea->srcWord17HbWord6) << ":";
- ss << "0x28 SRC Word 18:" << be32toh(i_tiDataArea->srcWord18HbWord7) << ":";
- ss << "0x2c SRC Word 19:" << be32toh(i_tiDataArea->srcWord19HbWord8) << ":";
- ss << "0x30 ASCII Data:" << be32toh(i_tiDataArea->asciiData0) << ":";
- ss << "0x34 ASCII Data:" << be32toh(i_tiDataArea->asciiData1) << ":";
- ss << "0x38 ASCII Data:" << be32toh(i_tiDataArea->asciiData2) << ":";
- ss << "0x3c ASCII Data:" << be32toh(i_tiDataArea->asciiData3) << ":";
- ss << "0x40 ASCII Data:" << be32toh(i_tiDataArea->asciiData4) << ":";
- ss << "0x44 ASCII Data:" << be32toh(i_tiDataArea->asciiData5) << ":";
- ss << "0x48 ASCII Data:" << be32toh(i_tiDataArea->asciiData6) << ":";
- ss << "0x4c ASCII Data:" << be32toh(i_tiDataArea->asciiData7) << ":";
- ss << "0x50 Location:" << (int)i_tiDataArea->location << ":";
- ss << "0x51 Code Sections:" << (int)i_tiDataArea->codeSection << ":";
- ss << "0x52 Additional Size:" << (int)i_tiDataArea->additionalSize << ":";
- ss << "0x53 Additional Data:" << (int)i_tiDataArea->andData;
+ ss << "0x00 TI Area Valid:" << std::setw(2) << std::setfill('0') << std::hex
+ << (int)i_tiDataArea->tiAreaValid << ":";
+ ss << "0x01 Command:" << std::setw(2) << std::setfill('0') << std::hex
+ << (int)i_tiDataArea->command << ":";
+ ss << "0x02 Num. Data Bytes:" << std::setw(4) << std::setfill('0')
+ << std::hex << be16toh(i_tiDataArea->numDataBytes) << ":";
+ ss << "0x04 Reserved:" << std::setw(2) << std::setfill('0') << std::hex
+ << (int)i_tiDataArea->reserved1 << ":";
+ ss << "0x06 HWDump Type:" << std::setw(4) << std::setfill('0') << std::hex
+ << be16toh(i_tiDataArea->hardwareDumpType) << ":";
+ ss << "0x08 SRC Format:" << std::setw(2) << std::setfill('0') << std::hex
+ << (int)i_tiDataArea->srcFormat << ":";
+ ss << "0x09 SRC Flags:" << std::setw(2) << std::setfill('0') << std::hex
+ << (int)i_tiDataArea->srcFlags << ":";
+ ss << "0x0a Num. ASCII Words:" << std::setw(2) << std::setfill('0')
+ << std::hex << (int)i_tiDataArea->numAsciiWords << ":";
+ ss << "0x0b Num. Hex Words:" << std::setw(2) << std::setfill('0')
+ << std::hex << (int)i_tiDataArea->numHexWords << ":";
+ ss << "0x0e Length of SRC:" << std::setw(4) << std::setfill('0') << std::hex
+ << be16toh(i_tiDataArea->lenSrc) << ":";
+ ss << "0x10 SRC Word 12:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord12HbWord0) << ":";
+ ss << "0x14 SRC Word 13:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord13HbWord2) << ":";
+ ss << "0x18 SRC Word 14:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord14HbWord3) << ":";
+ ss << "0x1c SRC Word 15:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord15HbWord4) << ":";
+ ss << "0x20 SRC Word 16:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord16HbWord5) << ":";
+ ss << "0x24 SRC Word 17:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord17HbWord6) << ":";
+ ss << "0x28 SRC Word 18:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord18HbWord7) << ":";
+ ss << "0x2c SRC Word 19:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord19HbWord8) << ":";
+ ss << "0x30 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->asciiData0) << ":";
+ ss << "0x34 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->asciiData1) << ":";
+ ss << "0x38 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->asciiData2) << ":";
+ ss << "0x3c ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->asciiData3) << ":";
+ ss << "0x40 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->asciiData4) << ":";
+ ss << "0x44 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->asciiData5) << ":";
+ ss << "0x48 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->asciiData6) << ":";
+ ss << "0x4c ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->asciiData7) << ":";
+ ss << "0x50 Location:" << std::setw(2) << std::setfill('0') << std::hex
+ << (int)i_tiDataArea->location << ":";
+ ss << "0x51 Code Sections:" << std::setw(2) << std::setfill('0') << std::hex
+ << (int)i_tiDataArea->codeSection << ":";
+ ss << "0x52 Additional Size:" << std::setw(2) << std::setfill('0')
+ << std::hex << (int)i_tiDataArea->additionalSize << ":";
+ ss << "0x53 Additional Data:" << std::setw(2) << std::setfill('0')
+ << std::hex << (int)i_tiDataArea->andData;
std::string key, value;
char delim = ':';
@@ -327,22 +356,36 @@
std::stringstream ss;
- ss << std::hex << std::showbase;
- ss << "0x00 TI Area Valid:" << (int)i_tiDataArea->tiAreaValid << ":";
- ss << "0x04 Reserved:" << (int)i_tiDataArea->reserved1 << ":";
- ss << "0x05 HB_Term. Type:" << (int)i_tiDataArea->hbTerminateType << ":";
- ss << "0x0c HB Dump Flag:" << (int)i_tiDataArea->hbDumpFlag << ":";
- ss << "0x0d Source:" << (int)i_tiDataArea->source << ":";
- ss << "0x10 HB Word 0:" << be32toh(i_tiDataArea->srcWord12HbWord0) << ":";
- ss << "0x14 HB Word 2:" << be32toh(i_tiDataArea->srcWord13HbWord2) << ":";
- ss << "0x18 HB Word 3:" << be32toh(i_tiDataArea->srcWord14HbWord3) << ":";
- ss << "0x1c HB Word 4:" << be32toh(i_tiDataArea->srcWord15HbWord4) << ":";
- ss << "0x20 HB Word 5:" << be32toh(i_tiDataArea->srcWord16HbWord5) << ":";
- ss << "0x24 HB Word 6:" << be32toh(i_tiDataArea->srcWord17HbWord6) << ":";
- ss << "0x28 HB Word 7:" << be32toh(i_tiDataArea->srcWord18HbWord7) << ":";
- ss << "0x2c HB Word 8:" << be32toh(i_tiDataArea->srcWord19HbWord8) << ":";
- ss << "0x30 error_data:" << be32toh(i_tiDataArea->asciiData0) << ":";
- ss << "0x34 EID:" << be32toh(i_tiDataArea->asciiData1);
+ ss << "0x00 TI Area Valid:" << std::setw(2) << std::setfill('0') << std::hex
+ << (int)i_tiDataArea->tiAreaValid << ":";
+ ss << "0x04 Reserved:" << std::setw(2) << std::setfill('0') << std::hex
+ << (int)i_tiDataArea->reserved1 << ":";
+ ss << "0x05 HB_Term. Type:" << std::setw(2) << std::setfill('0') << std::hex
+ << (int)i_tiDataArea->hbTerminateType << ":";
+ ss << "0x0c HB Dump Flag:" << std::setw(2) << std::setfill('0') << std::hex
+ << (int)i_tiDataArea->hbDumpFlag << ":";
+ ss << "0x0d Source:" << std::setw(2) << std::setfill('0') << std::hex
+ << (int)i_tiDataArea->source << ":";
+ ss << "0x10 HB Word 0:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord12HbWord0) << ":";
+ ss << "0x14 HB Word 2:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord13HbWord2) << ":";
+ ss << "0x18 HB Word 3:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord14HbWord3) << ":";
+ ss << "0x1c HB Word 4:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord15HbWord4) << ":";
+ ss << "0x20 HB Word 5:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord16HbWord5) << ":";
+ ss << "0x24 HB Word 6:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord17HbWord6) << ":";
+ ss << "0x28 HB Word 7:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord18HbWord7) << ":";
+ ss << "0x2c HB Word 8:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->srcWord19HbWord8) << ":";
+ ss << "0x30 error_data:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->asciiData0) << ":";
+ ss << "0x34 EID:" << std::setw(8) << std::setfill('0') << std::hex
+ << be32toh(i_tiDataArea->asciiData1);
std::string key, value;
char delim = ':';