ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
InterruptHandler.cpp
Go to the documentation of this file.
1
53
54using namespace etiss;
55
56InterruptHandler::InterruptHandler(etiss::InterruptVector *interruptVector, etiss::InterruptEnable *interruptEnable, std::shared_ptr<CPUArch> arch,
57 InterruptType itype, bool sync)
58 : itype_(itype), sync_(sync), vector_(interruptVector), enable_(interruptEnable), cpuarch_(arch)
59{
60 empty_ = true;
61}
62
64
65bool interrupt_handler_cmp(const std::pair<etiss::uint64, std::pair<unsigned, bool>> &o1,
66 const std::pair<etiss::uint64, std::pair<unsigned, bool>> &o2)
67{
68 return o1.first < o2.first;
69}
70
71void InterruptHandler::setLine(unsigned line, bool state, etiss::uint64 time_ps)
72{
73 if (vector_ == 0)
74 return;
75
76 if (sync_)
77 mu_.lock();
78 pending_.push_back(std::make_pair(time_ps, std::make_pair(line, state))); // add interrupt to list
80 empty_ = false;
81 if (sync_)
82 mu_.unlock();
83}
84
86{
87 etiss::uint64 time_ps = plugin_cpu_->cpuTime_ps;
88
89 if (vector_ == 0)
90 return etiss::RETURNCODE::NOERROR;
91
92 if (sync_)
93 mu_.lock();
94
95 bool mayinterrupt = (itype_ != EDGE_TRIGGERED); // edge triggered may only interrupt once after a rising edge
96
97 // if (itype_ == EDGE_TRIGGERED) {
98 // for (int i=0; i < vector_->width() * 8; ++i) {
99 // if (vector_->getBit(i)) {
100 // std::cout << "clearing\n";
101 // vector_->setBit(i, 0);
102 // }
103 // }
104 // }
105
106 // fast check for empty pending list
107 if (!empty_)
108 {
109
110 while (!pending_.empty() && pending_.front().first <= time_ps)
111 { // apply events from past
112 std::pair<etiss::uint64, std::pair<unsigned, bool>> &cur = pending_.front();
113
114 switch (itype_)
115 {
116 case EDGE_TRIGGERED:
117 if (cur.second.second)
118 { // if line high
119 if (ed_raised_.find(cur.second.first) == ed_raised_.end())
120 { // if line was low
121 ed_raised_.insert(cur.second.first);
122 mayinterrupt = true;
123 }
124 }
125 else
126 { // line low
127 ed_raised_.erase(cur.second.first);
128 }
129
130 vector_->setBit(cur.second.first, cur.second.second);
131 break;
132 case LEVEL_TRIGGERED:
133 // dont need to clear state in case of iss model (i.e. if not using interrupt listener plugin)
134 if (!cur.second.second && !vector_->consumed_by_interruptlistener_)
135 {
136 break;
137 }
138 vector_->setBit(cur.second.first, cur.second.second);
139 break;
140 default:
141 std::cout << "InterruptHandler::execute: ERROR: interrupt type is invalid" << stream_code_info
142 << std::endl;
143 }
144 pending_.pop_front();
145
146 // only handle one pending event in case of edge-triggered events
147 if (itype_ == EDGE_TRIGGERED && mayinterrupt)
148 {
149 break;
150 }
151 // only handle one pending event in case of level-triggered events
152 if (itype_ == LEVEL_TRIGGERED)
153 {
154 break;
155 }
156 }
157
158 empty_ = pending_.empty();
159 }
160
161 if (sync_)
162 mu_.unlock();
163
164 auto active = vector_->isActive();
165 auto enabled = enable_->isEnabled();
166
167 // std::cout << "active: " << active << ", enabled: " << enabled << std::endl;
168
169 return (mayinterrupt && active && enabled) ? etiss::RETURNCODE::INTERRUPT : etiss::RETURNCODE::NOERROR;
170}
171
173{
174 return "InterruptHandler";
175}
bool interrupt_handler_cmp(const std::pair< etiss::uint64, std::pair< unsigned, bool > > &o1, const std::pair< etiss::uint64, std::pair< unsigned, bool > > &o2)
interrupt checking and signaling
#define stream_code_info
Definition types.h:79
virtual std::string _getPluginName() const
InterruptHandler(etiss::InterruptVector *interruptVector, etiss::InterruptEnable *interruptEnable, std::shared_ptr< etiss::CPUArch > arch, InterruptType itype=EDGE_TRIGGERED, bool sync=true)
std::set< unsigned > ed_raised_
virtual etiss::int32 execute()
apply interrupt changes to the InterruptVector
std::list< std::pair< etiss::uint64, std::pair< unsigned, bool > > > pending_
list: (time , (line ,state) )
virtual void setLine(unsigned line, bool state, etiss::uint64 time_ps)
set the state of a line at a given time.
const InterruptType itype_
InterruptVector *const vector_
InterruptEnable *const enable_
interface to set interrupt bits
virtual bool isActive() const
virtual void setBit(unsigned bit, bool state)=0
set the bit of an interrupt line to state (true = raised)
ETISS_CPU * plugin_cpu_
holds a pointer to the cpu structure. will be set before init call and after cleanup call
Definition Plugin.h:195
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
Definition Benchmark.h:53
InterruptType
interrupt types supported by the default implementation
etiss_uint64 cpuTime_ps
simulation time of cpu
Definition CPU.h:97