diff --git a/src/core/sal/CMakeLists.txt b/src/core/sal/CMakeLists.txt index c46062d0..3e4ebc22 100644 --- a/src/core/sal/CMakeLists.txt +++ b/src/core/sal/CMakeLists.txt @@ -7,6 +7,7 @@ if(BUILD_BOCHS) SimulatorController.cc perf/BreakpointBuffer.cc bochs/BochsController.cc + bochs/BochsListener.cc ) elseif(BUILD_GEM5) set(SRCS diff --git a/src/core/sal/bochs/BochsController.cc b/src/core/sal/bochs/BochsController.cc index b3db42f5..d1c83a93 100644 --- a/src/core/sal/bochs/BochsController.cc +++ b/src/core/sal/bochs/BochsController.cc @@ -125,6 +125,22 @@ void BochsController::updateBPEventInfo(BX_CPU_C *context, bxInstruction_c *inst m_CurrentInstruction = instr; } +void BochsController::onTimerTrigger(void* thisPtr) +{ + // FIXME: The timer logic can be modified to use only one timer in Bochs. + // (For now, this suffices.) + TimerListener* pli = static_cast(thisPtr); + // Check for a matching TimerListener. (In fact, we are only + // interessted in the iterator pointing at pli.) + ListenerManager::iterator it = std::find(simulator.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). + simulator.m_LstList.makeActive(it); + simulator.m_LstList.triggerActiveListeners(); +} + void BochsController::onIOPort(unsigned char data, unsigned port, bool out) { // Check for active IOPortListeners: ListenerManager::iterator it = m_LstList.begin(); diff --git a/src/core/sal/bochs/BochsController.hpp b/src/core/sal/bochs/BochsController.hpp index 8aa1383b..46263e55 100644 --- a/src/core/sal/bochs/BochsController.hpp +++ b/src/core/sal/bochs/BochsController.hpp @@ -64,6 +64,23 @@ public: * @param out true if the I/O traffic has been outbound, false otherwise */ void onIOPort(unsigned char data, unsigned port, bool out); + /** + * Internal handler for TimerListeners. This method is called when a previously + * registered (Bochs) timer triggers. It searches for the provided TimerListener + * object within the ListenerManager and fires such an event by calling + * \c triggerActiveListeners(). + * @param thisPtr a pointer to the TimerListener-object triggered + * + * FIXME: Due to Bochs internal timer and ips-configuration related stuff, + * the simulator sometimes panics with "keyboard error:21" (see line + * 1777 in bios/rombios.c, function keyboard_init()) if a TimerListener + * is added *before* the bios has been loaded and initialized. To + * reproduce this error, try adding a \c TimerListener as the initial step + * in your experiment code and wait for it (\c addListenerAndResume()). + * This leads to the consequence that timers cannot be added/enabled at + * boot time. + */ + void onTimerTrigger(void *thisPtr); /* ******************************************************************** * Simulator Controller & Access API: * ********************************************************************/ diff --git a/src/core/sal/bochs/BochsListener.cc b/src/core/sal/bochs/BochsListener.cc index 6a68f2b0..46c71f47 100644 --- a/src/core/sal/bochs/BochsListener.cc +++ b/src/core/sal/bochs/BochsListener.cc @@ -1,23 +1,11 @@ #include "BochsListener.hpp" -#include "../Listener.hpp" -#include "../ListenerManager.hpp" +#include "../SALInst.hpp" namespace fail { void onTimerTrigger(void* thisPtr) { - // FIXME: The timer logic can be modified to use only one timer in Bochs. - // (For now, this suffices.) - TimerListener* pli = static_cast(thisPtr); - // Check for a matching TimerListener. (In fact, we are only - // interessted in the iterator pointing at pli.) - ListenerManager::iterator it = std::find(simulator.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). - simulator.m_LstList.makeActive(it); - simulator.m_LstList.triggerActiveListeners(); + simulator.onTimerTrigger(thisPtr); } } // end-of-namespace: fail diff --git a/src/core/sal/bochs/BochsListener.hpp b/src/core/sal/bochs/BochsListener.hpp index 81f217ad..f08a3298 100644 --- a/src/core/sal/bochs/BochsListener.hpp +++ b/src/core/sal/bochs/BochsListener.hpp @@ -4,20 +4,8 @@ namespace fail { /** - * Static internal handler for TimerListeners. This static function is - * called when a previously registered (Bochs) timer triggers. This function - * searches for the provided TimerListener object within the ListenerManager and - * fires such an event by calling \c triggerActiveListeners(). - * @param thisPtr a pointer to the TimerListener-object triggered - * - * FIXME: Due to Bochs internal timer and ips-configuration related stuff, - * the simulator sometimes panics with "keyboard error:21" (see line - * 1777 in bios/rombios.c, function keyboard_init()) if a TimerListener - * is added *before* the bios has been loaded and initialized. To - * reproduce this error, try adding a \c TimerListener as the initial step - * in your experiment code and wait for it (\c addListenerAndResume()). - * This leads to the consequence that timers cannot be added/enabled at - * boot time. + * Global internal handler for (Bochs) TimerListeners. The function just calls + * BochsController::onTimerTrigger(). */ void onTimerTrigger(void *thisPtr);