source: rtems/c/src/lib/libbsp/or1k/generic_or1k/clock/clockdrv.c @ 7cd2484

4.115
Last change on this file since 7cd2484 was 3d597c0, checked in by Hesham ALMatary <heshamelmatary@…>, on 04/18/15 at 16:25:51

Rename or1ksim BSP to generic_or1k

or1ksim BSP was initially named after or1ksim simulator, and it was
intented to only run there. But now it can also run on QEMU, jor1k and
real FPGA boards without modifications. It makes more sense to give
it a new generic name like generic_or1k.

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup bsp_clock
5 *
6 * @brief or1k clock support.
7 */
8
9/*
10 * generic_or1k Clock driver
11 *
12 * COPYRIGHT (c) 2014-2015 Hesham ALMatary <heshamelmatary@gmail.com>
13 *
14 * The license and distribution terms for this file may be
15 * found in the file LICENSE in this distribution or at
16 * http://www.rtems.org/license/LICENSE
17 */
18
19#include <rtems.h>
20#include <bsp.h>
21#include <bsp/irq.h>
22#include <bsp/generic_or1k.h>
23#include <rtems/score/cpu.h>
24#include <rtems/score/or1k-utility.h>
25
26/* The number of clock cycles before generating a tick timer interrupt. */
27#define TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT     0x09ED9
28#define OR1K_CLOCK_CYCLE_TIME_NANOSECONDS     10
29
30/* CPU counter */
31static CPU_Counter_ticks cpu_counter_ticks;
32
33/* This prototype is added here to Avoid warnings */
34void Clock_isr(void *arg);
35
36static void generic_or1k_clock_at_tick(void)
37{
38  uint32_t TTMR;
39
40 /* For TTMR register,
41  * The least significant 28 bits are the number of clock cycles
42  * before generating a tick timer interrupt. While the most
43  * significant 4 bits are used for mode configuration, tick timer
44  * interrupt enable and pending interrupts status.
45  */
46  TTMR = (CPU_OR1K_SPR_TTMR_MODE_RESTART | CPU_OR1K_SPR_TTMR_IE |
47           (TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT & CPU_OR1K_SPR_TTMR_TP_MASK)
48         ) & ~(CPU_OR1K_SPR_TTMR_IP);
49
50  _OR1K_mtspr(CPU_OR1K_SPR_TTMR, TTMR);
51  _OR1K_mtspr(CPU_OR1K_SPR_TTCR, 0);
52
53  cpu_counter_ticks += TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT;
54}
55
56static void generic_or1k_clock_handler_install(
57  proc_ptr new_isr,
58   proc_ptr old_isr
59)
60{
61  rtems_status_code sc = RTEMS_SUCCESSFUL;
62  old_isr = NULL;
63  _CPU_ISR_install_vector(OR1K_EXCEPTION_TICK_TIMER,
64                          new_isr,
65                          old_isr);
66
67  if (sc != RTEMS_SUCCESSFUL) {
68    rtems_fatal_error_occurred(0xdeadbeef);
69  }
70}
71
72static void generic_or1k_clock_initialize(void)
73{
74  uint32_t TTMR;
75
76 /* For TTMR register,
77  * The least significant 28 bits are the number of clock cycles
78  * before generating a tick timer interrupt. While the most
79  * significant 4 bits are used for mode configuration, tick timer
80  * interrupt enable and pending interrupts status.
81  */
82
83  /* FIXME: Long interval should pass since initializing the tick timer
84   * registers fires exceptions dispite interrupts has not been enabled yet.
85   */
86  TTMR = (CPU_OR1K_SPR_TTMR_MODE_RESTART | CPU_OR1K_SPR_TTMR_IE |
87           (0xFFED9 & CPU_OR1K_SPR_TTMR_TP_MASK)
88         ) & ~(CPU_OR1K_SPR_TTMR_IP);
89
90  _OR1K_mtspr(CPU_OR1K_SPR_TTMR, TTMR);
91  _OR1K_mtspr(CPU_OR1K_SPR_TTCR, 0);
92
93  /* Initialize CPU Counter */
94  cpu_counter_ticks = 0;
95}
96
97 static void generic_or1k_clock_cleanup(void)
98{
99 uint32_t sr;
100
101  sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
102
103  /* Disable tick timer exceptions */
104  _OR1K_mtspr(CPU_OR1K_SPR_SR, (sr & ~CPU_OR1K_SPR_SR_IEE)
105  & ~CPU_OR1K_SPR_SR_TEE);
106
107  /* Invalidate tick timer config registers */
108  _OR1K_mtspr(CPU_OR1K_SPR_TTCR, 0);
109  _OR1K_mtspr(CPU_OR1K_SPR_TTMR, 0);
110}
111
112/*
113 *  Return the nanoseconds since last tick
114 */
115static uint32_t generic_or1k_clock_nanoseconds_since_last_tick(void)
116{
117  return
118  TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT * OR1K_CLOCK_CYCLE_TIME_NANOSECONDS;
119}
120
121CPU_Counter_ticks _CPU_Counter_read(void)
122{
123  uint32_t ticks_since_last_timer_interrupt;
124
125  ticks_since_last_timer_interrupt = _OR1K_mfspr(CPU_OR1K_SPR_TTCR);
126
127  return cpu_counter_ticks + ticks_since_last_timer_interrupt;
128}
129
130CPU_Counter_ticks _CPU_Counter_difference(
131  CPU_Counter_ticks second,
132  CPU_Counter_ticks first
133)
134{
135  return second - first;
136}
137#define Clock_driver_support_at_tick() generic_or1k_clock_at_tick()
138
139#define Clock_driver_support_initialize_hardware() generic_or1k_clock_initialize()
140
141#define Clock_driver_support_install_isr(isr, old_isr) \
142  do {                                                 \
143    old_isr = NULL;                                    \
144    generic_or1k_clock_handler_install(isr, old_isr);       \
145  } while (0)
146
147#define Clock_driver_support_shutdown_hardware() generic_or1k_clock_cleanup()
148
149#define Clock_driver_nanoseconds_since_last_tick \
150  generic_or1k_clock_nanoseconds_since_last_tick
151
152#include "../../../shared/clockdrv_shell.h"
Note: See TracBrowser for help on using the repository browser.