blob: 83c7a3d5406b71dc165141633074dc49ed0bbb99 [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 Shelley4de8ff82020-05-14 15:39:01 -050026void __readRegister(ChipDataStream& io_stream, IsolationChip::Ptr& io_isoChip)
Zane Shelleyb9a8e762020-05-11 21:41:32 -050027{
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
Zane Shelley0165edc2020-05-11 22:28:29 -050038 for (unsigned int i = 0; i < numInsts; i++)
Zane Shelleyb9a8e762020-05-11 21:41:32 -050039 {
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();
Zane Shelley4de8ff82020-05-14 15:39:01 -050052 auto hwReg = factory.get(id, inst, attr, addr);
Zane Shelleyb9a8e762020-05-11 21:41:32 -050053
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();
Zane Shelley4de8ff82020-05-14 15:39:01 -050064 auto hwReg = factory.get(id, inst, attr, addr);
Zane Shelleyb9a8e762020-05-11 21:41:32 -050065
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 Shelley0165edc2020-05-11 22:28:29 -050078void __readExpr(ChipDataStream& io_stream, RegisterType_t i_regType)
79{
80 uint8_t exprType;
81 io_stream >> exprType;
82 switch (exprType)
83 {
84 case 0x01: // register reference
85 {
86 RegisterId_t regId;
87 Instance_t regInst;
88 io_stream >> regId >> regInst;
89 break;
90 }
91 case 0x02: // integer constant
92 {
93 if (REG_TYPE_SCOM == i_regType || REG_TYPE_ID_SCOM == i_regType)
94 {
95 uint64_t constant; // 8-byte value
96 io_stream >> constant;
97 }
98 else
99 {
100 HEI_ASSERT(false); // register type unsupported
101 }
102 break;
103 }
104 case 0x10: // AND operation
105 {
106 uint8_t numSubExpr;
107 io_stream >> numSubExpr;
108 for (uint8_t i = 0; i < numSubExpr; i++)
109 {
110 __readExpr(io_stream, i_regType);
111 }
112 break;
113 }
114 case 0x11: // OR operation
115 {
116 uint8_t numSubExpr;
117 io_stream >> numSubExpr;
118 for (uint8_t i = 0; i < numSubExpr; i++)
119 {
120 __readExpr(io_stream, i_regType);
121 }
122 break;
123 }
124 case 0x12: // NOT operation
125 {
126 __readExpr(io_stream, i_regType);
127 break;
128 }
129 case 0x13: // left shift operation
130 {
131 uint8_t shiftValue;
132 io_stream >> shiftValue;
133 __readExpr(io_stream, i_regType);
134 break;
135 }
136 case 0x14: // right shift operation
137 {
138 uint8_t shiftValue;
139 io_stream >> shiftValue;
140 __readExpr(io_stream, i_regType);
141 break;
142 }
143 default:
144 HEI_ASSERT(false); // unsupported expression type
145 }
146}
147
148//------------------------------------------------------------------------------
149
Zane Shelley4de8ff82020-05-14 15:39:01 -0500150void __readNode(ChipDataStream& io_stream, IsolationChip::Ptr& io_isoChip)
Zane Shelley0165edc2020-05-11 22:28:29 -0500151{
152 // Read the node metadata.
153 NodeId_t nodeId;
154 RegisterType_t regType;
155 Instance_t numInsts;
156 io_stream >> nodeId >> regType >> numInsts;
157
158 for (unsigned int i = 0; i < numInsts; i++)
159 {
160 // Read the node instance metadata.
161 Instance_t nodeInst;
162 uint8_t numCapRegs, numIsoRules, numChildNodes;
163 io_stream >> nodeInst >> numCapRegs >> numIsoRules >> numChildNodes;
164
165 // Add capture registers.
166 for (unsigned int j = 0; j < numCapRegs; j++)
167 {
168 RegisterId_t regId;
169 Instance_t regInst;
170 io_stream >> regId >> regInst;
171 }
172
173 // Add isolation rules.
174 for (unsigned int j = 0; j < numIsoRules; j++)
175 {
176 AttentionType_t attnType;
177 io_stream >> attnType;
178 __readExpr(io_stream, regType);
179 }
180
181 // Add child nodes.
182 for (unsigned int j = 0; j < numChildNodes; j++)
183 {
184 BitPosition_t bit;
185 NodeId_t nodeId;
186 Instance_t nodeInst;
187 io_stream >> bit >> nodeId >> nodeInst;
188 }
189 }
190}
191
192//------------------------------------------------------------------------------
193
Zane Shelley4de8ff82020-05-14 15:39:01 -0500194void __readRoot(ChipDataStream& io_stream, IsolationChip::Ptr& io_isoChip)
Zane Shelley0165edc2020-05-11 22:28:29 -0500195{
196 AttentionType_t attnType;
197 NodeId_t id;
198 Instance_t inst;
199 io_stream >> attnType >> id >> inst;
200}
201
202//------------------------------------------------------------------------------
203
Zane Shelleydd69c962020-05-05 22:19:11 -0500204void parseChipDataFile(void* i_buffer, size_t i_bufferSize,
Zane Shelley4de8ff82020-05-14 15:39:01 -0500205 IsolationChip::Map& io_isoChips)
Zane Shelleydd69c962020-05-05 22:19:11 -0500206{
207 ChipDataStream stream{i_buffer, i_bufferSize};
208
209 // Read the file metadata.
Zane Shelleyb9a8e762020-05-11 21:41:32 -0500210 FileKeyword_t fileKeyword;
211 ChipType_t chipType;
212 Version_t version;
213 stream >> fileKeyword >> chipType >> version;
Zane Shelleydd69c962020-05-05 22:19:11 -0500214
Zane Shelleyb9a8e762020-05-11 21:41:32 -0500215 // Check the file keyword.
216 HEI_ASSERT(KW_CHIPDATA == fileKeyword);
Zane Shelleydd69c962020-05-05 22:19:11 -0500217
218 // This chip type should not already exist.
219 HEI_ASSERT(io_isoChips.end() == io_isoChips.find(chipType));
220
Zane Shelleyb9a8e762020-05-11 21:41:32 -0500221 // So far there is only one supported version type so check it here.
222 HEI_ASSERT(VERSION_1 == version);
223
Zane Shelleydd69c962020-05-05 22:19:11 -0500224 // Allocate memory for the new isolation chip.
225 auto isoChip = std::make_unique<IsolationChip>(chipType);
226
Zane Shelleyb9a8e762020-05-11 21:41:32 -0500227 // Read the register list metadata.
228 SectionKeyword_t regsKeyword;
229 RegisterId_t numRegs;
230 stream >> regsKeyword >> numRegs;
231
232 // Check the register keyword.
233 HEI_ASSERT(KW_REGS == regsKeyword);
234
235 // There must be at least one register defined.
236 HEI_ASSERT(0 != numRegs);
237
Zane Shelley0165edc2020-05-11 22:28:29 -0500238 for (unsigned int i = 0; i < numRegs; i++)
Zane Shelleyb9a8e762020-05-11 21:41:32 -0500239 {
240 __readRegister(stream, isoChip);
241 }
Zane Shelleydd69c962020-05-05 22:19:11 -0500242
Zane Shelley0165edc2020-05-11 22:28:29 -0500243 // Read the node list metadata.
244 SectionKeyword_t nodeKeyword;
245 NodeId_t numNodes;
246 stream >> nodeKeyword >> numNodes;
247
248 // Check the node keyword.
249 HEI_ASSERT(KW_NODE == nodeKeyword);
250
251 // There must be at least one node defined.
252 HEI_ASSERT(0 != numNodes);
253
254 for (unsigned int i = 0; i < numNodes; i++)
255 {
256 __readNode(stream, isoChip);
257 }
258
259 // Read the root node list metadata.
260 SectionKeyword_t rootKeyword;
261 AttentionType_t numRoots;
262 stream >> rootKeyword >> numRoots;
263
264 // Check the root node keyword.
265 HEI_ASSERT(KW_ROOT == rootKeyword);
266
267 // There must be at least one register defined.
268 HEI_ASSERT(0 != numRoots);
269
270 for (unsigned int i = 0; i < numRoots; i++)
271 {
272 __readRoot(stream, isoChip);
273 }
274
275 // At this point, the stream is done and it should be at the end of the
276 // file.
277 HEI_ASSERT(stream.eof());
278
Zane Shelleydd69c962020-05-05 22:19:11 -0500279 // Add this isolation chip to the collective list of isolation chips.
280 auto ret = io_isoChips.emplace(chipType, std::move(isoChip));
281 HEI_ASSERT(ret.second); // Just in case.
282}
283
284//------------------------------------------------------------------------------
285
286} // namespace libhei