iLLD_TC27xC  1.0
IfxCpu.h
Go to the documentation of this file.
1 /**
2  * \file IfxCpu.h
3  * \brief CPU basic functionality
4  * \ingroup IfxLld_Cpu
5  *
6  * \version iLLD_0_1_0_10
7  * \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved.
8  *
9  *
10  * IMPORTANT NOTICE
11  *
12  *
13  * Infineon Technologies AG (Infineon) is supplying this file for use
14  * exclusively with Infineon's microcontroller products. This file can be freely
15  * distributed within development tools that are supporting such microcontroller
16  * products.
17  *
18  * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
19  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
21  * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
22  * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
23  *
24  * \defgroup IfxLld_Cpu CPU
25  * \ingroup IfxLld
26  * \defgroup IfxLld_Cpu_Std Standard Driver
27  * \ingroup IfxLld_Cpu
28  * \defgroup IfxLld_Cpu_Std_Core Cpu Core Functions
29  * \ingroup IfxLld_Cpu_Std
30  * \defgroup IfxLld_Cpu_Std_Interrupt Interrupt Utility Functions
31  * \ingroup IfxLld_Cpu_Std
32  * \defgroup IfxLld_Cpu_Std_Cache Cache Management Functions
33  * \ingroup IfxLld_Cpu_Std
34  * \defgroup IfxLld_Cpu_Std_PerformanceCounter Performance Counter Functions
35  * \ingroup IfxLld_Cpu_Std
36  * \defgroup IfxLld_Cpu_Std_Synchronization Synchronization Functions
37  * \ingroup IfxLld_Cpu_Std
38  * \defgroup IfxLld_Cpu_Std_Enum Enumerations
39  * \ingroup IfxLld_Cpu_Std
40  * \defgroup IfxLld_Cpu_Std_DataStructures Data Structures
41  * \ingroup IfxLld_Cpu_Std
42  */
43 
44 #ifndef IFXCPU_H
45 #define IFXCPU_H 1
46 
47 /******************************************************************************/
48 /*----------------------------------Includes----------------------------------*/
49 /******************************************************************************/
50 
51 #include "_Impl/IfxCpu_cfg.h"
52 #include "IfxSrc_reg.h"
53 #include "IfxScu_reg.h"
54 #include "Scu/Std/IfxScuWdt.h"
55 
56 /******************************************************************************/
57 /*-----------------------------------Macros-----------------------------------*/
58 /******************************************************************************/
59 
60 /** \brief Convert local DSPR address to global DSPR address which can be accessed from the SRI bus.
61  * Use this macro to convert a local DSPR address (in segment 0xd00.....) to
62  * a global DSPR address (in segment 0x700....., 0x600....., 0x500..... downwards) depending on
63  * the CPU number.
64  * Example usage:
65  * \code
66  * dmaChConfig.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), &sourceBuffer[i][0]);
67  * dmaChConfig.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), &destinationBuffer[i][0]);
68  * \endcode
69  */
70 #define IFXCPU_GLB_ADDR_DSPR(cpu, address) ((((((unsigned)(address) & 0xF0000000) == 0xD0000000) ? ((((unsigned)(address) & 0x000fffff) | 0x70000000) - ((cpu) * 0x10000000)) : (unsigned)(address))))
71 
72 /** \brief Convert local PSPR address to global PSPR address which can be accessed from the SRI bus.
73  * Use this macro to convert a local PSPR address (in segment 0xc......) to
74  * a global PSPR address (in segment 0x701....., 0x601....., 0x501..... downwards) depending on
75  * the CPU number.
76  *
77  * Example usage:
78  * \code
79  * dmaChConfig.sourceAddress = IFXCPU_GLB_ADDR_PSPR(IfxCpu_getCoreId(), &sourceBufferInPsprMemory);
80  * dmaChConfig.destinationAddress = IFXCPU_GLB_ADDR_PSPR(IfxCpu_getCoreId(), &destinationBufferInPsprMemory);
81  * \endcode
82  */
83 #define IFXCPU_GLB_ADDR_PSPR(cpu, address) ((((unsigned)(address) & 0x000fffff) | 0x70100000) - ((cpu) * 0x10000000))
84 
85 /******************************************************************************/
86 /*------------------------------Type Definitions------------------------------*/
87 /******************************************************************************/
88 
89 /** \brief Lock type Spin lock
90  */
91 typedef unsigned int IfxCpu_spinLock;
92 
93 /** \brief Lock type Mutex lock
94  */
95 typedef unsigned int IfxCpu_mutexLock;
96 
97 /******************************************************************************/
98 /*--------------------------------Enumerations--------------------------------*/
99 /******************************************************************************/
100 
101 /** \addtogroup IfxLld_Cpu_Std_Enum
102  * \{ */
103 /** \brief Enumeration for the Cpu mode
104  */
105 typedef enum
106 {
114 
115 /** \brief Performance conunter modes
116  */
117 typedef enum
118 {
119  IfxCpu_CounterMode_normal = 0, /**< \brief Normal counter mode:the counter increments on their respective triggers */
120  IfxCpu_CounterMode_task = 1 /**< \brief Normal counter mode:additional gating control from the debug unit which allows the data gathered in the performance counters to be filtered by some specific criteria */
122 
123 /** \} */
124 
125 /******************************************************************************/
126 /*-----------------------------Data Structures--------------------------------*/
127 /******************************************************************************/
128 
129 /** \addtogroup IfxLld_Cpu_Std_DataStructures
130  * \{ */
131 typedef struct
132 {
133  uint32 counter; /**< \brief Counter value */
134  boolean overlfow; /**< \brief sticky overlfow */
136 
137 /** \} */
138 
139 /** \addtogroup IfxLld_Cpu_Std_DataStructures
140  * \{ */
141 /** \brief Performance counter result
142  */
143 typedef struct
144 {
145  IfxCpu_Counter instruction; /**< \brief Instruction counter */
146  IfxCpu_Counter clock; /**< \brief CPU clock counter */
147  IfxCpu_Counter counter1; /**< \brief Multi counter 1 */
148  IfxCpu_Counter counter2; /**< \brief Multi counter 2 */
149  IfxCpu_Counter counter3; /**< \brief Multi counter 3 */
150 } IfxCpu_Perf;
151 
152 /** \} */
153 
154 /** \addtogroup IfxLld_Cpu_Std_Core
155  * \{ */
156 
157 /******************************************************************************/
158 /*-------------------------Inline Function Prototypes-------------------------*/
159 /******************************************************************************/
160 
161 /** \brief API to get resource index of the CPU of the caller
162  * \return Resource index of the CPU.
163  */
165 
166 /** \brief API to initialize the context save area of the CPU where this is called.
167  *
168  * This API can initialize the CSA of the host CPU where this API is called. This API
169  * shall not be used to initialize the CSA of another CPU
170  * \param csaBegin Pointer to start of context save area
171  * \param csaEnd Pointer to end of context save area
172  * \return None
173  */
174 IFX_INLINE void IfxCpu_initCSA(uint32 *csaBegin, uint32 *csaEnd);
175 
176 /******************************************************************************/
177 /*-------------------------Global Function Prototypes-------------------------*/
178 /******************************************************************************/
179 
180 /** \brief API to get the address for CPU HW module register memory map
181  * \param cpu Resource index of the CPU
182  * \return CPU module register address
183  */
185 
186 /** \brief API to get current mode of CPU
187  * \param cpu Pointer to the CPU HW module (register memory map)
188  * \return Current mode of the CPU
189  */
191 
192 /** \brief API to get current mode of CPU
193  * \param cpu Pointer to the CPU HW module (register memory map)
194  * \return Resource index of the CPU
195  */
197 
198 /** \brief API to set mode of the CPU
199  * \param cpu Pointer to the CPU HW module (register memory map)
200  * \param mode CPU mode to be set by this API
201  * \return Success status of the activity (setting the core mode).
202  * \retval TRUE: If the activity successfully be performed.
203  * \retval FALSE: If the activity can't be performed.
204  */
205 IFX_EXTERN boolean IfxCpu_setCoreMode(Ifx_CPU *cpu, IfxCpu_CoreMode mode);
206 
207 /** \brief API to set the program counter for the CPU specified.
208  * \param cpu Pointer to the CPU HW module (register memory map)
209  * \param programCounter Program counter value to be set
210  * \return success status of the activity (setting program counter value).
211  * \retval TRUE: If the activity successfully be performed.
212  * \retval FALSE: If the activity can't be performed
213  */
214 IFX_EXTERN boolean IfxCpu_setProgramCounter(Ifx_CPU *cpu, uint32 programCounter);
215 
216 /** \brief API to set the program counter for the CPU specified and start the CPU
217  * \param cpu Pointer to the CPU HW module (register memory map)
218  * \param programCounter Program counter value to start the CPU
219  * \return success status of the activity (setting program counter value).
220  * \retval TRUE: If the activity successfully be performed.
221  * \retval FALSE: If the activity can't be performed
222  */
223 IFX_EXTERN boolean IfxCpu_startCore(Ifx_CPU *cpu, uint32 programCounter);
224 
225 /** \} */
226 
227 /** \addtogroup IfxLld_Cpu_Std_Interrupt
228  * \{ */
229 
230 /******************************************************************************/
231 /*-------------------------Inline Function Prototypes-------------------------*/
232 /******************************************************************************/
233 
234 /** \brief API to get the status of global interrupt enable (ICR.IE) for the CPU which calls this API
235  * This API provides the status of CPU where this API is called
236  * \return Status of global interrupt enable bit.
237  * \retval TRUE: Global interrupts enabled.
238  * \retval FALSE: Global interrupts disabled
239  */
241 
242 /** \brief API to disable global interrupt and return the previous status.
243  *
244  * This API can be used only to disable the global interrupts of caller CPU. It cannot be
245  * used for this activity towards other CPUs
246  * \return Previous status of global interrupt enable bit.
247  * \retval TRUE: Previously, global interrupts enabled.
248  * \retval FALSE: Previously, global interrupts disabled
249  */
251 
252 /** \brief API to enable global interrupt.
253  * This API simply enables the global interrupt.
254  * \return None
255  */
257 
258 /** \brief API to restore global interrupt with that of the passed parameter.
259  *
260  * This API can be used only to disable the global interrupts of caller CPU. It cannot be
261  * used for this activity towards other CPUs
262  * \param enabled Previous status of the global interrupt enable bit
263  * \return None
264  */
265 IFX_INLINE void IfxCpu_restoreInterrupts(boolean enabled);
266 
267 /** \} */
268 
269 /** \addtogroup IfxLld_Cpu_Std_Cache
270  * \{ */
271 
272 /******************************************************************************/
273 /*-------------------------Inline Function Prototypes-------------------------*/
274 /******************************************************************************/
275 
276 /** \brief API to enable or bypass the data cache for the CPU which calls this API.
277  *
278  * This API can be used only to enable or bypass the data cache of caller CPU. It cannot be
279  * used for this activity towards other CPUs
280  * \param enable Command to enable or bypass the data cache
281  * TRUE: Enable the data cache.
282  * FALSE: Bypass the data cache.
283  * \return None
284  */
286 
287 /** \brief API to enable or bypass the program cache for the CPU which calls this API.
288  *
289  * This API can be used only to enable or bypass the program cache of caller CPU. It cannot be
290  * used for this activity towards other CPUs
291  * \param enable Command to enable or bypass the program cache.
292  * TRUE: Enable the program cache.
293  * FALSE: Bypass the program cache
294  * \return None
295  */
297 
298 /** \brief API to determine if an address is in a cachable or non-cachable Flash/LMU section
299  * \param address Address
300  * \return Status TRUE/FALSE
301  */
302 IFX_INLINE boolean IfxCpu_isAddressCachable(void *address);
303 
304 /** \brief API to enable/ disable the data cacheability for selected segments
305  * With this API cacheability for one or more segment can be enabled/disabled for the CPU core where this
306  * API is called.
307  * \note This API is to be called only if the PCACHE or DCACHE are not enabled before
308  * \param segmentNumberMask Mask where bitfield 0 represents segment 0 and bitfield 16 represent segment F.
309  * \param enable TRUE: to enable the cacheability for selected segment, FALSE: to disable.
310  */
312 
313 /** \brief API to enable/ disable the instruction cacheability for selected segments
314  * With this API cacheability for one or more segment can be enabled/disabled for the CPU core where this
315  * API is called.
316  * \note This API is to be called only if the PCACHE or DCACHE are not enabled before
317  * \param segmentNumberMask Mask where bitfield 0 represents segment 0 and bitfield 16 represent segment F.
318  * \param enable TRUE: to enable the cacheability for selected segment, FALSE: to disable.
319  */
321 
322 /** \brief API to invalidate the program cache
323  *
324  */
326 
327 /** \} */
328 
329 /** \addtogroup IfxLld_Cpu_Std_PerformanceCounter
330  * \{ */
331 
332 /******************************************************************************/
333 /*-------------------------Inline Function Prototypes-------------------------*/
334 /******************************************************************************/
335 
336 /** \brief API to read the clock counter for the CPU which calls this API.
337  *
338  * This API can be used to read clock counter of only the caller CPU. It cannot be
339  * used for this activity towards other CPUs.
340  * \return Counter value. 0 to 0x7FFFFFFF.
341  */
343 
344 /** \brief API to read the instruction counter for the CPU which calls this API.
345  *
346  * This API can be used to read instruction counter of only the caller CPU. It cannot be
347  * used for this activity towards other CPUs
348  * \return Counter value. 0 to 0x7FFFFFFF.
349  */
351 
352 /** \brief API to get sticky overflow bit of clock counter for the CPU, which calls this API.
353  *
354  * This API can be used to get sticky overflow bit of clock counter of only the caller CPU.
355  * It cannot be used for this activity towards other CPUs.
356  * This API also clears the sticky overflow after the read. While reading the sticky bit this API disables
357  * the counter for short time. (otherwise sticky bit cannot be cleared). This API shall be used after
358  * reading the counter
359  * \return Status of sticky overflow bit.
360  * \retval TRUE: Sticky overflow bit is set.
361  * \retval FALSE: Sticky overflow bit is reset
362  */
364 
365 /** \brief API to get sticky overflow bit of Instruction counter for the CPU, which calls this API.
366  *
367  * This API can be used to get sticky overflow bit of Instruction counter of only the caller CPU.
368  * It cannot be used for this activity towards other CPUs.
369  * This API also clears the sticky overflow after the read. While reading the sticky bit this API disables
370  * the counter for short time. (otherwise sticky bit cannot be cleared). This API shall be used after
371  * reading the counter
372  * \return Status of sticky overflow bit.
373  * \retval TRUE: Sticky overflow bit is set.
374  * \retval FALSE: Sticky overflow bit is reset
375  */
377 
378 /** \brief API to enable or disable performance counter for the CPU which calls this API.
379  *
380  * This API can be used to enable or disable performance counter of only the caller CPU. It cannot be
381  * used for this activity towards other CPUs.
382  * \param enable enable Command to enable or disable the performance counter.
383  * TRUE: Enable the performance counter.
384  * FALSE: Disable the performance counter
385  * \return None
386  */
388 
389 /** \brief API to update clock counter for the CPU which calls this API.
390  *
391  * This API can be used to update clock counter of only the caller CPU. It cannot be
392  * used for this activity towards other CPUs.
393  * \param count Counter value to be updated. 0 to 0x7FFFFFFF
394  * \return None
395  */
397 
398 /** \brief API to update Instruction counter for the CPU which calls this API.
399  *
400  * This API can be used to update Instruction counter of only the caller CPU. It cannot be
401  * used for this activity towards other CPUs.
402  * \param count Counter value to be updated. 0 to 0x7FFFFFFF
403  * \return None
404  */
406 
407 /** \brief Reset and start instruction, clock and multi counters
408  *
409  * Reset and start CCNT, ICNT, M1CNT, M2CNT, M3CNT. the overflow bits are cleared.
410  * \param mode Counter mode
411  * \return None
412  */
414 
415 /** \brief Stop instruction and clock counters, return their values
416  *
417  * Stop CCNT, ICNT, M1CNT, M2CNT, M3CNT and return their values;
418  * \Note The CCTRL is reset to 0, for more accurate measurements and has to be initialized again before strating the next performance measurement.
419  * \return Performance counter result
420  */
422 
423 /** \brief API to read the performance counter for the CPU which calls this API.
424  * \param address Address
425  * \return counter value
426  */
428 
429 /** \brief API to get sticky overflow bit of performance counter for the CPU, which calls this API.
430  * This is generic function to get sticky overflow bit of any performance counters
431  * \param address Address
432  * \return Status
433  */
435 
436 /** \brief API to update performance counter for the CPU which calls this API.
437  * This is generic function to update any of the performance counters
438  * \param address Address
439  * \param count Count
440  * \return None
441  */
443 
444 /** \} */
445 
446 /** \addtogroup IfxLld_Cpu_Std_Synchronization
447  * \{ */
448 
449 /******************************************************************************/
450 /*-------------------------Global Function Prototypes-------------------------*/
451 /******************************************************************************/
452 
453 /** \brief API to lock the resource in spin mode with the given timeout.
454  *
455  * This API can be used to spin lock for the lock for the given timeout period.
456  * \param lock lock pointer
457  * \param timeoutCount loop counter value used for timeout to acquire lock
458  * \return TRUE : lock acquired successfully. FALSE: Failed to acquire the lock
459  *
460  * \code
461  * IfxCpu_spinLock resourceLock;
462  * boolean flag = IfxCpu_setSpinLock(&resourceLock, 0xFFFF);
463  * if (flag){
464  * // critical section
465  * IfxCpu_resetSpinLock(&resourceLock);
466  * }
467  * \endcode
468  *
469  */
470 IFX_EXTERN boolean IfxCpu_setSpinLock(IfxCpu_spinLock *lock, uint32 timeoutCount);
471 
472 /** \brief API to unlock the resource .
473  *
474  * This API can be used to unlock the previously acquired lock
475  * \param lock lock pointer
476  * \return None
477  */
479 
480 /** \brief API to acquire the mutex (binary semaphore).
481  *
482  * This API can be used to acquire/get the mutex.
483  * \param lock lock pointer
484  * \return TRUE : lock acquired successfully. FALSE: Failed to acquire the lock
485  *
486  * \code
487  * IfxCpu_mutexLock resourceLock;
488  * boolean flag = IfxCpu_acquireMutex(&resourceLock);
489  * if (flag){
490  * // critical section
491  * IfxCpu_releaseMutex(&resourceLock);
492  * }
493  * \endcode
494  *
495  */
497 
498 /** \brief API to unlock the mutex .
499  *
500  * This API can be used to unlock the previously acquired mutex
501  * \param lock lock pointer
502  * \return None
503  *
504  * \code
505  * IfxCpu_mutexLock resourceLock;
506  * boolean flag = IfxCpu_acquireMutex(&resourceLock);
507  * if (flag){
508  * // critical section
509  * IfxCpu_releaseMutex(&resourceLock);
510  * }
511  * \endcode
512  *
513  */
515 
516 /** \} */
517 
518 /******************************************************************************/
519 /*---------------------Inline Function Implementations------------------------*/
520 /******************************************************************************/
521 
523 {
524  Ifx_CPU_CORE_ID reg;
525  reg.U = __mfcr(CPU_CORE_ID);
526  return (IfxCpu_ResourceCpu)reg.B.CORE_ID;
527 }
528 
529 
530 IFX_INLINE void IfxCpu_initCSA(uint32 *csaBegin, uint32 *csaEnd)
531 {
532  uint32 k;
533  uint32 nxt_cxi_val = 0;
534  uint32 *prvCsa = 0U;
535  uint32 *nxtCsa = csaBegin;
536 
537  for (k = 0; k < (((uint32)csaEnd - (uint32)csaBegin) / 64); k++)
538  {
539  nxt_cxi_val = ((uint32)nxtCsa & (0XFU << 28)) >> 12 | ((uint32)nxtCsa & (0XFFFFU << 6)) >> 6;
540 
541  if (k == 0)
542  {
543  __mtcr(CPU_FCX, nxt_cxi_val); /* store the new pcxi value to LCX */
544  }
545  else
546  {
547  *prvCsa = nxt_cxi_val; /* Store null pointer in last CSA (= very first time!) */
548  }
549 
550  prvCsa = (uint32 *)nxtCsa;
551  nxtCsa += 16; /* next CSA */
552  }
553 
554  *prvCsa = 0;
555  __mtcr(CPU_LCX, nxt_cxi_val); /* Last context save area is pointed in LCX to know if there is CSA depletion */
556 }
557 
558 
560 {
561  Ifx_CPU_ICR reg;
562  reg.U = __mfcr(CPU_ICR);
563  return reg.B.IE != 0;
564 }
565 
566 
568 {
569  boolean enabled;
570  enabled = IfxCpu_areInterruptsEnabled();
571  __disable();
572  __nop();
573  return enabled;
574 }
575 
576 
578 {
579  __enable();
580 }
581 
582 
584 {
585  if (enabled != FALSE)
586  {
587  __enable();
588  }
589 }
590 
591 
593 {
594  uint32 coreId = IfxCpu_getCoreId();
595  uint16 wdtPassword = IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[coreId]);
596  /*PCACHE enable steps */
597  { /* Step 1: Set PCBYP to 0 if cache is enabled */
598  IfxScuWdt_clearCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
599  Ifx_CPU_DCON0 dcon0;
600  dcon0.U = 0;
601  dcon0.B.DCBYP = enable ? 0 : 1; /*depending on the enable bypas bit is reset/set */
602  __mtcr(CPU_DCON0, dcon0.U);
603  IfxScuWdt_setCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
604  }
605  /* Step 2: Call Isync */
606  __isync();
607 }
608 
609 
611 {
612  if (enable)
613  { /* Step 3: Initiate invalidation of current cache contents if any */
614  Ifx_CPU_PCON1 pcon1;
615  pcon1.U = 0;
616  pcon1.B.PCINV = 1;
617  __mtcr(CPU_PCON1, pcon1.U);
618  }
619 
620  uint32 coreId = IfxCpu_getCoreId();
621  uint16 wdtPassword = IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[coreId]);
622  /*PCACHE enable steps */
623  { /* Step 1: Set PCBYP to 0 if cache is enabled */
624  IfxScuWdt_clearCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
625  Ifx_CPU_PCON0 pcon0;
626  pcon0.U = 0;
627  pcon0.B.PCBYP = enable ? 0 : 1; /*depending on the enable bypass bit is reset/set */
628  __mtcr(CPU_PCON0, pcon0.U);
629  IfxScuWdt_setCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
630  }
631  /* Step 2: Call Isync */
632  __isync();
633 }
634 
635 
636 IFX_INLINE boolean IfxCpu_isAddressCachable(void *address)
637 {
638  uint8 segment = (uint32)address >> 24;
639  return ((segment == IFXCPU_CACHABLE_FLASH_SEGMENT) || (segment == IFXCPU_CACHABLE_LMU_SEGMENT)) ? TRUE : FALSE;
640 }
641 
642 
644 {
645  uint32 cpu_pmaVal;
646  uint16 checkRestrictionMask;
647  uint32 coreId = IfxCpu_getCoreId();
648  uint16 wdtPassword = IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[coreId]);
649 
650  /*resolve the restrictions*/
651  /*In PMA0 Segment-C and Segment[7-CoreID] must have the same value */
652  checkRestrictionMask = ((uint16)1 << (7 - coreId)) | ((uint16)1 << 0xC);
653 
654  if ((segmentNumberMask & checkRestrictionMask) != 0)
655  {
656  segmentNumberMask |= checkRestrictionMask;
657  }
658 
659  cpu_pmaVal = __mfcr(CPU_PMA0); /* Read the CPU_PMA0 */
660 
661  cpu_pmaVal = enable ? (cpu_pmaVal | segmentNumberMask) : (cpu_pmaVal & ~segmentNumberMask); /* enable or disable the corresponding bitfield */
662 
663  /*The CPU_PMA registers are ENDINIT protected*/
664  IfxScuWdt_clearCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
665  /*When changing the value of the CPU_PMAx registers both the instruction and data caches should be invalidated*/
666  /*Write to PMA0 register for selecting the cacheability for data cache*/
667  __dsync(); /* DSYNC instruction should be executed immediately prior to the MTCR*/
668  __mtcr(CPU_PMA0, cpu_pmaVal);
669  __isync(); /* ISYNC instruction executed immediately following MTCR */
670  IfxScuWdt_setCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
671 }
672 
673 
675 {
676  uint32 cpu_pmaVal;
677  uint16 checkRestrictionMask;
678  uint32 coreId = IfxCpu_getCoreId();
679  uint16 wdtPassword = IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[coreId]);
680 
681  /*resolve the restrictions*/
682  /*In PMA1 Segment-D and Segment[7-CoreID] must have the same value */
683  checkRestrictionMask = ((uint16)1 << (7 - coreId)) | ((uint16)1 << 0xD);
684 
685  if ((segmentNumberMask & checkRestrictionMask) != 0)
686  {
687  segmentNumberMask |= checkRestrictionMask;
688  }
689 
690  cpu_pmaVal = __mfcr(CPU_PMA1); /* Read the CPU_PMA1 */
691 
692  cpu_pmaVal = enable ? (cpu_pmaVal | segmentNumberMask) : (cpu_pmaVal & ~segmentNumberMask); /* enable or disable the corresponding bitfield */
693 
694  /*The CPU_PMA registers are ENDINIT protected*/
695  IfxScuWdt_clearCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
696  /*When changing the value of the CPU_PMAx registers both the instruction and data caches should be invalidated*/
697  /*Write to PMA1 register for selecting the cacheability for data cache*/
698  __dsync(); /* DSYNC instruction should be executed immediately prior to the MTCR */
699  __mtcr(CPU_PMA1, cpu_pmaVal);
700  __isync(); /* ISYNC instruction executed immediately following MTCR */
701  IfxScuWdt_setCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
702 }
703 
704 
706 {
707  uint16 cpuWdtPassword = IfxScuWdt_getCpuWatchdogPassword();
708  {
709  IfxScuWdt_clearCpuEndinit(cpuWdtPassword);
710  Ifx_CPU_PCON1 pcon1;
711  pcon1.U = __mfcr(CPU_PCON1);
712  pcon1.B.PCINV = 1;
713  __mtcr(CPU_PCON1, pcon1.U);
714  IfxScuWdt_setCpuEndinit(cpuWdtPassword);
715  }
716 }
717 
718 
720 {
721  return IfxCpu_getPerformanceCounter(CPU_CCNT);
722 }
723 
724 
726 {
727  return IfxCpu_getPerformanceCounter(CPU_ICNT);
728 }
729 
730 
732 {
734 }
735 
736 
738 {
740 }
741 
742 
744 {
745  Ifx_CPU_CCTRL cctrl;
746  cctrl.U = __mfcr(CPU_CCTRL);
747  cctrl.B.CE = enable;
748  __mtcr(CPU_CCTRL, cctrl.U);
749 }
750 
751 
753 {
754  IfxCpu_updatePerformanceCounter(CPU_CCNT, count);
755 }
756 
757 
759 {
760  IfxCpu_updatePerformanceCounter(CPU_ICNT, count);
761 }
762 
763 
765 {
766  Ifx_CPU_CCTRL cctrl;
767  cctrl.U = __mfcr(CPU_CCTRL);
768  /*Disable the counters */
769  cctrl.B.CE = 0;
770  __mtcr(CPU_CCTRL, cctrl.U);
771 
772  /* reset the counters */
773  __mtcr(CPU_CCNT, 0);
774  __mtcr(CPU_ICNT, 0);
775  __mtcr(CPU_M1CNT, 0);
776  __mtcr(CPU_M2CNT, 0);
777  __mtcr(CPU_M3CNT, 0);
778 
779  /*Enable the counters, set the counter mode */
780  cctrl.B.CE = 1;
781  cctrl.B.CM = mode;
782  __mtcr(CPU_CCTRL, cctrl.U);
783 }
784 
785 
787 {
788  IfxCpu_Perf result;
789  /*Disable the counters, reset the control reg */
790  /* Use inline assembly to ensure constant implementation, and execution of the measurement routines */
792 
793  Ifx_CPU_CCNT ccnt;
794  ccnt.U = __mfcr(CPU_CCNT);
795  result.clock.counter = ccnt.B.CountValue;
796  result.clock.overlfow = ccnt.B.SOvf;
797 
798  Ifx_CPU_ICNT icnt;
799  icnt.U = __mfcr(CPU_ICNT);
800  result.instruction.counter = icnt.B.CountValue;
801  result.instruction.overlfow = icnt.B.SOvf;
802 
803  Ifx_CPU_M1CNT m1cnt;
804  m1cnt.U = __mfcr(CPU_M1CNT);
805  result.counter1.counter = m1cnt.B.CountValue;
806  result.counter1.overlfow = m1cnt.B.SOvf;
807 
808  Ifx_CPU_M2CNT m2cnt;
809  m2cnt.U = __mfcr(CPU_M2CNT);
810  result.counter2.counter = m2cnt.B.CountValue;
811  result.counter2.overlfow = m2cnt.B.SOvf;
812 
813  Ifx_CPU_M3CNT m3cnt;
814  m3cnt.U = __mfcr(CPU_M3CNT);
815  result.counter3.counter = m3cnt.B.CountValue;
816  result.counter3.overlfow = m3cnt.B.SOvf;
817  return result;
818 }
819 
820 
822 {
823  Ifx_CPU_CCNT ccnt;
824  ccnt.U = __mfcr(address);
825  return ccnt.B.CountValue;
826 }
827 
828 
830 {
831  Ifx_CPU_CCNT ccnt;
832 
833  ccnt.U = __mfcr(address); /*read the counter */
834 
835  return ccnt.B.SOvf;
836 }
837 
838 
840 {
841  Ifx_CPU_CCTRL cctrl;
842  boolean enableBit;
843  /*Disable the counters */
844  cctrl.U = __mfcr(CPU_CCTRL);
845  enableBit = cctrl.B.CE;
846  cctrl.B.CE = 0;
847  __mtcr(CPU_CCTRL, cctrl.U);
848 
849  /*Update the counter value */
850  count &= ~(1U << 31); /*clear sticky overflow bit if set */
851  __mtcr(address, count);
852 
853  /*restore the enable bit */
854  cctrl.B.CE = enableBit;
855  __mtcr(CPU_CCTRL, cctrl.U);
856 }
857 
858 
859 #endif /* IFXCPU_H */