arm:ensure read_tsc_64 always returns a valid value.
Before this change overflowing the free running clock counter between the time the timer was read and the time the overflow check was done resulted in read_tsc_64 returning a to high value. Change-Id: I1022f271213647f720477c4121d45f0c965456c6
This commit is contained in:
parent
02f6308a2b
commit
ed45d98dac
@ -269,11 +269,24 @@ static u32_t read_frc(void)
|
|||||||
return mmio_read(fr_timer.base + fr_timer.regs->TCRR);
|
return mmio_read(fr_timer.base + fr_timer.regs->TCRR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void frc_overflow_check(void)
|
/*
|
||||||
|
* Check if the free running clock has overflown and
|
||||||
|
* increase the high free running clock counter if
|
||||||
|
* so. This method takes the current timer value as
|
||||||
|
* parameter to ensure the overflow check is done
|
||||||
|
* on the current timer value.
|
||||||
|
*
|
||||||
|
* To compose the current timer value (64 bits) you
|
||||||
|
* need to follow the following sequence:
|
||||||
|
* read the current timer value.
|
||||||
|
* call the overflow check
|
||||||
|
* compose the 64 bits time based on the current timer value
|
||||||
|
* and high_frc.
|
||||||
|
*/
|
||||||
|
static void frc_overflow_check(u32_t cur_frc)
|
||||||
{
|
{
|
||||||
static int prev_frc_valid;
|
static int prev_frc_valid;
|
||||||
static u32_t prev_frc;
|
static u32_t prev_frc;
|
||||||
u32_t cur_frc = read_frc();
|
|
||||||
if(prev_frc_valid && prev_frc > cur_frc)
|
if(prev_frc_valid && prev_frc > cur_frc)
|
||||||
high_frc++;
|
high_frc++;
|
||||||
prev_frc = cur_frc;
|
prev_frc = cur_frc;
|
||||||
@ -283,7 +296,7 @@ static void frc_overflow_check(void)
|
|||||||
void omap3_timer_int_handler()
|
void omap3_timer_int_handler()
|
||||||
{
|
{
|
||||||
/* Clear all interrupts */
|
/* Clear all interrupts */
|
||||||
u32_t tisr;
|
u32_t tisr,now;
|
||||||
|
|
||||||
|
|
||||||
/* when the kernel itself is running interrupts are disabled.
|
/* when the kernel itself is running interrupts are disabled.
|
||||||
@ -294,14 +307,15 @@ void omap3_timer_int_handler()
|
|||||||
OMAP3_TISR_TCAR_IT_FLAG;
|
OMAP3_TISR_TCAR_IT_FLAG;
|
||||||
mmio_write(timer.base + timer.regs->TISR, tisr);
|
mmio_write(timer.base + timer.regs->TISR, tisr);
|
||||||
|
|
||||||
frc_overflow_check();
|
now = read_frc();
|
||||||
|
frc_overflow_check(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use the free running clock as TSC */
|
/* Use the free running clock as TSC */
|
||||||
void read_tsc_64(u64_t *t)
|
void read_tsc_64(u64_t *t)
|
||||||
{
|
{
|
||||||
u32_t now;
|
u32_t now;
|
||||||
frc_overflow_check();
|
|
||||||
now = read_frc();
|
now = read_frc();
|
||||||
|
frc_overflow_check(now);
|
||||||
*t = (u64_t) now + (high_frc << 32);
|
*t = (u64_t) now + (high_frc << 32);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user