Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:08

0001 /*  timer.c
0002  *
0003  *  This file implements a benchmark timer using timer 2.
0004  *
0005  *  COPYRIGHT (c) 1989-1998.
0006  *  On-Line Applications Research Corporation (OAR).
0007  *
0008  *  The license and distribution terms for this file may be
0009  *  found in the file LICENSE in this distribution or at
0010  *  http://www.rtems.org/license/LICENSE.
0011  *
0012  *  Ported to LEON implementation of the SPARC by On-Line Applications
0013  *  Research Corporation (OAR) under contract to the European Space
0014  *  Agency (ESA).
0015  *
0016  *  LEON modifications of respective RTEMS file: COPYRIGHT (c) 1995.
0017  *  European Space Agency.
0018  */
0019 
0020 
0021 #include <leon.h>
0022 #include <rtems/btimer.h>
0023 
0024 #if defined(RTEMS_MULTIPROCESSING)
0025   #define LEON3_TIMER_INDEX \
0026       ((rtems_configuration_get_user_multiprocessing_table()) ? \
0027         (rtems_configuration_get_user_multiprocessing_table()->node) - 1 : 1)
0028 #else
0029   #define LEON3_TIMER_INDEX 0
0030 #endif
0031 
0032 bool benchmark_timer_find_average_overhead;
0033 
0034 bool benchmark_timer_is_initialized = false;
0035 
0036 void benchmark_timer_initialize(void)
0037 {
0038   /*
0039    *  Timer runs long and accurate enough not to require an interrupt.
0040    */
0041   if (LEON3_Timer_Regs) {
0042     gptimer_timer *timer = &LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX];
0043     if ( benchmark_timer_is_initialized == false ) {
0044       /* approximately 1 us per countdown */
0045       grlib_store_32( &timer->trldval, 0xffffff );
0046       grlib_store_32( &timer->tcntval, 0xffffff );
0047     } else {
0048       benchmark_timer_is_initialized = true;
0049     }
0050     grlib_store_32( &timer->tctrl, GPTIMER_TCTRL_EN | GPTIMER_TCTRL_LD );
0051   }
0052 }
0053 
0054 #define AVG_OVERHEAD      3  /* It typically takes 3.0 microseconds */
0055                              /*     to start/stop the timer. */
0056 #define LEAST_VALID       2  /* Don't trust a value lower than this */
0057 
0058 benchmark_timer_t benchmark_timer_read(void)
0059 {
0060   uint32_t total;
0061 
0062   if (LEON3_Timer_Regs) {
0063     total =
0064       grlib_load_32( &LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].tcntval );
0065 
0066     total = 0xffffff - total;
0067 
0068     if ( benchmark_timer_find_average_overhead == true )
0069       return total;          /* in one microsecond units */
0070 
0071     if ( total < LEAST_VALID )
0072       return 0;            /* below timer resolution */
0073 
0074     return total - AVG_OVERHEAD;
0075   }
0076   return 0;
0077 }
0078 
0079 void benchmark_timer_disable_subtracting_average_overhead(
0080   bool find_flag
0081 )
0082 {
0083   benchmark_timer_find_average_overhead = find_flag;
0084 }