iLLD_TC27xC  1.0
IfxCpu.c
Go to the documentation of this file.
1 /**
2  * \file IfxCpu.c
3  * \brief CPU basic functionality
4  *
5  * \version iLLD_0_1_0_10
6  * \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved.
7  *
8  *
9  * IMPORTANT NOTICE
10  *
11  *
12  * Infineon Technologies AG (Infineon) is supplying this file for use
13  * exclusively with Infineon's microcontroller products. This file can be freely
14  * distributed within development tools that are supporting such microcontroller
15  * products.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
18  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
20  * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
21  * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
22  *
23  */
24 
25 /******************************************************************************/
26 /*----------------------------------Includes----------------------------------*/
27 /******************************************************************************/
28 
29 #include "IfxCpu.h"
30 #include "_Impl/IfxScu_cfg.h"
31 
32 /******************************************************************************/
33 /*-------------------------Function Implementations---------------------------*/
34 /******************************************************************************/
35 
37 {
38  Ifx_CPU *module;
39 
40  if (cpu < IfxCpu_ResourceCpu_none)
41  {
42  module = (Ifx_CPU *)IfxCpu_cfg_indexMap[cpu].module;
43  }
44  else
45  {
46  module = NULL_PTR;
47  }
48 
49  return module;
50 }
51 
52 
54 {
55  IfxCpu_CoreMode cpuMode;
56  Ifx_CPU_DBGSR dbgsr;
58 
59  cpuMode = IfxCpu_CoreMode_unknown;
60 
61  /*get the DBGSR.HALT status */
62  /*Check if the request is done for same cpu as the host for this call */
63  if (IfxCpu_getCoreId() != index)
64  { /*status request is for other cpu than the host */
65  dbgsr = cpu->DBGSR;
66  }
67  else
68  { /*status request is for same cpu as the host */
69  dbgsr.U = __mfcr(CPU_DBGSR);
70  }
71 
72  /*Check if the requested CPU is in DBG HALT mode */
73  if (dbgsr.B.HALT == (uint32)IfxCpu_DBGST_HALT_halt)
74  { /*CPU is in DBG HALT mode */
75  cpuMode = IfxCpu_CoreMode_halt;
76  }
77  else
78  {
79  if (dbgsr.B.HALT == (uint32)IfxCpu_DBGST_HALT_run)
80  { /*CPU is in DBG RUNNING mode now check PMCSR status */
81  Ifx_SCU_PMCSR *pmcsr_val;
82 
83  pmcsr_val = (Ifx_SCU_PMCSR *)&MODULE_SCU.PMCSR[index];
84 
85  if (pmcsr_val->B.PMST == (uint32)IfxCpu_PMCSR_PMST_normalMode)
86  { /*Cpu is in normal run mode */
87  cpuMode = IfxCpu_CoreMode_run;
88  }
89  else
90  { /*Cpu is not in run mode */
91  if (pmcsr_val->B.PMST == (uint32)IfxCpu_PMCSR_PMST_idleMode)
92  { /*Cpu is in idle mode */
93  cpuMode = IfxCpu_CoreMode_idle;
94  }
95  }
96  }
97  else
98  {
99  cpuMode = IfxCpu_CoreMode_unknown;
100  }
101  }
102 
103  return cpuMode;
104 }
105 
106 
108 {
109  IfxCpu_ResourceCpu result;
110  uint32 index;
111  result = IfxCpu_ResourceCpu_none;
112 
113  for (index = 0; index < IFXCPU_COUNT; index++)
114  {
115  if (IfxCpu_cfg_indexMap[index].module == cpu)
116  {
117  result = (IfxCpu_ResourceCpu)IfxCpu_cfg_indexMap[index].index;
118  break;
119  }
120  }
121 
122  return result;
123 }
124 
125 
126 boolean IfxCpu_setCoreMode(Ifx_CPU *cpu, IfxCpu_CoreMode mode)
127 {
128  // this switch is only temporary required
129  // once the IfxCan driver is generated via lldgen, we will vary the code without #ifdef
130 #ifdef IFX_TC27x
131 /* FIXME Copied from old TC27xA code, check that this is up to date code */
132  IfxCpu_CoreMode cpuMode;
133  boolean RetVal;
134  IfxScu_PMCSR_REQSLP modeSet;
135 
136  RetVal = TRUE;
137 
138  modeSet = IfxScu_PMCSR_REQSLP_Idle;
139 
140  /* Check the mode the CPU is in */
141  cpuMode = IfxCpu_getCoreMode(cpu);
142 
143  /* if requested mode is same as current mode nothing to do */
144  if (cpuMode != mode)
145  {
146  /* transition from halt to Run */
147  if (IfxCpu_CoreMode_halt == cpuMode)
148  {
149  if (IfxCpu_CoreMode_run == mode)
150  {
151  Ifx_CPU_DBGSR dbgsr;
152 
153  if (IfxCpu_getCoreId() != IfxCpu_getIndex(cpu))
154  {
155  cpu->DBGSR.B.HALT = 0x2;
156  }
157  else
158  {
159  dbgsr.U = __mfcr(CPU_DBGSR);
160  dbgsr.B.HALT = 0x2;
161  __mtcr(CPU_DBGSR, dbgsr.U);
162  }
163  }
164  else /* cannot go to any other mode e.g. IfxCpu_CoreMode_idle */
165  {
166  RetVal = FALSE;
167  }
168  }
169  /* From Run to Idle or vice versa */
170  else
171  {
172  if (IfxCpu_CoreMode_run == cpuMode)
173  {
174  if (IfxCpu_CoreMode_idle == mode)
175  {
176  modeSet = IfxScu_PMCSR_REQSLP_Idle;
177  }
178  else
179  {
180  RetVal = FALSE;
181  }
182  }
183  /* idle to Run */
184  else if (IfxCpu_CoreMode_idle == cpuMode)
185  {
186  if (IfxCpu_CoreMode_run == mode)
187  {
188  modeSet = IfxScu_PMCSR_REQSLP_Run;
189  }
190  else
191  {
192  RetVal = FALSE;
193  }
194  }
195  else
196  {
197  RetVal = FALSE;
198  }
199 
200  if (TRUE == RetVal)
201  {
202  /* To take care of the Work Around in A step
203  * In A Step the PMCSR is Cpu Endinit protected
204  * in B step it is by safety endinit*/
205  uint16 password;
206  uint32 wdtCon0_Val;
207  Ifx_SCU_WDTCPU *watchdog;
208  watchdog = &MODULE_SCU.WDTCPU[IfxCpu_getCoreId()]; /* FIXME access to the watchdog of an other CPU, this might not work! */
210  IfxScuWdt_clearCpuEndinit(password);
211  /* password access */
212  watchdog->CON0.U = (password << 2U) | 0x1U;
213  /* modify access, E=0 */
214  watchdog->CON0.U = (password << 2U) | 0x2U;
215  /* password access in advance */
216  watchdog->CON0.U = (password << 2U) | 0x1U;
217  /* prepare write value */
218  wdtCon0_Val = ((0x0000U) << 16U) | (password << 2U) | (0x3U);
219  MODULE_SCU.PMCSR[(uint32)IfxCpu_getIndex(cpu)].B.REQSLP = modeSet;
220  /* modify access, E=1, reload WDT */
221  watchdog->CON0.U = wdtCon0_Val;
222  IfxScuWdt_setCpuEndinit(password);
223  }
224  }
225  }
226 
227  return RetVal;
228 #else
229  uint8 reqslp;
230  boolean retValue;
231  IfxCpu_ResourceCpu index = IfxCpu_getIndex(cpu);
232 
233  /*Modes such as HALT, SLEEP and STBY are not handled at CPU level */
234  retValue = ((mode == IfxCpu_CoreMode_halt) || (mode == IfxCpu_CoreMode_sleep)
235  || (mode == IfxCpu_CoreMode_stby)) ? FALSE : TRUE;
236 
238 
239  if (retValue == TRUE)
240  {
241  /*Check if the same core is requesting to change the core run mode */
242  if (IfxCpu_getCoreId() != index)
243  { /*Request is for the other core */
244  /*To access PMCSR of other CPUs handle the safety EndInit protection */
246  IfxScuWdt_clearSafetyEndinit(safetyWdtPw);
247  MODULE_SCU.PMCSR[(uint32)IfxCpu_getIndex(cpu)].B.REQSLP = reqslp;
248  IfxScuWdt_setSafetyEndinit(safetyWdtPw);
249 
250  cpu->DBGSR.B.HALT = 2; /*reset the HALT bit, if it is already done it is no harm in writing again */
251  }
252  else
253  { /*Request is for self, this request normally only for halt, otherwise the core is already running anyway! */
254  /*To access PMCSR of self handle the cpu EndInit protection */
256  IfxScuWdt_clearCpuEndinit(cpuWdtPw);
257  MODULE_SCU.PMCSR[(uint32)index].B.REQSLP = reqslp;
258  IfxScuWdt_setCpuEndinit(cpuWdtPw);
259  }
260  }
261 
262  return retValue;
263 #endif
264 }
265 
266 
267 boolean IfxCpu_setProgramCounter(Ifx_CPU *cpu, uint32 programCounter)
268 {
269  boolean retVal = TRUE;
270 
271  if (cpu == IfxCpu_getAddress(IfxCpu_getCoreId()))
272  {
273  retVal = FALSE;
274  }
275  else
276  {
277  cpu->PC.B.PC = programCounter >> 1;
278  }
279 
280  return retVal;
281 }
282 
283 
284 boolean IfxCpu_startCore(Ifx_CPU *cpu, uint32 programCounter)
285 {
286  boolean retVal = TRUE;
287 
288  /* Set the PC for Core 1 */
289  retVal &= IfxCpu_setProgramCounter(cpu, programCounter);
290  /* Get the mode for Core 1 and set it to RUNNING */
291 
292  /* Core not running already */
294  {
295  retVal &= IfxCpu_setCoreMode(cpu, IfxCpu_CoreMode_run);
296  }
297 
298  return retVal;
299 }
300 
301 
302 boolean IfxCpu_setSpinLock(IfxCpu_spinLock *lock, uint32 timeoutCount)
303 {
304  boolean retVal;
305  volatile uint32 spinLockVal;
306 
307  retVal = FALSE;
308 
309  do
310  {
311  spinLockVal = 1UL;
312  spinLockVal =
313  (uint32)__cmpAndSwap(((unsigned int *)lock), spinLockVal, 0);
314 
315  /* Check if the SpinLock WAS set before the attempt to acquire spinlock */
316  if (spinLockVal == 0)
317  {
318  retVal = TRUE;
319  }
320  else
321  {
322  timeoutCount--;
323  }
324  } while ((retVal == FALSE) && (timeoutCount > 0));
325 
326  return retVal;
327 }
328 
329 
331 {
332  /*Reset the SpinLock*/
333  *lock = 0;
334 }
335 
336 
338 {
339  boolean retVal;
340  volatile uint32 spinLockVal;
341 
342  retVal = FALSE;
343 
344  spinLockVal = 1UL;
345  spinLockVal =
346  (uint32)__cmpAndSwap(((unsigned int *)lock), spinLockVal, 0);
347 
348  /* Check if the SpinLock WAS set before the attempt to acquire spinlock */
349  if (spinLockVal == 0)
350  {
351  retVal = TRUE;
352  }
353 
354  return retVal;
355 }
356 
357 
359 {
360  /*Reset the SpinLock*/
361  *lock = 0;
362 }