iLLD_TC27xD  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_1_0_0_11_0
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  *
25  * \defgroup IfxLld_Cpu_Std_Core Cpu Core Functions
26  * \ingroup IfxLld_Cpu_Std
27  * \defgroup IfxLld_Cpu_Std_Interrupt Interrupt Utility Functions
28  * \ingroup IfxLld_Cpu_Std
29  * \defgroup IfxLld_Cpu_Std_Cache Cache Management Functions
30  * \ingroup IfxLld_Cpu_Std
31  * \defgroup IfxLld_Cpu_Std_PerformanceCounter Performance Counter Functions
32  * \ingroup IfxLld_Cpu_Std
33  * \defgroup IfxLld_Cpu_Std_Synchronization Synchronization Functions
34  * \ingroup IfxLld_Cpu_Std
35  * \defgroup IfxLld_Cpu_Std_Utility Cpu Utility Functions
36  * \ingroup IfxLld_Cpu_Std
37  * \defgroup IfxLld_Cpu_Std_Enum Enumerations
38  * \ingroup IfxLld_Cpu_Std
39  * \defgroup IfxLld_Cpu_Std_DataStructures Data Structures
40  * \ingroup IfxLld_Cpu_Std
41  */
42 
43 #ifndef IFXCPU_H
44 #define IFXCPU_H 1
45 
46 /******************************************************************************/
47 /*----------------------------------Includes----------------------------------*/
48 /******************************************************************************/
49 
50 #include "_Impl/IfxCpu_cfg.h"
51 #include "IfxSrc_reg.h"
52 #include "IfxScu_reg.h"
53 #include "Scu/Std/IfxScuWdt.h"
54 #include "_Impl/IfxScu_cfg.h"
55 #include "_Utilities/Ifx_Assert.h"
56 
57 /******************************************************************************/
58 /*-----------------------------------Macros-----------------------------------*/
59 /******************************************************************************/
60 
61 /** \brief Convert local DSPR address to global DSPR address which can be accessed from the SRI bus.
62  * Use this macro to convert a local DSPR address (in segment 0xd00.....) to
63  * a global DSPR address (in segment 0x700....., 0x600....., 0x500..... downwards) depending on
64  * the CPU number.
65  * Example usage:
66  * \code
67  * dmaChConfig.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), &sourceBuffer[i][0]);
68  * dmaChConfig.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), &destinationBuffer[i][0]);
69  * \endcode
70  */
71 #define IFXCPU_GLB_ADDR_DSPR(cpu, address) ((((((unsigned)(address) & 0xF0000000) == 0xD0000000) ? ((((unsigned)(address) & 0x000fffff) | 0x70000000) - ((cpu) * 0x10000000)) : (unsigned)(address))))
72 
73 /** \brief Convert local PSPR address to global PSPR address which can be accessed from the SRI bus.
74  * Use this macro to convert a local PSPR address (in segment 0xc......) to
75  * a global PSPR address (in segment 0x701....., 0x601....., 0x501..... downwards) depending on
76  * the CPU number.
77  *
78  * Example usage:
79  * \code
80  * dmaChConfig.sourceAddress = IFXCPU_GLB_ADDR_PSPR(IfxCpu_getCoreId(), &sourceBufferInPsprMemory);
81  * dmaChConfig.destinationAddress = IFXCPU_GLB_ADDR_PSPR(IfxCpu_getCoreId(), &destinationBufferInPsprMemory);
82  * \endcode
83  */
84 #define IFXCPU_GLB_ADDR_PSPR(cpu, address) ((((unsigned)(address) & 0x000fffff) | 0x70100000) - ((cpu) * 0x10000000))
85 
86 /******************************************************************************/
87 /*------------------------------Type Definitions------------------------------*/
88 /******************************************************************************/
89 
90 /** \brief Lock type Spin lock
91  */
92 typedef unsigned int IfxCpu_spinLock;
93 
94 /** \brief Lock type Mutex lock
95  */
96 typedef unsigned int IfxCpu_mutexLock;
97 
98 /******************************************************************************/
99 /*--------------------------------Enumerations--------------------------------*/
100 /******************************************************************************/
101 
102 /** \addtogroup IfxLld_Cpu_Std_Enum
103  * \{ */
104 /** \brief Enumeration for the Cpu mode
105  */
106 typedef enum
107 {
115 
116 /** \brief Performance conunter modes
117  */
118 typedef enum
119 {
120  IfxCpu_CounterMode_normal = 0, /**< \brief Normal counter mode:the counter increments on their respective triggers */
121  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 */
123 
124 /** \} */
125 
126 /******************************************************************************/
127 /*-----------------------------Data Structures--------------------------------*/
128 /******************************************************************************/
129 
130 /** \addtogroup IfxLld_Cpu_Std_DataStructures
131  * \{ */
132 typedef struct
133 {
134  uint32 counter; /**< \brief Counter value */
135  boolean overlfow; /**< \brief sticky overlfow */
137 
138 /** \} */
139 
140 /** \addtogroup IfxLld_Cpu_Std_DataStructures
141  * \{ */
142 /** \brief Performance counter result
143  */
144 typedef struct
145 {
146  IfxCpu_Counter instruction; /**< \brief Instruction counter */
147  IfxCpu_Counter clock; /**< \brief CPU clock counter */
148  IfxCpu_Counter counter1; /**< \brief Multi counter 1 */
149  IfxCpu_Counter counter2; /**< \brief Multi counter 2 */
150  IfxCpu_Counter counter3; /**< \brief Multi counter 3 */
151 } IfxCpu_Perf;
152 
153 /** \} */
154 
155 /** \addtogroup IfxLld_Cpu_Std_Core
156  * \{ */
157 
158 /******************************************************************************/
159 /*-------------------------Inline Function Prototypes-------------------------*/
160 /******************************************************************************/
161 
162 /** \brief API to get core id of the CPU of the caller.
163  * Caution: Core id of the cpus may not be continguous and shouldn't be used to index cpu.
164  * Use IfxCpu_getCoreIndex() to get cpu no.
165  * \return Resource index of the CPU.
166  */
168 
169 /** \brief API to get cpu index of the caller CPU.
170  * Note: This api can be used whereever cpu no/index is needed.
171  * \return Resource index of the CPU.
172  */
174 
175 /** \brief API to initialize the context save area of the CPU where this is called.
176  *
177  * This API can initialize the CSA of the host CPU where this API is called. This API
178  * shall not be used to initialize the CSA of another CPU
179  * \param csaBegin Pointer to start of context save area
180  * \param csaEnd Pointer to end of context save area
181  * \return None
182  */
183 IFX_INLINE void IfxCpu_initCSA(uint32 *csaBegin, uint32 *csaEnd);
184 
185 /** \brief Set/Clear safety task identifier (PSW.S) on current CPU
186  * \return None
187  */
188 IFX_INLINE void IfxCpu_setSafetyTaskIdentifier(boolean safetyId);
189 
190 /** \brief Triggers Software Reset
191  * \return None
192  */
194 
195 /******************************************************************************/
196 /*-------------------------Global Function Prototypes-------------------------*/
197 /******************************************************************************/
198 
199 /** \brief API to get the address for CPU HW module register memory map
200  * \param cpu Resource index of the CPU
201  * \return CPU module register address
202  */
204 
205 /** \brief API to get current mode of CPU
206  * \param cpu Pointer to the CPU HW module (register memory map)
207  * \return Current mode of the CPU
208  */
210 
211 /** \brief API to get current mode of CPU
212  * \param cpu Pointer to the CPU HW module (register memory map)
213  * \return Resource index of the CPU
214  */
216 
217 /** \brief API to set mode of the CPU
218  * \param cpu Pointer to the CPU HW module (register memory map)
219  * \param mode CPU mode to be set by this API
220  * \return Success status of the activity (setting the core mode).
221  * \retval TRUE: If the activity successfully be performed.
222  * \retval FALSE: If the activity can't be performed.
223  */
224 IFX_EXTERN boolean IfxCpu_setCoreMode(Ifx_CPU *cpu, IfxCpu_CoreMode mode);
225 
226 /** \brief API to set the program counter for the CPU specified.
227  * \param cpu Pointer to the CPU HW module (register memory map)
228  * \param programCounter Program counter value to be set
229  * \return success status of the activity (setting program counter value).
230  * \retval TRUE: If the activity successfully be performed.
231  * \retval FALSE: If the activity can't be performed
232  */
233 IFX_EXTERN boolean IfxCpu_setProgramCounter(Ifx_CPU *cpu, uint32 programCounter);
234 
235 /** \brief API to set the program counter for the CPU specified and start the CPU
236  * \param cpu Pointer to the CPU HW module (register memory map)
237  * \param programCounter Program counter value to start the CPU
238  * \return success status of the activity (setting program counter value).
239  * \retval TRUE: If the activity successfully be performed.
240  * \retval FALSE: If the activity can't be performed
241  */
242 IFX_EXTERN boolean IfxCpu_startCore(Ifx_CPU *cpu, uint32 programCounter);
243 
244 /** \} */
245 
246 /** \addtogroup IfxLld_Cpu_Std_Interrupt
247  * \{ */
248 
249 /******************************************************************************/
250 /*-------------------------Inline Function Prototypes-------------------------*/
251 /******************************************************************************/
252 
253 /** \brief API to get the status of global interrupt enable (ICR.IE) for the CPU which calls this API
254  * This API provides the status of CPU where this API is called
255  * \return Status of global interrupt enable bit.
256  * \retval TRUE: Global interrupts enabled.
257  * \retval FALSE: Global interrupts disabled
258  */
260 
261 /** \brief API to disable global interrupt and return the previous status.
262  *
263  * This API can be used only to disable the global interrupts of caller CPU. It cannot be
264  * used for this activity towards other CPUs
265  * \return Previous status of global interrupt enable bit.
266  * \retval TRUE: Previously, global interrupts enabled.
267  * \retval FALSE: Previously, global interrupts disabled
268  */
270 
271 /** \brief API to enable global interrupt.
272  * This API simply enables the global interrupt.
273  * \return None
274  */
276 
277 /** \brief Disable the Global Interrupt
278  * \return None
279  */
281 
282 /** \brief API to restore global interrupt with that of the passed parameter.
283  *
284  * This API can be used only to disable the global interrupts of caller CPU. It cannot be
285  * used for this activity towards other CPUs
286  * \param enabled Previous status of the global interrupt enable bit
287  * \return None
288  */
289 IFX_INLINE void IfxCpu_restoreInterrupts(boolean enabled);
290 
291 /** \} */
292 
293 /** \addtogroup IfxLld_Cpu_Std_Cache
294  * \{ */
295 
296 /******************************************************************************/
297 /*-------------------------Inline Function Prototypes-------------------------*/
298 /******************************************************************************/
299 
300 /** \brief API to enable/ disable the data cacheability for selected segments
301  * With this API cacheability for one or more segment can be enabled/disabled for the CPU core where this API is called.
302  * \note This API is to be called only if the PCACHE or DCACHE are not enabled before
303  * \param segmentNumberMask Mask where bitfield 0 represents segment 0 and bitfield 16 represent segment F.
304  * \param enable TRUE: to enable the cacheability for selected segment, FALSE: to disable.
305  * \return None
306  */
308 
309 /** \brief API to enable/ disable the instruction cacheability for selected segments
310  * With this API cacheability for one or more segment can be enabled/disabled for the CPU core where this API is called.
311  * \note This API is to be called only if the PCACHE or DCACHE are not enabled before
312  * \param segmentNumberMask Mask where bitfield 0 represents segment 0 and bitfield 16 represent segment F.
313  * \param enable TRUE: to enable the cacheability for selected segment, FALSE: to disable.
314  * \return None
315  */
317 
318 /** \brief API to invalidate the program cache
319  * \return None
320  */
322 
323 /** \brief API to determine if an address is in a cachable or non-cachable Flash/LMU section
324  * \param address Address
325  * \return Status TRUE/FALSE
326  */
327 IFX_INLINE boolean IfxCpu_isAddressCachable(void *address);
328 
329 /** \brief API to enable or bypass the data cache for the CPU which calls this API.
330  *
331  * This API can be used only to enable or bypass the data cache of caller CPU. It cannot be
332  * used for this activity towards other CPUs
333  * \param enable Command to enable or bypass the data cache
334  * TRUE: Enable the data cache.
335  * FALSE: Bypass the data cache.
336  * \return None
337  */
339 
340 /** \brief API to enable or bypass the program cache for the CPU which calls this API.
341  *
342  * This API can be used only to enable or bypass the program cache of caller CPU. It cannot be
343  * used for this activity towards other CPUs
344  * \param enable Command to enable or bypass the program cache.
345  * TRUE: Enable the program cache.
346  * FALSE: Bypass the program cache
347  * \return None
348  */
350 
351 /** \} */
352 
353 /** \addtogroup IfxLld_Cpu_Std_PerformanceCounter
354  * \{ */
355 
356 /******************************************************************************/
357 /*-------------------------Inline Function Prototypes-------------------------*/
358 /******************************************************************************/
359 
360 /** \brief API to read the clock counter for the CPU which calls this API.
361  *
362  * This API can be used to read clock counter of only the caller CPU. It cannot be
363  * used for this activity towards other CPUs.
364  * \return Counter value. 0 to 0x7FFFFFFF.
365  */
367 
368 /** \brief API to get sticky overflow bit of clock counter for the CPU, which calls this API.
369  *
370  * This API can be used to get sticky overflow bit of clock counter of only the caller CPU.
371  * It cannot be used for this activity towards other CPUs.
372  * This API also clears the sticky overflow after the read. While reading the sticky bit this API disables
373  * the counter for short time. (otherwise sticky bit cannot be cleared). This API shall be used after
374  * reading the counter
375  * \return Status of sticky overflow bit.
376  * \retval TRUE: Sticky overflow bit is set.
377  * \retval FALSE: Sticky overflow bit is reset
378  */
380 
381 /** \brief API to read the instruction counter for the CPU which calls this API.
382  *
383  * This API can be used to read instruction counter of only the caller CPU. It cannot be
384  * used for this activity towards other CPUs
385  * \return Counter value. 0 to 0x7FFFFFFF.
386  */
388 
389 /** \brief API to get sticky overflow bit of Instruction counter for the CPU, which calls this API.
390  *
391  * This API can be used to get sticky overflow bit of Instruction counter of only the caller CPU.
392  * It cannot be used for this activity towards other CPUs.
393  * This API also clears the sticky overflow after the read. While reading the sticky bit this API disables
394  * the counter for short time. (otherwise sticky bit cannot be cleared). This API shall be used after
395  * reading the counter
396  * \return Status of sticky overflow bit.
397  * \retval TRUE: Sticky overflow bit is set.
398  * \retval FALSE: Sticky overflow bit is reset
399  */
401 
402 /** \brief API to read the performance counter for the CPU which calls this API.
403  * \param address Address
404  * \return counter value
405  */
407 
408 /** \brief API to get sticky overflow bit of performance counter for the CPU, which calls this API.
409  * This is generic function to get sticky overflow bit of any performance counters
410  * \param address Address
411  * \return Status
412  */
414 
415 /** \brief Reset and start instruction, clock and multi counters
416  *
417  * Reset and start CCNT, ICNT, M1CNT, M2CNT, M3CNT. the overflow bits are cleared.
418  * \param mode Counter mode
419  * \return None
420  */
422 
423 /** \brief API to enable or disable performance counter for the CPU which calls this API.
424  *
425  * This API can be used to enable or disable performance counter of only the caller CPU. It cannot be
426  * used for this activity towards other CPUs.
427  * \param enable enable Command to enable or disable the performance counter.
428  * TRUE: Enable the performance counter.
429  * FALSE: Disable the performance counter
430  * \return None
431  */
433 
434 /** \brief Stop instruction and clock counters, return their values
435  *
436  * Stop CCNT, ICNT, M1CNT, M2CNT, M3CNT and return their values;
437  * \Note The CCTRL is reset to 0, for more accurate measurements and has to be initialized again before strating the next performance measurement.
438  * \return Performance counter result
439  */
441 
442 /** \brief API to update clock counter for the CPU which calls this API.
443  *
444  * This API can be used to update clock counter of only the caller CPU. It cannot be
445  * used for this activity towards other CPUs.
446  * \param count Counter value to be updated. 0 to 0x7FFFFFFF
447  * \return None
448  */
450 
451 /** \brief API to update Instruction counter for the CPU which calls this API.
452  *
453  * This API can be used to update Instruction counter of only the caller CPU. It cannot be
454  * used for this activity towards other CPUs.
455  * \param count Counter value to be updated. 0 to 0x7FFFFFFF
456  * \return None
457  */
459 
460 /** \brief API to update performance counter for the CPU which calls this API.
461  * This is generic function to update any of the performance counters
462  * \param address Address
463  * \param count Count
464  * \return None
465  */
467 
468 /** \} */
469 
470 /** \addtogroup IfxLld_Cpu_Std_Synchronization
471  * \{ */
472 
473 /******************************************************************************/
474 /*-------------------------Global Function Prototypes-------------------------*/
475 /******************************************************************************/
476 
477 /** \brief API to acquire the mutex (binary semaphore).
478  *
479  * This API can be used to acquire/get the mutex.
480  * \param lock lock pointer
481  * \return TRUE : lock acquired successfully. FALSE: Failed to acquire the lock
482  *
483  * \code
484  * IfxCpu_mutexLock resourceLock;
485  * boolean flag = IfxCpu_acquireMutex(&resourceLock);
486  * if (flag){
487  * // critical section
488  * IfxCpu_releaseMutex(&resourceLock);
489  * }
490  * \endcode
491  *
492  */
494 
495 /** \brief API to unlock the mutex .
496  *
497  * This API can be used to unlock the previously acquired mutex
498  * \param lock lock pointer
499  * \return None
500  *
501  * \code
502  * IfxCpu_mutexLock resourceLock;
503  * boolean flag = IfxCpu_acquireMutex(&resourceLock);
504  * if (flag){
505  * // critical section
506  * IfxCpu_releaseMutex(&resourceLock);
507  * }
508  * \endcode
509  *
510  */
512 
513 /** \brief API to unlock the resource .
514  *
515  * This API can be used to unlock the previously acquired lock
516  * \param lock lock pointer
517  * \return None
518  */
520 
521 /** \brief API to lock the resource in spin mode with the given timeout.
522  *
523  * This API can be used to spin lock for the lock for the given timeout period.
524  * \param lock lock pointer
525  * \param timeoutCount loop counter value used for timeout to acquire lock
526  * \return TRUE : lock acquired successfully. FALSE: Failed to acquire the lock
527  *
528  * \code
529  * IfxCpu_spinLock resourceLock;
530  * boolean flag = IfxCpu_setSpinLock(&resourceLock, 0xFFFF);
531  * if (flag){
532  * // critical section
533  * IfxCpu_resetSpinLock(&resourceLock);
534  * }
535  * \endcode
536  *
537  */
538 IFX_EXTERN boolean IfxCpu_setSpinLock(IfxCpu_spinLock *lock, uint32 timeoutCount);
539 
540 /** \} */
541 
542 /** \addtogroup IfxLld_Cpu_Std_Utility
543  * \{ */
544 
545 /******************************************************************************/
546 /*-------------------------Global Function Prototypes-------------------------*/
547 /******************************************************************************/
548 
549 /** \brief API to get random value
550  * \param seed Pointer to seed value
551  * \return random value
552  */
554 
555 /** \brief API to get random value with in the range
556  * \param seed Pointer to seed value
557  * \param min minimum range value
558  * \param max maximum range value
559  * \return random value
560  */
562 
563 /** \} */
564 
565 /******************************************************************************/
566 /*---------------------Inline Function Implementations------------------------*/
567 /******************************************************************************/
568 
570 {
571  Ifx_CPU_ICR reg;
572  reg.U = __mfcr(CPU_ICR);
573  return reg.B.IE != 0;
574 }
575 
576 
578 {
579  boolean enabled;
580  enabled = IfxCpu_areInterruptsEnabled();
581  __disable();
582  __nop();
583  return enabled;
584 }
585 
586 
588 {
589  __enable();
590 }
591 
592 
594 {
595  uint32 cpu_pmaVal;
596  uint16 checkRestrictionMask;
597  uint32 coreId = IfxCpu_getCoreIndex();
598  uint16 wdtPassword = IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[coreId]);
599 
600  /*resolve the restrictions*/
601  /*In PMA0 Segment-C and Segment[7-CoreID] must have the same value */
602  checkRestrictionMask = ((uint16)1 << (7 - coreId)) | ((uint16)1 << 0xC);
603 
604  if ((segmentNumberMask & checkRestrictionMask) != 0)
605  {
606  segmentNumberMask |= checkRestrictionMask;
607  }
608 
609  cpu_pmaVal = __mfcr(CPU_PMA0); /* Read the CPU_PMA0 */
610 
611  cpu_pmaVal = enable ? (cpu_pmaVal | segmentNumberMask) : (cpu_pmaVal & ~segmentNumberMask); /* enable or disable the corresponding bitfield */
612 
613  /*The CPU_PMA registers are ENDINIT protected*/
614  IfxScuWdt_clearCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
615  /*When changing the value of the CPU_PMAx registers both the instruction and data caches should be invalidated*/
616  /*Write to PMA0 register for selecting the cacheability for data cache*/
617  __dsync(); /* DSYNC instruction should be executed immediately prior to the MTCR*/
618  __mtcr(CPU_PMA0, cpu_pmaVal);
619  __isync(); /* ISYNC instruction executed immediately following MTCR */
620  IfxScuWdt_setCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
621 }
622 
623 
625 {
626  uint32 cpu_pmaVal;
627  uint16 checkRestrictionMask;
628  uint32 coreId = IfxCpu_getCoreIndex();
629  uint16 wdtPassword = IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[coreId]);
630 
631  /*resolve the restrictions*/
632  /*In PMA1 Segment-D and Segment[7-CoreID] must have the same value */
633  checkRestrictionMask = ((uint16)1 << (7 - coreId)) | ((uint16)1 << 0xD);
634 
635  if ((segmentNumberMask & checkRestrictionMask) != 0)
636  {
637  segmentNumberMask |= checkRestrictionMask;
638  }
639 
640  cpu_pmaVal = __mfcr(CPU_PMA1); /* Read the CPU_PMA1 */
641 
642  cpu_pmaVal = enable ? (cpu_pmaVal | segmentNumberMask) : (cpu_pmaVal & ~segmentNumberMask); /* enable or disable the corresponding bitfield */
643 
644  /*The CPU_PMA registers are ENDINIT protected*/
645  IfxScuWdt_clearCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
646  /*When changing the value of the CPU_PMAx registers both the instruction and data caches should be invalidated*/
647  /*Write to PMA1 register for selecting the cacheability for data cache*/
648  __dsync(); /* DSYNC instruction should be executed immediately prior to the MTCR */
649  __mtcr(CPU_PMA1, cpu_pmaVal);
650  __isync(); /* ISYNC instruction executed immediately following MTCR */
651  IfxScuWdt_setCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
652 }
653 
654 
656 {
657  __disable();
658  __nop();
659 }
660 
661 
663 {
664  return IfxCpu_getPerformanceCounter(CPU_CCNT);
665 }
666 
667 
669 {
671 }
672 
673 
675 {
676  Ifx_CPU_CORE_ID reg;
677  reg.U = __mfcr(CPU_CORE_ID);
678  return (IfxCpu_ResourceCpu)reg.B.CORE_ID;
679 }
680 
681 
683 {
684  Ifx_CPU_CORE_ID reg;
685  reg.U = __mfcr(CPU_CORE_ID);
686  return (IfxCpu_ResourceCpu)reg.B.CORE_ID;
687 }
688 
689 
691 {
692  return IfxCpu_getPerformanceCounter(CPU_ICNT);
693 }
694 
695 
697 {
699 }
700 
701 
703 {
704  Ifx_CPU_CCNT ccnt;
705  ccnt.U = __mfcr(address);
706  return ccnt.B.CountValue;
707 }
708 
709 
711 {
712  Ifx_CPU_CCNT ccnt;
713 
714  ccnt.U = __mfcr(address); /*read the counter */
715 
716  return ccnt.B.SOvf;
717 }
718 
719 
720 IFX_INLINE void IfxCpu_initCSA(uint32 *csaBegin, uint32 *csaEnd)
721 {
722  uint32 k;
723  uint32 nxt_cxi_val = 0;
724  uint32 *prvCsa = 0U;
725  uint32 *nxtCsa = csaBegin;
726 
727  for (k = 0; k < (((uint32)csaEnd - (uint32)csaBegin) / 64); k++)
728  {
729  nxt_cxi_val = ((uint32)nxtCsa & (0XFU << 28)) >> 12 | ((uint32)nxtCsa & (0XFFFFU << 6)) >> 6;
730 
731  if (k == 0)
732  {
733  __mtcr(CPU_FCX, nxt_cxi_val); /* store the new pcxi value to LCX */
734  }
735  else
736  {
737  *prvCsa = nxt_cxi_val; /* Store null pointer in last CSA (= very first time!) */
738  }
739 
740  prvCsa = (uint32 *)nxtCsa;
741  nxtCsa += 16; /* next CSA */
742  }
743 
744  *prvCsa = 0;
745  __mtcr(CPU_LCX, nxt_cxi_val); /* Last context save area is pointed in LCX to know if there is CSA depletion */
746 }
747 
748 
750 {
751  uint16 cpuWdtPassword = IfxScuWdt_getCpuWatchdogPassword();
752  {
753  IfxScuWdt_clearCpuEndinit(cpuWdtPassword);
754  Ifx_CPU_PCON1 pcon1;
755  pcon1.U = __mfcr(CPU_PCON1);
756  pcon1.B.PCINV = 1;
757  __mtcr(CPU_PCON1, pcon1.U);
758  IfxScuWdt_setCpuEndinit(cpuWdtPassword);
759  }
760 }
761 
762 
763 IFX_INLINE boolean IfxCpu_isAddressCachable(void *address)
764 {
765  uint8 segment = (uint32)address >> 24;
766  return ((segment == IFXCPU_CACHABLE_FLASH_SEGMENT) || (segment == IFXCPU_CACHABLE_LMU_SEGMENT)) ? TRUE : FALSE;
767 }
768 
769 
771 {
772  Ifx_CPU_CCTRL cctrl;
773  cctrl.U = __mfcr(CPU_CCTRL);
774  /*Disable the counters */
775  cctrl.B.CE = 0;
776  __mtcr(CPU_CCTRL, cctrl.U);
777 
778  /* reset the counters */
779  __mtcr(CPU_CCNT, 0);
780  __mtcr(CPU_ICNT, 0);
781  __mtcr(CPU_M1CNT, 0);
782  __mtcr(CPU_M2CNT, 0);
783  __mtcr(CPU_M3CNT, 0);
784 
785  /*Enable the counters, set the counter mode */
786  cctrl.B.CE = 1;
787  cctrl.B.CM = mode;
788  __mtcr(CPU_CCTRL, cctrl.U);
789 }
790 
791 
793 {
794  if (enabled != FALSE)
795  {
796  __enable();
797  }
798 }
799 
800 
802 {
803  uint32 coreId = IfxCpu_getCoreIndex();
804  uint16 wdtPassword = IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[coreId]);
805  /*PCACHE enable steps */
806  { /* Step 1: Set PCBYP to 0 if cache is enabled */
807  IfxScuWdt_clearCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
808  Ifx_CPU_DCON0 dcon0;
809  dcon0.U = 0;
810  dcon0.B.DCBYP = enable ? 0 : 1; /*depending on the enable bypas bit is reset/set */
811  __mtcr(CPU_DCON0, dcon0.U);
812  IfxScuWdt_setCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
813  }
814  /* Step 2: Call Isync */
815  __isync();
816 }
817 
818 
820 {
821  Ifx_CPU_CCTRL cctrl;
822  cctrl.U = __mfcr(CPU_CCTRL);
823  cctrl.B.CE = enable;
824  __mtcr(CPU_CCTRL, cctrl.U);
825 }
826 
827 
829 {
830  if (enable)
831  { /* Step 3: Initiate invalidation of current cache contents if any */
832  Ifx_CPU_PCON1 pcon1;
833  pcon1.U = 0;
834  pcon1.B.PCINV = 1;
835  __mtcr(CPU_PCON1, pcon1.U);
836  }
837 
838  uint32 coreId = IfxCpu_getCoreIndex();
839  uint16 wdtPassword = IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[coreId]);
840  /*PCACHE enable steps */
841  { /* Step 1: Set PCBYP to 0 if cache is enabled */
842  IfxScuWdt_clearCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
843  Ifx_CPU_PCON0 pcon0;
844  pcon0.U = 0;
845  pcon0.B.PCBYP = enable ? 0 : 1; /*depending on the enable bypass bit is reset/set */
846  __mtcr(CPU_PCON0, pcon0.U);
847  IfxScuWdt_setCpuEndinitInline(&MODULE_SCU.WDTCPU[coreId], wdtPassword);
848  }
849  /* Step 2: Call Isync */
850  __isync();
851 }
852 
853 
855 {
856  Ifx_CPU_PSW psw;
857  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (safetyId == 0 || safetyId == 1));
858  psw.U = __mfcr(CPU_PSW);
859  psw.B.S = safetyId;
860  __mtcr(CPU_PSW, (uint32)psw.U);
861 }
862 
863 
865 {
866  IfxCpu_Perf result;
867  /*Disable the counters, reset the control reg */
868  /* Use inline assembly to ensure constant implementation, and execution of the measurement routines */
870 
871  Ifx_CPU_CCNT ccnt;
872  ccnt.U = __mfcr(CPU_CCNT);
873  result.clock.counter = ccnt.B.CountValue;
874  result.clock.overlfow = ccnt.B.SOvf;
875 
876  Ifx_CPU_ICNT icnt;
877  icnt.U = __mfcr(CPU_ICNT);
878  result.instruction.counter = icnt.B.CountValue;
879  result.instruction.overlfow = icnt.B.SOvf;
880 
881  Ifx_CPU_M1CNT m1cnt;
882  m1cnt.U = __mfcr(CPU_M1CNT);
883  result.counter1.counter = m1cnt.B.CountValue;
884  result.counter1.overlfow = m1cnt.B.SOvf;
885 
886  Ifx_CPU_M2CNT m2cnt;
887  m2cnt.U = __mfcr(CPU_M2CNT);
888  result.counter2.counter = m2cnt.B.CountValue;
889  result.counter2.overlfow = m2cnt.B.SOvf;
890 
891  Ifx_CPU_M3CNT m3cnt;
892  m3cnt.U = __mfcr(CPU_M3CNT);
893  result.counter3.counter = m3cnt.B.CountValue;
894  result.counter3.overlfow = m3cnt.B.SOvf;
895  return result;
896 }
897 
898 
900 {
901  MODULE_SCU.SWRSTCON.B.SWRSTREQ = 1;
902 
903  /* Wait till reset */
904  while (1)
905  {}
906 }
907 
908 
910 {
911  IfxCpu_updatePerformanceCounter(CPU_CCNT, count);
912 }
913 
914 
916 {
917  IfxCpu_updatePerformanceCounter(CPU_ICNT, count);
918 }
919 
920 
922 {
923  Ifx_CPU_CCTRL cctrl;
924  boolean enableBit;
925  /*Disable the counters */
926  cctrl.U = __mfcr(CPU_CCTRL);
927  enableBit = cctrl.B.CE;
928  cctrl.B.CE = 0;
929  __mtcr(CPU_CCTRL, cctrl.U);
930 
931  /*Update the counter value */
932  count &= ~(1U << 31); /*clear sticky overflow bit if set */
933  __mtcr(address, count);
934 
935  /*restore the enable bit */
936  cctrl.B.CE = enableBit;
937  __mtcr(CPU_CCTRL, cctrl.U);
938 }
939 
940 
941 #endif /* IFXCPU_H */