event data outsourced, SAL config flags revised, tiny coding-style fixes.
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1462 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
@ -3,7 +3,7 @@ if(BUILD_BOCHS)
|
|||||||
BufferCache.cc
|
BufferCache.cc
|
||||||
Listener.cc
|
Listener.cc
|
||||||
ListenerManager.cc
|
ListenerManager.cc
|
||||||
Memory.cc
|
SALConfig.cc
|
||||||
Register.cc
|
Register.cc
|
||||||
SimulatorController.cc
|
SimulatorController.cc
|
||||||
bochs/BochsController.cc
|
bochs/BochsController.cc
|
||||||
@ -14,7 +14,7 @@ elseif(BUILD_OVP)
|
|||||||
BufferCache.cc
|
BufferCache.cc
|
||||||
Listener.cc
|
Listener.cc
|
||||||
ListenerManager.cc
|
ListenerManager.cc
|
||||||
Memory.cc
|
SALConfig.cc
|
||||||
Register.cc
|
Register.cc
|
||||||
SimulatorController.cc
|
SimulatorController.cc
|
||||||
${VARIANT}/OVPController.cc
|
${VARIANT}/OVPController.cc
|
||||||
@ -24,7 +24,7 @@ elseif(BUILD_GEM5)
|
|||||||
BufferCache.cc
|
BufferCache.cc
|
||||||
Listener.cc
|
Listener.cc
|
||||||
ListenerManager.cc
|
ListenerManager.cc
|
||||||
Memory.cc
|
SALConfig.cc
|
||||||
Register.cc
|
Register.cc
|
||||||
SimulatorController.cc
|
SimulatorController.cc
|
||||||
gem5/Gem5Controller.cc
|
gem5/Gem5Controller.cc
|
||||||
|
|||||||
329
src/core/sal/Event.hpp
Normal file
329
src/core/sal/Event.hpp
Normal file
@ -0,0 +1,329 @@
|
|||||||
|
#ifndef __EVENT_HPP__
|
||||||
|
#define __EVENT_HPP__
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
#include <string>
|
||||||
|
#include <cassert>
|
||||||
|
#include <vector>
|
||||||
|
#include <utility>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "SALConfig.hpp"
|
||||||
|
|
||||||
|
namespace fail {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class BaseEvent
|
||||||
|
* This is the base class for all event types. It just encapsulates the
|
||||||
|
* information reported by the simulator-backend when triggering an "event".
|
||||||
|
*/
|
||||||
|
class BaseEvent {
|
||||||
|
public:
|
||||||
|
BaseEvent() { }
|
||||||
|
virtual ~BaseEvent() { }
|
||||||
|
};
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Specialized events:
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class BPEvent
|
||||||
|
* A Breakpoint event to observe instruction changes within a given address space.
|
||||||
|
*/
|
||||||
|
class BPEvent : virtual public BaseEvent {
|
||||||
|
protected:
|
||||||
|
address_t m_TriggerInstrPtr; //!< the address which triggered the event
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new breakpoint event. The range information is specific to
|
||||||
|
* the subclasses.
|
||||||
|
* @param trigger the triggering address of the breakpoint event
|
||||||
|
*/
|
||||||
|
BPEvent(address_t trigger) : m_TriggerInstrPtr(trigger) { }
|
||||||
|
/**
|
||||||
|
* Returns the instruction pointer that triggered this event.
|
||||||
|
* @return triggering IP
|
||||||
|
*/
|
||||||
|
address_t getTriggerInstructionPointer() const { return m_TriggerInstrPtr; }
|
||||||
|
/**
|
||||||
|
* Sets the instruction pointer that triggered this event.
|
||||||
|
* @param iptr new IP which caused this event
|
||||||
|
*/
|
||||||
|
void setTriggerInstructionPointer(address_t iptr) { m_TriggerInstrPtr = iptr; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class MemAccessEvent
|
||||||
|
* Observes memory read/write accesses.
|
||||||
|
* FIXME? currently >8-bit accesses only match if their lowest address is being watched
|
||||||
|
* (e.g., a 32-bit write to 0x4 also accesses 0x7, but this cannot be matched)
|
||||||
|
*/
|
||||||
|
class MemAccessEvent : virtual public BaseEvent {
|
||||||
|
public:
|
||||||
|
enum access_type_t {
|
||||||
|
MEM_UNKNOWN = 0x0, //!< internal initialization flag, indicating an uninitialized state
|
||||||
|
MEM_READ = 0x1, //!< read access flag
|
||||||
|
MEM_WRITE = 0x2, //!< write access flag
|
||||||
|
MEM_READWRITE = 0x3 //!< read and write access flag
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
//! Specific guest system *memory* address that actually triggered the event.
|
||||||
|
address_t m_TriggerAddr;
|
||||||
|
//! Width of the memory access (# bytes).
|
||||||
|
size_t m_TriggerWidth;
|
||||||
|
//! Address of the \b instruction that caused the memory access.
|
||||||
|
address_t m_TriggerIP;
|
||||||
|
//! Memory access type at m_TriggerAddr.
|
||||||
|
access_type_t m_AccessType;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new \c MemAccessEvent using default initialization values, i.e.
|
||||||
|
* \c setTriggerAddress(ANY_ADDR), \c setTriggerWidth(0), \c setTriggerAccessType(MEM_UNKNOWN)
|
||||||
|
* and \c setTriggerInstructionPointer(ANY_ADDR).
|
||||||
|
*/
|
||||||
|
MemAccessEvent()
|
||||||
|
: m_TriggerAddr(ANY_ADDR), m_TriggerWidth(0),
|
||||||
|
m_TriggerIP(ANY_ADDR), m_AccessType(MEM_UNKNOWN) { }
|
||||||
|
/**
|
||||||
|
* Creates a new \c MemAccessEvent and initializes the provided values.
|
||||||
|
* @param triggerAddr actual address that triggered the event
|
||||||
|
* @param width width of memory access (= # Bytes)
|
||||||
|
* @param triggerIP the instruction pointer that actually triggered the memory access
|
||||||
|
* @param type the type of memory access (r, w, rw)
|
||||||
|
*/
|
||||||
|
MemAccessEvent(address_t triggerAddr, size_t width, address_t triggerIP, access_type_t type)
|
||||||
|
: m_TriggerAddr(triggerAddr), m_TriggerWidth(width),
|
||||||
|
m_TriggerIP(triggerIP), m_AccessType(type) { }
|
||||||
|
/**
|
||||||
|
* Returns the specific memory address that actually triggered the event.
|
||||||
|
* @return the triggering address
|
||||||
|
*/
|
||||||
|
address_t getTriggerAddress() const { return m_TriggerAddr; }
|
||||||
|
/**
|
||||||
|
* Sets the specific memory address that actually triggered the event.
|
||||||
|
* Should not be used by experiment code.
|
||||||
|
* @param addr the new triggering address
|
||||||
|
*/
|
||||||
|
void setTriggerAddress(address_t addr) { m_TriggerAddr = addr; }
|
||||||
|
/**
|
||||||
|
* Returns the specific number of bytes read or written at \c getTriggerAddress().
|
||||||
|
* @return the width of the memory access
|
||||||
|
*/
|
||||||
|
size_t getTriggerWidth() const { return m_TriggerWidth; }
|
||||||
|
/**
|
||||||
|
* Sets the specific memory access width.
|
||||||
|
* @param new width (number of bytes)
|
||||||
|
*/
|
||||||
|
void setTriggerWidth(size_t width) { m_TriggerWidth = width; }
|
||||||
|
/**
|
||||||
|
* Returns the address of the instruction causing this memory access.
|
||||||
|
* @return triggering IP
|
||||||
|
*/
|
||||||
|
address_t getTriggerInstructionPointer() const { return m_TriggerIP; }
|
||||||
|
/**
|
||||||
|
* Sets the address of the instruction causing this memory access.
|
||||||
|
* @param addr new triggering IP
|
||||||
|
*/
|
||||||
|
void setTriggerInstructionPointer(address_t addr) { m_TriggerIP = addr; }
|
||||||
|
/**
|
||||||
|
* Returns type (MEM_READ || MEM_WRITE) of the memory access that
|
||||||
|
* triggered this event.
|
||||||
|
* @return the type of memory access (r or w) of this event
|
||||||
|
*/
|
||||||
|
access_type_t getTriggerAccessType() const { return m_AccessType; }
|
||||||
|
/**
|
||||||
|
* Sets type of the memory access that triggered this event.
|
||||||
|
* @param type type of memory access
|
||||||
|
*/
|
||||||
|
void setTriggerAccessType(access_type_t type) { m_AccessType = type; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class TroubleEvent
|
||||||
|
* Observes interrupt/trap activties.
|
||||||
|
*/
|
||||||
|
class TroubleEvent : virtual public BaseEvent {
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Specific guest system interrupt/trap number that actually
|
||||||
|
* trigger the event.
|
||||||
|
*/
|
||||||
|
int m_TriggerNumber;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs a default initialized \c TroubleEvent, setting the trigger-number
|
||||||
|
* to -1.
|
||||||
|
*/
|
||||||
|
TroubleEvent() : m_TriggerNumber(-1) { }
|
||||||
|
/**
|
||||||
|
* Constructs a new \c TroubleEvent.
|
||||||
|
* @param triggerNum system and type specific number identifying the requestet
|
||||||
|
* "trouble-type"
|
||||||
|
*/
|
||||||
|
TroubleEvent(int triggerNum)
|
||||||
|
: m_TriggerNumber(triggerNum) { }
|
||||||
|
/**
|
||||||
|
* Sets the specific interrupt-/trap-number that actually triggered the event.
|
||||||
|
* @param triggerNum system and type specific number identifying the requested
|
||||||
|
* "trouble-type"
|
||||||
|
*/
|
||||||
|
void setTriggerNumber(unsigned triggerNum) { m_TriggerNumber = triggerNum; }
|
||||||
|
/**
|
||||||
|
* Returns the specific interrupt-/trap-number that actually triggered the event.
|
||||||
|
* @return the trigger number
|
||||||
|
*/
|
||||||
|
unsigned getTriggerNumber() const { return m_TriggerNumber; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class InterruptEvent
|
||||||
|
* Observes interrupts of the guest system.
|
||||||
|
*/
|
||||||
|
class InterruptEvent : virtual public TroubleEvent {
|
||||||
|
private:
|
||||||
|
bool m_IsNMI; //!< non maskable interrupt flag
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs a default initialized \c InterruptEvent, setting the non maskable
|
||||||
|
* interrupt flag to \c false.
|
||||||
|
*/
|
||||||
|
InterruptEvent() : m_IsNMI(false) { }
|
||||||
|
/**
|
||||||
|
* Creates a new \c InterruptEvent.
|
||||||
|
* @param nmi the new NMI (non maskable interrupt) flag state
|
||||||
|
*/
|
||||||
|
InterruptEvent(bool nmi) : m_IsNMI(nmi) { }
|
||||||
|
/**
|
||||||
|
* Returns \c true if the interrupt is non maskable, \c false otherwise.
|
||||||
|
* @return \c true if NMI flag is set, \c false otherwise
|
||||||
|
*/
|
||||||
|
bool isNMI() { return m_IsNMI; }
|
||||||
|
/**
|
||||||
|
* Sets the interrupt type (non maskable or not).
|
||||||
|
* @param nmi the new NMI (non maskable interrupt) flag state
|
||||||
|
*/
|
||||||
|
void setNMI(bool enabled) { m_IsNMI = enabled; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class GuestEvent
|
||||||
|
* Used to receive data from the guest system.
|
||||||
|
*/
|
||||||
|
// FIXME: cf. GuestListener
|
||||||
|
class GuestEvent : virtual public BaseEvent {
|
||||||
|
private:
|
||||||
|
char m_Data; //!< guest event data
|
||||||
|
unsigned m_Port; //!< communication port
|
||||||
|
public:
|
||||||
|
GuestEvent() : m_Data(0), m_Port(0) { }
|
||||||
|
/**
|
||||||
|
* Returns the data, transmitted by the guest system.
|
||||||
|
*/
|
||||||
|
char getData() const { return m_Data; }
|
||||||
|
/**
|
||||||
|
* Sets the data which had been transmitted by the guest system.
|
||||||
|
*/
|
||||||
|
void setData(char data) { m_Data = data; }
|
||||||
|
/**
|
||||||
|
* Returns the data length, transmitted by the guest system.
|
||||||
|
*/
|
||||||
|
unsigned getPort() const { return m_Port; }
|
||||||
|
/**
|
||||||
|
* Sets the data length which had been transmitted by the guest system.
|
||||||
|
*/
|
||||||
|
void setPort(unsigned port) { m_Port = port; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class IOPortEvent
|
||||||
|
* Observes I/O access on architectures with a separate I/O access mechanism (e.g. IA-32)
|
||||||
|
*/
|
||||||
|
class IOPortEvent : virtual public BaseEvent {
|
||||||
|
private:
|
||||||
|
unsigned char m_Data;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Initialises an IOPortEvent
|
||||||
|
* @param data the data which has been communicated through the I/O port
|
||||||
|
*/
|
||||||
|
IOPortEvent(unsigned char data = 0) : m_Data(data) { }
|
||||||
|
/**
|
||||||
|
* Returns the data sent to the specified port
|
||||||
|
*/
|
||||||
|
unsigned char getData() const { return m_Data; }
|
||||||
|
/**
|
||||||
|
* Sets the data which had been transmitted.
|
||||||
|
*/
|
||||||
|
void setData(unsigned char data) { m_Data = data; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class JumpEvent
|
||||||
|
* JumpEvents are used to observe conditional jumps (if...else if...else).
|
||||||
|
*/
|
||||||
|
class JumpEvent : virtual public BaseEvent {
|
||||||
|
private:
|
||||||
|
unsigned m_OpcodeTrigger;
|
||||||
|
bool m_FlagTriggered;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs a new event object.
|
||||||
|
* @param opcode the opcode of the jump-instruction to be observed
|
||||||
|
* or ANY_INSTR to match all jump-instructions
|
||||||
|
* @param flagreg \c true if the event has been triggered due to a
|
||||||
|
* specific FLAG register content, \c false otherwise
|
||||||
|
*/
|
||||||
|
JumpEvent(unsigned opcode = ANY_INSTR, bool flagreg = false)
|
||||||
|
: m_OpcodeTrigger(opcode), m_FlagTriggered(flagreg) { }
|
||||||
|
/**
|
||||||
|
* Retrieves the opcode of the jump-instruction.
|
||||||
|
*/
|
||||||
|
unsigned getTriggerOpcode() const { return m_OpcodeTrigger; }
|
||||||
|
/**
|
||||||
|
* Returns \c true, if the event was triggered due to specific register
|
||||||
|
* content, \c false otherwise.
|
||||||
|
*/
|
||||||
|
bool isRegisterTriggered() const { return !m_FlagTriggered; }
|
||||||
|
/**
|
||||||
|
* Returns \c true, of the event was triggered due to specific FLAG
|
||||||
|
* state, \c false otherwise. This is the common case.
|
||||||
|
*/
|
||||||
|
bool isFlagTriggered() const { return m_FlagTriggered; }
|
||||||
|
/**
|
||||||
|
* Sets the requestet jump-instruction opcode.
|
||||||
|
*/
|
||||||
|
void setTriggerOpcode(unsigned oc) { oc = m_OpcodeTrigger; }
|
||||||
|
/**
|
||||||
|
* Sets the trigger flag.
|
||||||
|
*/
|
||||||
|
void setFlagTriggered(bool flagTriggered) { m_FlagTriggered = flagTriggered; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class GenericTimerEvent
|
||||||
|
* This event type is used to encapsulate timeout-specific data.
|
||||||
|
*/
|
||||||
|
class GenericTimerEvent : public BaseEvent {
|
||||||
|
protected:
|
||||||
|
timer_id_t m_Id; //!< internal timer id (sim-specific)
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new timer event.
|
||||||
|
*/
|
||||||
|
GenericTimerEvent(timer_id_t id = INVALID_TIMER) : m_Id(id) { }
|
||||||
|
~GenericTimerEvent() { }
|
||||||
|
/**
|
||||||
|
* Retrieves the internal timer id. Maybe useful for debug output.
|
||||||
|
* @return the timer id or \c INVALID_TIMER if the timer is invalid
|
||||||
|
*/
|
||||||
|
timer_id_t getId() const { return m_Id; }
|
||||||
|
/**
|
||||||
|
* Sets the internal timer id. This should not be used by the experiment.
|
||||||
|
* @param id the new timer id, given by the underlying simulator-backend
|
||||||
|
*/
|
||||||
|
void setId(timer_id_t id) { m_Id = id; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end-of-namespace: fail
|
||||||
|
|
||||||
|
#endif // __EVENT_HPP__
|
||||||
@ -34,13 +34,13 @@ bool TroubleListener::addWatchNumber(unsigned troubleNumber)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemAccessListener::isMatching(address_t addr, size_t width, accessType_t accesstype) const
|
bool MemAccessListener::isMatching(address_t addr, size_t width,
|
||||||
|
MemAccessEvent::access_type_t accesstype) const
|
||||||
{
|
{
|
||||||
if (!(m_WatchType & accesstype)) {
|
if (!(m_WatchType & accesstype)) {
|
||||||
return false;
|
return false;
|
||||||
} else if (m_WatchAddr != ANY_ADDR
|
} else if (m_WatchAddr != ANY_ADDR
|
||||||
&& (m_WatchAddr >= addr + width
|
&& (m_WatchAddr >= addr + width || m_WatchAddr + m_WatchWidth <= addr)) {
|
||||||
|| m_WatchAddr + m_WatchWidth <= addr)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -9,19 +9,15 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "SALConfig.hpp"
|
#include "SALConfig.hpp"
|
||||||
|
#include "Event.hpp"
|
||||||
|
|
||||||
namespace fail {
|
namespace fail {
|
||||||
|
|
||||||
class ExperimentFlow;
|
class ExperimentFlow;
|
||||||
|
|
||||||
//! address wildcard (e.g. for BPListeners)
|
// FIXME(?): Maybe it suffices to provide a "setEventData" method in order to
|
||||||
const address_t ANY_ADDR = static_cast<address_t>(-1);
|
// set the event data at once. (Consequently, all actual setters for
|
||||||
//! instruction wildcard
|
// attributes of the event-data objects could be removed.)
|
||||||
const unsigned ANY_INSTR = static_cast<unsigned>(-1);
|
|
||||||
//! trap wildcard
|
|
||||||
const unsigned ANY_TRAP = static_cast<unsigned>(-1);
|
|
||||||
//! interrupt wildcard
|
|
||||||
const unsigned ANY_INTERRUPT = static_cast<unsigned>(-1);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class BaseListener
|
* \class BaseListener
|
||||||
@ -115,8 +111,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
class BPListener : virtual public BaseListener {
|
class BPListener : virtual public BaseListener {
|
||||||
private:
|
private:
|
||||||
|
BPEvent m_Data;
|
||||||
address_t m_CR3;
|
address_t m_CR3;
|
||||||
address_t m_TriggerInstrPtr;
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Creates a new breakpoint listener. The range information is specific to
|
* Creates a new breakpoint listener. The range information is specific to
|
||||||
@ -128,7 +124,7 @@ public:
|
|||||||
* in a random address space.
|
* in a random address space.
|
||||||
*/
|
*/
|
||||||
BPListener(address_t address_space = ANY_ADDR)
|
BPListener(address_t address_space = ANY_ADDR)
|
||||||
: m_CR3(address_space), m_TriggerInstrPtr(ANY_ADDR) { }
|
: m_Data(address_space), m_CR3(ANY_ADDR) { }
|
||||||
/**
|
/**
|
||||||
* Returns the address space register of this listener.
|
* Returns the address space register of this listener.
|
||||||
*/
|
*/
|
||||||
@ -148,12 +144,12 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Returns the instruction pointer that triggered this listener.
|
* Returns the instruction pointer that triggered this listener.
|
||||||
*/
|
*/
|
||||||
address_t getTriggerInstructionPointer() const { return m_TriggerInstrPtr; }
|
address_t getTriggerInstructionPointer() const { return m_Data.getTriggerInstructionPointer(); }
|
||||||
/**
|
/**
|
||||||
* Sets the instruction pointer that triggered this listener. Should not
|
* Sets the instruction pointer that triggered this listener. Should not
|
||||||
* be used by experiment code.
|
* be used by experiment code.
|
||||||
*/
|
*/
|
||||||
void setTriggerInstructionPointer(address_t iptr) { m_TriggerInstrPtr = iptr; }
|
void setTriggerInstructionPointer(address_t iptr) { m_Data.setTriggerInstructionPointer(iptr); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -183,14 +179,12 @@ public:
|
|||||||
* @return the instruction pointer specified in the constructor or by
|
* @return the instruction pointer specified in the constructor or by
|
||||||
* calling \c setWatchInstructionPointer()
|
* calling \c setWatchInstructionPointer()
|
||||||
*/
|
*/
|
||||||
address_t getWatchInstructionPointer() const
|
address_t getWatchInstructionPointer() const { return m_WatchInstrPtr; }
|
||||||
{ return m_WatchInstrPtr; }
|
|
||||||
/**
|
/**
|
||||||
* Sets the instruction pointer this listener waits for.
|
* Sets the instruction pointer this listener waits for.
|
||||||
* @param iptr the new instruction ptr to wait for
|
* @param iptr the new instruction ptr to wait for
|
||||||
*/
|
*/
|
||||||
void setWatchInstructionPointer(address_t iptr)
|
void setWatchInstructionPointer(address_t iptr) { m_WatchInstrPtr = iptr; }
|
||||||
{ m_WatchInstrPtr = iptr; }
|
|
||||||
/**
|
/**
|
||||||
* Checks whether a given address is matching.
|
* Checks whether a given address is matching.
|
||||||
* @param addr address to check
|
* @param addr address to check
|
||||||
@ -216,8 +210,7 @@ public:
|
|||||||
* space.
|
* space.
|
||||||
*/
|
*/
|
||||||
BPRangeListener(address_t start = 0, address_t end = 0, address_t address_space = ANY_ADDR)
|
BPRangeListener(address_t start = 0, address_t end = 0, address_t address_space = ANY_ADDR)
|
||||||
: BPListener(address_space), m_WatchStartAddr(start), m_WatchEndAddr(end)
|
: BPListener(address_space), m_WatchStartAddr(start), m_WatchEndAddr(end) { }
|
||||||
{ }
|
|
||||||
/**
|
/**
|
||||||
* Returns the instruction pointer watch range of this listener.
|
* Returns the instruction pointer watch range of this listener.
|
||||||
* @return the listener's range
|
* @return the listener's range
|
||||||
@ -246,13 +239,6 @@ public:
|
|||||||
* Observes memory read/write accesses.
|
* Observes memory read/write accesses.
|
||||||
*/
|
*/
|
||||||
class MemAccessListener : virtual public BaseListener {
|
class MemAccessListener : virtual public BaseListener {
|
||||||
public:
|
|
||||||
enum accessType_t {
|
|
||||||
MEM_UNKNOWN = 0x0,
|
|
||||||
MEM_READ = 0x1,
|
|
||||||
MEM_WRITE = 0x2,
|
|
||||||
MEM_READWRITE = 0x3
|
|
||||||
};
|
|
||||||
private:
|
private:
|
||||||
//! Specific physical guest system address to watch, or ANY_ADDR.
|
//! Specific physical guest system address to watch, or ANY_ADDR.
|
||||||
address_t m_WatchAddr;
|
address_t m_WatchAddr;
|
||||||
@ -262,25 +248,14 @@ private:
|
|||||||
* Memory access type we want to watch
|
* Memory access type we want to watch
|
||||||
* (MEM_READ || MEM_WRITE || MEM_READWRITE).
|
* (MEM_READ || MEM_WRITE || MEM_READWRITE).
|
||||||
*/
|
*/
|
||||||
accessType_t m_WatchType;
|
MemAccessEvent::access_type_t m_WatchType;
|
||||||
//! Specific physical guest system address that actually triggered the listener.
|
MemAccessEvent m_Data;
|
||||||
address_t m_TriggerAddr;
|
|
||||||
//! Width of the memory access (# bytes).
|
|
||||||
size_t m_TriggerWidth;
|
|
||||||
//! Address of the instruction that caused the memory access.
|
|
||||||
address_t m_TriggerIP;
|
|
||||||
//! Memory access type at m_TriggerAddr.
|
|
||||||
accessType_t m_AccessType;
|
|
||||||
public:
|
public:
|
||||||
MemAccessListener(accessType_t watchtype = MEM_READWRITE)
|
MemAccessListener(MemAccessEvent::access_type_t type = MemAccessEvent::MEM_READWRITE)
|
||||||
: m_WatchAddr(ANY_ADDR), m_WatchWidth(1), m_WatchType(watchtype),
|
: m_WatchAddr(ANY_ADDR), m_WatchWidth(1), m_WatchType(type) { }
|
||||||
m_TriggerAddr(ANY_ADDR), m_TriggerIP(ANY_ADDR),
|
MemAccessListener(address_t addr,
|
||||||
m_AccessType(MEM_UNKNOWN) { }
|
MemAccessEvent::access_type_t type = MemAccessEvent::MEM_READWRITE)
|
||||||
MemAccessListener(address_t addr,
|
: m_WatchAddr(addr), m_WatchWidth(1), m_WatchType(type) { }
|
||||||
accessType_t watchtype = MEM_READWRITE)
|
|
||||||
: m_WatchAddr(addr), m_WatchWidth(1), m_WatchType(watchtype),
|
|
||||||
m_TriggerAddr(ANY_ADDR), m_TriggerIP(ANY_ADDR),
|
|
||||||
m_AccessType(MEM_UNKNOWN) { }
|
|
||||||
/**
|
/**
|
||||||
* Returns the physical memory address to be observed.
|
* Returns the physical memory address to be observed.
|
||||||
*/
|
*/
|
||||||
@ -300,51 +275,53 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Checks whether a given physical memory access is matching.
|
* Checks whether a given physical memory access is matching.
|
||||||
*/
|
*/
|
||||||
bool isMatching(address_t addr, size_t width, accessType_t accesstype) const;
|
bool isMatching(address_t addr, size_t width, MemAccessEvent::access_type_t accesstype) const;
|
||||||
/**
|
/**
|
||||||
* Returns the specific physical memory address that actually triggered the
|
* Returns the specific physical memory address that actually triggered the
|
||||||
* listener.
|
* listener.
|
||||||
*/
|
*/
|
||||||
address_t getTriggerAddress() const { return m_TriggerAddr; }
|
address_t getTriggerAddress() const { return m_Data.getTriggerAddress(); }
|
||||||
/**
|
/**
|
||||||
* Sets the specific physical memory address that actually triggered the
|
* Sets the specific physical memory address that actually triggered the
|
||||||
* listener. Should not be used by experiment code.
|
* listener. Should not be used by experiment code.
|
||||||
*/
|
*/
|
||||||
void setTriggerAddress(address_t addr) { m_TriggerAddr = addr; }
|
void setTriggerAddress(address_t addr) { m_Data.setTriggerAddress(addr); }
|
||||||
/**
|
/**
|
||||||
* Returns the width (in bytes) of the memory access that triggered this
|
* Returns the width (in bytes) of the memory access that triggered this
|
||||||
* listener.
|
* listener.
|
||||||
*/
|
*/
|
||||||
size_t getTriggerWidth() const { return m_TriggerWidth; }
|
size_t getTriggerWidth() const { return m_Data.getTriggerWidth(); }
|
||||||
/**
|
/**
|
||||||
* Sets the width (in bytes) of the memory access that triggered this
|
* Sets the width (in bytes) of the memory access that triggered this
|
||||||
* listener. Should not be used by experiment code.
|
* listener. Should not be used by experiment code.
|
||||||
*/
|
*/
|
||||||
void setTriggerWidth(size_t width) { m_TriggerWidth = width; }
|
void setTriggerWidth(size_t width) { m_Data.setTriggerWidth(width); }
|
||||||
/**
|
/**
|
||||||
* Returns the address of the instruction causing this memory access.
|
* Returns the address of the instruction causing this memory access.
|
||||||
*/
|
*/
|
||||||
address_t getTriggerInstructionPointer() const { return m_TriggerIP; }
|
address_t getTriggerInstructionPointer() const { return m_Data.getTriggerInstructionPointer(); }
|
||||||
/**
|
/**
|
||||||
* Sets the address of the instruction causing this memory access. Should
|
* Sets the address of the instruction causing this memory access. Should
|
||||||
* not be used by experiment code.
|
* not be used by experiment code.
|
||||||
*/
|
*/
|
||||||
void setTriggerInstructionPointer(address_t addr) { m_TriggerIP = addr; }
|
void setTriggerInstructionPointer(address_t addr) { m_Data.setTriggerInstructionPointer(addr); }
|
||||||
/**
|
/**
|
||||||
* Returns type (MEM_READ || MEM_WRITE) of the memory access that triggered
|
* Returns type (MEM_READ || MEM_WRITE) of the memory access that triggered
|
||||||
* this listener.
|
* this listener.
|
||||||
*/
|
*/
|
||||||
accessType_t getTriggerAccessType() const { return m_AccessType; }
|
MemAccessEvent::access_type_t getTriggerAccessType() const
|
||||||
|
{ return m_Data.getTriggerAccessType(); }
|
||||||
/**
|
/**
|
||||||
* Sets type of the memory access that triggered this listener. Should not
|
* Sets the type of the memory access that triggered this listener.
|
||||||
* be used by experiment code.
|
* Should not be used by experiment code.
|
||||||
*/
|
*/
|
||||||
void setTriggerAccessType(accessType_t type) { m_AccessType = type; }
|
void setTriggerAccessType(MemAccessEvent::access_type_t type)
|
||||||
|
{ m_Data.setTriggerAccessType(type); }
|
||||||
/**
|
/**
|
||||||
* Returns memory access types (MEM_READ || MEM_WRITE || MEM_READWRITE)
|
* Returns memory access types (MEM_READ || MEM_WRITE || MEM_READWRITE)
|
||||||
* this listener watches. Should not be used by experiment code.
|
* this listener watches. Should not be used by experiment code.
|
||||||
*/
|
*/
|
||||||
accessType_t getWatchAccessType() const { return m_WatchType; }
|
MemAccessEvent::access_type_t getWatchAccessType() const { return m_WatchType; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -354,9 +331,9 @@ public:
|
|||||||
class MemReadListener : virtual public MemAccessListener {
|
class MemReadListener : virtual public MemAccessListener {
|
||||||
public:
|
public:
|
||||||
MemReadListener()
|
MemReadListener()
|
||||||
: MemAccessListener(MEM_READ) { }
|
: MemAccessListener(MemAccessEvent::MEM_READ) { }
|
||||||
MemReadListener(address_t addr)
|
MemReadListener(address_t addr)
|
||||||
: MemAccessListener(addr, MEM_READ) { }
|
: MemAccessListener(addr, MemAccessEvent::MEM_READ) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -366,9 +343,9 @@ public:
|
|||||||
class MemWriteListener : virtual public MemAccessListener {
|
class MemWriteListener : virtual public MemAccessListener {
|
||||||
public:
|
public:
|
||||||
MemWriteListener()
|
MemWriteListener()
|
||||||
: MemAccessListener(MEM_READ) { }
|
: MemAccessListener(MemAccessEvent::MEM_READ) { }
|
||||||
MemWriteListener(address_t addr)
|
MemWriteListener(address_t addr)
|
||||||
: MemAccessListener(addr, MEM_WRITE) { }
|
: MemAccessListener(addr, MemAccessEvent::MEM_WRITE) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -377,23 +354,17 @@ public:
|
|||||||
*/
|
*/
|
||||||
class TroubleListener : virtual public BaseListener {
|
class TroubleListener : virtual public BaseListener {
|
||||||
private:
|
private:
|
||||||
/**
|
TroubleEvent m_Data; //!< event related data, e.g. trap number
|
||||||
* Specific guest system interrupt/trap number that actually
|
|
||||||
* trigger the listener.
|
|
||||||
*/
|
|
||||||
int m_TriggerNumber;
|
|
||||||
/**
|
/**
|
||||||
* Specific guest system interrupt/trap numbers to watch,
|
* Specific guest system interrupt/trap numbers to watch,
|
||||||
* or ANY_INTERRUPT/ANY_TRAP.
|
* or ANY_INTERRUPT/ANY_TRAP.
|
||||||
*/
|
*/
|
||||||
std::vector<unsigned> m_WatchNumbers;
|
std::vector<unsigned> m_WatchNumbers;
|
||||||
public:
|
public:
|
||||||
TroubleListener() : m_TriggerNumber (-1) { }
|
TroubleListener() { }
|
||||||
TroubleListener(unsigned troubleNumber)
|
TroubleListener(unsigned troubleNumber) { addWatchNumber(troubleNumber); }
|
||||||
: m_TriggerNumber(-1)
|
|
||||||
{ addWatchNumber(troubleNumber); }
|
|
||||||
/**
|
/**
|
||||||
* Add an interrupt/trap-number which should be observed
|
* Add an interrupt/trap-number which should be observed.
|
||||||
* @param troubleNumber number of an interrupt or trap
|
* @param troubleNumber number of an interrupt or trap
|
||||||
* @return \c true if number is added to the list \c false if the number
|
* @return \c true if number is added to the list \c false if the number
|
||||||
* was already in the list
|
* was already in the list
|
||||||
@ -401,14 +372,14 @@ public:
|
|||||||
bool addWatchNumber(unsigned troubleNumber);
|
bool addWatchNumber(unsigned troubleNumber);
|
||||||
/**
|
/**
|
||||||
* Remove an interrupt/trap-number which is in the list of observed
|
* Remove an interrupt/trap-number which is in the list of observed
|
||||||
* numbers
|
* numbers.
|
||||||
* @param troubleNumber number of an interrupt or trap
|
* @param troubleNumber number of an interrupt or trap
|
||||||
* @return \c true if the number was found and removed \c false if the
|
* @return \c true if the number was found and removed \c false if the
|
||||||
* number was not in the list
|
* number was not in the list
|
||||||
*/
|
*/
|
||||||
bool removeWatchNumber(unsigned troubleNum);
|
bool removeWatchNumber(unsigned troubleNum);
|
||||||
/**
|
/**
|
||||||
* Returns the list of observed numbers
|
* Returns the list of observed numbers.
|
||||||
* @return a copy of the list which contains all observed numbers
|
* @return a copy of the list which contains all observed numbers
|
||||||
*/
|
*/
|
||||||
std::vector<unsigned> getWatchNumbers() { return m_WatchNumbers; }
|
std::vector<unsigned> getWatchNumbers() { return m_WatchNumbers; }
|
||||||
@ -420,13 +391,12 @@ public:
|
|||||||
* Sets the specific interrupt-/trap-number that actually triggered
|
* Sets the specific interrupt-/trap-number that actually triggered
|
||||||
* the listener. Should not be used by experiment code.
|
* the listener. Should not be used by experiment code.
|
||||||
*/
|
*/
|
||||||
void setTriggerNumber(unsigned troubleNum)
|
void setTriggerNumber(unsigned troubleNum) { m_Data.setTriggerNumber(troubleNum); }
|
||||||
{ m_TriggerNumber = troubleNum; }
|
|
||||||
/**
|
/**
|
||||||
* Returns the specific interrupt-/trap-number that actually triggered
|
* Returns the specific interrupt-/trap-number that actually triggered
|
||||||
* the listener.
|
* the listener.
|
||||||
*/
|
*/
|
||||||
unsigned getTriggerNumber() { return m_TriggerNumber; }
|
unsigned getTriggerNumber() const { return m_Data.getTriggerNumber(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -435,19 +405,18 @@ public:
|
|||||||
*/
|
*/
|
||||||
class InterruptListener : virtual public TroubleListener {
|
class InterruptListener : virtual public TroubleListener {
|
||||||
private:
|
private:
|
||||||
bool m_IsNMI; //!< non maskable interrupt flag
|
InterruptEvent m_Data; //!< event related data, e.g. NMI flag
|
||||||
public:
|
public:
|
||||||
InterruptListener() : m_IsNMI(false) { }
|
InterruptListener() { }
|
||||||
InterruptListener(unsigned interrupt) : m_IsNMI(false)
|
InterruptListener(unsigned interrupt) { addWatchNumber(interrupt); }
|
||||||
{ addWatchNumber(interrupt); }
|
|
||||||
/**
|
/**
|
||||||
* Returns \c true if the interrupt is non maskable, \c false otherwise.
|
* Returns \c true if the interrupt is non maskable, \c false otherwise.
|
||||||
*/
|
*/
|
||||||
bool isNMI() { return m_IsNMI; }
|
bool isNMI() { return m_Data.isNMI(); }
|
||||||
/**
|
/**
|
||||||
* Sets the interrupt type (non maskable or not).
|
* Sets the interrupt type (non maskable or not).
|
||||||
*/
|
*/
|
||||||
void setNMI(bool enabled) { m_IsNMI = enabled; }
|
void setNMI(bool enabled) { m_Data.setNMI(enabled); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -464,28 +433,30 @@ public:
|
|||||||
* \class GuestListener
|
* \class GuestListener
|
||||||
* Used to receive data from the guest system.
|
* Used to receive data from the guest system.
|
||||||
*/
|
*/
|
||||||
|
// FIXME: This is not a "clean design" ... IOPortListener looks much like a copy of this class.
|
||||||
|
// Additionaly, the port is fixed (at least in Bochs) but can be modified using setPort
|
||||||
|
// (effectless for now).
|
||||||
class GuestListener : virtual public BaseListener {
|
class GuestListener : virtual public BaseListener {
|
||||||
private:
|
private:
|
||||||
char m_Data;
|
GuestEvent m_Data;
|
||||||
unsigned m_Port;
|
|
||||||
public:
|
public:
|
||||||
GuestListener() : m_Data(0), m_Port(0) { }
|
GuestListener() { }
|
||||||
/**
|
/**
|
||||||
* Returns the data, transmitted by the guest system.
|
* Returns the data, transmitted by the guest system.
|
||||||
*/
|
*/
|
||||||
char getData() const { return m_Data; }
|
char getData() const { return m_Data.getData(); }
|
||||||
/**
|
/**
|
||||||
* Sets the data which had been transmitted by the guest system.
|
* Sets the data which had been transmitted by the guest system.
|
||||||
*/
|
*/
|
||||||
void setData(char data) { m_Data = data; }
|
void setData(char data) { m_Data.setData(data); }
|
||||||
/**
|
/**
|
||||||
* Returns the data length, transmitted by the guest system.
|
* Returns the data length, transmitted by the guest system.
|
||||||
*/
|
*/
|
||||||
unsigned getPort() const { return m_Port; }
|
unsigned getPort() const { return m_Data.getPort(); }
|
||||||
/**
|
/**
|
||||||
* Sets the data length which had been transmitted by the guest system.
|
* Sets the data length which had been transmitted by the guest system.
|
||||||
*/
|
*/
|
||||||
void setPort(unsigned port) { m_Port = port; }
|
void setPort(unsigned port) { m_Data.setPort(port); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -494,27 +465,27 @@ public:
|
|||||||
*/
|
*/
|
||||||
class IOPortListener : virtual public BaseListener {
|
class IOPortListener : virtual public BaseListener {
|
||||||
private:
|
private:
|
||||||
unsigned char m_Data;
|
IOPortEvent m_Data;
|
||||||
unsigned m_Port;
|
unsigned m_Port;
|
||||||
bool m_Out;
|
bool m_Out;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Initialises an IOPortListener
|
* Initialises an IOPortListener
|
||||||
*
|
*
|
||||||
* @param port the port the listener ist listening on
|
* @param port the port the listener is listening on
|
||||||
* @param out Defines the direction of the listener.
|
* @param out Defines the direction of the listener.
|
||||||
* \arg \c true Output on the given port is captured.
|
* \arg \c true Output on the given port is captured.
|
||||||
* \arg \c false Input on the given port is captured.
|
* \arg \c false Input on the given port is captured.
|
||||||
*/
|
*/
|
||||||
IOPortListener(unsigned port, bool out) : m_Data(0), m_Port(port), m_Out(out) { }
|
IOPortListener(unsigned port, bool out) : m_Port(port), m_Out(out) { }
|
||||||
/**
|
/**
|
||||||
* Returns the data sent to the specified port
|
* Returns the data sent to the specified port
|
||||||
*/
|
*/
|
||||||
unsigned char getData() const { return m_Data; }
|
unsigned char getData() const { return m_Data.getData(); }
|
||||||
/**
|
/**
|
||||||
* Sets the data which had been transmitted.
|
* Sets the data which had been transmitted.
|
||||||
*/
|
*/
|
||||||
void setData(unsigned char data) { m_Data = data; }
|
void setData(unsigned char data) { m_Data.setData(data); }
|
||||||
/**
|
/**
|
||||||
* Retrieves the port which this listener is bound to.
|
* Retrieves the port which this listener is bound to.
|
||||||
*/
|
*/
|
||||||
@ -528,13 +499,14 @@ public:
|
|||||||
* @param p The port number an I/O listener occured on
|
* @param p The port number an I/O listener occured on
|
||||||
* @param out True if the communication was outbound, false otherwise
|
* @param out True if the communication was outbound, false otherwise
|
||||||
*/
|
*/
|
||||||
bool isMatching(unsigned p, bool out) const { return ( out = isOutListener() && p == getPort()); }
|
bool isMatching(unsigned p, bool out) const { return out = isOutListener() && p == getPort(); }
|
||||||
/**
|
/**
|
||||||
* Tells you if this listener is capturing outbound communication (inbound if false)
|
* Tells you if this listener is capturing outbound communication (inbound if false)
|
||||||
*/
|
*/
|
||||||
bool isOutListener() const { return m_Out; }
|
bool isOutListener() const { return m_Out; }
|
||||||
/**
|
/**
|
||||||
* Change the listener direction.
|
* Change the listener direction.
|
||||||
|
* @param out direction flag
|
||||||
* \arg \c true Output on the given port is captured.
|
* \arg \c true Output on the given port is captured.
|
||||||
* \arg \c false Input on the given port is captured.
|
* \arg \c false Input on the given port is captured.
|
||||||
*/
|
*/
|
||||||
@ -547,56 +519,52 @@ public:
|
|||||||
*/
|
*/
|
||||||
class JumpListener : virtual public BaseListener {
|
class JumpListener : virtual public BaseListener {
|
||||||
private:
|
private:
|
||||||
unsigned m_Opcode;
|
JumpEvent m_Data;
|
||||||
bool m_FlagTriggered;
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructs a new listener object.
|
* Constructs a new listener object.
|
||||||
* @param parent the parent object
|
|
||||||
* @param opcode the opcode of the jump-instruction to be observed
|
* @param opcode the opcode of the jump-instruction to be observed
|
||||||
* or ANY_INSTR to match all jump-instructions
|
* or \c ANY_INSTR to match all jump-instructions
|
||||||
*/
|
*/
|
||||||
JumpListener(unsigned opcode = ANY_INSTR)
|
JumpListener(unsigned opcode = ANY_INSTR) : m_Data(opcode) { }
|
||||||
: m_Opcode(opcode), m_FlagTriggered(false) { }
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the opcode of the jump-instruction.
|
* Retrieves the opcode of the jump-instruction.
|
||||||
*/
|
*/
|
||||||
unsigned getOpcode() const { return m_Opcode; }
|
unsigned getOpcode() const { return m_Data.getTriggerOpcode(); }
|
||||||
/**
|
/**
|
||||||
* Returns \c true, if the listener was triggered due to specific register
|
* Returns \c true, if the listener was triggered due to specific register
|
||||||
* content, \c false otherwise.
|
* content, \c false otherwise.
|
||||||
*/
|
*/
|
||||||
bool isRegisterTriggered() { return !m_FlagTriggered; }
|
bool isRegisterTriggered() const { return m_Data.isRegisterTriggered(); }
|
||||||
/**
|
/**
|
||||||
* Returns \c true, of the listener was triggered due to specific FLAG
|
* Returns \c true, of the listener was triggered due to specific FLAG
|
||||||
* state, \c false otherwise. This is the common case.
|
* state, \c false otherwise. This is the common case.
|
||||||
*/
|
*/
|
||||||
bool isFlagTriggered() { return m_FlagTriggered; }
|
bool isFlagTriggered() const { return m_Data.isFlagTriggered(); }
|
||||||
/**
|
/**
|
||||||
* Sets the requestet jump-instruction opcode.
|
* Sets the requestet jump-instruction opcode.
|
||||||
*/
|
*/
|
||||||
void setOpcode(unsigned oc) { oc = m_Opcode; }
|
void setOpcode(unsigned oc) { m_Data.setTriggerOpcode(oc); }
|
||||||
/**
|
/**
|
||||||
* Sets the trigger flag.
|
* Sets the trigger flag.
|
||||||
*/
|
*/
|
||||||
void setFlagTriggered(bool flagTriggered) { m_FlagTriggered = flagTriggered; }
|
void setFlagTriggered(bool flagTriggered) { m_Data.setFlagTriggered(flagTriggered); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class GenericTimerListener
|
* \class GenericTimerListener
|
||||||
* This listener type is used to create timeouts within in an experiment.
|
* This listener type is used to create timeouts within in an experiment.
|
||||||
*
|
*
|
||||||
* Depending on your simulator backend, a concrete class needs to be derived
|
* Depending on your simulator backend, a concrete class needs to be derived from
|
||||||
* from \c GenericTimerListener. \c onListenerAddition should be used to register and
|
* \c GenericTimerListener. \c onAddition should be used to register and \c onDeletion
|
||||||
* \c onListenerDeletion to unregister the timer. \c onListenerTrigger can be used to
|
* to unregister the timer. \c onTrigger can be used to re-register the timer if a
|
||||||
* re-register the timer if a repetitive timer is requested and the back-
|
* repetitive timer is requested and the back-end doesn't support such timer types
|
||||||
* end doesn't support such timer types natively.
|
* natively.
|
||||||
*/
|
*/
|
||||||
class GenericTimerListener : public BaseListener {
|
class GenericTimerListener : public BaseListener {
|
||||||
protected:
|
protected:
|
||||||
unsigned m_Timeout; //!< timeout interval in milliseconds
|
unsigned m_Timeout; //!< timeout interval in milliseconds
|
||||||
timer_id_t m_Id; //!< internal timer id (sim-specific)
|
GenericTimerEvent m_Data;
|
||||||
bool m_Once; //!< \c true, if the timer should be triggered only once, \c false otherwise
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Creates a new timer listener. This can be used to implement a timeout-
|
* Creates a new timer listener. This can be used to implement a timeout-
|
||||||
@ -605,19 +573,18 @@ public:
|
|||||||
* @param timeout the time intervall in milliseconds (ms)
|
* @param timeout the time intervall in milliseconds (ms)
|
||||||
* @see SimulatorController::addListener
|
* @see SimulatorController::addListener
|
||||||
*/
|
*/
|
||||||
GenericTimerListener(unsigned timeout)
|
GenericTimerListener(unsigned timeout) : m_Timeout(timeout) { }
|
||||||
: m_Timeout(timeout), m_Id(-1) { }
|
|
||||||
~GenericTimerListener() { }
|
~GenericTimerListener() { }
|
||||||
/**
|
/**
|
||||||
* Retrieves the internal timer id. Maybe useful for debug output.
|
* Retrieves the internal timer id. Maybe useful for debug output.
|
||||||
* @return the timer id
|
* @return the timer id
|
||||||
*/
|
*/
|
||||||
timer_id_t getId() const { return m_Id; }
|
timer_id_t getId() const { return m_Data.getId(); }
|
||||||
/**
|
/**
|
||||||
* Sets the internal timer id. This should not be used by the experiment.
|
* Sets the internal timer id. This should not be used by the experiment.
|
||||||
* @param id the new timer id, given by the underlying simulator-backend
|
* @param id the new timer id, given by the underlying simulator-backend
|
||||||
*/
|
*/
|
||||||
void setId(timer_id_t id) { m_Id = id; }
|
void setId(timer_id_t id) { m_Data.setId(id); }
|
||||||
/**
|
/**
|
||||||
* Retrieves the timer's timeout value.
|
* Retrieves the timer's timeout value.
|
||||||
* @return the timout in milliseconds
|
* @return the timout in milliseconds
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
#include "Memory.hpp"
|
|
||||||
|
|
||||||
namespace fail {
|
|
||||||
|
|
||||||
const guest_address_t ADDR_INV = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
12
src/core/sal/SALConfig.cc
Normal file
12
src/core/sal/SALConfig.cc
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include "SALConfig.hpp"
|
||||||
|
|
||||||
|
namespace fail {
|
||||||
|
|
||||||
|
const address_t ADDR_INV = static_cast<address_t> (0);
|
||||||
|
const address_t ANY_ADDR = static_cast<address_t> (-1);
|
||||||
|
const unsigned ANY_INSTR = static_cast<unsigned> (-1);
|
||||||
|
const unsigned ANY_TRAP = static_cast<unsigned> (-1);
|
||||||
|
const unsigned ANY_INTERRUPT = static_cast<unsigned> (-1);
|
||||||
|
const timer_id_t INVALID_TIMER = static_cast<timer_id_t> (-1);
|
||||||
|
|
||||||
|
} // end-of-namespace: fail
|
||||||
@ -24,7 +24,22 @@ typedef uint32_t regwidth_t; //!< type of register width [bits]
|
|||||||
typedef register_data_t regdata_t; //!< type of register data
|
typedef register_data_t regdata_t; //!< type of register data
|
||||||
typedef timer_t timer_id_t; //!< type of timer IDs
|
typedef timer_t timer_id_t; //!< type of timer IDs
|
||||||
|
|
||||||
extern const address_t ADDR_INV; //!< invalid address flag (defined in Memory.cc)
|
// The following flags are defined in SALConfig.cc.
|
||||||
|
|
||||||
|
// FIXME: The flags should be initialized based on simulator-specific values!
|
||||||
|
|
||||||
|
//! invalid address flag (e.g. for memory address ptrs)
|
||||||
|
extern const address_t ADDR_INV;
|
||||||
|
//! address wildcard (e.g. for breakpoint listeners)
|
||||||
|
extern const address_t ANY_ADDR;
|
||||||
|
//! instruction wildcard (e.g. for jump listeners)
|
||||||
|
extern const unsigned ANY_INSTR;
|
||||||
|
//! trap wildcard
|
||||||
|
extern const unsigned ANY_TRAP;
|
||||||
|
//! interrupt wildcard
|
||||||
|
extern const unsigned ANY_INTERRUPT;
|
||||||
|
//! invalid timer id (e.g. for timer listeners)
|
||||||
|
extern const timer_id_t INVALID_TIMER;
|
||||||
|
|
||||||
} // end-of-namespace: fail
|
} // end-of-namespace: fail
|
||||||
|
|
||||||
|
|||||||
@ -75,9 +75,9 @@ void SimulatorController::onMemoryAccess(address_t addr, size_t len,
|
|||||||
bool is_write, address_t instrPtr)
|
bool is_write, address_t instrPtr)
|
||||||
{
|
{
|
||||||
// FIXME: Improve performance!
|
// FIXME: Improve performance!
|
||||||
MemAccessListener::accessType_t accesstype =
|
MemAccessEvent::access_type_t accesstype =
|
||||||
is_write ? MemAccessListener::MEM_WRITE
|
is_write ? MemAccessEvent::MEM_WRITE
|
||||||
: MemAccessListener::MEM_READ;
|
: MemAccessEvent::MEM_READ;
|
||||||
|
|
||||||
ListenerManager::iterator it = m_LstList.begin();
|
ListenerManager::iterator it = m_LstList.begin();
|
||||||
while (it != m_LstList.end()) { // check for active events
|
while (it != m_LstList.end()) { // check for active events
|
||||||
|
|||||||
Reference in New Issue
Block a user