1 /*
2  * Trace Recorder for Tracealyzer v4.10.3
3  * Copyright 2023 Percepio AB
4  * www.percepio.com
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  *
8  * The hardware abstraction layer for the trace recorder.
9  */
10 
11 #ifndef TRC_HARDWARE_PORT_H
12 #define TRC_HARDWARE_PORT_H
13 
14 #include <trcDefines.h>
15 
16 /*
17  * @brief
18  * This macro must be used as name for the variable in the critical section allocation.
19  * Example: #define TRACE_ALLOC_CRITICAL_SECTION uint32_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
20  */
21 #define TRACE_ALLOC_CRITICAL_SECTION_NAME xTraceCriticalSectionStatus
22 
23 #if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NOT_SET)
24 	#error "TRC_CFG_HARDWARE_PORT not selected - see trcConfig.h"
25 #endif
26 
27 /*******************************************************************************
28  * TRC_IRQ_PRIORITY_ORDER
29  *
30  * Macro which should be defined as an integer of 0 or 1.
31  *
32  * This should be 0 if lower IRQ priority values implies higher priority
33  * levels, such as on ARM Cortex M. If the opposite scheme is used, i.e.,
34  * if higher IRQ priority values means higher priority, this should be 1.
35  *
36  * This setting is not critical. It is used only to sort and colorize the
37  * interrupts in priority order, in case you record interrupts using
38  * the vTraceStoreISRBegin and vTraceStoreISREnd routines.
39  *
40  ******************************************************************************
41  *
42  * HWTC Macros
43  *
44  * These macros provides a hardware isolation layer representing the
45  * hardware timer/counter used for the event timestamping.
46  *
47  * TRC_HWTC_COUNT: How to read the current value of the timer/counter.
48  *
49  * TRC_HWTC_TYPE: Tells the type of timer/counter used for TRC_HWTC_COUNT:
50  *
51  * - TRC_FREE_RUNNING_32BIT_INCR:
52  *   Free-running 32-bit timer/counter, counting upwards from 0.
53  *
54  * - TRC_FREE_RUNNING_32BIT_DECR
55  *   Free-running 32-bit timer/counter, counting downwards from 0xFFFFFFFF.
56  *
57  * - TRC_OS_TIMER_INCR
58  *	 Periodic timer that drives the OS tick interrupt, counting upwards
59  *   from 0 until (TRC_HWTC_PERIOD-1).
60  *
61  * - TRC_OS_TIMER_DECR
62  *	 Periodic timer that drives the OS tick interrupt, counting downwards
63  *   from TRC_HWTC_PERIOD-1 until 0.
64  *
65  * - TRC_CUSTOM_TIMER_INCR
66  *   A custom timer or counter independent of the OS tick, counting
67  *   downwards from TRC_HWTC_PERIOD-1 until 0. (Currently only supported
68  *   in streaming mode).
69  *
70  * - TRC_CUSTOM_TIMER_DECR
71  *   A custom timer independent of the OS tick, counting downwards
72  *   from TRC_HWTC_PERIOD-1 until 0. (Currently only supported
73  *   in streaming mode).
74  *
75  * TRC_HWTC_PERIOD: The number of HWTC_COUNT ticks until the timer wraps
76  * around. If using TRC_FREE_RUNNING_32BIT_INCR/DECR, this should be 0.
77  *
78  * TRC_HWTC_FREQ_HZ: The clock rate of the TRC_HWTC_COUNT counter in Hz. If using
79  * TRC_OS_TIMER_INCR/DECR, this is should be TRC_HWTC_PERIOD * TRC_TICK_RATE_HZ.
80  * If using a free-running timer, this is often TRACE_CPU_CLOCK_HZ (if running at
81  * the core clock rate). If using TRC_CUSTOM_TIMER_INCR/DECR, this should match
82  * the clock rate of your custom timer (i.e., TRC_HWTC_COUNT). If the default value
83  * of TRC_HWTC_FREQ_HZ is incorrect for your setup, you can override it by calling
84  * vTraceSetFrequency before calling vTraceEnable.
85  *
86  * TRC_HWTC_DIVISOR (used in snapshot mode only):
87  * In snapshot mode, the timestamp resolution is TRC_HWTC_FREQ_HZ/TRC_HWTC_DIVISOR.
88  * If the timer frequency is very high (hundreds of MHz), we recommend increasing
89  * the TRC_HWTC_DIVISOR prescaler, to reduce the bandwidth needed to store
90  * timestamps. This since extra "XTS" events are inserted if the time since the
91  * previous event exceeds a certain limit (255 or 65535 depending on event type).
92  * It is advised to keep the time between most events below 65535 native ticks
93  * (after division by TRC_HWTC_DIVISOR) to avoid frequent XTS events.
94  ******************************************************************************/
95 
96 #if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NOT_SET)
97 	#error "TRC_CFG_HARDWARE_PORT not selected - see trcConfig.h"
98 #endif
99 
100 #if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32)
101 /* This can be used as a template for any free-running 32-bit counter */
102 void vTraceTimerReset(void);
103 uint32_t uiTraceTimerGetFrequency(void);
104 uint32_t uiTraceTimerGetValue(void);
105 
106 #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
107 #define TRC_HWTC_COUNT ((TraceUnsignedBaseType_t)uiTraceTimerGetValue())
108 #define TRC_HWTC_PERIOD 0
109 #define TRC_HWTC_DIVISOR 1
110 #define TRC_HWTC_FREQ_HZ ((TraceUnsignedBaseType_t)uiTraceTimerGetFrequency())
111 
112 #define TRC_IRQ_PRIORITY_ORDER 1
113 
114 #define TRC_PORT_SPECIFIC_INIT() vTraceTimerReset()
115 
116 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win64)
117 /* This can be used as a template for any free-running 32-bit counter */
118 void vTraceTimerReset(void);
119 uint32_t uiTraceTimerGetFrequency(void);
120 uint32_t uiTraceTimerGetValue(void);
121 
122 #define TRC_BASE_TYPE int64_t
123 
124 #define TRC_UNSIGNED_BASE_TYPE uint64_t
125 
126 #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
127 #define TRC_HWTC_COUNT ((TraceUnsignedBaseType_t)uiTraceTimerGetValue())
128 #define TRC_HWTC_PERIOD 0
129 #define TRC_HWTC_DIVISOR 1
130 #define TRC_HWTC_FREQ_HZ ((TraceUnsignedBaseType_t)uiTraceTimerGetFrequency())
131 
132 #define TRC_IRQ_PRIORITY_ORDER 1
133 
134 #define TRC_PORT_SPECIFIC_INIT() vTraceTimerReset()
135 
136 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_HWIndependent)
137 	/* Timestamping by OS tick only (typically 1 ms resolution) */
138 	#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
139 	#define TRC_HWTC_COUNT 0
140 	#define TRC_HWTC_PERIOD 1
141 	#define TRC_HWTC_DIVISOR 1
142 	#define TRC_HWTC_FREQ_HZ TRC_TICK_RATE_HZ
143 
144 	/* Set the meaning of IRQ priorities in ISR tracing - see above */
145 	#define TRC_IRQ_PRIORITY_ORDER NOT_SET
146 
147 /* This hardware port is deprecated and should not be used due to the low timer accuracy. */
148 #error TRC_HARDWARE_PORT_HWIndependent is deprecated
149 
150 #elif ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M_NRF_SD))
151 
152 	#ifndef __CORTEX_M
153 	#error "Can't find the CMSIS API. Please include your processor's header file in trcConfig.h"
154 	#endif
155 
156 #if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M)
157 	#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
158 	#define TRACE_ENTER_CRITICAL_SECTION() {TRACE_ALLOC_CRITICAL_SECTION_NAME = __get_PRIMASK(); __set_PRIMASK(1);} /* PRIMASK disables ALL interrupts - allows for tracing in any ISR */
159 	#define TRACE_EXIT_CRITICAL_SECTION() {__set_PRIMASK(TRACE_ALLOC_CRITICAL_SECTION_NAME);}
160 #else
161         #include "nrf_nvic.h"
162         #define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
163         #define TRACE_ENTER_CRITICAL_SECTION() {(void) sd_nvic_critical_region_enter((uint8_t*)&TRACE_ALLOC_CRITICAL_SECTION_NAME);}
164         #define TRACE_EXIT_CRITICAL_SECTION() {(void) sd_nvic_critical_region_exit((uint8_t)TRACE_ALLOC_CRITICAL_SECTION_NAME);}
165 #endif
166 
167 	/**************************************************************************
168 	* For Cortex-M3, M4 and M7, the DWT cycle counter is used for timestamping.
169 	* For Cortex-M0 and M0+, the SysTick timer is used since DWT is not
170 	* available. Systick timestamping can also be forced on Cortex-M3, M4 and
171 	* M7 by defining the preprocessor directive TRC_CFG_ARM_CM_USE_SYSTICK,
172 	* either directly below or in trcConfig.h.
173 	*
174 	* #define TRC_CFG_ARM_CM_USE_SYSTICK
175     **************************************************************************/
176 
177 	#if ((__CORTEX_M >= 0x03) && (! defined TRC_CFG_ARM_CM_USE_SYSTICK))
178 
179 		void xTraceHardwarePortInitCortexM(void);
180 
181 		#define TRC_REG_DEMCR (*(volatile uint32_t*)0xE000EDFC)
182 		#define TRC_REG_DWT_CTRL (*(volatile uint32_t*)0xE0001000)
183 		#define TRC_REG_DWT_CYCCNT (*(volatile uint32_t*)0xE0001004)
184 		#define TRC_REG_DWT_EXCCNT (*(volatile uint32_t*)0xE000100C)
185 
186 		#define TRC_REG_ITM_LOCKACCESS (*(volatile uint32_t*)0xE0001FB0)
187 		#define TRC_ITM_LOCKACCESS_UNLOCK (0xC5ACCE55)
188 
189 		/* Bit mask for TRCENA bit in DEMCR - Global enable for DWT and ITM */
190 		#define TRC_DEMCR_TRCENA (1 << 24)
191 
192 		/* Bit mask for NOPRFCNT bit in DWT_CTRL. If 1, DWT_EXCCNT is not supported */
193 		#define TRC_DWT_CTRL_NOPRFCNT (1 << 24)
194 
195 		/* Bit mask for NOCYCCNT bit in DWT_CTRL. If 1, DWT_CYCCNT is not supported */
196 		#define TRC_DWT_CTRL_NOCYCCNT (1 << 25)
197 
198 		/* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_EXCCNT */
199 		#define TRC_DWT_CTRL_EXCEVTENA (1 << 18)
200 
201 		/* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_CYCCNT */
202 		#define TRC_DWT_CTRL_CYCCNTENA (1)
203 
204 		#define TRC_PORT_SPECIFIC_INIT() xTraceHardwarePortInitCortexM()
205 
206 		#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
207 		#define TRC_HWTC_COUNT TRC_REG_DWT_CYCCNT
208 		#define TRC_HWTC_PERIOD 0
209 		#define TRC_HWTC_DIVISOR 4
210 		#define TRC_HWTC_FREQ_HZ TRACE_CPU_CLOCK_HZ
211 		#define TRC_IRQ_PRIORITY_ORDER 0
212 
213 	#else
214 		/* Uses the lower bits of the 64-bit free running timer in the RP2040. SysTick can not be used since it is different for both cores. */
215 		#if defined(_CMSIS_RP2040_H_) || defined(RP2040_H)
216 			#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
217 			#define TRC_HWTC_COUNT (*((volatile uint32_t*)0x4005400c))
218 			#define TRC_HWTC_PERIOD 0
219 			#define TRC_HWTC_DIVISOR 1
220 			#define TRC_HWTC_FREQ_HZ 1000000
221 			#define TRC_IRQ_PRIORITY_ORDER 0
222 		#else
223 			#define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
224 			#define TRC_HWTC_COUNT (*((volatile uint32_t*)0xE000E018))
225 			#define TRC_HWTC_PERIOD ((*((volatile uint32_t*)0xE000E014)) + 1)
226 			#define TRC_HWTC_DIVISOR 4
227 			#define TRC_HWTC_FREQ_HZ TRACE_CPU_CLOCK_HZ
228 			#define TRC_IRQ_PRIORITY_ORDER 0
229 		#endif
230 
231 	#endif
232 
233 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Renesas_RX600)
234 	#define TRACE_ALLOC_CRITICAL_SECTION() TraceBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
235 	#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = TRC_KERNEL_PORT_SET_INTERRUPT_MASK(); }
236 	#define TRACE_EXIT_CRITICAL_SECTION() { TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK(TRACE_ALLOC_CRITICAL_SECTION_NAME); }
237 
238 	#include <iodefine.h>
239 
240 	#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
241 
242 		#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
243 		#define TRC_HWTC_COUNT (CMT0.CMCNT)
244 
245 	#elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
246 
247 		/* Decreasing counters better for Tickless Idle? */
248 		#define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
249 		#define TRC_HWTC_COUNT (CMT0.CMCOR - CMT0.CMCNT)
250 
251 	#endif
252 
253 	#define TRC_HWTC_PERIOD (CMT0.CMCOR + 1)
254 	#define TRC_HWTC_DIVISOR 1
255 	#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
256 	#define TRC_IRQ_PRIORITY_ORDER 1
257 
258 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32)
259 
260 	#define TRACE_ALLOC_CRITICAL_SECTION() TraceBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
261 	#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = TRC_KERNEL_PORT_SET_INTERRUPT_MASK(); }
262 	#define TRACE_EXIT_CRITICAL_SECTION() { TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK(TRACE_ALLOC_CRITICAL_SECTION_NAME); }
263 
264 	#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
265 	#define TRC_HWTC_COUNT (TMR1)
266 	#define TRC_HWTC_PERIOD (PR1 + 1)
267 	#define TRC_HWTC_DIVISOR 1
268 	#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
269 	#define TRC_IRQ_PRIORITY_ORDER 1
270 
271 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48)
272 
273 	#define TRC_RTIFRC0 *((uint32_t *)0xFFFFFC10)
274 	#define TRC_RTICOMP0 *((uint32_t *)0xFFFFFC50)
275 	#define TRC_RTIUDCP0 *((uint32_t *)0xFFFFFC54)
276 
277 	#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
278 	#define TRC_HWTC_COUNT (TRC_RTIFRC0 - (TRC_RTICOMP0 - TRC_RTIUDCP0))
279 	#define TRC_HWTC_PERIOD (TRC_RTIUDCP0)
280 	#define TRC_HWTC_DIVISOR 1
281 	#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
282 	#define TRC_IRQ_PRIORITY_ORDER 0
283 
284 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Atmel_AT91SAM7)
285 
286 	/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
287 
288 	#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
289 	#define TRC_HWTC_COUNT ((uint32_t)(AT91C_BASE_PITC->PITC_PIIR & 0xFFFFF))
290 	#define TRC_HWTC_PERIOD ((uint32_t)(AT91C_BASE_PITC->PITC_PIMR + 1))
291 	#define TRC_HWTC_DIVISOR 1
292 	#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
293 	#define TRC_IRQ_PRIORITY_ORDER 1
294 
295 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Atmel_UC3A0)
296 
297 	/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO*/
298 
299 	/* For Atmel AVR32 (AT32UC3A) */
300 
301 	#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
302 	#define TRC_HWTC_COUNT ((uint32_t)sysreg_read(AVR32_COUNT))
303 	#define TRC_HWTC_PERIOD ((uint32_t)(sysreg_read(AVR32_COMPARE) + 1))
304 	#define TRC_HWTC_DIVISOR 1
305 	#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
306 	#define TRC_IRQ_PRIORITY_ORDER 1
307 
308 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NXP_LPC210X)
309 
310 	/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
311 
312 	/* Tested with LPC2106, but should work with most LPC21XX chips. */
313 
314 	#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
315 	#define TRC_HWTC_COUNT *((uint32_t *)0xE0004008 )
316 	#define TRC_HWTC_PERIOD *((uint32_t *)0xE0004018 )
317 	#define TRC_HWTC_DIVISOR 1
318 	#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
319 	#define TRC_IRQ_PRIORITY_ORDER 0
320 
321 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_MSP430)
322 
323 	/* UNOFFICIAL PORT - NOT YET VERIFIED */
324 
325 	#define TRC_HWTC_TYPE TRC_OS_TIMER_INCR
326 	#define TRC_HWTC_COUNT (TA0R)
327 	#define TRC_HWTC_PERIOD (((uint16_t)TACCR0)+1)
328 	#define TRC_HWTC_DIVISOR 1
329 	#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
330 	#define TRC_IRQ_PRIORITY_ORDER 1
331 
332 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_PPC405)
333 
334 	/* UNOFFICIAL PORT - NOT YET VERIFIED */
335 
336 	#define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
337 	#define TRC_HWTC_COUNT mfspr(0x3db)
338 	#define TRC_HWTC_PERIOD (TRACE_CPU_CLOCK_HZ / TRC_TICK_RATE_HZ)
339 	#define TRC_HWTC_DIVISOR 1
340 	#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
341 	#define TRC_IRQ_PRIORITY_ORDER 0
342 
343 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_PPC440)
344 
345 	/* UNOFFICIAL PORT */
346 
347 	/* This should work with most PowerPC chips */
348 
349 	#define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
350 	#define TRC_HWTC_COUNT mfspr(0x016)
351 	#define TRC_HWTC_PERIOD (TRACE_CPU_CLOCK_HZ / TRC_TICK_RATE_HZ)
352 	#define TRC_HWTC_DIVISOR 1
353 	#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
354 	#define TRC_IRQ_PRIORITY_ORDER 0
355 
356 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_MICROBLAZE)
357 
358 	/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
359 
360 	/* This should work with most Microblaze configurations.
361 	 * It uses the AXI Timer 0 - the tick interrupt source.
362 	 * If an AXI Timer 0 peripheral is available on your hardware platform, no modifications are required.
363 	 */
364 	#include <xtmrctr_l.h>
365 
366 	#define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
367 	#define TRC_HWTC_COUNT XTmrCtr_GetTimerCounterReg( XPAR_TMRCTR_0_BASEADDR, 0 )
368  	#define TRC_HWTC_PERIOD (XTmrCtr_GetLoadReg( XPAR_TMRCTR_0_BASEADDR, 0) + 1)
369 	#define TRC_HWTC_DIVISOR 16
370 	#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
371 	#define TRC_IRQ_PRIORITY_ORDER 0
372 
373 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5)
374 
375 	extern uint32_t cortex_a9_r5_enter_critical(void);
376 	extern void cortex_a9_r5_exit_critical(uint32_t irq_already_masked_at_enter);
377 
378 	#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
379 
380 	#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = (TraceUnsignedBaseType_t)cortex_a9_r5_enter_critical(); }
381 
382 	#define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical((uint32_t)TRACE_ALLOC_CRITICAL_SECTION_NAME); }
383 
384 	#include <xttcps_hw.h>
385 
386 	#define TRC_HWTC_TYPE  TRC_OS_TIMER_INCR
387 	#define TRC_HWTC_COUNT  (*(volatile uint32_t *)(configTIMER_BASEADDR + XTTCPS_COUNT_VALUE_OFFSET))
388 	#define TRC_HWTC_PERIOD  (*(volatile uint32_t *)(configTIMER_BASEADDR + XTTCPS_INTERVAL_VAL_OFFSET))
389 	#define TRC_HWTC_DIVISOR  16
390 	#define TRC_HWTC_FREQ_HZ  (TRC_HWTC_PERIOD * TRC_TICK_RATE_HZ)
391 	#define TRC_IRQ_PRIORITY_ORDER  0
392 
393 	#ifdef __GNUC__
394 
prvGetCPSR(void)395 	static inline uint32_t prvGetCPSR(void)
396 	{
397 		unsigned long ret;
398 		/* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */
399 		asm volatile (" mrs  %0, cpsr" : "=r" (ret) : /* no inputs */  );
400 		return ret;
401 	}
402 	#else
403 		#error "Only GCC Supported!"
404 	#endif
405 
406 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Altera_NiosII)
407 
408     /* OFFICIAL PORT */
409 
410 	#include <system.h>
411 	#include <altera_avalon_timer_regs.h>
412 	#include <sys/alt_irq.h>
413 
414 	#define TRACE_ALLOC_CRITICAL_SECTION() alt_irq_context TRACE_ALLOC_CRITICAL_SECTION_NAME;
415 	#define TRACE_ENTER_CRITICAL_SECTION(){TRACE_ALLOC_CRITICAL_SECTION_NAME = alt_irq_disable_all();}
416 	#define TRACE_EXIT_CRITICAL_SECTION() {alt_irq_enable_all(TRACE_ALLOC_CRITICAL_SECTION_NAME);}
417 
418 	#define NOT_SET 1
419 
420 	/* The base address for the sustem timer set.
421 	 * The name user for the system timer can be found in the BSP editor.
422 	 * If the name of the timer is sys_tmr SYSTEM_TIMER_BASE should be set to SYS_TMR_BASE.
423 	*/
424 	#define SYSTEM_TIMER_BASE NOT_SET
425 
426 	#if (SYSTEM_TIMER == NOT_SET)
427 		#error "Set SYSTEM_TIMER_BASE to the timer base used for system ticks."
428 	#endif
429 
altera_nios2_GetTimerSnapReg(void)430  	static inline uint32_t altera_nios2_GetTimerSnapReg(void)
431 	{
432 		/* A processor can read the current counter value by first writing to either snapl or snaph to request a coherent snapshot of the counter,
433 		 * and then reading snapl and snaph for the full 32-bit value.
434 		*/
435 		IOWR_ALTERA_AVALON_TIMER_SNAPL(SYSTEM_TIMER_BASE, 0);
436 		return (IORD_ALTERA_AVALON_TIMER_SNAPH(SYSTEM_TIMER_BASE) << 16) | IORD_ALTERA_AVALON_TIMER_SNAPL(SYSTEM_TIMER_BASE);
437 	}
438 
439 	#define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
440 	#define TRC_HWTC_COUNT altera_nios2_GetTimerSnapReg()
441 	#define TRC_HWTC_PERIOD (configCPU_CLOCK_HZ / configTICK_RATE_HZ )
442 	#define TRC_HWTC_DIVISOR 16
443 	#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
444 	#define TRC_IRQ_PRIORITY_ORDER 0
445 
446 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9)
447 
448 	/**************************************************************************
449 	* This hardware port only supports FreeRTOS and the GCC compiler at the
450 	* moment, due to the implementation of critical sections (trcKernelPort.h).
451 	*
452 	* Assuming FreeRTOS is used:
453 	*
454     * For critical sections, this uses vTaskEnterCritical is when called from
455 	* task context and ulPortSetInterruptMask when called from ISR context.
456 	* Thus, it does not disable all ISRs. This means that the trace recorder
457 	* can only be called from ISRs with priority less or equal to
458 	* configMAX_API_CALL_INTERRUPT_PRIORITY (like FreeRTOS fromISR functions).
459 	*
460     * This hardware port has been tested on a Xilinx Zync 7000 (Cortex-A9).
461 
462 	**************************************************************************/
463 
464 
465 	extern uint32_t cortex_a9_r5_enter_critical(void);
466 	extern void cortex_a9_r5_exit_critical(uint32_t irq_already_masked_at_enter);
467 
468 	#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
469 	#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = (TraceUnsignedBaseType_t)cortex_a9_r5_enter_critical(); }
470 	#define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical((uint32_t)TRACE_ALLOC_CRITICAL_SECTION_NAME); }
471 
472 	/* INPUT YOUR PERIPHERAL BASE ADDRESS HERE (0xF8F00000 for Xilinx Zynq 7000)*/
473 	#define TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS	0
474 
475 	#if (TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS == 0)
476 		#error "Please specify TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS."
477 	#endif
478 
479 	#define TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET	0x0600
480 	#define TRC_CA9_MPCORE_PRIVCTR_PERIOD_REG	(*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x00))
481 	#define TRC_CA9_MPCORE_PRIVCTR_COUNTER_REG	(*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x04))
482 	#define TRC_CA9_MPCORE_PRIVCTR_CONTROL_REG	(*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x08))
483 
484 	#define TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK    0x0000FF00
485 	#define TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT   8
486 	#define TRC_CA9_MPCORE_PRIVCTR_PRESCALER        (((TRC_CA9_MPCORE_PRIVCTR_CONTROL_REG & TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK) >> TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT) + 1)
487 
488     #define TRC_HWTC_TYPE                           TRC_OS_TIMER_DECR
489     #define TRC_HWTC_COUNT                          TRC_CA9_MPCORE_PRIVCTR_COUNTER_REG
490     #define TRC_HWTC_PERIOD                         (TRC_CA9_MPCORE_PRIVCTR_PERIOD_REG + 1)
491 
492     /****************************************************************************************
493 	NOTE: The private timer ticks with a very high frequency (half the core-clock usually),
494 	depending on the prescaler used. If a low prescaler is used, the number of HW ticks between
495 	the trace events gets large, and thereby inefficient to store (sometimes extra events are
496 	needed). To improve efficiency, you may use the TRC_HWTC_DIVISOR as an additional prescaler.
497     *****************************************************************************************/
498 	#define TRC_HWTC_DIVISOR 1
499 
500 	#define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD)
501     #define TRC_IRQ_PRIORITY_ORDER 0
502 
503 	#ifdef __GNUC__
504 
prvGetCPSR(void)505 	static inline uint32_t prvGetCPSR(void)
506 	{
507 		unsigned long ret;
508 		/* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */
509 		asm volatile (" mrs  %0, cpsr" : "=r" (ret) : /* no inputs */  );
510 		return ret;
511 	}
512 	#else
513 		#error "Only GCC Supported!"
514 	#endif
515 
516 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_CYCLONE_V_HPS)
517 	#include "alt_clock_manager.h"
518 
519 
520 	extern uint32_t cortex_a9_r5_enter_critical(void);
521 	extern void cortex_a9_r5_exit_critical(uint32_t irq_already_masked_at_enter);
522 
523 	#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
524 	#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = (TraceUnsignedBaseType_t)cortex_a9_r5_enter_critical(); }
525 	#define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical((uint32_t)TRACE_ALLOC_CRITICAL_SECTION_NAME); }
526 
527 	#define TRC_HWTC_TYPE							TRC_FREE_RUNNING_32BIT_INCR
528 	#define TRC_HWTC_COUNT							*((uint32_t *)0xFFFEC200)
529 	#define TRC_HWTC_PERIOD							0
530 	#define TRC_HWTC_DIVISOR 						1
531 	#define TRC_HWTC_FREQ_HZ						(({		\
532 		uint32_t __freq;									\
533 		alt_clk_freq_get( ALT_CLK_MPU_PERIPH, &__freq );	\
534 		__freq;												\
535 	}))
536 	#define TRC_IRQ_PRIORITY_ORDER 					0
537 
538 	#ifdef __GNUC__
539 	/* For Arm Cortex-A and Cortex-R in general. */
prvGetCPSR(void)540 	static inline uint32_t prvGetCPSR(void)
541 	{
542 		unsigned long ret;
543 		/* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */
544 		__asm__ __volatile__(" mrs  %0, cpsr" : "=r" (ret) : /* no inputs */  );
545 		return ret;
546 	}
547 	#else
548 		#error "Only GCC Supported!"
549 	#endif
550 
551 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ZEPHYR)
552 	#ifdef CONFIG_64BIT
553 		#define TRC_BASE_TYPE int64_t
554 		#define TRC_UNSIGNED_BASE_TYPE uint64_t
555 	#else
556 		#define TRC_BASE_TYPE int32_t
557 		#define TRC_UNSIGNED_BASE_TYPE uint32_t
558 	#endif
559 
560 	#define TRACE_ALLOC_CRITICAL_SECTION() TraceBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
561 	#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = irq_lock(); }
562 	#define TRACE_EXIT_CRITICAL_SECTION() { irq_unlock(TRACE_ALLOC_CRITICAL_SECTION_NAME); }
563 
564 	#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
565 	#define TRC_HWTC_COUNT k_cycle_get_32()
566 	#define TRC_HWTC_PERIOD (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
567 	#define TRC_HWTC_DIVISOR 4
568 	#define TRC_HWTC_FREQ_HZ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
569 	#define TRC_IRQ_PRIORITY_ORDER 0 // Lower IRQ priority values are more significant
570 
571 	#define TRC_PORT_SPECIFIC_INIT()
572 
573 #elif ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XTensa_LX6) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XTensa_LX7))
574 	/**
575 	 * @note	When running with SMP FreeRTOS we cannot use the CCOUNT register for timestamping,
576 	 * 			instead we use the external 40MHz timer for synchronized timestamping between the cores.
577 	 */
578 	#if CONFIG_FREERTOS_UNICORE == 1
579 
580 		#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
581 		#define TRACE_ENTER_CRITICAL_SECTION() {TRACE_ALLOC_CRITICAL_SECTION_NAME = __extension__({ unsigned __tmp; 	\
582 				__asm__ __volatile__("rsil	%0, 15\n" 												\
583 						: "=a" (__tmp) : : "memory" ); 												\
584 						__tmp;});}
585 		#define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(TRACE_ALLOC_CRITICAL_SECTION_NAME);}
586 
587 		#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
588 		#define TRC_HWTC_COUNT ({ unsigned int __ccount; 			\
589 			__asm__ __volatile__("rsr.ccount %0" : "=a"(__ccount)); \
590 			__ccount; })
591 #ifdef CONFIG_IDF_TARGET_ESP32
592 		#define TRC_HWTC_FREQ_HZ (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000)
593 #elif defined(CONFIG_IDF_TARGET_ESP32S2)
594 		#define TRC_HWTC_FREQ_HZ (CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ * 1000000)
595 #else
596 		#error "Invalid IDF target, check your sdkconfig."
597 #endif
598 		#define TRC_HWTC_PERIOD 0
599 		#define TRC_HWTC_DIVISOR 4
600 		#define TRC_IRQ_PRIORITY_ORDER 0
601 	#else
602 		/**
603 		 * @brief 	Fetch core agnostic timestamp using the external boot timestamp timer used by ESP IDF.
604 		 *
605 		 * @return 	Ticks since the timer started
606 		 */
607 		uint32_t prvGetSMPTimestamp();
608 
609 		#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
610 		#define TRC_HWTC_COUNT prvGetSMPTimestamp()
611 		#define TRC_HWTC_FREQ_HZ 1000000
612 		#define TRC_HWTC_PERIOD 0
613 		#define TRC_HWTC_DIVISOR 4
614 		#define TRC_IRQ_PRIORITY_ORDER 0
615 	#endif
616 
617 	#if !defined(TRC_HWTC_FREQ_HZ)
618 		#error "The XTensa LX6/LX7 trace hardware clock frequency is not defined."
619 	#endif
620 
621 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_RISCV_RV32I)
622 	#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
623 	#define TRACE_ENTER_CRITICAL_SECTION() __asm__ __volatile__("csrr %0, mstatus	\n\t"	\
624 																"csrci mstatus, 8	\n\t"	\
625 																"andi %0, %0, 8		\n\t"	\
626 																: "=r"(TRACE_ALLOC_CRITICAL_SECTION_NAME))
627     #define TRACE_EXIT_CRITICAL_SECTION() __asm__ __volatile__("csrr a1, mstatus	\n\t"	\
628     															"or %0, %0, a1		\n\t"	\
629 																"csrs mstatus, %0	\n\t"	\
630 																:							\
631 																: "r" (TRACE_ALLOC_CRITICAL_SECTION_NAME)	\
632 																: "a1")
633 	#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
634 	#define TRC_HWTC_COUNT ({ unsigned int __count;			\
635 		__asm__ __volatile__("rdcycle %0" : "=r"(__count));	\
636 		__count; })
637 	#define TRC_HWTC_PERIOD 0
638 	#define TRC_HWTC_DIVISOR 1
639 	#define TRC_HWTC_FREQ_HZ 16000000
640 	#define TRC_IRQ_PRIORITY_ORDER 0
641 
642 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XMOS_XCOREAI)
643 	#define TRC_PORT_SPECIFIC_INIT()
644 	#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
645 	#define TRC_HWTC_COUNT xscope_gettime()
646 	#define TRC_HWTC_PERIOD (configCPU_CLOCK_HZ / configTICK_RATE_HZ )
647 	#define TRC_HWTC_DIVISOR 4
648 	#define TRC_HWTC_FREQ_HZ 100000000
649 	#define TRC_IRQ_PRIORITY_ORDER 0
650 
651 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_POWERPC_Z4)
652 
653     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
654 
655 	#define TRACE_ALLOC_CRITICAL_SECTION() TraceBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
656 	#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = TRC_KERNEL_PORT_SET_INTERRUPT_MASK(); }
657 	#define TRACE_EXIT_CRITICAL_SECTION() { TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK(TRACE_ALLOC_CRITICAL_SECTION_NAME); }
658 
659     #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR
660     //#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
661     #define TRC_HWTC_COUNT PIT.TIMER[configTICK_PIT_CHANNEL].CVAL.R // must be the PIT channel used for the systick
662     #define TRC_HWTC_PERIOD ((configPIT_CLOCK_HZ / configTICK_RATE_HZ) - 1U) // TODO FIXME or maybe not -1? what's the right "period" value?
663     #define TRC_HWTC_FREQ_HZ configPIT_CLOCK_HZ
664     #define TRC_HWTC_DIVISOR 1
665     #define TRC_IRQ_PRIORITY_ORDER 1 // higher IRQ priority values are more significant
666 
667 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARMv8AR_A32)
668 	extern uint32_t cortex_a9_r5_enter_critical(void);
669 	extern void cortex_a9_r5_exit_critical(uint32_t irq_already_masked_at_enter);
670 
671 	#define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
672 	#define TRACE_ENTER_CRITICAL_SECTION() { TRACE_ALLOC_CRITICAL_SECTION_NAME = (TraceUnsignedBaseType_t)cortex_a9_r5_enter_critical(); }
673 	#define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical((uint32_t)TRACE_ALLOC_CRITICAL_SECTION_NAME); }
674 
675     #include <cmsis_compiler.h>
676 
677     #define TRC_HWTC_TYPE  TRC_FREE_RUNNING_32BIT_INCR
678     #define TRC_HWTC_COUNT  ((uint32_t)__get_CNTPCT())
679     #define TRC_HWTC_PERIOD  0
680     #define TRC_HWTC_DIVISOR  16
681     #define TRC_HWTC_FREQ_HZ  (R_GSC->CNTFID0)
682     #define TRC_IRQ_PRIORITY_ORDER  0
683 
684     #ifdef __GNUC__
685     /* For Arm Cortex-A and Cortex-R in general. */
prvGetCPSR(void)686     static inline uint32_t prvGetCPSR(void)
687     {
688         unsigned long ret;
689         /* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */
690         __asm volatile (" mrs  %0, cpsr" : "=r" (ret) : /* no inputs */  );
691         return ret;
692     }
693     #else
694         #error "Only GCC Supported!"
695     #endif
696 
697 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ADSP_SC5XX_SHARC)
698 
699     #define TRACE_ALLOC_CRITICAL_SECTION() TraceUnsignedBaseType_t TRACE_ALLOC_CRITICAL_SECTION_NAME;
700     #define TRACE_ENTER_CRITICAL_SECTION() {TRACE_ALLOC_CRITICAL_SECTION_NAME = (TraceUnsignedBaseType_t)portSET_INTERRUPT_MASK_FROM_ISR();}
701     #define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR((UBaseType_t)TRACE_ALLOC_CRITICAL_SECTION_NAME);}
702 
703     #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR
704     #define TRC_HWTC_COUNT ( *pREG_CGU0_TSCOUNT0 )
705     #define TRC_HWTC_PERIOD 1
706     #define TRC_HWTC_DIVISOR 1
707     #define TRC_HWTC_FREQ_HZ ( configCPU_CLOCK_HZ >> 1u )
708 
709     #define TRC_PORT_SPECIFIC_INIT() {*pREG_CGU0_TSCTL |= BITM_CGU_TSCTL_EN;}
710 
711 	/* Set the meaning of IRQ priorities in ISR tracing - see above */
712 	#define TRC_IRQ_PRIORITY_ORDER 1
713 
714 #elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_APPLICATION_DEFINED)
715 
716 	#if !( defined (TRC_HWTC_TYPE) && defined (TRC_HWTC_COUNT) && defined (TRC_HWTC_PERIOD) && defined (TRC_HWTC_FREQ_HZ) && defined (TRC_IRQ_PRIORITY_ORDER) )
717 		#error "The hardware port is not completely defined!"
718 	#endif
719 
720 #elif (TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET)
721 
722 	#error "TRC_CFG_HARDWARE_PORT had unsupported value!"
723 	#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET
724 
725 #endif
726 
727 #ifndef TRC_HWTC_DIVISOR
728 	#define TRC_HWTC_DIVISOR 1
729 #endif
730 
731 #ifndef TRC_PORT_SPECIFIC_INIT
732 	#define TRC_PORT_SPECIFIC_INIT()
733 #endif
734 
735 /* If Win32 port */
736 #ifdef WIN32
737 
738 	#undef _WIN32_WINNT
739 	#define _WIN32_WINNT 0x0600
740 
741 	/* Standard includes. */
742 	#include <stdio.h>
743 	#include <windows.h>
744 	#include <direct.h>
745 
746     /***************************************************************************
747     * The Win32 port by default saves the trace to file and then kills the
748     * program when the recorder is stopped, to facilitate quick, simple tests
749     * of the recorder.
750     ***************************************************************************/
751 	#define WIN32_PORT_SAVE_WHEN_STOPPED 1
752 	#define WIN32_PORT_EXIT_WHEN_STOPPED 1
753 
754 #endif
755 
756 #if (TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET)
757 
758 	#ifndef TRC_HWTC_TYPE
759 	#error "TRC_HWTC_TYPE is not set!"
760 	#endif
761 
762 	#ifndef TRC_HWTC_COUNT
763 	#error "TRC_HWTC_COUNT is not set!"
764 	#endif
765 
766 	#ifndef TRC_HWTC_PERIOD
767 	#error "TRC_HWTC_PERIOD is not set!"
768 	#endif
769 
770 	#ifndef TRC_HWTC_DIVISOR
771 	#error "TRC_HWTC_DIVISOR is not set!"
772 	#endif
773 
774 	#ifndef TRC_IRQ_PRIORITY_ORDER
775 	#error "TRC_IRQ_PRIORITY_ORDER is not set!"
776 	#elif (TRC_IRQ_PRIORITY_ORDER != 0) && (TRC_IRQ_PRIORITY_ORDER != 1)
777 	#error "TRC_IRQ_PRIORITY_ORDER has bad value!"
778 	#endif
779 
780 	#if (TRC_HWTC_DIVISOR < 1)
781 	#error "TRC_HWTC_DIVISOR must be a non-zero positive value!"
782 	#endif
783 
784 	#ifndef TRC_HWTC_FREQ_HZ
785 	#error "TRC_HWTC_FREQ_HZ not defined!"
786 	#endif
787 
788 #endif
789 
790 /* If a custom TRC_CFG_ALLOC_CRITICAL_SECTION is defined it will override the default definition */
791 #ifdef TRC_CFG_ALLOC_CRITICAL_SECTION
792 #undef TRACE_ALLOC_CRITICAL_SECTION
793 #define TRACE_ALLOC_CRITICAL_SECTION() TRC_CFG_ALLOC_CRITICAL_SECTION()
794 #endif
795 
796 /* If a custom TRC_CFG_ENTER_CRITICAL_SECTION is defined it will override the default definition */
797 #ifdef TRC_CFG_ENTER_CRITICAL_SECTION
798 #undef TRACE_ENTER_CRITICAL_SECTION
799 #define TRACE_ENTER_CRITICAL_SECTION() TRC_CFG_ENTER_CRITICAL_SECTION()
800 #endif
801 
802 /* If a custom TRC_CFG_EXIT_CRITICAL_SECTION is defined it will override the default definition */
803 #ifdef TRC_CFG_EXIT_CRITICAL_SECTION
804 #undef TRACE_EXIT_CRITICAL_SECTION
805 #define TRACE_EXIT_CRITICAL_SECTION() TRC_CFG_EXIT_CRITICAL_SECTION()
806 #endif
807 
808 #ifndef TRACE_ALLOC_CRITICAL_SECTION
809 #define TRACE_ALLOC_CRITICAL_SECTION() TRC_KERNEL_PORT_ALLOC_CRITICAL_SECTION()
810 #endif
811 #ifndef TRACE_ENTER_CRITICAL_SECTION
812 #define TRACE_ENTER_CRITICAL_SECTION() TRC_KERNEL_PORT_ENTER_CRITICAL_SECTION()
813 #endif
814 #ifndef TRACE_EXIT_CRITICAL_SECTION
815 #define TRACE_EXIT_CRITICAL_SECTION() TRC_KERNEL_PORT_EXIT_CRITICAL_SECTION()
816 #endif
817 
818 #endif /*TRC_HARDWARE_PORT_H*/
819