blob: a6f1c10158e6072cb485d5b1efbf5e184ff9cbb1 [file] [log] [blame]
Zane Shelleydd69c962020-05-05 22:19:11 -05001#include <chip_data/hei_chip_data.hpp>
2#include <chip_data/hei_chip_data_stream.hpp>
Zane Shelleyb9a8e762020-05-11 21:41:32 -05003#include <register/hei_scom_register.hpp>
Zane Shelleydd69c962020-05-05 22:19:11 -05004
5namespace libhei
6{
7
8//------------------------------------------------------------------------------
9
10using FileKeyword_t = uint64_t;
11
12constexpr FileKeyword_t KW_CHIPDATA = 0x4348495044415441; // "CHIPDATA" ASCII
13
14using SectionKeyword_t = uint32_t;
15
Zane Shelleyb9a8e762020-05-11 21:41:32 -050016constexpr SectionKeyword_t KW_REGS = 0x52454753; // "REGS" ASCII
Zane Shelleydd69c962020-05-05 22:19:11 -050017constexpr SectionKeyword_t KW_NODE = 0x4e4f4445; // "NODE" ASCII
18constexpr SectionKeyword_t KW_ROOT = 0x524f4f54; // "ROOT" ASCII
19
20using Version_t = uint8_t;
21
22constexpr Version_t VERSION_1 = 0x01;
23
24//------------------------------------------------------------------------------
25
Zane Shelleyb9a8e762020-05-11 21:41:32 -050026void __readRegister(ChipDataStream& io_stream, IsolationChipPtr& io_isoChip)
27{
28 // Read the register metadata.
29 RegisterId_t id;
30 RegisterType_t type;
31 RegisterAttributeFlags_t attr;
32 Instance_t numInsts;
33 io_stream >> id >> type >> attr >> numInsts;
34
35 // Must have at least one instance.
36 HEI_ASSERT(0 != numInsts);
37
38 for (Instance_t i = 0; i < numInsts; i++)
39 {
40 // Read the register instance metadata.
41 Instance_t inst;
42 io_stream >> inst;
43
44 // The address size is dependent on the register type.
45 if (REG_TYPE_SCOM == type)
46 {
47 uint32_t addr; // 4-byte address.
48 io_stream >> addr;
49
50 // Get this register from the flyweight factory.
51 auto& factory = Flyweight<const ScomRegister>::getSingleton();
52 HardwareRegisterPtr hwReg = factory.get(id, inst, attr, addr);
53
54 // Add this register to the isolation chip.
55 io_isoChip->addHardwareRegister(hwReg);
56 }
57 else if (REG_TYPE_ID_SCOM == type)
58 {
59 uint64_t addr; // 8-byte address.
60 io_stream >> addr;
61
62 // Get this register from the flyweight factory.
63 auto& factory = Flyweight<const IdScomRegister>::getSingleton();
64 HardwareRegisterPtr hwReg = factory.get(id, inst, attr, addr);
65
66 // Add this register to the isolation chip.
67 io_isoChip->addHardwareRegister(hwReg);
68 }
69 else
70 {
71 HEI_ASSERT(false); // Register type unsupported.
72 }
73 }
74}
75
76//------------------------------------------------------------------------------
77
Zane Shelleydd69c962020-05-05 22:19:11 -050078void parseChipDataFile(void* i_buffer, size_t i_bufferSize,
79 IsolationChipMap& io_isoChips)
80{
81 ChipDataStream stream{i_buffer, i_bufferSize};
82
83 // Read the file metadata.
Zane Shelleyb9a8e762020-05-11 21:41:32 -050084 FileKeyword_t fileKeyword;
85 ChipType_t chipType;
86 Version_t version;
87 stream >> fileKeyword >> chipType >> version;
Zane Shelleydd69c962020-05-05 22:19:11 -050088
Zane Shelleyb9a8e762020-05-11 21:41:32 -050089 // Check the file keyword.
90 HEI_ASSERT(KW_CHIPDATA == fileKeyword);
Zane Shelleydd69c962020-05-05 22:19:11 -050091
92 // This chip type should not already exist.
93 HEI_ASSERT(io_isoChips.end() == io_isoChips.find(chipType));
94
Zane Shelleyb9a8e762020-05-11 21:41:32 -050095 // So far there is only one supported version type so check it here.
96 HEI_ASSERT(VERSION_1 == version);
97
Zane Shelleydd69c962020-05-05 22:19:11 -050098 // Allocate memory for the new isolation chip.
99 auto isoChip = std::make_unique<IsolationChip>(chipType);
100
Zane Shelleyb9a8e762020-05-11 21:41:32 -0500101 // Read the register list metadata.
102 SectionKeyword_t regsKeyword;
103 RegisterId_t numRegs;
104 stream >> regsKeyword >> numRegs;
105
106 // Check the register keyword.
107 HEI_ASSERT(KW_REGS == regsKeyword);
108
109 // There must be at least one register defined.
110 HEI_ASSERT(0 != numRegs);
111
112 for (uint32_t i = 0; i < numRegs; i++)
113 {
114 __readRegister(stream, isoChip);
115 }
Zane Shelleydd69c962020-05-05 22:19:11 -0500116
117 // Add this isolation chip to the collective list of isolation chips.
118 auto ret = io_isoChips.emplace(chipType, std::move(isoChip));
119 HEI_ASSERT(ret.second); // Just in case.
120}
121
122//------------------------------------------------------------------------------
123
124} // namespace libhei