C++ Device API Reference Manual
Reference documentation for the Simics C++ Device API.
 
Loading...
Searching...
No Matches
callback_overlay.h
Go to the documentation of this file.
1/*
2 © 2023 Intel Corporation
3
4 This software and the related documents are Intel copyrighted materials, and
5 your use of them is governed by the express license under which they were
6 provided to you ("License"). Unless the License provides otherwise, you may
7 not use, modify, copy, publish, distribute, disclose or transmit this software
8 or the related documents without Intel's prior written permission.
9
10 This software and the related documents are provided as is, with no express or
11 implied warranties, other than those that are expressly stated in the License.
12*/
13
14//-*- C++ -*-
15
16#ifndef CPP_API_EXTENSIONS_SRC_SME_OVERLAYS_CALLBACK_OVERLAY_H
17#define CPP_API_EXTENSIONS_SRC_SME_OVERLAYS_CALLBACK_OVERLAY_H
18
19#include <stdarg.h>
20#include <iostream>
21
23
26
35
36#include "sme/overlays/I_bank_element.hpp"
37
38namespace sme
39{
40
45class callback_overlay : public I_bank_element {
46public:
52 : m_pre_read( nullptr)
53 , m_post_read( nullptr)
54 , m_pre_write( nullptr)
55 , m_post_write( nullptr)
56 {;}
57
63 if (m_pre_read != nullptr) {
64 // Delete the rules within the container
66 // Delete the rule container
67 delete m_pre_read;
68 }
69 if (m_post_read != nullptr) {
70 // Delete the rules within the container
72 // Delete the rule container
73 delete m_post_read;
74 }
75 if (m_pre_write != nullptr) {
76 // Delete the rules within the container
78 // Delete the rule container
79 delete m_pre_write;
80 }
81 if (m_post_write != nullptr) {
82 // Delete the rules within the container
84 // Delete the rule container
85 delete m_post_write;
86 }
87 }
88
96 switch( _stage) {
97 case stage::PRE_READ:
98 if( m_pre_read == nullptr) m_pre_read = new pattern_rule_container();
99 return( m_pre_read);
100 break;
101 case stage::POST_READ:
102 if( m_post_read == nullptr) m_post_read = new pattern_rule_container();
103 return( m_post_read);
104 break;
105 case stage::PRE_WRITE:
106 if( m_pre_write == nullptr) m_pre_write = new pattern_rule_container();
107 return( m_pre_write);
108 break;
109 case stage::POST_WRITE:
110 if( m_post_write == nullptr) m_post_write = new pattern_rule_container();
111 return( m_post_write);
112 break;
113 default:
114 std::cerr << "[ERROR][get_rule_container]: Invalid stage for rule container! (" << _stage << ")" << std::endl;
115 break;
116 }
117 return( nullptr);
118 }
119
126 void deactivate_rule( stage::E _stage, std::string _name) {
127 pattern_rule_container *container = get_rule_container(_stage);
128 if (container) {
129 container->deactivate_rule(_name);
130 }
131 }
132
139 void activate_rule( stage::E _stage, std::string _name) {
140 pattern_rule_container *container = get_rule_container(_stage);
141 if (container) {
142 container->activate_rule(_name);
143 }
144 }
145
152 void process_pre_read_rules( uint64_t _old_value, uint64_t _new_value) {
153 if( this->m_pre_read != nullptr) {
154 this->m_pre_read->process_active_rules( _old_value, _new_value);
155 }
156 }
157
164 void process_post_read_rules( uint64_t _old_value, uint64_t _new_value) {
165 if( this->m_post_read != nullptr) {
166 this->m_post_read->process_active_rules( _old_value, _new_value);
167 }
168 }
169
176 void process_pre_write_rules( uint64_t _old_value, uint64_t _new_value) {
177 if( this->m_pre_write != nullptr) {
178 this->m_pre_write->process_active_rules( _old_value, _new_value);
179 }
180 }
181
188 void process_post_write_rules( uint64_t _old_value, uint64_t _new_value) {
189 if( this->m_post_write != nullptr) {
190 this->m_post_write->process_active_rules( _old_value, _new_value);
191 }
192 }
193
207 I_pattern_rule * add_rule( std::function< void()> _func, stage::E _stage, type::E _type, std::string _name, ...) {
208 va_list args;
209 std::vector<uint64_t> ordered_arguments;
210 va_start(args, _name);
211 // 3 is the max, va_args will just put junk if we go beyond what is filled out by the user
212 for (int i = 0; i < 3; ++i) {
213 ordered_arguments.push_back(va_arg(args, uint64_t));
214 }
215 va_end(args);
216 I_pattern_rule * retval = this->__add_rule( _func, _stage, _type, _name, ordered_arguments);
217 return( retval);
218 }
219
220 I_pattern_rule * add_user_rule( std::function< void( uint64_t, uint64_t)> _func, stage::E _stage, std::string _name, ...) {
221 va_list args;
222 va_start( args, _name);
223 I_pattern_rule * retval = this->__add_rule( _func, _stage, type::E::USER_DEFINED, _name, args);
224 va_end( args);
225 return( retval);
226 }
227
228protected:
239 _keep_hot I_pattern_rule * __add_rule( std::function< void()> _func, stage::E _stage, type::E _type, std::string _name, std::vector<uint64_t> &_ordered_args) {
240 I_pattern_rule *rule = nullptr;
242
243 switch( _type)
244 {
245 case type::NOTIFY:
246 rule = new sme::rules::notify();
247 break;
248 case type::MASKED:
249 rule = new sme::rules::masked(_ordered_args[0]);
250 break;
251 case type::PATTERN:
252 rule = new sme::rules::pattern(_ordered_args[0], _ordered_args[1], _ordered_args[2]);
253 break;
254 case type::RISING_BIT:
255 rule = new sme::rules::rising_bit(uint8_t(_ordered_args[0]));
256 break;
257 case type::FALLING_BIT:
258 rule = new sme::rules::falling_bit(uint8_t(_ordered_args[0]));
259 break;
260 case type::RISING:
261 rule = new sme::rules::rising();
262 break;
263 case type::FALLING:
264 rule = new sme::rules::falling();
265 break;
266 case type::USER_DEFINED:
267 std::cerr << "[ERROR][add_rule]: User defined rules must use add_user_rule and prototype 'void func( uint64_t & _old, uint64_t & _new)'" << std::endl;
268 break;
269 default:
270 std::cerr << "[ERROR][add_rule]: Invalid stage for rule container! (" << _stage << ")" << std::endl;
271 break;
272 }
273
274 if (rules != nullptr && rule != nullptr) {
275 rules->add_rule( _name, rule);
276 rule->action( _func);
277 }
278 else if (rules == nullptr) {
279 // If the container is invalid we can't have a valid rule
280 if (rule) {
281 delete(rule);
282 rule = nullptr;
283 }
284 }
285
286 return(rule);
287 }
288
299 _keep_hot I_pattern_rule * __add_rule( std::function< void( uint64_t, uint64_t)> _func, stage::E _stage, type::E _type, std::string _name, va_list & args) {
300
301 I_pattern_rule *rule = nullptr;
303
304 switch( _type)
305 {
306 case type::NOTIFY:
307 case type::MASKED:
308 case type::PATTERN:
309 case type::RISING_BIT:
310 case type::FALLING_BIT:
311 case type::RISING:
312 case type::FALLING:
313 std::cerr << "[ERROR][add_rule]: Non user defined rules must use add rule and prototype 'void func()'" << std::endl;
314 break;
315 case type::USER_DEFINED:
316 rule = new sme::rules::user_defined();
317 break;
318 default:
319 std::cerr << "[ERROR][__add_rule]: Invalid stage for rule container! (" << _stage << ")" << std::endl;
320 break;
321 }
322
323 if (rules != nullptr && rule != nullptr) {
324 rules->add_rule( _name, rule);
325 rule->action( _func);
326 }
327 else if (rules == nullptr) {
328 // If the container is invalid we can't have a valid rule
329 if (rule) {
330 delete(rule);
331 rule = nullptr;
332 }
333 }
334
335 return(rule);
336 }
337
344 // Delete the rules within the container
345 std::map< std::string, I_pattern_rule *> rule_map = _rule_container->get_active_rules();
346 std::map< std::string, I_pattern_rule *>::iterator it;
347 for(it = rule_map.begin(); it != rule_map.end(); ++it) {
348 delete(it->second);
349 }
350 rule_map = _rule_container->get_inactive_rules();
351 for(it = rule_map.begin(); it != rule_map.end(); ++it) {
352 delete(it->second);
353 }
354 }
355
356
362
368
374
380
381};
382
383}
384
385#endif
#define _keep_hot
Definition: _inline.h:32
Interface and base class for all notification rule types.
Definition: I_pattern_rule.h:32
virtual void action(std::function< void()> _action)=0
Binds a void(void) lambda as the callback action to this rule.
class which houses all four rule containers, only allocated if utilized.
Definition: callback_overlay.h:45
callback_overlay()
Construct a new callback overlay object.
Definition: callback_overlay.h:51
pattern_rule_container * m_post_read
post_read rule container (ptr).
Definition: callback_overlay.h:367
_keep_hot I_pattern_rule * __add_rule(std::function< void()> _func, stage::E _stage, type::E _type, std::string _name, std::vector< uint64_t > &_ordered_args)
real implementation of add a rule to this entity (decompressed va_list).
Definition: callback_overlay.h:239
void delete_rules_from_container(pattern_rule_container *_rule_container)
Free the memory from the rules within the rule container.
Definition: callback_overlay.h:343
~callback_overlay()
Destroy the callback overlay object.
Definition: callback_overlay.h:62
I_pattern_rule * add_rule(std::function< void()> _func, stage::E _stage, type::E _type, std::string _name,...)
add a rule to this entity.
Definition: callback_overlay.h:207
void process_pre_write_rules(uint64_t _old_value, uint64_t _new_value)
processes pre_write_rules.
Definition: callback_overlay.h:176
pattern_rule_container * m_pre_write
pre_write rule container (ptr).
Definition: callback_overlay.h:373
void deactivate_rule(stage::E _stage, std::string _name)
deactivates rule by name at stage.
Definition: callback_overlay.h:126
void process_post_write_rules(uint64_t _old_value, uint64_t _new_value)
processes post_write_rules.
Definition: callback_overlay.h:188
pattern_rule_container * get_rule_container(stage::E _stage)
Get the rule container object.
Definition: callback_overlay.h:95
_keep_hot I_pattern_rule * __add_rule(std::function< void(uint64_t, uint64_t)> _func, stage::E _stage, type::E _type, std::string _name, va_list &args)
real implementation of add a rule to this entity (decompressed va_list).
Definition: callback_overlay.h:299
void process_pre_read_rules(uint64_t _old_value, uint64_t _new_value)
processes pre_read_rules.
Definition: callback_overlay.h:152
pattern_rule_container * m_pre_read
pre_read rule container (ptr).
Definition: callback_overlay.h:361
void process_post_read_rules(uint64_t _old_value, uint64_t _new_value)
processes post_read_rules.
Definition: callback_overlay.h:164
void activate_rule(stage::E _stage, std::string _name)
activates rule by name at stage.
Definition: callback_overlay.h:139
pattern_rule_container * m_post_write
post_write rule container (ptr).
Definition: callback_overlay.h:379
I_pattern_rule * add_user_rule(std::function< void(uint64_t, uint64_t)> _func, stage::E _stage, std::string _name,...)
Definition: callback_overlay.h:220
tracks all rules of a single type for a particular target.
Definition: pattern_rule_container.h:38
void activate_rule(std::string _name)
activate rule by name.
Definition: pattern_rule_container.h:107
const std::map< std::string, I_pattern_rule * > & get_inactive_rules() const
return const reference to 'inactive' string map of pattern rules.
Definition: pattern_rule_container.h:194
bool add_rule(std::string _name, I_pattern_rule *_rule, bool _active=true)
Adds a descendant of I_pattern_rule by name to this container.
Definition: pattern_rule_container.h:64
void deactivate_rule(std::string _name)
deactivate rule by name.
Definition: pattern_rule_container.h:87
void process_active_rules(uint64_t _old_value, uint64_t _new_value)
processes all active rules.
Definition: pattern_rule_container.h:128
const std::map< std::string, I_pattern_rule * > & get_active_rules() const
return const reference to 'active' string map of pattern rules.
Definition: pattern_rule_container.h:185
rule specifically to monitor a single bit for falling edge.
Definition: falling_bit.h:32
rule specifically to monitor the edge when all bits in the register have fallen.
Definition: falling.h:33
rule executes if anything "masked" changes between the old and new value.
Definition: masked.h:31
Basic rule executes with access (no change required).
Definition: notify.h:31
rule executes if the masked pattern matches the start (old) and end (new) values.
Definition: pattern.h:32
rule specifically to monitor a single bit for rising edge.
Definition: rising_bit.h:32
rule specifically to monitor the edge when any bit in the register is first to rise.
Definition: rising.h:33
Basic rule executes with access (no change required).
Definition: user_defined.h:31
Definition: expression_vector.h:25