forked from Imagelibrary/rtems
powerpc/shared/clock/clock.c: Remove clock major/minor and clean up
This commit is contained in:
@@ -42,10 +42,6 @@ extern uint32_t bsp_time_base_frequency;
|
||||
|
||||
volatile uint32_t Clock_driver_ticks = 0;
|
||||
|
||||
rtems_device_major_number rtems_clock_major = UINT32_MAX;
|
||||
|
||||
rtems_device_minor_number rtems_clock_minor = UINT32_MAX;
|
||||
|
||||
static uint32_t ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX;
|
||||
|
||||
static uint32_t ppc_clock_next_time_base;
|
||||
@@ -54,212 +50,221 @@ static uint64_t ppc_clock_factor;
|
||||
|
||||
static void ppc_clock_no_tick(void)
|
||||
{
|
||||
/* Do nothing */
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
static void (*ppc_clock_tick)(void) = ppc_clock_no_tick;
|
||||
|
||||
static int ppc_clock_exception_handler( BSP_Exception_frame *frame, unsigned number)
|
||||
static int ppc_clock_exception_handler(
|
||||
BSP_Exception_frame *frame,
|
||||
unsigned number
|
||||
)
|
||||
{
|
||||
uint32_t delta = ppc_clock_decrementer_value;
|
||||
uint32_t next = ppc_clock_next_time_base;
|
||||
uint32_t dec = 0;
|
||||
uint32_t now = 0;
|
||||
uint32_t msr = 0;
|
||||
uint32_t delta = ppc_clock_decrementer_value;
|
||||
uint32_t next = ppc_clock_next_time_base;
|
||||
uint32_t dec = 0;
|
||||
uint32_t now = 0;
|
||||
uint32_t msr = 0;
|
||||
|
||||
do {
|
||||
/* Increment clock ticks */
|
||||
Clock_driver_ticks += 1;
|
||||
do {
|
||||
/* Increment clock ticks */
|
||||
Clock_driver_ticks += 1;
|
||||
|
||||
/* Enable external exceptions */
|
||||
msr = ppc_external_exceptions_enable();
|
||||
/* Enable external exceptions */
|
||||
msr = ppc_external_exceptions_enable();
|
||||
|
||||
/* Call clock ticker */
|
||||
ppc_clock_tick();
|
||||
/* Call clock ticker */
|
||||
ppc_clock_tick();
|
||||
|
||||
/* Restore machine state */
|
||||
ppc_external_exceptions_disable( msr);
|
||||
/* Restore machine state */
|
||||
ppc_external_exceptions_disable( msr);
|
||||
|
||||
/* Next time base */
|
||||
next += delta;
|
||||
/* Next time base */
|
||||
next += delta;
|
||||
|
||||
/* Current time */
|
||||
now = ppc_time_base();
|
||||
/* Current time */
|
||||
now = ppc_time_base();
|
||||
|
||||
/* New decrementer value */
|
||||
dec = next - now;
|
||||
} while (dec > delta);
|
||||
/* New decrementer value */
|
||||
dec = next - now;
|
||||
} while (dec > delta);
|
||||
|
||||
/* Set decrementer */
|
||||
ppc_set_decrementer_register( dec);
|
||||
/* Set decrementer */
|
||||
ppc_set_decrementer_register( dec);
|
||||
|
||||
/* Expected next time base */
|
||||
ppc_clock_next_time_base = next;
|
||||
/* Expected next time base */
|
||||
ppc_clock_next_time_base = next;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ppc_clock_exception_handler_first( BSP_Exception_frame *frame, unsigned number)
|
||||
static int ppc_clock_exception_handler_first(
|
||||
BSP_Exception_frame *frame,
|
||||
unsigned number
|
||||
)
|
||||
{
|
||||
/* We have to clear the first pending decrementer exception this way */
|
||||
/* We have to clear the first pending decrementer exception this way */
|
||||
|
||||
if (ppc_decrementer_register() >= 0x80000000) {
|
||||
ppc_clock_exception_handler( frame, number);
|
||||
}
|
||||
if (ppc_decrementer_register() >= 0x80000000) {
|
||||
ppc_clock_exception_handler( frame, number);
|
||||
}
|
||||
|
||||
ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler);
|
||||
ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ppc_clock_exception_handler_booke( BSP_Exception_frame *frame, unsigned number)
|
||||
static int ppc_clock_exception_handler_booke(
|
||||
BSP_Exception_frame *frame,
|
||||
unsigned number
|
||||
)
|
||||
{
|
||||
uint32_t msr;
|
||||
uint32_t msr;
|
||||
|
||||
/* Acknowledge decrementer request */
|
||||
PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_TSR, BOOKE_TSR_DIS);
|
||||
/* Acknowledge decrementer request */
|
||||
PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_TSR, BOOKE_TSR_DIS);
|
||||
|
||||
/* Increment clock ticks */
|
||||
Clock_driver_ticks += 1;
|
||||
/* Increment clock ticks */
|
||||
Clock_driver_ticks += 1;
|
||||
|
||||
/* Enable external exceptions */
|
||||
msr = ppc_external_exceptions_enable();
|
||||
/* Enable external exceptions */
|
||||
msr = ppc_external_exceptions_enable();
|
||||
|
||||
/* Call clock ticker */
|
||||
ppc_clock_tick();
|
||||
/* Call clock ticker */
|
||||
ppc_clock_tick();
|
||||
|
||||
/* Restore machine state */
|
||||
ppc_external_exceptions_disable( msr);
|
||||
/* Restore machine state */
|
||||
ppc_external_exceptions_disable( msr);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ppc_clock_exception_handler_ppc405(BSP_Exception_frame *frame, unsigned number)
|
||||
{
|
||||
uint32_t msr;
|
||||
uint32_t msr;
|
||||
|
||||
/* Acknowledge PIT request */
|
||||
PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_TSR, BOOKE_TSR_DIS);
|
||||
/* Acknowledge PIT request */
|
||||
PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_TSR, BOOKE_TSR_DIS);
|
||||
|
||||
/* Increment clock ticks */
|
||||
Clock_driver_ticks += 1;
|
||||
/* Increment clock ticks */
|
||||
Clock_driver_ticks += 1;
|
||||
|
||||
/* Enable external exceptions */
|
||||
msr = ppc_external_exceptions_enable();
|
||||
/* Enable external exceptions */
|
||||
msr = ppc_external_exceptions_enable();
|
||||
|
||||
/* Call clock ticker */
|
||||
ppc_clock_tick();
|
||||
/* Call clock ticker */
|
||||
ppc_clock_tick();
|
||||
|
||||
/* Restore machine state */
|
||||
ppc_external_exceptions_disable(msr);
|
||||
/* Restore machine state */
|
||||
ppc_external_exceptions_disable(msr);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t ppc_clock_nanoseconds_since_last_tick(void)
|
||||
{
|
||||
uint64_t k = ppc_clock_factor;
|
||||
uint32_t c = ppc_decrementer_register();
|
||||
uint32_t i = ppc_clock_decrementer_value + 1;
|
||||
uint64_t k = ppc_clock_factor;
|
||||
uint32_t c = ppc_decrementer_register();
|
||||
uint32_t i = ppc_clock_decrementer_value + 1;
|
||||
|
||||
return (uint32_t) (((i - c) * k) >> 32);
|
||||
return (uint32_t) (((i - c) * k) >> 32);
|
||||
}
|
||||
|
||||
static uint32_t ppc_clock_nanoseconds_since_last_tick_ppc405(void)
|
||||
{
|
||||
uint64_t k = ppc_clock_factor;
|
||||
uint32_t i = ppc_clock_decrementer_value;
|
||||
uint32_t c = i - PPC_SPECIAL_PURPOSE_REGISTER(PPC405_PIT);
|
||||
uint64_t k = ppc_clock_factor;
|
||||
uint32_t i = ppc_clock_decrementer_value;
|
||||
uint32_t c = i - PPC_SPECIAL_PURPOSE_REGISTER(PPC405_PIT);
|
||||
|
||||
if ((PPC_SPECIAL_PURPOSE_REGISTER(PPC405_TSR) & BOOKE_TSR_DIS) != 0) {
|
||||
c = i - PPC_SPECIAL_PURPOSE_REGISTER(PPC405_PIT) + i;
|
||||
}
|
||||
if ((PPC_SPECIAL_PURPOSE_REGISTER(PPC405_TSR) & BOOKE_TSR_DIS) != 0) {
|
||||
c = i - PPC_SPECIAL_PURPOSE_REGISTER(PPC405_PIT) + i;
|
||||
}
|
||||
|
||||
return (uint32_t) ((c * k) >> 32);
|
||||
return (uint32_t) ((c * k) >> 32);
|
||||
}
|
||||
|
||||
void Clock_exit(void)
|
||||
{
|
||||
/* Set the decrementer to the maximum value */
|
||||
ppc_set_decrementer_register( PPC_CLOCK_DECREMENTER_MAX);
|
||||
/* Set the decrementer to the maximum value */
|
||||
ppc_set_decrementer_register( PPC_CLOCK_DECREMENTER_MAX);
|
||||
|
||||
/* Use default clock handler */
|
||||
ppc_clock_tick = ppc_clock_no_tick;
|
||||
/* Use default clock handler */
|
||||
ppc_clock_tick = ppc_clock_no_tick;
|
||||
}
|
||||
|
||||
rtems_device_driver Clock_initialize( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
|
||||
rtems_device_driver Clock_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
uint64_t frequency = bsp_time_base_frequency;
|
||||
uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
|
||||
uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000);
|
||||
uint64_t frequency = bsp_time_base_frequency;
|
||||
uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
|
||||
uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000);
|
||||
|
||||
/* Make major/minor available to others such as shared memory driver */
|
||||
rtems_clock_major = major;
|
||||
rtems_clock_minor = minor;
|
||||
/*
|
||||
* Set default ticker.
|
||||
*
|
||||
* The function rtems_clock_tick() returns a status code. This value
|
||||
* will be discarded since the RTEMS documentation claims that it is
|
||||
* always successful.
|
||||
*/
|
||||
ppc_clock_tick = (void (*)(void)) rtems_clock_tick;
|
||||
|
||||
/*
|
||||
* Set default ticker.
|
||||
*
|
||||
* The function rtems_clock_tick() returns a status code. This value
|
||||
* will be discarded since the RTEMS documentation claims that it is
|
||||
* always successful.
|
||||
*/
|
||||
ppc_clock_tick = (void (*)(void)) rtems_clock_tick;
|
||||
/* Factor for nano seconds extension */
|
||||
ppc_clock_factor = (1000000000ULL << 32) / frequency;
|
||||
|
||||
/* Factor for nano seconds extension */
|
||||
ppc_clock_factor = (1000000000ULL << 32) / frequency;
|
||||
if (ppc_cpu_is_bookE() != PPC_BOOKE_405) {
|
||||
/* Decrementer value */
|
||||
ppc_clock_decrementer_value = interval - 1;
|
||||
|
||||
if (ppc_cpu_is_bookE() != PPC_BOOKE_405) {
|
||||
/* Decrementer value */
|
||||
ppc_clock_decrementer_value = interval - 1;
|
||||
/* Check decrementer value */
|
||||
if (ppc_clock_decrementer_value == 0) {
|
||||
ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX;
|
||||
RTEMS_SYSLOG_ERROR( "decrementer value would be zero, will be set to maximum value instead\n");
|
||||
}
|
||||
|
||||
/* Check decrementer value */
|
||||
if (ppc_clock_decrementer_value == 0) {
|
||||
ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX;
|
||||
RTEMS_SYSLOG_ERROR( "decrementer value would be zero, will be set to maximum value instead\n");
|
||||
}
|
||||
/* Set the nanoseconds since last tick handler */
|
||||
rtems_clock_set_nanoseconds_extension( ppc_clock_nanoseconds_since_last_tick);
|
||||
|
||||
/* Set the nanoseconds since last tick handler */
|
||||
rtems_clock_set_nanoseconds_extension( ppc_clock_nanoseconds_since_last_tick);
|
||||
if (ppc_cpu_is_bookE()) {
|
||||
/* Set decrementer auto-reload value */
|
||||
PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_DECAR, ppc_clock_decrementer_value);
|
||||
|
||||
if (ppc_cpu_is_bookE()) {
|
||||
/* Set decrementer auto-reload value */
|
||||
PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_DECAR, ppc_clock_decrementer_value);
|
||||
/* Install exception handler */
|
||||
ppc_exc_set_handler( ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_booke);
|
||||
|
||||
/* Install exception handler */
|
||||
ppc_exc_set_handler( ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_booke);
|
||||
/* Enable decrementer and auto-reload */
|
||||
PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( BOOKE_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE);
|
||||
} else {
|
||||
/* Here the decrementer value is actually the interval */
|
||||
++ppc_clock_decrementer_value;
|
||||
|
||||
/* Enable decrementer and auto-reload */
|
||||
PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( BOOKE_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE);
|
||||
} else {
|
||||
/* Here the decrementer value is actually the interval */
|
||||
++ppc_clock_decrementer_value;
|
||||
/* Initialize next time base */
|
||||
ppc_clock_next_time_base = ppc_time_base() + ppc_clock_decrementer_value;
|
||||
|
||||
/* Initialize next time base */
|
||||
ppc_clock_next_time_base = ppc_time_base() + ppc_clock_decrementer_value;
|
||||
/* Install exception handler */
|
||||
ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler_first);
|
||||
}
|
||||
|
||||
/* Install exception handler */
|
||||
ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler_first);
|
||||
}
|
||||
/* Set the decrementer value */
|
||||
ppc_set_decrementer_register( ppc_clock_decrementer_value);
|
||||
} else {
|
||||
/* PIT interval value */
|
||||
ppc_clock_decrementer_value = interval;
|
||||
|
||||
/* Set the decrementer value */
|
||||
ppc_set_decrementer_register( ppc_clock_decrementer_value);
|
||||
} else {
|
||||
/* PIT interval value */
|
||||
ppc_clock_decrementer_value = interval;
|
||||
/* Set the nanoseconds since last tick handler */
|
||||
rtems_clock_set_nanoseconds_extension(ppc_clock_nanoseconds_since_last_tick_ppc405);
|
||||
|
||||
/* Set the nanoseconds since last tick handler */
|
||||
rtems_clock_set_nanoseconds_extension(ppc_clock_nanoseconds_since_last_tick_ppc405);
|
||||
/* Install exception handler */
|
||||
ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_ppc405);
|
||||
|
||||
/* Install exception handler */
|
||||
ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_ppc405);
|
||||
/* Enable PIT and auto-reload */
|
||||
PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(PPC405_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE);
|
||||
|
||||
/* Enable PIT and auto-reload */
|
||||
PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(PPC405_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE);
|
||||
/* Set PIT auto-reload and initial value */
|
||||
PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_PIT, interval);
|
||||
}
|
||||
|
||||
/* Set PIT auto-reload and initial value */
|
||||
PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_PIT, interval);
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user