16#ifndef SIMICS_HIERARCHICAL_OBJECT_H
17#define SIMICS_HIERARCHICAL_OBJECT_H
19#include <simics/base/log.h>
20#include <fmt/fmt/format.h>
39constexpr static const char &SEPARATOR =
'.';
47 const std::string &
name)
49 hierarchical_name_(
name) {
51 throw std::invalid_argument {
52 "HierarchicalObject cannot be constructed from a NULL dev_obj"
58 const std::string &
name,
64 const std::string &
name,
70 const std::string &
name,
77 auto *obj = bank_obj_ref_.
object();
79 if (SIM_object_is_configured(obj)) {
80 if (!SIM_marked_for_deletion(obj)) {
81 SIM_LOG_CRITICAL(obj, 0,
82 "Hierarchical object can't be deleted"
83 " during the simulation");
94 : dev_obj_(rhs.dev_obj_),
95 hierarchical_name_(std::move(rhs.hierarchical_name_)),
96 desc_(std::move(rhs.desc_)),
97 bank_obj_ref_(rhs.bank_obj_ref_),
105 std::swap(dev_obj_, temp.dev_obj_);
106 std::swap(hierarchical_name_, temp.hierarchical_name_);
107 std::swap(desc_, temp.desc_);
108 std::swap(bank_obj_ref_, temp.bank_obj_ref_);
109 std::swap(level_, temp.level_);
115 std::string err =
"Bank name (" + hierarchical_name_ \
116 +
") does not match the bank level (bankA)";
118 throw std::invalid_argument { err };
125 std::string err =
"Register name (" + hierarchical_name_ \
126 +
") does not match the register level (bankA.registerB)";
128 throw std::invalid_argument { err };
135 std::string err =
"Field name (" + hierarchical_name_ \
136 +
") does not match the field level (bankA.registerB.fieldC)";
138 throw std::invalid_argument { err };
144 return hierarchical_name_;
147 std::string_view
name()
const override {
182 return bank_obj_ref_;
186 static_assert(std::is_base_of<MappableConfObject, T>::value,
187 "T needs be a MappableConfObject");
188 return dynamic_cast<T *
>(
dev_obj());
203 SIM_LOG_ERROR(dev_obj_->
obj(), 0,
204 "Look up field should be called after finalize"
206 return field_interface;
210 fmt::format(
"Invalid field name: {}",
name));
211 return field_interface;
215 if (field_name_level == 0) {
219 hierarchical_name_ + SEPARATOR +
name);
222 hierarchical_name_.substr(0, hierarchical_name_.rfind(
226 SIM_LOG_ERROR(dev_obj_->
obj(), 0,
227 "Unable to lookup a field with field name only"
230 }
else if (field_name_level == 1) {
238 if (!field_interface) {
240 fmt::format(
"Lookup field failed: {}",
name));
242 return field_interface;
248 SIM_LOG_ERROR(dev_obj_->
obj(), 0,
249 "Look up register should be called after finalize"
251 return register_interface;
255 fmt::format(
"Invalid register name: {}",
name));
256 return register_interface;
262 fmt::format(
"Invalid register name: {}",
name));
268 if (!register_interface) {
270 fmt::format(
"Lookup register failed: {}",
name));
272 return register_interface;
278 SIM_LOG_ERROR(dev_obj_->
obj(), 0,
279 "Look up bank should be called after finalize phase");
280 return bank_interface;
284 fmt::format(
"Invalid bank name: {}",
name));
285 return bank_interface;
289 if (bank_name_level >
static_cast<int>(
Level::BANK)) {
291 fmt::format(
"Invalid bank name: {}",
name));
296 if (!bank_interface) {
298 fmt::format(
"Lookup bank failed: {}",
name));
300 return bank_interface;
305 static const char *allowed_characters {
306 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ[]._"
312 if (isdigit(
name[0]) ||
name[0] ==
'['
313 ||
name[0] ==
']' ||
name[0] ==
'_') {
316 if (
name.find_first_not_of(allowed_characters) != std::string::npos) {
319 if (std::count(
name.cbegin(),
name.cend(), SEPARATOR) > 2) {
322 if (
name.find(std::string(2, SEPARATOR)) != std::string::npos) {
325 if (
name.find(SEPARATOR) == 0
326 ||
name.rfind(SEPARATOR) ==
name.length() - 1) {
333 assert(!
name.empty());
336 return std::count(
name.cbegin(),
name.cend(), SEPARATOR);
346 std::string err =
"Cannot set with invalid name string: " \
347 + hierarchical_name_;
349 throw std::invalid_argument { err };
352 level_ =
static_cast<Level>(
355 std::string
bank_name {hierarchical_name_};
357 auto pos_first_separator = hierarchical_name_.find(SEPARATOR);
358 assert(pos_first_separator != std::string::npos);
359 bank_name = hierarchical_name_.substr(0, pos_first_separator);
362 bank_obj_ref_ = SIM_object_descendant(
364 if (bank_obj_ref_.
object() ==
nullptr) {
365 std::string err = fmt::format(
"{}.bank.{} does not exist",
369 throw std::invalid_argument { err };
373 MappableConfObject *dev_obj_;
374 std::string hierarchical_name_;
376 ConfObjectRef bank_obj_ref_;
Definition: bank-interface.h:45
Represents Simics C type conf_object_t.
Definition: conf-object.h:37
conf_object_t * object() const
Get a pointer to the configuration object represented by this ConfObjectRef.
Definition: conf-object.h:57
const std::string & name() const
Get the name of the underlying configuration object.
virtual bool finalized()
Return if the finalize method has been called.
Definition: conf-object.h:137
ConfObjectRef obj() const
Return a ConfObjectRef represents this object.
Definition: conf-object.h:134
Definition: field-interface.h:34
Definition: hierarchical-object-interface.h:32
Definition: hierarchical-object.h:43
T * dev_ptr()
Definition: hierarchical-object.h:185
static const uint64_t Register_Read
Log group ID for Register_Read and Register_Write is fixed.
Definition: hierarchical-object.h:340
HierarchicalObject(HierarchicalObject &&rhs) noexcept
Definition: hierarchical-object.h:93
void init_iface(BankInterface *iface)
Definition: hierarchical-object.h:113
HierarchicalObject & operator=(const HierarchicalObject &)=delete
virtual ~HierarchicalObject()
Definition: hierarchical-object.h:76
HierarchicalObject(MappableConfObject *dev_obj, const std::string &name, RegisterInterface *iface)
Definition: hierarchical-object.h:63
HierarchicalObject(MappableConfObject *dev_obj, const std::string &name, BankInterface *iface)
Definition: hierarchical-object.h:69
std::string_view bank_name() const override
Definition: hierarchical-object.h:168
BankInterface * lookup_bank(const std::string &name) const override
Definition: hierarchical-object.h:275
static const uint64_t Register_Write
Definition: hierarchical-object.h:341
HierarchicalObject(MappableConfObject *dev_obj, const std::string &name, FieldInterface *iface)
Definition: hierarchical-object.h:57
void init_iface(FieldInterface *iface)
Definition: hierarchical-object.h:133
RegisterInterface * lookup_register(const std::string &name) const override
Definition: hierarchical-object.h:245
ConfObjectRef bank_obj_ref() const override
Definition: hierarchical-object.h:181
HierarchicalObject(MappableConfObject *dev_obj, const std::string &name)
Definition: hierarchical-object.h:46
FieldInterface * lookup_field(const std::string &name) const override
Definition: hierarchical-object.h:200
HierarchicalObject & operator=(HierarchicalObject &&rhs) noexcept
Definition: hierarchical-object.h:99
void init_iface(RegisterInterface *iface)
Definition: hierarchical-object.h:123
static bool is_valid_hierarchical_name(std::string_view name)
Definition: hierarchical-object.h:303
std::string_view name() const override
Definition: hierarchical-object.h:147
Level hierarchy_level() const override
Definition: hierarchical-object.h:164
std::string_view parent_name() const override
Definition: hierarchical-object.h:191
const std::string & description() const override
Definition: hierarchical-object.h:156
void set_description(std::string_view desc) override
Definition: hierarchical-object.h:160
MappableConfObject * dev_obj() const override
Definition: hierarchical-object.h:177
static int level_of_hierarchical_name(std::string_view name)
Definition: hierarchical-object.h:332
HierarchicalObject(const HierarchicalObject &)=delete
const std::string & hierarchical_name() const override
Definition: hierarchical-object.h:143
Definition: mappable-conf-object.h:131
void set_iface(const std::string &name, IFACE *iface)
Definition: mappable-conf-object.h:138
IFACE * get_iface(const std::string &name) const
Definition: mappable-conf-object.h:170
Definition: register-interface.h:36
#define SIM_LOG_CRITICAL_STR(obj, group, str)
Definition: log.h:43
#define SIM_LOG_ERROR_STR(obj, group, str)
Definition: log.h:40
Definition: attr-value.h:23
Level
Definition: hierarchical-object-interface.h:30