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