qemu: TimerListeners
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1639 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
@ -7,6 +7,6 @@ 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);
|
||||
const timer_id_t INVALID_TIMER = static_cast<timer_id_t> (0);
|
||||
|
||||
} // end-of-namespace: fail
|
||||
|
||||
@ -8,12 +8,14 @@
|
||||
|
||||
// FIXME: qemu/targphys.h defines address types (but relies on a global preprocessor macro)
|
||||
|
||||
struct QEMUTimer;
|
||||
|
||||
namespace fail {
|
||||
|
||||
typedef uint64_t guest_address_t; //!< the guest memory address type
|
||||
typedef unsigned char* host_address_t; //!< the host memory address type
|
||||
typedef uint64_t register_data_t; //!< register data type (64 bit)
|
||||
typedef int timer_t; //!< type of timer IDs
|
||||
typedef QEMUTimer* timer_t; //!< type of timer IDs
|
||||
|
||||
} // end-of-namespace: fail
|
||||
|
||||
|
||||
@ -40,4 +40,20 @@ void QEMUController::onIOPort(unsigned char data, unsigned port, bool out) {
|
||||
m_LstList.triggerActiveListeners();
|
||||
}
|
||||
|
||||
void QEMUController::onTimerTrigger(TimerListener *pli)
|
||||
{
|
||||
// FIXME: The timer logic can be modified to use only one timer in QEMU.
|
||||
// (For now, this suffices.)
|
||||
|
||||
// Check for a matching TimerListener. (In fact, we are only
|
||||
// interessted in the iterator pointing at pli.)
|
||||
ListenerManager::iterator it = std::find(m_LstList.begin(),
|
||||
simulator.m_LstList.end(), pli);
|
||||
// TODO: This has O(|m_LstList|) time complexity. We can further improve this
|
||||
// by creating a method such that makeActive(pli) works as well,
|
||||
// reducing the time complexity to O(1).
|
||||
m_LstList.makeActive(it);
|
||||
m_LstList.triggerActiveListeners();
|
||||
}
|
||||
|
||||
} // end-of-namespace: fail
|
||||
|
||||
@ -38,9 +38,9 @@ public:
|
||||
*/
|
||||
void onIOPort(unsigned char data, unsigned port, bool out);
|
||||
/**
|
||||
* Static internal handler for TimerListeners. TODO.
|
||||
* Internal handler for TimerListeners.
|
||||
*/
|
||||
static void onTimerTrigger(void *thisPtr) {}
|
||||
void onTimerTrigger(TimerListener *pli);
|
||||
/* ********************************************************************
|
||||
* Simulator Controller & Access API:
|
||||
* ********************************************************************/
|
||||
|
||||
@ -25,4 +25,21 @@ void QEMUMemWriteListener::onDeletion()
|
||||
failqemu_remove_watchpoint(simulator.m_cpuenv, m_WatchAddr, m_WatchWidth, 1);
|
||||
}
|
||||
|
||||
bool QEMUTimerListener::onAddition()
|
||||
{
|
||||
//std::cout << "QEMUTimerListener::onAddition" << std::endl;
|
||||
setId(failqemu_register_timer(getTimeout(), (void *)this));
|
||||
//std::cout << "this = " << std::hex << (unsigned) this << std::endl;
|
||||
//std::cout << "id = " << std::hex << (unsigned) getId() << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void QEMUTimerListener::onDeletion()
|
||||
{
|
||||
//std::cout << "QEMUTimerListener::onDeletion" << std::endl;
|
||||
//std::cout << "this = " << std::hex << (unsigned) this << std::endl;
|
||||
//std::cout << "id = " << std::hex << (unsigned) getId() << std::endl;
|
||||
failqemu_unregister_timer(getId());
|
||||
}
|
||||
|
||||
} // end-of-namespace: fail
|
||||
|
||||
@ -8,14 +8,19 @@ namespace fail {
|
||||
typedef GenericBPSingleListener BPSingleListener;
|
||||
|
||||
/**
|
||||
* \class TimerListener
|
||||
* \class QEMUTimerListener
|
||||
* Concrete TimerListener implementation of GenericTimerListener for QEMU.
|
||||
*/
|
||||
class TimerListener : public GenericTimerListener {
|
||||
class QEMUTimerListener : public GenericTimerListener {
|
||||
private:
|
||||
public:
|
||||
// TODO
|
||||
QEMUTimerListener(unsigned timeout)
|
||||
: GenericTimerListener(timeout) { }
|
||||
~QEMUTimerListener() { onDeletion(); } // FIXME ~BaseListener should automatically dequeue a Listener, and then indirectly calls onDeletion. In the current implementation, no dequeueing happens at all.
|
||||
bool onAddition();
|
||||
void onDeletion();
|
||||
};
|
||||
typedef QEMUTimerListener TimerListener;
|
||||
|
||||
class QEMUMemWriteListener : public GenericMemWriteListener {
|
||||
public:
|
||||
|
||||
@ -29,4 +29,10 @@ void fail_io(int port, int width, int32_t data, int is_write)
|
||||
fail::simulator.onIOPort((unsigned char)data, port, is_write == 1);
|
||||
}
|
||||
|
||||
void fail_timer_callback(void *opaque)
|
||||
{
|
||||
fail::TimerListener *l = static_cast<fail::TimerListener *>(opaque);
|
||||
fail::simulator.onTimerTrigger(l);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user