| 1 | /* |
| 2 | * General purpose implementation of a simple periodic countdown timer. |
| 3 | * |
| 4 | * Copyright (c) 2007 CodeSourcery. |
| 5 | * |
| 6 | * This code is licensed under the GNU LGPL. |
| 7 | */ |
| 8 | #ifndef PTIMER_H |
| 9 | #define PTIMER_H |
| 10 | |
| 11 | #include "qemu/timer.h" |
| 12 | |
| 13 | /* |
| 14 | * The ptimer API implements a simple periodic countdown timer. |
| 15 | * The countdown timer has a value (which can be read and written via |
| 16 | * ptimer_get_count() and ptimer_set_count()). When it is enabled |
| 17 | * using ptimer_run(), the value will count downwards at the frequency |
| 18 | * which has been configured using ptimer_set_period() or ptimer_set_freq(). |
| 19 | * When it reaches zero it will trigger a callback function, and |
| 20 | * can be set to either reload itself from a specified limit value |
| 21 | * and keep counting down, or to stop (as a one-shot timer). |
| 22 | * |
| 23 | * A transaction-based API is used for modifying ptimer state: all calls |
| 24 | * to functions which modify ptimer state must be between matched calls to |
| 25 | * ptimer_transaction_begin() and ptimer_transaction_commit(). |
| 26 | * When ptimer_transaction_commit() is called it will evaluate the state |
| 27 | * of the timer after all the changes in the transaction, and call the |
| 28 | * callback if necessary. (See the ptimer_init() documentation for the full |
| 29 | * list of state-modifying functions and detailed semantics of the callback.) |
| 30 | * |
| 31 | * Forgetting to set the period/frequency (or setting it to zero) is a |
| 32 | * bug in the QEMU device and will cause warning messages to be printed |
| 33 | * to stderr when the guest attempts to enable the timer. |
| 34 | */ |
| 35 | |
| 36 | /* |
| 37 | * The 'legacy' ptimer policy retains backward compatibility with the |
| 38 | * traditional ptimer behaviour from before policy flags were introduced. |
| 39 | * It has several weird behaviours which don't match typical hardware |
| 40 | * timer behaviour. For a new device using ptimers, you should not |
| 41 | * use PTIMER_POLICY_LEGACY, but instead check the actual behaviour |
| 42 | * that you need and specify the right set of policy flags to get that. |
| 43 | * |
| 44 | * If you are overhauling an existing device that uses PTIMER_POLICY_LEGACY |
| 45 | * and are in a position to check or test the real hardware behaviour, |
| 46 | * consider updating it to specify the right policy flags. |
| 47 | * |
| 48 | * The rough edges of the default policy: |
| 49 | * - Starting to run with a period = 0 emits error message and stops the |
| 50 | * timer without a trigger. |
| 51 | * |
| 52 | * - Setting period to 0 of the running timer emits error message and |
| 53 | * stops the timer without a trigger. |
| 54 | * |
| 55 | * - Starting to run with counter = 0 or setting it to "0" while timer |
| 56 | * is running causes a trigger and reloads counter with a limit value. |
| 57 | * If limit = 0, ptimer emits error message and stops the timer. |
| 58 | * |
| 59 | * - Counter value of the running timer is one less than the actual value. |
| 60 | * |
| 61 | * - Changing period/frequency of the running timer loses time elapsed |
| 62 | * since the last period, effectively restarting the timer with a |
| 63 | * counter = counter value at the moment of change (.i.e. one less). |
| 64 | */ |
| 65 | #define PTIMER_POLICY_LEGACY 0 |
| 66 | |
| 67 | /* Periodic timer counter stays with "0" for a one period before wrapping |
| 68 | * around. */ |
| 69 | #define PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD (1 << 0) |
| 70 | |
| 71 | /* Running periodic timer that has counter = limit = 0 would continuously |
| 72 | * re-trigger every period. */ |
| 73 | #define PTIMER_POLICY_CONTINUOUS_TRIGGER (1 << 1) |
| 74 | |
| 75 | /* Starting to run with/setting counter to "0" won't trigger immediately, |
| 76 | * but after a one period for both oneshot and periodic modes. */ |
| 77 | #define PTIMER_POLICY_NO_IMMEDIATE_TRIGGER (1 << 2) |
| 78 | |
| 79 | /* Starting to run with/setting counter to "0" won't re-load counter |
| 80 | * immediately, but after a one period. */ |
| 81 | #define PTIMER_POLICY_NO_IMMEDIATE_RELOAD (1 << 3) |
| 82 | |
| 83 | /* Make counter value of the running timer represent the actual value and |
| 84 | * not the one less. */ |
| 85 | #define PTIMER_POLICY_NO_COUNTER_ROUND_DOWN (1 << 4) |
| 86 | |
| 87 | /* |
| 88 | * Starting to run with a zero counter, or setting the counter to "0" via |
| 89 | * ptimer_set_count() or ptimer_set_limit() will not trigger the timer |
| 90 | * (though it will cause a reload). Only a counter decrement to "0" |
| 91 | * will cause a trigger. Not compatible with NO_IMMEDIATE_TRIGGER; |
| 92 | * ptimer_init() will assert() that you don't set both. |
| 93 | */ |
| 94 | #define PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT (1 << 5) |
| 95 | |
| 96 | /* ptimer.c */ |
| 97 | typedef struct ptimer_state ptimer_state; |
| 98 | typedef void (*ptimer_cb)(void *opaque); |
| 99 | |
| 100 | /** |
| 101 | * ptimer_init - Allocate and return a new ptimer |
| 102 | * @callback: function to call on ptimer expiry |
| 103 | * @callback_opaque: opaque pointer passed to @callback |
| 104 | * @policy: PTIMER_POLICY_* bits specifying behaviour |
| 105 | * |
| 106 | * The ptimer returned must be freed using ptimer_free(). |
| 107 | * |
| 108 | * If a ptimer is created using this API then will use the |
| 109 | * transaction-based API for modifying ptimer state: all calls |
| 110 | * to functions which modify ptimer state: |
| 111 | * - ptimer_set_period() |
| 112 | * - ptimer_set_freq() |
| 113 | * - ptimer_set_limit() |
| 114 | * - ptimer_set_count() |
| 115 | * - ptimer_run() |
| 116 | * - ptimer_stop() |
| 117 | * must be between matched calls to ptimer_transaction_begin() |
| 118 | * and ptimer_transaction_commit(). When ptimer_transaction_commit() |
| 119 | * is called it will evaluate the state of the timer after all the |
| 120 | * changes in the transaction, and call the callback if necessary. |
| 121 | * |
| 122 | * The callback function is always called from within a transaction |
| 123 | * begin/commit block, so the callback should not call the |
| 124 | * ptimer_transaction_begin() function itself. If the callback changes |
| 125 | * the ptimer state such that another ptimer expiry is triggered, then |
| 126 | * the callback will be called a second time after the first call returns. |
| 127 | */ |
| 128 | ptimer_state *ptimer_init(ptimer_cb callback, |
| 129 | void *callback_opaque, |
| 130 | uint8_t policy_mask); |
| 131 | |
| 132 | /** |
| 133 | * ptimer_free - Free a ptimer |
| 134 | * @s: timer to free |
| 135 | * |
| 136 | * Free a ptimer created using ptimer_init(). |
| 137 | */ |
| 138 | void ptimer_free(ptimer_state *s); |
| 139 | |
| 140 | /** |
| 141 | * ptimer_transaction_begin() - Start a ptimer modification transaction |
| 142 | * |
| 143 | * This function must be called before making any calls to functions |
| 144 | * which modify the ptimer's state (see the ptimer_init() documentation |
| 145 | * for a list of these), and must always have a matched call to |
| 146 | * ptimer_transaction_commit(). |
| 147 | * It is an error to call this function for a BH-based ptimer; |
| 148 | * attempting to do this will trigger an assert. |
| 149 | */ |
| 150 | void ptimer_transaction_begin(ptimer_state *s); |
| 151 | |
| 152 | /** |
| 153 | * ptimer_transaction_commit() - Commit a ptimer modification transaction |
| 154 | * |
| 155 | * This function must be called after calls to functions which modify |
| 156 | * the ptimer's state, and completes the update of the ptimer. If the |
| 157 | * ptimer state now means that we should trigger the timer expiry |
| 158 | * callback, it will be called directly. |
| 159 | */ |
| 160 | void ptimer_transaction_commit(ptimer_state *s); |
| 161 | |
| 162 | /** |
| 163 | * ptimer_set_period - Set counter increment interval in nanoseconds |
| 164 | * @s: ptimer to configure |
| 165 | * @period: period of the counter in nanoseconds |
| 166 | * |
| 167 | * Note that if your counter behaviour is specified as having a |
| 168 | * particular frequency rather than a period then ptimer_set_freq() |
| 169 | * may be more appropriate. |
| 170 | * |
| 171 | * This function will assert if it is called outside a |
| 172 | * ptimer_transaction_begin/commit block. |
| 173 | */ |
| 174 | void ptimer_set_period(ptimer_state *s, int64_t period); |
| 175 | |
| 176 | /** |
| 177 | * ptimer_set_period_from_clock - Set counter increment from a Clock |
| 178 | * @s: ptimer to configure |
| 179 | * @clk: pointer to Clock object to take period from |
| 180 | * @divisor: value to scale the clock frequency down by |
| 181 | * |
| 182 | * If the ptimer is being driven from a Clock, this is the preferred |
| 183 | * way to tell the ptimer about the period, because it avoids any |
| 184 | * possible rounding errors that might happen if the internal |
| 185 | * representation of the Clock period was converted to either a period |
| 186 | * in ns or a frequency in Hz. |
| 187 | * |
| 188 | * If the ptimer should run at the same frequency as the clock, |
| 189 | * pass 1 as the @divisor; if the ptimer should run at half the |
| 190 | * frequency, pass 2, and so on. |
| 191 | * |
| 192 | * This function will assert if it is called outside a |
| 193 | * ptimer_transaction_begin/commit block. |
| 194 | */ |
| 195 | void ptimer_set_period_from_clock(ptimer_state *s, const Clock *clock, |
| 196 | unsigned int divisor); |
| 197 | |
| 198 | /** |
| 199 | * ptimer_set_freq - Set counter frequency in Hz |
| 200 | * @s: ptimer to configure |
| 201 | * @freq: counter frequency in Hz |
| 202 | * |
| 203 | * This does the same thing as ptimer_set_period(), so you only |
| 204 | * need to call one of them. If the counter behaviour is specified |
| 205 | * as setting the frequency then this function is more appropriate, |
| 206 | * because it allows specifying an effective period which is |
| 207 | * precise to fractions of a nanosecond, avoiding rounding errors. |
| 208 | * |
| 209 | * This function will assert if it is called outside a |
| 210 | * ptimer_transaction_begin/commit block. |
| 211 | */ |
| 212 | void ptimer_set_freq(ptimer_state *s, uint32_t freq); |
| 213 | |
| 214 | /** |
| 215 | * ptimer_get_limit - Get the configured limit of the ptimer |
| 216 | * @s: ptimer to query |
| 217 | * |
| 218 | * This function returns the current limit (reload) value |
| 219 | * of the down-counter; that is, the value which it will be |
| 220 | * reset to when it hits zero. |
| 221 | * |
| 222 | * Generally timer devices using ptimers should be able to keep |
| 223 | * their reload register state inside the ptimer using the get |
| 224 | * and set limit functions rather than needing to also track it |
| 225 | * in their own state structure. |
| 226 | */ |
| 227 | uint64_t ptimer_get_limit(ptimer_state *s); |
| 228 | |
| 229 | /** |
| 230 | * ptimer_set_limit - Set the limit of the ptimer |
| 231 | * @s: ptimer |
| 232 | * @limit: initial countdown value |
| 233 | * @reload: if nonzero, then reset the counter to the new limit |
| 234 | * |
| 235 | * Set the limit value of the down-counter. The @reload flag can |
| 236 | * be used to emulate the behaviour of timers which immediately |
| 237 | * reload the counter when their reload register is written to. |
| 238 | * |
| 239 | * This function will assert if it is called outside a |
| 240 | * ptimer_transaction_begin/commit block. |
| 241 | */ |
| 242 | void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload); |
| 243 | |
| 244 | /** |
| 245 | * ptimer_get_count - Get the current value of the ptimer |
| 246 | * @s: ptimer |
| 247 | * |
| 248 | * Return the current value of the down-counter. This will |
| 249 | * return the correct value whether the counter is enabled or |
| 250 | * disabled. |
| 251 | */ |
| 252 | uint64_t ptimer_get_count(ptimer_state *s); |
| 253 | |
| 254 | /** |
| 255 | * ptimer_set_count - Set the current value of the ptimer |
| 256 | * @s: ptimer |
| 257 | * @count: count value to set |
| 258 | * |
| 259 | * Set the value of the down-counter. If the counter is currently |
| 260 | * enabled this will arrange for a timer callback at the appropriate |
| 261 | * point in the future. |
| 262 | * |
| 263 | * This function will assert if it is called outside a |
| 264 | * ptimer_transaction_begin/commit block. |
| 265 | */ |
| 266 | void ptimer_set_count(ptimer_state *s, uint64_t count); |
| 267 | |
| 268 | /** |
| 269 | * ptimer_run - Start a ptimer counting |
| 270 | * @s: ptimer |
| 271 | * @oneshot: non-zero if this timer should only count down once |
| 272 | * |
| 273 | * Start a ptimer counting down; when it reaches zero the callback function |
| 274 | * passed to ptimer_init() will be invoked. |
| 275 | * If the @oneshot argument is zero, |
| 276 | * the counter value will then be reloaded from the limit and it will |
| 277 | * start counting down again. If @oneshot is non-zero, then the counter |
| 278 | * will disable itself when it reaches zero. |
| 279 | * |
| 280 | * This function will assert if it is called outside a |
| 281 | * ptimer_transaction_begin/commit block. |
| 282 | */ |
| 283 | void ptimer_run(ptimer_state *s, int oneshot); |
| 284 | |
| 285 | /** |
| 286 | * ptimer_stop - Stop a ptimer counting |
| 287 | * @s: ptimer |
| 288 | * |
| 289 | * Pause a timer (the count stays at its current value until ptimer_run() |
| 290 | * is called to start it counting again). |
| 291 | * |
| 292 | * Note that this can cause it to "lose" time, even if it is immediately |
| 293 | * restarted. |
| 294 | * |
| 295 | * This function will assert if it is called outside a |
| 296 | * ptimer_transaction_begin/commit block. |
| 297 | */ |
| 298 | void ptimer_stop(ptimer_state *s); |
| 299 | |
| 300 | extern const VMStateDescription vmstate_ptimer; |
| 301 | |
| 302 | #define VMSTATE_PTIMER(_field, _state) \ |
| 303 | VMSTATE_STRUCT_POINTER_V(_field, _state, 1, vmstate_ptimer, ptimer_state) |
| 304 | |
| 305 | #define VMSTATE_PTIMER_ARRAY(_f, _s, _n) \ |
| 306 | VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(_f, _s, _n, 0, \ |
| 307 | vmstate_ptimer, ptimer_state) |
| 308 | |
| 309 | #endif |