1 //////////////////////////////////////////////////////////////////////// 2 // $Id: virt_timer.h 14109 2021-01-30 23:55:24Z vruppert $ 3 ///////////////////////////////////////////////////////////////////////// 4 // 5 // Copyright (C) 2002-2021 The Bochs Project 6 // 7 // This library is free software; you can redistribute it and/or 8 // modify it under the terms of the GNU Lesser General Public 9 // License as published by the Free Software Foundation; either 10 // version 2 of the License, or (at your option) any later version. 11 // 12 // This library is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 // Lesser General Public License for more details. 16 // 17 // You should have received a copy of the GNU Lesser General Public 18 // License along with this library; if not, write to the Free Software 19 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 ///////////////////////////////////////////////////////////////////////// 21 22 #ifndef _BX_VIRT_TIMER_H 23 #define _BX_VIRT_TIMER_H 24 25 #include "pc_system.h" 26 27 // should be adjusted if want to support more SMP processors 28 #define BX_MAX_VIRTUAL_TIMERS (32) 29 30 #define BX_MAX_VIRTUAL_TIME (0x7fffffff) 31 32 class BOCHSAPI bx_virt_timer_c : public logfunctions { 33 private: 34 35 struct { 36 bool inUse; // Timer slot is in-use (currently registered). 37 Bit64u period; // Timer periodocity in virtual useconds. 38 Bit64u timeToFire; // Time to fire next (in virtual useconds). 39 bool active; // 0=inactive, 1=active. 40 bool continuous; // 0=one-shot timer, 1=continuous periodicity. 41 bool realtime; // 0=standard timer, 1=use realtime mode 42 bx_timer_handler_t funct; // A callback function for when the 43 // timer fires. 44 // This function MUST return. 45 void *this_ptr; // The this-> pointer for C++ callbacks 46 // has to be stored as well. 47 char id[BxMaxTimerIDLen]; // String ID of timer. 48 } timer[BX_MAX_VIRTUAL_TIMERS]; 49 50 unsigned numTimers; // Number of currently allocated timers. 51 52 struct { 53 //Variables for the timer subsystem: 54 Bit64u current_timers_time; 55 Bit64u timers_next_event_time; 56 Bit64u last_sequential_time; 57 58 //Variables for the time sync subsystem: 59 Bit64u virtual_next_event_time; 60 Bit64u current_virtual_time; 61 62 int system_timer_id; 63 } s[2]; 64 65 bool in_timer_handler; 66 67 // Local copy of IPS value 68 Bit64u ips; 69 70 bool init_done; 71 72 //Real time variables: 73 Bit64u last_real_time; 74 Bit64u total_real_usec; 75 Bit64u last_realtime_delta; 76 Bit64u real_time_delay; 77 //System time variables: 78 Bit64u last_usec; 79 Bit64u usec_per_second; 80 Bit64u stored_delta; 81 Bit64u last_system_usec; 82 Bit64u em_last_realtime; 83 //Virtual timer variables: 84 Bit64u total_ticks; 85 Bit64u last_realtime_ticks; 86 Bit64u ticks_per_second; 87 88 // A special null timer is always inserted in the timer[0] slot. This 89 // make sure that at least one timer is always active, and that the 90 // duration is always less than a maximum 32-bit integer, so a 32-bit 91 // counter can be used for the current countdown. 92 static const Bit64u NullTimerInterval; 93 static void nullTimer(void* this_ptr); 94 95 //Step the given number of cycles, optionally calling any timer handlers. 96 void periodic(Bit64u time_passed, bool mode); 97 98 //Called when next_event_time changes. 99 void next_event_time_update(bool mode); 100 101 //Called to advance the virtual time. 102 // calls periodic as needed. 103 void advance_virtual_time(Bit64u time_passed, bool mode); 104 105 public: 106 107 bx_virt_timer_c(); ~bx_virt_timer_c()108 virtual ~bx_virt_timer_c() {} 109 110 //Get the current virtual time. 111 // This may return the same value on subsequent calls. 112 Bit64u time_usec(bool mode); 113 114 //Get the current virtual time. 115 // This will return a monotonically increasing value. 116 // MUST NOT be called from within a timer handler. 117 Bit64u time_usec_sequential(bool mode); 118 119 //Register a timer handler to go off after a given interval. 120 //Register a timer handler to go off with a periodic interval. 121 int register_timer(void *this_ptr, bx_timer_handler_t handler, 122 Bit32u useconds, bool continuous, 123 bool active, bool realtime, const char *id); 124 125 //unregister a previously registered timer. 126 bool unregisterTimer(unsigned timerID); 127 128 void start_timers(void); 129 130 //activate a deactivated but registered timer. 131 void activate_timer(unsigned timer_index, Bit32u useconds, 132 bool continuous); 133 134 //deactivate (but don't unregister) a currently registered timer. 135 void deactivate_timer(unsigned timer_index); 136 137 138 //Timer handlers passed to pc_system 139 static void pc_system_timer_handler_0(void* this_ptr); 140 static void pc_system_timer_handler_1(void* this_ptr); 141 142 //The real timer handler. 143 void timer_handler(bool mode); 144 145 //Initialization step #1 in constructor and for cleanup 146 void setup(void); 147 148 //Initialization step #2 149 void init(void); 150 151 void register_state(void); 152 153 //Determine the real time elapsed during runtime config or between save and 154 //restore. 155 void set_realtime_delay(void); 156 }; 157 158 BOCHSAPI extern bx_virt_timer_c bx_virt_timer; 159 160 #endif // _BX_VIRT_TIMER_H 161