Build HardwareRegister objects from Chip Data Files
Change-Id: I4fbcdd5ba012008000b8d1f324dd47d95ef2d932
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
diff --git a/src/chip_data/hei_chip_data.cpp b/src/chip_data/hei_chip_data.cpp
index f10589d..a6f1c10 100644
--- a/src/chip_data/hei_chip_data.cpp
+++ b/src/chip_data/hei_chip_data.cpp
@@ -1,5 +1,6 @@
#include <chip_data/hei_chip_data.hpp>
#include <chip_data/hei_chip_data_stream.hpp>
+#include <register/hei_scom_register.hpp>
namespace libhei
{
@@ -12,7 +13,7 @@
using SectionKeyword_t = uint32_t;
-constexpr SectionKeyword_t KW_REGS = 0x43484950; // "REGS" ASCII
+constexpr SectionKeyword_t KW_REGS = 0x52454753; // "REGS" ASCII
constexpr SectionKeyword_t KW_NODE = 0x4e4f4445; // "NODE" ASCII
constexpr SectionKeyword_t KW_ROOT = 0x524f4f54; // "ROOT" ASCII
@@ -22,27 +23,96 @@
//------------------------------------------------------------------------------
+void __readRegister(ChipDataStream& io_stream, IsolationChipPtr& io_isoChip)
+{
+ // Read the register metadata.
+ RegisterId_t id;
+ RegisterType_t type;
+ RegisterAttributeFlags_t attr;
+ Instance_t numInsts;
+ io_stream >> id >> type >> attr >> numInsts;
+
+ // Must have at least one instance.
+ HEI_ASSERT(0 != numInsts);
+
+ for (Instance_t i = 0; i < numInsts; i++)
+ {
+ // Read the register instance metadata.
+ Instance_t inst;
+ io_stream >> inst;
+
+ // The address size is dependent on the register type.
+ if (REG_TYPE_SCOM == type)
+ {
+ uint32_t addr; // 4-byte address.
+ io_stream >> addr;
+
+ // Get this register from the flyweight factory.
+ auto& factory = Flyweight<const ScomRegister>::getSingleton();
+ HardwareRegisterPtr hwReg = factory.get(id, inst, attr, addr);
+
+ // Add this register to the isolation chip.
+ io_isoChip->addHardwareRegister(hwReg);
+ }
+ else if (REG_TYPE_ID_SCOM == type)
+ {
+ uint64_t addr; // 8-byte address.
+ io_stream >> addr;
+
+ // Get this register from the flyweight factory.
+ auto& factory = Flyweight<const IdScomRegister>::getSingleton();
+ HardwareRegisterPtr hwReg = factory.get(id, inst, attr, addr);
+
+ // Add this register to the isolation chip.
+ io_isoChip->addHardwareRegister(hwReg);
+ }
+ else
+ {
+ HEI_ASSERT(false); // Register type unsupported.
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
void parseChipDataFile(void* i_buffer, size_t i_bufferSize,
IsolationChipMap& io_isoChips)
{
ChipDataStream stream{i_buffer, i_bufferSize};
// Read the file metadata.
- FileKeyword_t file_kw = 0;
- ChipType_t chipType = 0;
- Version_t version = 0;
- stream >> file_kw >> chipType >> version;
+ FileKeyword_t fileKeyword;
+ ChipType_t chipType;
+ Version_t version;
+ stream >> fileKeyword >> chipType >> version;
- // Check the file ID.
- HEI_ASSERT(KW_CHIPDATA == file_kw);
+ // Check the file keyword.
+ HEI_ASSERT(KW_CHIPDATA == fileKeyword);
// This chip type should not already exist.
HEI_ASSERT(io_isoChips.end() == io_isoChips.find(chipType));
+ // So far there is only one supported version type so check it here.
+ HEI_ASSERT(VERSION_1 == version);
+
// Allocate memory for the new isolation chip.
auto isoChip = std::make_unique<IsolationChip>(chipType);
- // TODO
+ // Read the register list metadata.
+ SectionKeyword_t regsKeyword;
+ RegisterId_t numRegs;
+ stream >> regsKeyword >> numRegs;
+
+ // Check the register keyword.
+ HEI_ASSERT(KW_REGS == regsKeyword);
+
+ // There must be at least one register defined.
+ HEI_ASSERT(0 != numRegs);
+
+ for (uint32_t i = 0; i < numRegs; i++)
+ {
+ __readRegister(stream, isoChip);
+ }
// Add this isolation chip to the collective list of isolation chips.
auto ret = io_isoChips.emplace(chipType, std::move(isoChip));