]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo_bsp/ps7_cortexa9_0/libsrc/standalone_v4_1/src/profile/_profile_timer_hw.c
f3552b8c8b06b6ffe5d0bc4039a3f28adeaf96ee
[freertos] / FreeRTOS / Demo / CORTEX_A9_Zynq_ZC702 / RTOSDemo_bsp / ps7_cortexa9_0 / libsrc / standalone_v4_1 / src / profile / _profile_timer_hw.c
1 // $Id: _profile_timer_hw.c,v 1.1.2.1 2011/05/17 04:37:56 sadanan Exp $
2 /******************************************************************************
3 *
4 * Copyright (C) 2004 - 2014 Xilinx, Inc.  All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * Use of the Software is limited solely to applications:
17 * (a) running on a Xilinx device, or
18 * (b) that interact with a Xilinx device through a bus or interconnect.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
25 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 *
28 * Except as contained in this notice, the name of the Xilinx shall not be used
29 * in advertising or otherwise to promote the sale, use or other dealings in
30 * this Software without prior written authorization from Xilinx.
31 *
32 ******************************************************************************
33 *
34 *  _program_timer_hw.c:
35 *       Timer related functions
36 *
37 ******************************************************************************/
38
39 #include "profile.h"
40 #include "_profile_timer_hw.h"
41
42 #include "xil_exception.h"
43
44 #ifdef PROC_PPC
45 #include "xtime_l.h"
46 #include "xpseudo_asm.h"
47 #endif
48
49 #ifdef TIMER_CONNECT_INTC
50 #include "xintc_l.h"
51 #include "xintc.h"
52 #endif  // TIMER_CONNECT_INTC
53
54 //#ifndef PPC_PIT_INTERRUPT
55 #if (!defined PPC_PIT_INTERRUPT && !defined PROC_CORTEXA9)
56 #include "xtmrctr_l.h"
57 #endif
58
59 extern unsigned int timer_clk_ticks ;
60
61 //--------------------------------------------------------------------
62 // PowerPC Target - Timer related functions
63 //--------------------------------------------------------------------
64 #ifdef PROC_PPC405
65
66
67 //--------------------------------------------------------------------
68 // PowerPC PIT Timer Init.
69 //      Defined only if PIT Timer is used for Profiling
70 //
71 //--------------------------------------------------------------------
72 #ifdef PPC_PIT_INTERRUPT
73 int ppc_pit_init( void )
74 {
75         // 1. Register Profile_intr_handler as Interrupt handler
76         // 2. Set PIT Timer Interrupt and Enable it.
77         Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_PIT_INT,
78                             (Xil_ExceptionHandler)profile_intr_handler,(void *)0);
79         XTime_PITSetInterval( timer_clk_ticks ) ;
80         XTime_PITEnableAutoReload() ;
81         return 0;
82 }
83 #endif
84
85
86 //--------------------------------------------------------------------
87 // PowerPC Timer Initialization functions.
88 //      For PowerPC, PIT and opb_timer can be used for Profiling. This
89 //      is selected by the user in standalone BSP
90 //
91 //--------------------------------------------------------------------
92 int powerpc405_init()
93 {
94         Xil_ExceptionInit() ;
95         Xil_ExceptionDisableMask( XIL_EXCEPTION_NON_CRITICAL ) ;
96
97         // Initialize the Timer.
98         // 1. If PowerPC PIT Timer has to be used, initialize PIT timer.
99         // 2. Else use opb_timer. It can be directly connected or thru intc to PowerPC
100 #ifdef PPC_PIT_INTERRUPT
101         ppc_pit_init();
102 #else
103 #ifdef TIMER_CONNECT_INTC
104         Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_NON_CRITICAL_INT,
105                               (Xil_ExceptionHandler)XIntc_DeviceInterruptHandler,(void *)0);
106         XIntc_RegisterHandler( INTC_BASEADDR, PROFILE_TIMER_INTR_ID,
107                              (XInterruptHandler)profile_intr_handler,(void*)0);
108 #else
109         Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_NON_CRITICAL_INT,
110                               (Xil_ExceptionHandler)profile_intr_handler,(void *)0);
111 #endif
112         // Initialize the timer with Timer Ticks
113         opb_timer_init() ;
114 #endif
115
116         // Enable Interrupts in the System, if Profile Timer is the only Interrupt
117         // in the System.
118 #ifdef ENABLE_SYS_INTR
119 #ifdef PPC_PIT_INTERRUPT
120         XTime_PITEnableInterrupt() ;
121 #elif TIMER_CONNECT_INTC
122         XIntc_MasterEnable( INTC_BASEADDR );
123         XIntc_SetIntrSvcOption( INTC_BASEADDR, XIN_SVC_ALL_ISRS_OPTION);
124         XIntc_EnableIntr( INTC_BASEADDR, PROFILE_TIMER_INTR_MASK );
125 #endif
126         Xil_ExceptionEnableMask( XIL_EXCEPTION_NON_CRITICAL ) ;
127 #endif
128         return 0;
129 }
130
131 #endif  // PROC_PPC
132
133
134
135 //--------------------------------------------------------------------
136 // PowerPC440 Target - Timer related functions
137 //--------------------------------------------------------------------
138 #ifdef PROC_PPC440
139
140
141 //--------------------------------------------------------------------
142 // PowerPC DEC Timer Init.
143 //      Defined only if DEC Timer is used for Profiling
144 //
145 //--------------------------------------------------------------------
146 #ifdef PPC_PIT_INTERRUPT
147 int ppc_dec_init( void )
148 {
149         // 1. Register Profile_intr_handler as Interrupt handler
150         // 2. Set DEC Timer Interrupt and Enable it.
151         Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_DEC_INT,
152                             (Xil_ExceptionHandler)profile_intr_handler,(void *)0);
153         XTime_DECSetInterval( timer_clk_ticks ) ;
154         XTime_DECEnableAutoReload() ;
155         return 0;
156 }
157 #endif
158
159
160 //--------------------------------------------------------------------
161 // PowerPC Timer Initialization functions.
162 //      For PowerPC, DEC and opb_timer can be used for Profiling. This
163 //      is selected by the user in standalone BSP
164 //
165 //--------------------------------------------------------------------
166 int powerpc405_init(void)
167 {
168         Xil_ExceptionInit();
169         Xil_ExceptionDisableMask( XIL_EXCEPTION_NON_CRITICAL ) ;
170
171         // Initialize the Timer.
172         // 1. If PowerPC DEC Timer has to be used, initialize DEC timer.
173         // 2. Else use opb_timer. It can be directly connected or thru intc to PowerPC
174 #ifdef PPC_PIT_INTERRUPT
175         ppc_dec_init();
176 #else
177 #ifdef TIMER_CONNECT_INTC
178         Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_NON_CRITICAL_INT,
179                                      (Xil_ExceptionHandler)XIntc_DeviceInterruptHandler,(void *)0);
180
181         XIntc_RegisterHandler( INTC_BASEADDR, PROFILE_TIMER_INTR_ID,
182                              (XInterruptHandler)profile_intr_handler,(void*)0);
183 #else
184         Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_NON_CRITICAL_INT,
185                               (Xil_ExceptionHandler)profile_intr_handler,(void *)0);
186         Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_NON_CRITICAL_INT,
187                               (Xil_ExceptionHandler)profile_intr_handler,(void *)0);
188 #endif
189         // Initialize the timer with Timer Ticks
190         opb_timer_init() ;
191 #endif
192
193         // Enable Interrupts in the System, if Profile Timer is the only Interrupt
194         // in the System.
195 #ifdef ENABLE_SYS_INTR
196 #ifdef PPC_PIT_INTERRUPT
197         XTime_DECEnableInterrupt() ;
198 #elif TIMER_CONNECT_INTC
199         XIntc_MasterEnable( INTC_BASEADDR );
200         XIntc_SetIntrSvcOption( INTC_BASEADDR, XIN_SVC_ALL_ISRS_OPTION);
201         XIntc_EnableIntr( INTC_BASEADDR, PROFILE_TIMER_INTR_MASK );
202 #endif
203         Xil_ExceptionEnableMask( XEXC_NON_CRITICAL ) ;
204 #endif
205         return 0;
206 }
207
208 #endif  // PROC_PPC440
209
210 //--------------------------------------------------------------------
211 // opb_timer Initialization for PowerPC and MicroBlaze. This function
212 // is not needed if DEC timer is used in PowerPC
213 //
214 //--------------------------------------------------------------------
215 //#ifndef PPC_PIT_INTERRUPT
216 #if (!defined PPC_PIT_INTERRUPT && !defined PROC_CORTEXA9)
217 int opb_timer_init( void )
218 {
219         // set the number of cycles the timer counts before interrupting
220         XTmrCtr_SetLoadReg(PROFILE_TIMER_BASEADDR, 0, timer_clk_ticks);
221
222         // reset the timers, and clear interrupts
223         XTmrCtr_SetControlStatusReg(PROFILE_TIMER_BASEADDR, 0,
224                                      XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK );
225
226         // start the timers
227         XTmrCtr_SetControlStatusReg(PROFILE_TIMER_BASEADDR, 0, XTC_CSR_ENABLE_TMR_MASK
228                              | XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK);
229         return 0;
230 }
231 #endif
232
233
234 //--------------------------------------------------------------------
235 // MicroBlaze Target - Timer related functions
236 //--------------------------------------------------------------------
237 #ifdef PROC_MICROBLAZE
238
239 //--------------------------------------------------------------------
240 // Initialize the Profile Timer for MicroBlaze Target.
241 //      For MicroBlaze, opb_timer is used. The opb_timer can be directly
242 //      connected to MicroBlaze or connected through Interrupt Controller.
243 //
244 //--------------------------------------------------------------------
245 int microblaze_init(void)
246 {
247         // Register profile_intr_handler
248         // 1. If timer is connected to Interrupt Controller, register the handler
249         //    to Interrupt Controllers vector table.
250         // 2. If timer is directly connected to MicroBlaze, register the handler
251         //    as Interrupt handler
252         Xil_ExceptionInit();
253
254 #ifdef TIMER_CONNECT_INTC
255         XIntc_RegisterHandler( INTC_BASEADDR, PROFILE_TIMER_INTR_ID,
256                              (XInterruptHandler)profile_intr_handler,(void*)0);
257 #else
258         Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
259                                      (Xil_ExceptionHandler)profile_intr_handler,
260                                      (void *)0) ;
261 #endif
262
263         // Initialize the timer with Timer Ticks
264         opb_timer_init() ;
265
266         // Enable Interrupts in the System, if Profile Timer is the only Interrupt
267         // in the System.
268 #ifdef ENABLE_SYS_INTR
269 #ifdef TIMER_CONNECT_INTC
270         XIntc_MasterEnable( INTC_BASEADDR );
271         XIntc_SetIntrSvcOption( INTC_BASEADDR, XIN_SVC_ALL_ISRS_OPTION);
272         XIntc_EnableIntr( INTC_BASEADDR, PROFILE_TIMER_INTR_MASK );
273         Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
274                                      (Xil_ExceptionHandler)XIntc_DeviceInterruptHandler,(void *)0);
275 #endif
276
277 #endif
278
279         Xil_ExceptionEnable();
280
281         return 0;
282
283 }
284
285 #endif  // PROC_MICROBLAZE
286
287
288
289 //--------------------------------------------------------------------
290 // Cortex A9 Target - Timer related functions
291 //--------------------------------------------------------------------
292 #ifdef PROC_CORTEXA9
293
294 //--------------------------------------------------------------------
295 // Initialize the Profile Timer for Cortex A9 Target.
296 //      The scu private timer is connected to the Scu GIC controller.
297 //
298 //--------------------------------------------------------------------
299 int scu_timer_init( void )
300 {
301         // set the number of cycles the timer counts before interrupting
302         // scu timer runs at half the cpu clock
303         XScuTimer_SetLoadReg(PROFILE_TIMER_BASEADDR, timer_clk_ticks/2);
304
305         // clear any pending interrupts
306         XScuTimer_SetIntrReg(PROFILE_TIMER_BASEADDR, 1);
307
308         // enable interrupts, auto-reload mode and start the timer
309         XScuTimer_SetControlReg(PROFILE_TIMER_BASEADDR, XSCUTIMER_CONTROL_IRQ_ENABLE_MASK |
310                                 XSCUTIMER_CONTROL_AUTO_RELOAD_MASK | XSCUTIMER_CONTROL_ENABLE_MASK);
311
312         return 0;
313 }
314
315 int cortexa9_init(void)
316 {
317
318         Xil_ExceptionInit();
319
320         XScuGic_DeviceInitialize(0);
321
322         /*
323          * Connect the interrupt controller interrupt handler to the hardware
324          * interrupt handling logic in the processor.
325          */
326         Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
327                                 (Xil_ExceptionHandler)XScuGic_DeviceInterruptHandler,
328                                 (void *)0);
329
330         /*
331          * Connect the device driver handler that will be called when an
332          * interrupt for the device occurs, the handler defined above performs
333          * the specific interrupt processing for the device.
334          */
335         XScuGic_RegisterHandler(SCUGIC_CPU_BASEADDR,
336                                 PROFILE_TIMER_INTR_ID,
337                                 (Xil_ExceptionHandler)profile_intr_handler,
338                                 (void *)0);
339
340         /*
341          * Enable the interrupt for scu timer.
342          */
343         XScuGic_EnableIntr(SCUGIC_DIST_BASEADDR, PROFILE_TIMER_INTR_ID);
344
345         /*
346          * Enable interrupts in the Processor.
347          */
348         Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
349
350         /*
351          * Initialize the timer with Timer Ticks
352          */
353         scu_timer_init() ;
354
355         Xil_ExceptionEnable();
356
357         return 0;
358 }
359
360 #endif  // PROC_CORTEXA9