16#ifndef SIMICS_BANK_PORT_H
17#define SIMICS_BANK_PORT_H
19#include <simics/base/attr-value.h>
20#include <simics/base/notifier.h>
21#include <simics/simulator-api.h>
22#include <simics/c++/model-iface/transaction.h>
23#include <simics/c++/model-iface/register-view.h>
24#include <simics/c++/model-iface/register-view-read-only.h>
53template <
typename TParent>
58 public iface::RegisterViewInterface,
59 public iface::RegisterViewReadOnlyInterface,
60 public iface::TransactionInterface {
62 std::is_base_of<MappableConfObject, TParent>::value,
63 "BankPort requires the parent class be a MappableConfObject");
74 bank_name_(bank_name_from_port_obj(o)) {
76 SIM_hap_add_callback_obj(
77 "Core_Conf_Object_Created", o.
object(), 0,
78 reinterpret_cast<obj_hap_func_t
>(object_created),
nullptr);
87 if (bank ==
nullptr) {
88 throw std::invalid_argument(
"Bank pointer cannot be nullptr");
98 SIM_hap_delete_callback_obj(
100 reinterpret_cast<obj_hap_func_t
>(object_created),
nullptr);
117#if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
118 if (bank_iface_ ==
nullptr) { [[unlikely]]
120 if (bank_iface_ ==
nullptr) {
123 "BankPort should have one bank");
132 "bank iface can only be set once");
136 bank_iface_ =
dev_obj()->template get_iface<BankInterface>(bank_name_);
139 "Used user defined bank for %s",
142 allocated_bank_.reset(
new Bank(
dev_obj(), bank_name_));
143 bank_iface_ = allocated_bank_.get();
145 "Created a new default bank for %s",
148 auto &[
name, desc, registers] = bank;
151 for (
auto ® : registers) {
159 return Sim_PE_IO_Not_Taken;
182 return SIM_make_attr_nil();
190 return SIM_make_attr_nil();
197 return reg_iface ? reg_iface->get() : 0;
214 return reg_iface ? reg_iface->is_read_only() :
false;
220 get_interface<BankPortInterface>(
obj)->validate_bank_iface();
223 static std::string_view bank_name_from_port_obj(ConfObjectRef port_obj) {
224 std::string_view port_name = port_obj.name();
225 if (port_name.find(bank_name_keyword) == std::string::npos) {
226 throw std::invalid_argument(
227 "Invalid bank port name (" + port_obj.name() +
")");
229 return port_name.substr(port_name.rfind(bank_name_keyword) + \
230 bank_name_keyword.size());
234 const RegisterInterface *i) {
235 attr_value_t info = SIM_alloc_attr_list(6);
236 SIM_attr_list_set_item(&info, 0,
237 SIM_make_attr_string(i->name().data()));
238 SIM_attr_list_set_item(&info, 1,
239 SIM_make_attr_string(i->description().c_str()));
240 SIM_attr_list_set_item(&info, 2,
241 SIM_make_attr_uint64(i->number_of_bytes()));
242 SIM_attr_list_set_item(&info, 3, SIM_make_attr_uint64(address));
244 auto fields_info = i->fields_info();
246 attr_value_t fields = SIM_alloc_attr_list(fields_info.size());
248 for (
const auto &[
name, desc, offset, width] : fields_info) {
250 attr_value_t field_info = SIM_alloc_attr_list(4);
251 SIM_attr_list_set_item(&field_info, 0,
252 SIM_make_attr_string(
name.data()));
253 SIM_attr_list_set_item(&field_info, 1,
254 SIM_make_attr_string(desc.data()));
255 SIM_attr_list_set_item(&field_info, 2,
256 SIM_make_attr_uint64(offset));
257 SIM_attr_list_set_item(&field_info, 3,
258 SIM_make_attr_uint64(offset + width - 1));
259 SIM_attr_list_set_item(&fields,
index++, field_info);
261 SIM_attr_list_set_item(&info, 4, fields);
262 SIM_attr_list_set_item(&info, 5,
268 static constexpr std::string_view bank_name_keyword {
".bank."};
270 BankInterface *bank_iface_ {
nullptr };
272 std::string bank_name_;
274 std::unique_ptr<BankInterface> allocated_bank_;
279 auto port = simics::make_class<TBankPort>(
name,
"", desc);
280 port->add(simics::iface::TransactionInterface::Info());
281 port->add(simics::iface::RegisterViewInterface::Info());
282 port->add(simics::iface::RegisterViewReadOnlyInterface::Info());
283 port->add(simics::iface::BankInstrumentationSubscribeInterface::Info());
284 port->add(simics::iface::InstrumentationOrderInterface::Info());
286 SIM_register_notifier(*port, Sim_Notify_Bank_Register_Value_Change,
291template <
typename TBankPort,
typename TArg>
ConfClassPtr
293 auto port = simics::make_class<TBankPort>(
name,
"", desc, arg);
294 port->add(simics::iface::TransactionInterface::Info());
295 port->add(simics::iface::RegisterViewInterface::Info());
296 port->add(simics::iface::RegisterViewReadOnlyInterface::Info());
297 port->add(simics::iface::BankInstrumentationSubscribeInterface::Info());
298 port->add(simics::iface::InstrumentationOrderInterface::Info());
300 SIM_register_notifier(*port, Sim_Notify_Bank_Register_Value_Change,
309template <
typename TParent>
311 const auto &[
name, desc, registers] = bank;
313 cls->
name() + SEPARATOR + std::string(
name.base_name()),
315 std::string(
"bank.") +
name.data());
318template <
typename TParent>
320 ConfClass *cls, std::initializer_list<bank_t> register_data) {
321 for (
auto &bank : register_data) {
322 create_hierarchy_from_register_data<TParent>(cls, bank);
#define NULL
Definition: _null.h:24
struct transaction transaction_t
Definition: bank-interface.h:30
struct conf_object conf_object_t
Definition: bank-issue-callbacks-interface.h:23
Definition: bank-instrumentation-subscribe-connection.h:44
Definition: bank-interface.h:45
virtual void set_description(std::string_view desc)=0
virtual unsigned number_of_registers() const =0
virtual void add_register(const register_t ®)=0
virtual void set_callbacks(BankIssueCallbacksInterface *callbacks)=0
virtual exception_type_t transaction_access(transaction_t *t, uint64_t offset)=0
virtual std::pair< size_t, RegisterInterface * > register_at_index(unsigned index) const =0
virtual const std::string & description() const =0
virtual ByteOrder get_byte_order() const =0
Definition: bank-port-interface.h:30
Definition: bank-port.h:60
BankPort & operator=(const BankPort &)=delete
const char * description() override
Definition: bank-port.h:165
std::string_view bank_name() const override
Definition: bank-port.h:104
BankPort(ConfObjectRef o, const bank_t *bank)
Definition: bank-port.h:85
void set_bank(const bank_t &bank) override
Definition: bank-port.h:129
bool validate_bank_iface() const override
Definition: bank-port.h:116
uint64 get_register_value(unsigned reg) override
Definition: bank-port.h:192
bool is_read_only(unsigned reg) override
Definition: bank-port.h:209
virtual ~BankPort()
Definition: bank-port.h:97
bool big_endian_bitorder() override
Definition: bank-port.h:171
unsigned number_of_registers() override
Definition: bank-port.h:174
BankPort(const BankPort &)=delete
exception_type_t issue(transaction_t *t, uint64 addr) override
Definition: bank-port.h:157
const BankInterface * bank_iface() const override
Definition: bank-port.h:108
attr_value_t register_info(unsigned reg) override
Definition: bank-port.h:180
MappableConfObject * dev_obj() const override
Definition: bank-port.h:112
void set_register_value(unsigned reg, uint64 val) override
Definition: bank-port.h:199
BankPort(ConfObjectRef o)
Definition: bank-port.h:72
Represents Simics C type conf_class_t.
Definition: conf-class.h:63
const std::string & name() const
Return the class name.
Definition: conf-class.h:96
ConfClass * add(const iface::InterfaceInfo &iface)
A function to register that ConfClass implements the iface interface.
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
ConfObjectRef obj() const
Return a ConfObjectRef represents this object.
Definition: conf-object.h:134
Definition: mappable-conf-object.h:131
void set_bank_as_initialized(const std::string &name)
Definition: mappable-conf-object.h:236
Represents a Simics port object base class.
Definition: port.h:35
TParent * parent() const
Return a pointer to the C++ object associated with the Simics parent object.
Definition: port.h:47
const std::string & name()
Return the port name.
Definition: port.h:52
int index() const
Return the index of an array-type object name.
Definition: port.h:57
Definition: attr-value.h:23
std::initializer_list< std::string > LogGroups
Type used for log group names.
Definition: log.h:26
std::unique_ptr< ConfClass > ConfClassPtr
Definition: conf-class.h:35
std::tuple< Name, Description, std::vector< register_t > > bank_t
Definition: bank-type.h:38
ByteOrder
Definition: bank-interface.h:34
void create_hierarchy_from_register_data(ConfClass *cls, const bank_t &bank)
Definition: bank-port.h:310
ConfClassPtr make_bank_port(const std::string &name, const std::string &desc)
Definition: bank-port.h:278