ARM timer counts down, not up.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2214 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									417f38f066
								
							
						
					
					
						commit
						ec2db7de7a
					
				@ -107,29 +107,29 @@ static void arm_timer_update(arm_timer_state *s, int64_t now)
 | 
				
			|||||||
/* Return the current value of the timer.  */
 | 
					/* Return the current value of the timer.  */
 | 
				
			||||||
static uint32_t arm_timer_getcount(arm_timer_state *s, int64_t now)
 | 
					static uint32_t arm_timer_getcount(arm_timer_state *s, int64_t now)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int64_t elapsed;
 | 
					    int64_t left;
 | 
				
			||||||
    int64_t period;
 | 
					    int64_t period;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (s->count == 0)
 | 
					    if (s->count == 0)
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    if ((s->control & TIMER_CTRL_ENABLE) == 0)
 | 
					    if ((s->control & TIMER_CTRL_ENABLE) == 0)
 | 
				
			||||||
        return s->count;
 | 
					        return s->count;
 | 
				
			||||||
    elapsed = now - s->loaded;
 | 
					    left = s->expires - now;
 | 
				
			||||||
    period = s->expires - s->loaded;
 | 
					    period = s->expires - s->loaded;
 | 
				
			||||||
    /* If the timer should have expired then return 0.  This can happen
 | 
					    /* If the timer should have expired then return 0.  This can happen
 | 
				
			||||||
       when the host timer signal doesnt occur immediately.  It's better to
 | 
					       when the host timer signal doesnt occur immediately.  It's better to
 | 
				
			||||||
       have a timer appear to sit at zero for a while than have it wrap
 | 
					       have a timer appear to sit at zero for a while than have it wrap
 | 
				
			||||||
       around before the guest interrupt is raised.  */
 | 
					       around before the guest interrupt is raised.  */
 | 
				
			||||||
    /* ??? Could we trigger the interrupt here?  */
 | 
					    /* ??? Could we trigger the interrupt here?  */
 | 
				
			||||||
    if (elapsed > period)
 | 
					    if (left < 0)
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    /* We need to calculate count * elapsed / period without overfowing.
 | 
					    /* We need to calculate count * elapsed / period without overfowing.
 | 
				
			||||||
       Scale both elapsed and period so they fit in a 32-bit int.  */
 | 
					       Scale both elapsed and period so they fit in a 32-bit int.  */
 | 
				
			||||||
    while (period != (int32_t)period) {
 | 
					    while (period != (int32_t)period) {
 | 
				
			||||||
        period >>= 1;
 | 
					        period >>= 1;
 | 
				
			||||||
        elapsed >>= 1;
 | 
					        left >>= 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return ((uint64_t)s->count * (uint64_t)(int32_t)elapsed)
 | 
					    return ((uint64_t)s->count * (uint64_t)(int32_t)left)
 | 
				
			||||||
            / (int32_t)period;
 | 
					            / (int32_t)period;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user