Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:48

0001 /**
0002  * @file
0003  *
0004  * This file manages the benchmark timer used by the RTEMS Timing Test Suite.
0005  * Each measured time period is demarcated by calls to
0006  * benchmark_timer_initialize() and benchmark_timer_read().
0007  * benchmark_timer_read() usually returns the number of microseconds
0008  * since benchmark_timer_initialize() exitted.
0009  *
0010  * These functions are prototyped in rtems/btimer.h and
0011  * must be implemented as part of the BSP.
0012  *
0013  * This port does not allow the application to select which timer on the
0014  * MVME167 to use for the timer, nor does it allow the application to
0015  * configure the timer. The timer uses the VMEchip2 Tick Timer #1. This timer
0016  * is distinct from the clock, which uses Tick Timer #2 in the VMEchip2.
0017  *
0018  * All page references are to the MVME166/MVME167/MVME187 Single Board
0019  * Computer Programmer's Reference Guide (MVME187PG/D2) with the April 1993
0020  *  supplements/addenda (MVME187PG/D2A1).
0021  */
0022 
0023 /*
0024  *  COPYRIGHT (c) 1989-1999.
0025  *  On-Line Applications Research Corporation (OAR).
0026  *
0027  *  The license and distribution terms for this file may be
0028  *  found in the file LICENSE in this distribution or at
0029  *  http://www.rtems.org/license/LICENSE.
0030  *
0031  *  Modifications of respective RTEMS file:
0032  *  Copyright (c) 1998, National Research Council of Canada
0033  */
0034 
0035 #include <rtems.h>
0036 #include <rtems/btimer.h>
0037 #include <bsp.h>
0038 
0039 /* Periodic tick interval */
0040 #define TICK_INTERVAL         10000UL     /* T1's countdown constant (10 ms) */
0041 #define TIMER_INT_LEVEL       6           /* T1's interrupt level */
0042 #define TIMER_VECTOR (VBR0 * 0x10 + 0x8)  /* T1 is vector $X8 (p. 2-71)*/
0043 
0044 /* Number of interrupts since timer was re-initialized */
0045 uint32_t            Ttimer_val;
0046 
0047 /*
0048  *  Set to true to return raw value. Normally zero. Depends on being allocated
0049  *  in the .bss section and on that section being explicitly zeroed at boot
0050  *  time.
0051  */
0052 bool benchmark_timer_find_average_overhead;
0053 
0054 rtems_isr timerisr(rtems_vector_number);
0055 
0056 /*
0057  *  This routine initializes the Tick Timer 1 on the MVME167 board.
0058  *
0059  *  Input parameters:  NONE
0060  *
0061  *  Output parameters:  NONE
0062  *
0063  *  NOTE: This routine may not work if the optimizer is enabled for some
0064  *        compilers. The multiple writes may be optimized away.
0065  *
0066  *        It is important that the timer start/stop overhead be
0067  *        determined when porting or modifying this code.
0068  *
0069  *  THE VMECHIP2 PRESCALER REGISTER IS ASSUMED TO BE SET!
0070  *  The prescaler is used by all VMEchip2 timers, including the VMEbus grant
0071  *  timeout counter, the DMAC time off timer, the DMAC timer on timer, and the
0072  *  VMEbus global timeout timer. The prescaler value is normally set by the
0073  *  boot ROM to provide a 1 MHz clock to the timers. For a 25 MHz MVME167, the
0074  *  prescaler value should be 0xE7 (page 2-63).
0075  */
0076 void benchmark_timer_initialize(void)
0077 {
0078   (void) set_vector( timerisr, TIMER_VECTOR, 0 );
0079 
0080   Ttimer_val = 0;                       /* clear timer ISR count */
0081   lcsr->intr_ena &= 0xFEFFFFFF;         /* disable tick timer 1 interrupt */
0082   lcsr->intr_clear |= 0x01000000;       /* clear tick timer 1 interrupt */
0083   lcsr->intr_level[0] =                 /* set int level */
0084         (lcsr->intr_level[0] & 0xFFFFFFF0) | TIMER_INT_LEVEL;
0085   lcsr->timer_cmp_1 = TICK_INTERVAL;    /* period in compare register */
0086   lcsr->timer_cnt_1 = 0;                /* clear tick timer 1 counter */
0087   lcsr->board_ctl |= 7;                 /* start tick timer 1, reset-on-compare, */
0088                                         /*   and clear overflow counter */
0089 
0090   lcsr->intr_ena |= 0x01000000;         /* enable tick timer 1 interrupt */
0091   lcsr->vector_base |= MASK_INT;        /* unmask VMEchip2 interrupts */
0092 }
0093 
0094 #define AVG_OVERHEAD      3UL   /* It typically takes 3.0 microseconds */
0095                                 /* (3 countdowns) to start/stop the timer. */
0096 #define LEAST_VALID       3UL   /* Don't trust a value lower than this */
0097 
0098 /*
0099  *  This routine reads the Tick Timer 1 on the MVME167 board.
0100  *
0101  *  Input parameters:  NONE
0102  *
0103  *  Output parameters:  time in microseconds
0104  *
0105  *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
0106  *  is usually deducted from the number returned.
0107  *
0108  *  LEAST_VALID is the lowest number this routine should trust.  Numbers
0109  *  below this are "noise" and zero is returned.
0110  */
0111 benchmark_timer_t benchmark_timer_read(void)
0112 {
0113   uint32_t            total;
0114 
0115   total = (Ttimer_val * TICK_INTERVAL) + lcsr->timer_cnt_1;
0116 
0117   if ( benchmark_timer_find_average_overhead )
0118     return total;          /* in one microsecond units */
0119 
0120   if ( total < LEAST_VALID )
0121     return 0;            /* below timer resolution */
0122 
0123   return total - AVG_OVERHEAD;
0124 }
0125 
0126 /*
0127  *  This routine sets the benchmark_timer_find_average_overhead flag in this
0128  *  module.
0129  *
0130  *  Input parameters:  NONE
0131  *
0132  *  Output parameters:  time in microseconds
0133  */
0134 void benchmark_timer_disable_subtracting_average_overhead(
0135   bool find_flag
0136 )
0137 {
0138   benchmark_timer_find_average_overhead = find_flag;
0139 }