summaryrefslogtreecommitdiffstats
path: root/bsps/mips/shared/timer/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/mips/shared/timer/timer.c')
-rw-r--r--bsps/mips/shared/timer/timer.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/bsps/mips/shared/timer/timer.c b/bsps/mips/shared/timer/timer.c
new file mode 100644
index 0000000000..da5291a48a
--- /dev/null
+++ b/bsps/mips/shared/timer/timer.c
@@ -0,0 +1,113 @@
+/**
+ * @file
+ * @brief IDT 4650 Timer Driver.
+ *
+ * This file manages the benchmark timer used by the RTEMS Timing Test
+ * Suite.
+ */
+
+/*
+ * Author: Craig Lebakken <craigl@transition.com>
+ *
+ * COPYRIGHT (c) 1996 by Transition Networks Inc.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Transition Networks not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * Transition Networks makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * derived from src/lib/libbsp/no_cpu/no_bsp/timer/timer.c
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <rtems/btimer.h>
+
+#define CLOCKS_PER_MICROSECOND ( CPU_CLOCK_RATE_MHZ )
+#define TIMER_MAX_VALUE 0xffffffff
+
+extern uint32_t mips_read_timer( void );
+
+static bool benchmark_timer_find_average_overhead;
+static uint32_t benchmark_timer_initial_value = 0;
+
+void benchmark_timer_initialize( void )
+{
+ benchmark_timer_initial_value = mips_read_timer();
+ /*
+ * Somehow start the timer
+ */
+
+ /* Timer on 4650 is always running */
+}
+
+/*
+ * The following controls the behavior of benchmark_timer_read().
+ *
+ * AVG_OVEREHAD is the overhead for starting and stopping the timer. It
+ * is usually deducted from the number returned.
+ *
+ * LEAST_VALID is the lowest number this routine should trust. Numbers
+ * below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD 8 /* It typically takes X.X microseconds */
+ /* (Y countdowns) to start/stop the timer. */
+ /* This value is in cycles. */
+#define LEAST_VALID 1 /* Don't trust a clicks value lower than this */
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+ uint64_t clicks;
+ uint32_t total;
+
+ /*
+ * Read the timer and see how many clicks it has been since we started.
+ */
+
+ clicks = mips_read_timer(); /* XXX: read some HW here */
+ if (clicks < benchmark_timer_initial_value)
+ {
+ clicks += TIMER_MAX_VALUE;
+ }
+ clicks -= benchmark_timer_initial_value;
+
+ /*
+ * Total is calculated by taking into account the number of timer overflow
+ * interrupts since the timer was initialized and clicks since the last
+ * interrupts.
+ */
+#if 0 /* leave total in number of cycles */
+ total = clicks / CLOCKS_PER_MICROSECOND;
+#else
+ total = clicks;
+#endif
+
+ if ( benchmark_timer_find_average_overhead == 1 )
+ return total; /* in # cycles units */
+ else {
+ if ( total < LEAST_VALID )
+ return 0; /* below timer resolution */
+ /*
+ * leave total in cycles
+ */
+ return (total - AVG_OVERHEAD);
+ }
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+ benchmark_timer_find_average_overhead = find_flag;
+}