From c984fb32fc252f868d0318e252165d00e000c75a Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Sat, 22 May 2004 15:14:31 +0000 Subject: 2004-05-22 Till Strauman PR 619/bsps * mpc6xx/clock/c_clock.c: The PPC decrementer must be reloaded on each clock tick. Currently, this is done by just reloading a fixed value. The attached patch takes into account the time that elapsed since the decrementer crossed zero in order to adjust the value to be re-loaded. Without the patch, the effective system clock cycle is increased by the exception handler latency. --- c/src/lib/libcpu/powerpc/ChangeLog | 10 +++++++ c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c | 35 ++++++++++++++++--------- 2 files changed, 33 insertions(+), 12 deletions(-) (limited to 'c/src') diff --git a/c/src/lib/libcpu/powerpc/ChangeLog b/c/src/lib/libcpu/powerpc/ChangeLog index a21e63db71..14c811ff36 100644 --- a/c/src/lib/libcpu/powerpc/ChangeLog +++ b/c/src/lib/libcpu/powerpc/ChangeLog @@ -1,3 +1,13 @@ +2004-05-22 Till Strauman + + PR 619/bsps + * mpc6xx/clock/c_clock.c: The PPC decrementer must be reloaded on each + clock tick. Currently, this is done by just reloading a fixed value. + The attached patch takes into account the time that elapsed since the + decrementer crossed zero in order to adjust the value to be + re-loaded. Without the patch, the effective system clock cycle is + increased by the exception handler latency. + 2004-04-13 Ralf Corsepius * mpc5xx/clock/clock.c, mpc5xx/irq/irq_asm.S, mpc5xx/vectors/vectors.S: diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c b/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c index 28b6521cf6..b5cdd3f5d4 100644 --- a/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c +++ b/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c @@ -73,21 +73,23 @@ void clockOn(void* unused) * Return values: NONE * */ + void clockIsr() { +int decr; /* * The driver has seen another tick. */ + do { + asm volatile ("mfdec %0; add %0, %0, %1; mtdec %0":"=r"(decr):"r"(Clock_Decrementer_value)); - PPC_Set_decrementer( Clock_Decrementer_value ); - - Clock_driver_ticks += 1; - - /* - * Real Time Clock counter/timer is set to automatically reload. - */ + Clock_driver_ticks += 1; - rtems_clock_tick(); + /* + * Real Time Clock counter/timer is set to automatically reload. + */ + rtems_clock_tick(); + } while ( decr < 0 ); } int clockIsOn(void* unused) @@ -144,6 +146,18 @@ rtems_device_driver Clock_initialize( Clock_Decrementer_value = (BSP_bus_frequency/BSP_time_base_divisor)* (rtems_configuration_get_microseconds_per_tick()/1000); + /* set the decrementer now, prior to installing the handler + * so no interrupts will happen in a while. + */ + PPC_Set_decrementer( (unsigned)-1 ); + + /* if a decrementer exception was pending, it is cleared by + * executing the default (nop) handler at this point; + * The next exception will then be taken by our clock handler. + * Clock handler installation initializes the decrementer to + * the correct value. + */ + if (!BSP_connect_clock_handler ()) { printk("Unable to initialize system clock\n"); rtems_fatal_error_occurred(1); @@ -190,10 +204,7 @@ rtems_device_driver Clock_control( clockIsr(); else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) { - if (!BSP_connect_clock_handler ()) { - printk("Error installing clock interrupt handler!\n"); - rtems_fatal_error_occurred(1); - } + Clock_initialize(major, minor, 0); } done: return RTEMS_SUCCESSFUL; -- cgit v1.2.3