Commit ec2db7de7a280ce8d943e1a14463609d44b2b3e8
1 parent
417f38f0
ARM timer counts down, not up.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2214 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
5 additions
and
5 deletions
hw/arm_timer.c
| ... | ... | @@ -107,29 +107,29 @@ static void arm_timer_update(arm_timer_state *s, int64_t now) |
| 107 | 107 | /* Return the current value of the timer. */ |
| 108 | 108 | static uint32_t arm_timer_getcount(arm_timer_state *s, int64_t now) |
| 109 | 109 | { |
| 110 | - int64_t elapsed; | |
| 110 | + int64_t left; | |
| 111 | 111 | int64_t period; |
| 112 | 112 | |
| 113 | 113 | if (s->count == 0) |
| 114 | 114 | return 0; |
| 115 | 115 | if ((s->control & TIMER_CTRL_ENABLE) == 0) |
| 116 | 116 | return s->count; |
| 117 | - elapsed = now - s->loaded; | |
| 117 | + left = s->expires - now; | |
| 118 | 118 | period = s->expires - s->loaded; |
| 119 | 119 | /* If the timer should have expired then return 0. This can happen |
| 120 | 120 | when the host timer signal doesnt occur immediately. It's better to |
| 121 | 121 | have a timer appear to sit at zero for a while than have it wrap |
| 122 | 122 | around before the guest interrupt is raised. */ |
| 123 | 123 | /* ??? Could we trigger the interrupt here? */ |
| 124 | - if (elapsed > period) | |
| 124 | + if (left < 0) | |
| 125 | 125 | return 0; |
| 126 | 126 | /* We need to calculate count * elapsed / period without overfowing. |
| 127 | 127 | Scale both elapsed and period so they fit in a 32-bit int. */ |
| 128 | 128 | while (period != (int32_t)period) { |
| 129 | 129 | period >>= 1; |
| 130 | - elapsed >>= 1; | |
| 130 | + left >>= 1; | |
| 131 | 131 | } |
| 132 | - return ((uint64_t)s->count * (uint64_t)(int32_t)elapsed) | |
| 132 | + return ((uint64_t)s->count * (uint64_t)(int32_t)left) | |
| 133 | 133 | / (int32_t)period; |
| 134 | 134 | } |
| 135 | 135 | ... | ... |