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