summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepak Kodihalli <dkodihal@in.ibm.com>2016-11-22 22:02:14 -0600
committerDeepak Kodihalli <dkodihal@in.ibm.com>2016-12-08 06:14:37 -0600
commit023112f485be11b6c4d93dee32e195f143335130 (patch)
tree6441449d262f462c97077464ee907519d36ea08a
parent810c9defd7cd473d3eef14f177c6a24d6500fae1 (diff)
downloadopenpower-vpd-parser-023112f485be11b6c4d93dee32e195f143335130.tar.gz
openpower-vpd-parser-023112f485be11b6c4d93dee32e195f143335130.zip
parser : read table of contents record
This change implements logic to read the OpenPOWER VPD VTOC record, which contains information about offsets to other records in the VPD. Change-Id: Id40dee0f940815766bf2e956c6ab08c875e6f79b Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
-rw-r--r--impl.cpp93
-rw-r--r--impl.hpp25
2 files changed, 117 insertions, 1 deletions
diff --git a/impl.cpp b/impl.cpp
index 74a8969..091d6f9 100644
--- a/impl.cpp
+++ b/impl.cpp
@@ -10,12 +10,28 @@ namespace vpd
namespace parser
{
+namespace
+{
+
+using RecordId = uint8_t;
+using RecordOffset = uint16_t;
+using RecordSize = uint16_t;
+using RecordType = uint16_t;
+using RecordLength = uint16_t;
+using KwSize = uint8_t;
+using ECCOffset = uint16_t;
+using ECCLength = uint16_t;
+
+}
+
namespace offsets
{
enum Offsets
{
- VHDR = 17
+ VHDR = 17,
+ VHDR_TOC_ENTRY = 29,
+ VTOC_PTR = 35,
};
}
@@ -26,6 +42,7 @@ namespace lengths
enum Lengths
{
RECORD_NAME = 4,
+ KW_NAME = 2,
RECORD_MIN = 44,
};
@@ -50,6 +67,80 @@ void Impl::checkHeader() const
}
}
+internal::OffsetList Impl::readTOC() const
+{
+ internal::OffsetList offsets {};
+
+ // The offset to VTOC could be 1 or 2 bytes long
+ RecordOffset vtocOffset = vpd.at(offsets::VTOC_PTR);
+ RecordOffset highByte = vpd.at(offsets::VTOC_PTR + 1);
+ vtocOffset |= (highByte << 8);
+
+ // Got the offset to VTOC, skip past record header and keyword header
+ // to get to the record name.
+ auto iterator = vpd.cbegin();
+ std::advance(iterator,
+ vtocOffset +
+ sizeof(RecordId) +
+ sizeof(RecordSize) +
+ // Skip past the RT keyword, which contains
+ // the record name.
+ lengths::KW_NAME +
+ sizeof(KwSize));
+
+ auto stop = std::next(iterator, lengths::RECORD_NAME);
+ std::string record(iterator, stop);
+ if ("VTOC" != record)
+ {
+ throw std::runtime_error("VTOC record not found");
+ }
+
+ // VTOC record name is good, now read through the TOC, stored in the PT
+ // PT keyword; vpdBuffer is now pointing at the first character of the
+ // name 'VTOC', jump to PT data.
+ // Skip past record name and KW name, 'PT'
+ std::advance(iterator, lengths::RECORD_NAME + lengths::KW_NAME);
+ // Note size of PT
+ std::size_t ptLen = *iterator;
+ // Skip past PT size
+ std::advance(iterator, sizeof(KwSize));
+
+ // vpdBuffer is now pointing to PT data
+ return readPT(iterator, ptLen);
+}
+
+internal::OffsetList Impl::readPT(Binary::const_iterator iterator,
+ std::size_t ptLength) const
+{
+ internal::OffsetList offsets{};
+
+ auto end = iterator;
+ std::advance(end, ptLength);
+
+ // Look at each entry in the PT keyword. In the entry,
+ // we care only about the record offset information.
+ while (iterator < end)
+ {
+ // Skip record name and record type
+ std::advance(iterator, lengths::RECORD_NAME + sizeof(RecordType));
+
+ // Get record offset
+ RecordOffset offset = *iterator;
+ RecordOffset highByte = *(iterator + 1);
+ offset |= (highByte << 8);
+ offsets.push_back(offset);
+
+ // Jump record size, record length, ECC offset and ECC length
+ std::advance(iterator,
+ sizeof(RecordSize) +
+ sizeof(RecordLength) +
+ sizeof(ECCOffset) +
+ sizeof(ECCLength));
+ }
+
+ return offsets;
+}
+
} // namespace parser
} // namespace vpd
} // namespace openpower
diff --git a/impl.hpp b/impl.hpp
index 63128bf..31bf22a 100644
--- a/impl.hpp
+++ b/impl.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <cstddef>
#include "store.hpp"
namespace openpower
@@ -9,6 +10,13 @@ namespace vpd
namespace parser
{
+namespace internal
+{
+
+using OffsetList = std::vector<uint32_t>;
+
+}
+
/** @class Impl
* @brief Implements parser for OpenPOWER VPD
*
@@ -54,6 +62,23 @@ class Impl
Store run();
private:
+ /** @brief Process the table of contents record, VHDR
+ *
+ * @returns List of offsets to records in VPD
+ */
+ internal::OffsetList readTOC() const;
+
+ /** @brief Read the PT keyword contained in the VHDR record,
+ * to obtain offsets to other records in the VPD.
+ *
+ * @param[in] iterator - iterator to buffer containing VPD
+ * @param[in] ptLength - Length of PT keyword data
+ *
+ * @returns List of offsets to records in VPD
+ */
+ internal::OffsetList readPT(Binary::const_iterator iterator,
+ std::size_t ptLen) const;
+
/** @brief Checks if the VHDR record is present in the VPD */
void checkHeader() const;
OpenPOWER on IntegriCloud