[5d02459] | 1 | /* timer.c |
---|
| 2 | * |
---|
| 3 | * This file manages the benchmark timer used by the RTEMS Timing Test Suite. |
---|
[6b2923cb] | 4 | * Each measured time period is demarcated by calls to benchmark_timer_initialize() and |
---|
| 5 | * benchmark_timer_read(). benchmark_timer_read() usually returns the number of microseconds |
---|
| 6 | * since benchmark_timer_initialize() exitted. |
---|
[5d02459] | 7 | * |
---|
| 8 | * These functions are prototyped in rtems/c/src/lib/include/timerdrv.h and |
---|
| 9 | * must be implemented as part of the BSP. |
---|
| 10 | * |
---|
| 11 | * This port does not allow the application to select which timer on the |
---|
| 12 | * MVME167 to use for the timer, nor does it allow the application to |
---|
| 13 | * configure the timer. The timer uses the VMEchip2 Tick Timer #1. This timer |
---|
| 14 | * is distinct from the clock, which uses Tick Timer #2 in the VMEchip2. |
---|
| 15 | * |
---|
| 16 | * All page references are to the MVME166/MVME167/MVME187 Single Board |
---|
| 17 | * Computer Programmer's Reference Guide (MVME187PG/D2) with the April 1993 |
---|
| 18 | * supplements/addenda (MVME187PG/D2A1). |
---|
| 19 | * |
---|
[08311cc3] | 20 | * COPYRIGHT (c) 1989-1999. |
---|
[5d02459] | 21 | * On-Line Applications Research Corporation (OAR). |
---|
| 22 | * |
---|
| 23 | * The license and distribution terms for this file may be |
---|
| 24 | * found in the file LICENSE in this distribution or at |
---|
[c499856] | 25 | * http://www.rtems.org/license/LICENSE. |
---|
[5d02459] | 26 | * |
---|
| 27 | * Modifications of respective RTEMS file: |
---|
| 28 | * Copyright (c) 1998, National Research Council of Canada |
---|
| 29 | */ |
---|
| 30 | |
---|
| 31 | #include <rtems.h> |
---|
[26c17377] | 32 | #include <rtems/btimer.h> |
---|
[5d02459] | 33 | #include <bsp.h> |
---|
| 34 | |
---|
| 35 | /* Periodic tick interval */ |
---|
| 36 | #define TICK_INTERVAL 10000UL /* T1's countdown constant (10 ms) */ |
---|
| 37 | #define TIMER_INT_LEVEL 6 /* T1's interrupt level */ |
---|
| 38 | #define TIMER_VECTOR (VBR0 * 0x10 + 0x8) /* T1 is vector $X8 (p. 2-71)*/ |
---|
| 39 | |
---|
| 40 | /* Number of interrupts since timer was re-initialized */ |
---|
[2a7e204] | 41 | uint32_t Ttimer_val; |
---|
[5d02459] | 42 | |
---|
| 43 | /* |
---|
[907bf4b8] | 44 | * Set to true to return raw value. Normally zero. Depends on being allocated |
---|
[5d02459] | 45 | * in the .bss section and on that section being explicitly zeroed at boot |
---|
| 46 | * time. |
---|
| 47 | */ |
---|
[907bf4b8] | 48 | bool benchmark_timer_find_average_overhead; |
---|
[5d02459] | 49 | |
---|
[94e6d84] | 50 | rtems_isr_entry timerisr(rtems_vector_number); |
---|
[5d02459] | 51 | |
---|
| 52 | /* |
---|
| 53 | * This routine initializes the Tick Timer 1 on the MVME167 board. |
---|
| 54 | * |
---|
| 55 | * Input parameters: NONE |
---|
| 56 | * |
---|
| 57 | * Output parameters: NONE |
---|
| 58 | * |
---|
| 59 | * NOTE: This routine may not work if the optimizer is enabled for some |
---|
| 60 | * compilers. The multiple writes may be optimized away. |
---|
| 61 | * |
---|
| 62 | * It is important that the timer start/stop overhead be |
---|
| 63 | * determined when porting or modifying this code. |
---|
| 64 | * |
---|
[6128a4a] | 65 | * THE VMECHIP2 PRESCALER REGISTER IS ASSUMED TO BE SET! |
---|
[5d02459] | 66 | * The prescaler is used by all VMEchip2 timers, including the VMEbus grant |
---|
| 67 | * timeout counter, the DMAC time off timer, the DMAC timer on timer, and the |
---|
| 68 | * VMEbus global timeout timer. The prescaler value is normally set by the |
---|
| 69 | * boot ROM to provide a 1 MHz clock to the timers. For a 25 MHz MVME167, the |
---|
| 70 | * prescaler value should be 0xE7 (page 2-63). |
---|
| 71 | */ |
---|
[6b2923cb] | 72 | void benchmark_timer_initialize(void) |
---|
[5d02459] | 73 | { |
---|
| 74 | (void) set_vector( timerisr, TIMER_VECTOR, 0 ); |
---|
[6128a4a] | 75 | |
---|
[5d02459] | 76 | Ttimer_val = 0; /* clear timer ISR count */ |
---|
| 77 | lcsr->intr_ena &= 0xFEFFFFFF; /* disable tick timer 1 interrupt */ |
---|
| 78 | lcsr->intr_clear |= 0x01000000; /* clear tick timer 1 interrupt */ |
---|
| 79 | lcsr->intr_level[0] = /* set int level */ |
---|
| 80 | (lcsr->intr_level[0] & 0xFFFFFFF0) | TIMER_INT_LEVEL; |
---|
| 81 | lcsr->timer_cmp_1 = TICK_INTERVAL; /* period in compare register */ |
---|
| 82 | lcsr->timer_cnt_1 = 0; /* clear tick timer 1 counter */ |
---|
| 83 | lcsr->board_ctl |= 7; /* start tick timer 1, reset-on-compare, */ |
---|
| 84 | /* and clear overflow counter */ |
---|
| 85 | |
---|
| 86 | lcsr->intr_ena |= 0x01000000; /* enable tick timer 1 interrupt */ |
---|
| 87 | lcsr->vector_base |= MASK_INT; /* unmask VMEchip2 interrupts */ |
---|
| 88 | } |
---|
| 89 | |
---|
| 90 | #define AVG_OVERHEAD 3UL /* It typically takes 3.0 microseconds */ |
---|
| 91 | /* (3 countdowns) to start/stop the timer. */ |
---|
| 92 | #define LEAST_VALID 3UL /* Don't trust a value lower than this */ |
---|
| 93 | |
---|
| 94 | /* |
---|
| 95 | * This routine reads the Tick Timer 1 on the MVME167 board. |
---|
| 96 | * |
---|
| 97 | * Input parameters: NONE |
---|
| 98 | * |
---|
| 99 | * Output parameters: time in microseconds |
---|
| 100 | * |
---|
| 101 | * AVG_OVEREHAD is the overhead for starting and stopping the timer. It |
---|
| 102 | * is usually deducted from the number returned. |
---|
| 103 | * |
---|
| 104 | * LEAST_VALID is the lowest number this routine should trust. Numbers |
---|
| 105 | * below this are "noise" and zero is returned. |
---|
| 106 | */ |
---|
[26c17377] | 107 | uint32_t benchmark_timer_read(void) |
---|
[5d02459] | 108 | { |
---|
[2a7e204] | 109 | uint32_t total; |
---|
[5d02459] | 110 | |
---|
| 111 | total = (Ttimer_val * TICK_INTERVAL) + lcsr->timer_cnt_1; |
---|
| 112 | |
---|
[6b2923cb] | 113 | if ( benchmark_timer_find_average_overhead ) |
---|
[5d02459] | 114 | return total; /* in one microsecond units */ |
---|
| 115 | |
---|
| 116 | if ( total < LEAST_VALID ) |
---|
| 117 | return 0; /* below timer resolution */ |
---|
| 118 | |
---|
| 119 | return total - AVG_OVERHEAD; |
---|
| 120 | } |
---|
| 121 | |
---|
| 122 | /* |
---|
[6b2923cb] | 123 | * This routine sets the benchmark_timer_find_average_overhead flag in this |
---|
[5d02459] | 124 | * module. |
---|
| 125 | * |
---|
| 126 | * Input parameters: NONE |
---|
| 127 | * |
---|
| 128 | * Output parameters: time in microseconds |
---|
| 129 | */ |
---|
[6b2923cb] | 130 | void benchmark_timer_disable_subtracting_average_overhead( |
---|
[907bf4b8] | 131 | bool find_flag |
---|
[5d02459] | 132 | ) |
---|
| 133 | { |
---|
[6b2923cb] | 134 | benchmark_timer_find_average_overhead = find_flag; |
---|
[5d02459] | 135 | } |
---|