C++ Device API Reference Manual
Reference documentation for the Simics C++ Device API.
 
Loading...
Searching...
No Matches
after-bank.h
Go to the documentation of this file.
1// -*- mode: C++; c-file-style: "virtutech-c++" -*-
2
3/*
4 © 2024 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// Register bank extension for after feature
17
18#ifndef SIMICS_AFTER_BANK_H
19#define SIMICS_AFTER_BANK_H
20
21#include <string>
22#include <tuple>
23#include <utility>
24
25#include "simics/after.h"
32
33namespace simics {
34
35// RegBankFunctionCall contains class member function for bank/register/field
36// information like object name, function name, arguments and the function
37// pointer
38template<typename Class, typename... Args>
40 public:
41 using RegBankFunctionType = void (Class::*)(Args...);
42
44 : func_(func), name_(name + typeid(func).name()),
45 obj_(nullptr), dev_obj_(nullptr), hierarchical_object_name_("") {}
46
47 std::string name() const override {
48 return name_;
49 }
50
51 void set_args(const attr_value_t &value) override {
52 auto t = attr_to_std<std::tuple<
53 ConfObjectRef, std::string, Args...>>(value);
54 dev_obj_ = std::get<0>(t);
55 hierarchical_object_name_ = std::get<1>(t);
56 set_args_impl(t, std::index_sequence_for<Args...>{});
57 }
58
60 // The allocated pointer is deleted after the function call is invoked
61 return new RegBankFunctionCall<Class, Args...>(*this);
62 }
63
64 attr_value_t get_value() override {
65 auto rest = std::tuple_cat(
66 std::make_tuple(dev_obj_, hierarchical_object_name_),
67 args_);
68 return std_to_attr(std::make_pair(name_, rest));
69 }
70
71 private:
72 void invoke() override {
73 auto level = static_cast<Level>(
75 hierarchical_object_name_));
76 auto *dev = from_obj<MappableConfObject>(dev_obj_);
77 switch (level) {
78 case Level::BANK:
79 obj_ = dynamic_cast<Class *>(dev->get_iface<BankInterface>(
80 hierarchical_object_name_));
81 break;
82 case Level::REGISTER:
83 obj_ = dynamic_cast<Class *>(dev->get_iface<RegisterInterface>(
84 hierarchical_object_name_));
85 break;
86 case Level::FIELD:
87 obj_ = dynamic_cast<Class *>(dev->get_iface<FieldInterface>(
88 hierarchical_object_name_));
89 break;
90 default:
91 SIM_LOG_ERROR(dev_obj_, 0,
92 "%s is not a valid hierarchical object name",
93 hierarchical_object_name_.c_str());
94 }
95 invoke_impl(std::index_sequence_for<Args...>{});
96 }
97
98 // Helper function to unpack the tuple and call the function
99 template<std::size_t... I>
100 void invoke_impl(std::index_sequence<I...>) {
101 (obj_->*func_)(std::get<I>(args_)...);
102 }
103
104 // Helper function to return a tuple by removing the first item
105 template <std::size_t... Is>
106 void set_args_impl(const std::tuple<ConfObjectRef, std::string,
107 Args...>& input_tuple,
108 std::index_sequence<Is...>) {
109 args_ = std::make_tuple(std::get<Is + 2>(input_tuple)...);
110 }
111
113 std::string name_;
114 Class *obj_ {nullptr};
115 ConfObjectRef dev_obj_;
116 std::string hierarchical_object_name_;
117 std::tuple<Args...> args_;
118};
119
120
121// Helper function to create a RegBankFunctionCall object with deduced types
122template<typename Class, typename... Args>
123constexpr auto make_reg_bank_function_call(void (Class::*func)(Args...),
124 const std::string &name) {
125 return new RegBankFunctionCall<Class, Args...>(func, name);
126}
127
128} // namespace simics
129
130#define REGISTER_REG_BANK_AFTER_CALL(f) \
131 simics::AfterCall::addIface(simics::make_reg_bank_function_call( \
132 FUNC_AND_NAME(f)));
133
134
135#endif
Definition: after-interface.h:27
An interface implemented by a Simics bank.
Definition: bank-interface.h:47
Represents Simics C type conf_object_t.
Definition: conf-object.h:38
Definition: field-interface.h:34
static std::string_view::size_type level_of_hierarchical_name(std::string_view name)
Definition: after-bank.h:39
attr_value_t get_value() override
Definition: after-bank.h:64
std::string name() const override
Definition: after-bank.h:47
AfterCallInterface * make_copy() override
Definition: after-bank.h:59
RegBankFunctionCall(RegBankFunctionType func, const std::string &name)
Definition: after-bank.h:43
void(Class::*)(Args...) RegBankFunctionType
Definition: after-bank.h:41
void set_args(const attr_value_t &value) override
Definition: after-bank.h:51
Definition: register-interface.h:37
Definition: after-bank.h:33
constexpr auto make_reg_bank_function_call(void(Class::*func)(Args...), const std::string &name)
Definition: after-bank.h:123
std::enable_if< std::is_enum< T >::value, attr_value_t >::type std_to_attr(const T &src)
Function transforms C++ enum type T to Simics attr_value_t.
Definition: attribute-traits.h:163
std::enable_if< std::is_enum< T >::value, T >::type attr_to_std(attr_value_t src)
Function transforms Simics attr_value_t to C++ enum type.
Definition: attribute-traits.h:207
Level
Enum representing the hierarchy level of an object.
Definition: hierarchical-object-interface.h:37