forked from Imagelibrary/rtems
bsps/powerpc: Fix a clock driver
PowerPC Book E: Account for an extra tick period if a tick increment's pending. Close #2230.
This commit is contained in:
committed by
Sebastian Huber
parent
40d062f5cb
commit
d11b711b3e
@@ -46,7 +46,13 @@ volatile uint32_t Clock_driver_ticks;
|
|||||||
/*
|
/*
|
||||||
* This is the value programmed into the count down timer.
|
* This is the value programmed into the count down timer.
|
||||||
*/
|
*/
|
||||||
uint32_t Clock_Decrementer_value;
|
static uint32_t Clock_Decrementer_value;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the value by which elapsed count down timer ticks are multiplied to
|
||||||
|
* give an elapsed duration in nanoseconds, left-shifted by 32 bits
|
||||||
|
*/
|
||||||
|
static uint64_t Clock_Decrementer_reference;
|
||||||
|
|
||||||
void clockOff(void* unused)
|
void clockOff(void* unused)
|
||||||
{
|
{
|
||||||
@@ -209,6 +215,37 @@ static uint32_t Clock_driver_nanoseconds_since_last_tick(void)
|
|||||||
return tmp * 1000;
|
return tmp * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t Clock_driver_nanoseconds_since_last_tick_bookE(void)
|
||||||
|
{
|
||||||
|
uint32_t clicks;
|
||||||
|
uint64_t c;
|
||||||
|
|
||||||
|
PPC_Get_decrementer( clicks );
|
||||||
|
c = Clock_Decrementer_value - clicks;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether a clock tick interrupt is pending and hence that the
|
||||||
|
* decrementer's wrapped. If it has, we'll compensate by returning a time one
|
||||||
|
* tick period longer.
|
||||||
|
*
|
||||||
|
* We have to check interrupt status after reading the decrementer. If we
|
||||||
|
* don't, we may miss an interrupt and read a wrapped decrementer value
|
||||||
|
* without compensating for it
|
||||||
|
*/
|
||||||
|
if ( _read_BOOKE_TSR() & BOOKE_TSR_DIS )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Re-read the decrementer: The tick interrupt may have been
|
||||||
|
* generated and the decrementer wrapped during the time since we
|
||||||
|
* last read it and the time we checked the interrupt status
|
||||||
|
*/
|
||||||
|
PPC_Get_decrementer( clicks );
|
||||||
|
c = (Clock_Decrementer_value - clicks) + Clock_Decrementer_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint32_t)((c * Clock_Decrementer_reference) >> 32);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clock_initialize
|
* Clock_initialize
|
||||||
*
|
*
|
||||||
@@ -223,7 +260,10 @@ rtems_device_driver Clock_initialize(
|
|||||||
rtems_interrupt_level l,tcr;
|
rtems_interrupt_level l,tcr;
|
||||||
|
|
||||||
Clock_Decrementer_value = (BSP_bus_frequency/BSP_time_base_divisor)*
|
Clock_Decrementer_value = (BSP_bus_frequency/BSP_time_base_divisor)*
|
||||||
(rtems_configuration_get_microseconds_per_tick()/1000);
|
rtems_configuration_get_milliseconds_per_tick();
|
||||||
|
|
||||||
|
Clock_Decrementer_reference = ((uint64_t)1000000U<<32)/
|
||||||
|
(BSP_bus_frequency/BSP_time_base_divisor);
|
||||||
|
|
||||||
/* set the decrementer now, prior to installing the handler
|
/* set the decrementer now, prior to installing the handler
|
||||||
* so no interrupts will happen in a while.
|
* so no interrupts will happen in a while.
|
||||||
@@ -244,14 +284,22 @@ rtems_device_driver Clock_initialize(
|
|||||||
|
|
||||||
rtems_interrupt_enable(l);
|
rtems_interrupt_enable(l);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the nanoseconds since last tick handler
|
||||||
|
*/
|
||||||
|
rtems_clock_set_nanoseconds_extension(
|
||||||
|
Clock_driver_nanoseconds_since_last_tick_bookE
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* Set the nanoseconds since last tick handler
|
* Set the nanoseconds since last tick handler
|
||||||
*/
|
*/
|
||||||
rtems_clock_set_nanoseconds_extension(
|
rtems_clock_set_nanoseconds_extension(
|
||||||
Clock_driver_nanoseconds_since_last_tick
|
Clock_driver_nanoseconds_since_last_tick
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If a decrementer exception was pending, it is cleared by
|
* If a decrementer exception was pending, it is cleared by
|
||||||
|
|||||||
Reference in New Issue
Block a user