ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
InterruptHandler.cpp
Go to the documentation of this file.
1 
52 #include "etiss/InterruptHandler.h"
53 
54 using namespace etiss;
55 
56 InterruptHandler::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 
65 bool 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 
71 void 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 {
88 
89  if (vector_ == 0)
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 }
etiss_int32 int32
Definition: 386-GCC.h:81
etiss_uint64 uint64
Definition: 386-GCC.h:82
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 bool isEnabled()
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
MM_EXPORT const int32_t NOERROR
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
@ EDGE_TRIGGERED
@ LEVEL_TRIGGERED
etiss_uint64 cpuTime_ps
simulation time of cpu
Definition: CPU.h:97