C++ Device API Reference Manual
Reference documentation for the Simics C++ Device API.
 
Loading...
Searching...
No Matches
field-templates.h
Go to the documentation of this file.
1// -*- mode: C++; c-file-style: "virtutech-c++" -*-
2
3/*
4 © 2022 Intel Corporation
5
6 This software and the related documents are Intel copyrighted materials, and
7 your use of them is governed by the express license under which they were
8 provided to you ("License"). Unless the License provides otherwise, you may
9 not use, modify, copy, publish, distribute, disclose or transmit this software
10 or the related documents without Intel's prior written permission.
11
12 This software and the related documents are provided as is, with no express or
13 implied warranties, other than those that are expressly stated in the License.
14*/
15
16#ifndef SIMICS_FIELD_TEMPLATES_H
17#define SIMICS_FIELD_TEMPLATES_H
18
19#include <string>
20#include <limits>
21
22#include "field.h"
24
25namespace simics {
26
27/*
28 * Field with map information
29 * This class creates a field object and add it to the <arg>reg_iface</arg>.
30 * Customized fields such as ReadConstantField takes additional arguments.
31 */
32template <typename TField = Field, typename... Args>
33class RegisterField : public TField {
34 static_assert(std::is_base_of<Field, TField>::value,
35 "TField must be derived from Field");
36 public:
38 Offset offset, BitWidth size, Args... args)
39 : TField(reg_iface, name, args ...) {
40 reg_iface->parse_field({name, desc, offset, size});
41 }
42};
43
44// Templates
45// Writes are ignored.
46class IgnoreWriteField : public Field {
47 public:
48 using Field::Field;
49
50 void write(uint64_t value, uint64_t enabled_bits) override {}
51};
52
53// Reads return 0. Writes are unaffected by this template.
54class Read0Field : public Field {
55 public:
56 using Field::Field;
57
58 uint64_t read(uint64_t enabled_bits) override {
60 fmt::format("Read from read-zero field {} -> 0x0.",
61 name()));
62 return 0;
63 }
64};
65
66// Write only and reads return 0. Same as Read0Field thus derived from it.
67class WriteOnlyField : public Read0Field {
68 public:
69 using Read0Field::Read0Field;
70
71 uint64_t read(uint64_t enabled_bits) override {
73 fmt::format("Read from write-only field {} -> 0x0.",
74 name()));
75 return 0;
76 }
77};
78
79// The object value is read-only for software, the object value
80// can be modified by hardware.
81class ReadOnlyField : public Field {
82 public:
83 using Field::Field;
84
85 void write(uint64_t value, uint64_t enabled_bits) override {
86 if ((value & enabled_bits) != (get() & enabled_bits)) {
87 SIM_LOG_SPEC_VIOLATION_STR(logged_once_ ? 2 : 1, bank_obj_ref(), 0,
88 fmt::format("Write to read-only field {} (value written"
89 " = {:#010x}, contents = {:#010x}).",
90 name(), value & enabled_bits, get()));
91 logged_once_ = true;
92 }
93 }
94
95 private:
96 bool logged_once_ {false};
97};
98
99// Software can only clear bits. This feature is often used when
100// hardware sets bits and software clears them to acknowledge.
101// Software write 1's to clear bits. The new object value is a
102// bitwise AND of the old object value and the bitwise complement
103// of the value written by software.
104class Write1ClearsField : public Field {
105 public:
106 using Field::Field;
107
108 void write(uint64_t value, uint64_t enabled_bits) override {
109 Field::write(~value, enabled_bits & value);
110 }
111};
112
113// Software reads return the object value. The object value is
114// then reset to 0 as a side-effect of the read.
115class ClearOnReadField : public Field {
116 public:
117 using Field::Field;
118
119 uint64_t read(uint64_t enabled_bits) override {
120 uint64_t value = get();
121 set(0);
122 return value & enabled_bits;
123 }
124};
125
126// Software can only set bits to 1. The new object value is
127// the bitwise OR of the old object value and the value written
128// by software.
129class Write1OnlyField : public Field {
130 public:
131 using Field::Field;
132
133 void write(uint64_t value, uint64_t enabled_bits) override {
134 Field::write(get() | value, enabled_bits);
135 }
136};
137
138// Software can only set bits to 0. The new object value is
139// the bitwise AND of the old object value and the value
140// written by software.
141class Write0OnlyField : public Field {
142 public:
143 using Field::Field;
144
145 void write(uint64_t value, uint64_t enabled_bits) override {
146 Field::write(value & get(), enabled_bits);
147 }
148};
149
150// Reads return a constant value
151class ReadConstantField : public Field {
152 public:
153 ReadConstantField(MappableConfObject *obj, const std::string &name,
154 uint64_t read_val) :
155 Field(obj, name),
156 read_val_(read_val) {}
157
158 ReadConstantField(RegisterInterface *parent, std::string_view field_name,
159 uint64_t read_val) :
160 Field(parent, field_name),
161 read_val_(read_val) {}
162
163 uint64_t read(uint64_t enabled_bits) override {
164 return read_val_ & enabled_bits;
165 }
166
167 private:
168 uint64_t read_val_;
169};
170
171// Writes are forbidden and have no effect. TODO(xiuliang): no_reset?
172class ConstantField : public Field {
173 public:
174 ConstantField(MappableConfObject *obj, const std::string &name,
175 uint64_t init_val) :
176 Field(obj, name),
177 init_val_(init_val) {}
178
179 ConstantField(RegisterInterface *parent, std::string_view field_name,
180 uint64_t init_val) :
181 Field(parent, field_name),
182 init_val_(init_val) {}
183
184 void write(uint64_t value, uint64_t enabled_bits) override {
185 if ((value & enabled_bits) != (get() & enabled_bits)) {
186 SIM_LOG_SPEC_VIOLATION_STR(logged_once_ ? 2 : 1, bank_obj_ref(), 0,
187 fmt::format("Write to constant field {} (value written"
188 " = {:#010x}, contents = {:#010x}).", name(),
189 value & enabled_bits, get()));
190 logged_once_ = true;
191 }
192 }
193
194 void init(std::string_view desc, const bits_type &bits,
195 int8_t offset) override {
196 Field::init(desc, bits, offset);
197 set(init_val_);
198 }
199
200 private:
201 bool logged_once_ {false};
202 uint64_t init_val_;
203};
204
205// The object value will remain constant. Writes are ignored
206// and do not update the object value.
208 public:
210
211 void write(uint64_t value, uint64_t enabled_bits) override {}
212};
213
214// The object value is constant 0. Software writes are forbidden
215// and do not update the object value.
216class ZerosField : public ConstantField {
217 public:
218 ZerosField(MappableConfObject *obj, const std::string &name)
219 : ConstantField(obj, name, 0) {}
220
221 ZerosField(RegisterInterface *parent, std::string_view field_name)
222 : ConstantField(parent, field_name, 0) {}
223};
224
225// The object is constant all 1's. Software writes do not update
226// the object value.
227class OnesField : public ConstantField {
228 public:
229 OnesField(MappableConfObject *obj, const std::string &name)
230 : ConstantField(obj, name,
231 std::numeric_limits<uint64_t>::max()) {}
232
233 OnesField(RegisterInterface *parent, std::string_view field_name)
234 : ConstantField(parent, field_name,
235 std::numeric_limits<uint64_t>::max()) {}
236};
237
238// The object's functionality is unimportant. Reads return 0.
239// Writes are ignored.
241 public:
242 using IgnoreWriteField::IgnoreWriteField;
243
244 uint64_t read(uint64_t enabled_bits) override {
245 return 0;
246 }
247};
248
249// The object is marked reserved and should not be used by software.
250// Writes update the object value. Reads return the object value.
251class ReservedField : public Field {
252 public:
253 using Field::Field;
254
255 void write(uint64_t value, uint64_t enabled_bits) override {
256 if (!has_logged_ && (value & enabled_bits) != (get() & enabled_bits)) {
258 fmt::format("Write to reserved field {} (value written"
259 " = {:#010x}, contents = {:#010x}), will not warn"
260 " again.", name(), value & enabled_bits, get()));
261 has_logged_ = true;
262 }
263 Field::write(value, enabled_bits);
264 }
265
266 private:
267 bool has_logged_ {false};
268};
269
270// The object functionality associated to a read access is
271// unimplemented. Write access is using default implementation.
272class ReadUnimplField : public Field {
273 public:
274 ReadUnimplField(MappableConfObject *obj, const std::string &name)
275 : Field(obj, name) {
276 set_description("Read access not implemented. " + description());
277 }
278
279 ReadUnimplField(RegisterInterface *parent, std::string_view field_name)
280 : Field(parent, field_name) {
281 set_description("Read access not implemented. " + description());
282 }
283
284 uint64_t read(uint64_t enabled_bits) override {
285 return get() & enabled_bits;
286 }
287};
288
289// The object functionality is unimplemented. Warn when software
290// is using the object. Writes and reads are implemented as default
291// writes and reads.
292class UnimplField : public Field {
293 public:
294 UnimplField(MappableConfObject *obj, const std::string &name)
295 : Field(obj, name) {
296 set_description("Not implemented. " + description());
297 }
298
299 UnimplField(RegisterInterface *parent, std::string_view field_name)
300 : Field(parent, field_name) {
301 set_description("Not implemented. " + description());
302 }
303
304 uint64_t read(uint64_t enabled_bits) override {
305 return get() & enabled_bits;
306 }
307
308 void write(uint64_t value, uint64_t enabled_bits) override {
309 if ((value & enabled_bits) != (get() & enabled_bits)) {
310 SIM_LOG_UNIMPLEMENTED_STR(logged_once_ ? 3 : 1, bank_obj_ref(), 0,
311 fmt::format("Write to unimplemented field {} (value written"
312 " = {:#010x}, contents = {:#010x}).",
313 name(), value & enabled_bits, get()));
314 logged_once_ = true;
315 }
316 Field::write(value, enabled_bits);
317 }
318
319 private:
320 bool logged_once_ {false};
321};
322
323// The object functionality associated to a write access is
324// unimplemented. Read access is using default implementation.
325class WriteUnimplField : public Field {
326 public:
327 WriteUnimplField(MappableConfObject *obj, const std::string &name)
328 : Field(obj, name) {
329 set_description("Write access not implemented. " + description());
330 }
331
332 WriteUnimplField(RegisterInterface *parent, std::string_view field_name)
333 : Field(parent, field_name) {
334 set_description("Write access not implemented. " + description());
335 }
336
337 void write(uint64_t value, uint64_t enabled_bits) override {
338 if ((value & enabled_bits) != (get() & enabled_bits)) {
339 SIM_LOG_UNIMPLEMENTED_STR(logged_once_ ? 3 : 1, bank_obj_ref(), 0,
340 fmt::format("Write to unimplemented field {} (value written"
341 " = {:#010x}, contents = {:#010x}).",
342 name(), value & enabled_bits, get()));
343 logged_once_ = true;
344 }
345 Field::write(value, enabled_bits);
346 }
347
348 private:
349 bool logged_once_ {false};
350};
351
352// The object functionality is unimplemented, but do not print
353// a lot of log-messages when reading or writing. Writes and
354// reads are implemented as default writes and reads.
355class SilentUnimplField : public Field {
356 public:
357 using Field::Field;
358
359 uint64_t read(uint64_t enabled_bits) override {
360 return get() & enabled_bits;
361 }
362
363 void write(uint64_t value, uint64_t enabled_bits) override {
364 if ((value & enabled_bits) != (get() & enabled_bits)) {
365 SIM_LOG_UNIMPLEMENTED_STR(logged_once_ ? 3 : 2, bank_obj_ref(), 0,
366 fmt::format("Write to unimplemented field {} (value written"
367 " = {:#010x}, contents = {:#010x}).",
368 name(), value & enabled_bits, get()));
369 logged_once_ = true;
370 }
371 Field::write(value, enabled_bits);
372 }
373
374 private:
375 bool logged_once_ {false};
376};
377
378// The object functionality is undocumented or poorly documented.
379// Writes and reads are implemented as default writes and reads.
380class UndocumentedField : public Field {
381 public:
382 using Field::Field;
383
384 uint64_t read(uint64_t enabled_bits) override {
385 SIM_LOG_SPEC_VIOLATION_STR(logged_once_read_ ? 2 : 1, bank_obj_ref(), 0,
386 fmt::format("Read from poorly or non-documented field {}"
387 " (contents = {:#010x}).",
388 name(), get() & enabled_bits));
389 logged_once_read_ = true;
390 return get() & enabled_bits;
391 }
392
393 void write(uint64_t value, uint64_t enabled_bits) override {
394 SIM_LOG_SPEC_VIOLATION_STR(logged_once_read_ ? 2 : 1, bank_obj_ref(), 0,
395 fmt::format("Write to poorly or non-documented field {} (value"
396 " written = {:#010x}, contents = {:#010x}).",
397 name(), value & enabled_bits, get()));
398 logged_once_write_ = true;
399 Field::write(value, enabled_bits);
400 }
401
402 private:
403 bool logged_once_read_ {false};
404 bool logged_once_write_ {false};
405};
406
407// The object's functionality is not in the model's scope and has been
408// left unimplemented as a design decision. Software and hardware writes
409// and reads are implemented as default writes and reads. Debug fields
410// are a prime example of when to use this template. This is different from
411// unimplemented which is intended to be implement (if required) but is a
412// limitation in the current model.
414 public:
416 : Field(obj, name) {
417 set_description(std::string("Not implemented (design limitation).")
418 + " This field is a dummy field with no side effects. "
419 + description());
420 }
421
423 std::string_view field_name)
424 : Field(parent, field_name) {
425 set_description(std::string("Not implemented (design limitation).")
426 + " This field is a dummy field with no side effects. "
427 + description());
428 }
429};
430
431// The object value can be written only once
432class WriteOnceField : public Field {
433 public:
434 using Field::Field;
435
436 void write(uint64_t value, uint64_t enabled_bits) override {
437 if (written_) {
439 fmt::format("Write to write-once field {} (value written"
440 " = {:#010x}, contents = {:#010x})",
441 name(), value & enabled_bits, get()));
442 return;
443 }
444 Field::write(value, enabled_bits);
445 written_ = true;
446 }
447
448 private:
449 bool written_ {false};
450};
451
452// Combinations of the basic templates
453// Software reads return the object value. The object value is
454// read-only for software then reset to 0 as a side-effect of the read.
456 public:
457 using ReadOnlyField::ReadOnlyField;
458
459 uint64_t read(uint64_t enabled_bits) override {
460 uint64_t value = get();
461 set(0);
462 return value & enabled_bits;
463 }
464};
465
466} // namespace simics
467
468#endif
Definition: field-templates.h:115
uint64_t read(uint64_t enabled_bits) override
Definition: field-templates.h:119
Definition: field-templates.h:172
ConstantField(MappableConfObject *obj, const std::string &name, uint64_t init_val)
Definition: field-templates.h:174
ConstantField(RegisterInterface *parent, std::string_view field_name, uint64_t init_val)
Definition: field-templates.h:179
void write(uint64_t value, uint64_t enabled_bits) override
Definition: field-templates.h:184
void init(std::string_view desc, const bits_type &bits, int8_t offset) override
Definition: field-templates.h:194
Definition: field-templates.h:413
DesignLimitationField(RegisterInterface *parent, std::string_view field_name)
Definition: field-templates.h:422
DesignLimitationField(MappableConfObject *obj, const std::string &name)
Definition: field-templates.h:415
Definition: field.h:40
RegisterInterface * parent() const override
Definition: field.h:113
void write(uint64_t value, uint64_t enabled_bits) override
Definition: field.h:154
uint64_t get() const override
Definition: field.h:117
size_t offset() const
Definition: field.h:160
const std::string & description() const override
Definition: field.h:88
std::string_view name() const override
Definition: field.h:84
Field(MappableConfObject *dev_obj, const std::string &name)
Definition: field.h:44
void set(uint64_t value) override
Definition: field.h:128
ConfObjectRef bank_obj_ref() const override
Definition: hierarchical-object.h:181
void set_description(std::string_view desc) override
Definition: hierarchical-object.h:160
Definition: field-templates.h:240
uint64_t read(uint64_t enabled_bits) override
Definition: field-templates.h:244
Definition: field-templates.h:46
void write(uint64_t value, uint64_t enabled_bits) override
Definition: field-templates.h:50
Definition: mappable-conf-object.h:131
Definition: field-templates.h:227
OnesField(RegisterInterface *parent, std::string_view field_name)
Definition: field-templates.h:233
OnesField(MappableConfObject *obj, const std::string &name)
Definition: field-templates.h:229
Definition: field-templates.h:54
uint64_t read(uint64_t enabled_bits) override
Definition: field-templates.h:58
Definition: field-templates.h:151
ReadConstantField(MappableConfObject *obj, const std::string &name, uint64_t read_val)
Definition: field-templates.h:153
ReadConstantField(RegisterInterface *parent, std::string_view field_name, uint64_t read_val)
Definition: field-templates.h:158
uint64_t read(uint64_t enabled_bits) override
Definition: field-templates.h:163
Definition: field-templates.h:455
uint64_t read(uint64_t enabled_bits) override
Definition: field-templates.h:459
Definition: field-templates.h:81
void write(uint64_t value, uint64_t enabled_bits) override
Definition: field-templates.h:85
Definition: field-templates.h:272
ReadUnimplField(RegisterInterface *parent, std::string_view field_name)
Definition: field-templates.h:279
ReadUnimplField(MappableConfObject *obj, const std::string &name)
Definition: field-templates.h:274
uint64_t read(uint64_t enabled_bits) override
Definition: field-templates.h:284
Definition: field-templates.h:33
RegisterField(RegisterInterface *reg_iface, Name name, Description desc, Offset offset, BitWidth size, Args... args)
Definition: field-templates.h:37
Definition: register-interface.h:36
virtual void parse_field(const field_t &f)=0
Definition: field-templates.h:251
void write(uint64_t value, uint64_t enabled_bits) override
Definition: field-templates.h:255
Definition: field-templates.h:207
void write(uint64_t value, uint64_t enabled_bits) override
Definition: field-templates.h:211
Definition: field-templates.h:355
uint64_t read(uint64_t enabled_bits) override
Definition: field-templates.h:359
void write(uint64_t value, uint64_t enabled_bits) override
Definition: field-templates.h:363
Definition: field-templates.h:380
uint64_t read(uint64_t enabled_bits) override
Definition: field-templates.h:384
void write(uint64_t value, uint64_t enabled_bits) override
Definition: field-templates.h:393
Definition: field-templates.h:292
UnimplField(MappableConfObject *obj, const std::string &name)
Definition: field-templates.h:294
void write(uint64_t value, uint64_t enabled_bits) override
Definition: field-templates.h:308
UnimplField(RegisterInterface *parent, std::string_view field_name)
Definition: field-templates.h:299
uint64_t read(uint64_t enabled_bits) override
Definition: field-templates.h:304
Definition: field-templates.h:141
void write(uint64_t value, uint64_t enabled_bits) override
Definition: field-templates.h:145
Definition: field-templates.h:104
void write(uint64_t value, uint64_t enabled_bits) override
Definition: field-templates.h:108
Definition: field-templates.h:129
void write(uint64_t value, uint64_t enabled_bits) override
Definition: field-templates.h:133
Definition: field-templates.h:432
void write(uint64_t value, uint64_t enabled_bits) override
Definition: field-templates.h:436
Definition: field-templates.h:67
uint64_t read(uint64_t enabled_bits) override
Definition: field-templates.h:71
Definition: field-templates.h:325
WriteUnimplField(MappableConfObject *obj, const std::string &name)
Definition: field-templates.h:327
void write(uint64_t value, uint64_t enabled_bits) override
Definition: field-templates.h:337
WriteUnimplField(RegisterInterface *parent, std::string_view field_name)
Definition: field-templates.h:332
Definition: field-templates.h:216
ZerosField(MappableConfObject *obj, const std::string &name)
Definition: field-templates.h:218
ZerosField(RegisterInterface *parent, std::string_view field_name)
Definition: field-templates.h:221
Literal type that extends size_t type.
Definition: common-types.h:27
Definition: hierarchical-object-name.h:37
#define SIM_LOG_UNIMPLEMENTED_STR(level, obj, group, str)
Definition: log.h:37
#define SIM_LOG_INFO_STR(level, obj, group, str)
Special macro to handle string object (for example, fmt::format)
Definition: log.h:31
#define SIM_LOG_SPEC_VIOLATION_STR(level, obj, group, str)
Definition: log.h:34
Definition: attr-value.h:23
std::vector< std::pair< uint8_t *, uint8_t > > bits_type
Definition: field-interface.h:30
std::string_view Description
Type used to describe a resource.
Definition: common-types.h:43
Definition: common-types.h:63