iLLD_TC29x  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_1_0_0_11_0
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 /******************************************************************************/
27 /*----------------------------------Includes----------------------------------*/
28 /******************************************************************************/
29 
30 #include "IfxCpu.h"
31 
32 /******************************************************************************/
33 /*-------------------------Function Implementations---------------------------*/
34 /******************************************************************************/
35 
37 {
38  boolean retVal;
39  volatile uint32 spinLockVal;
40 
41  retVal = FALSE;
42 
43  spinLockVal = 1UL;
44  spinLockVal =
45  (uint32)__cmpAndSwap(((unsigned int *)lock), spinLockVal, 0);
46 
47  /* Check if the SpinLock WAS set before the attempt to acquire spinlock */
48  if (spinLockVal == 0)
49  {
50  retVal = TRUE;
51  }
52 
53  return retVal;
54 }
55 
56 
58 {
59  Ifx_CPU *module;
60 
61  if (cpu < IfxCpu_ResourceCpu_none)
62  {
63  module = (Ifx_CPU *)IfxCpu_cfg_indexMap[cpu].module;
64  }
65  else
66  {
67  module = NULL_PTR;
68  }
69 
70  return module;
71 }
72 
73 
75 {
76  IfxCpu_CoreMode cpuMode;
77  Ifx_CPU_DBGSR dbgsr;
79 
80  cpuMode = IfxCpu_CoreMode_unknown;
81 
82  /*get the DBGSR.HALT status */
83  /*Check if the request is done for same cpu as the host for this call */
84  if (IfxCpu_getCoreIndex() != index)
85  { /*status request is for other cpu than the host */
86  dbgsr = cpu->DBGSR;
87  }
88  else
89  { /*status request is for same cpu as the host */
90  dbgsr.U = __mfcr(CPU_DBGSR);
91  }
92 
93  /*Check if the requested CPU is in DBG HALT mode */
94  if (dbgsr.B.HALT == (uint32)IfxCpu_DBGST_HALT_halt)
95  { /*CPU is in DBG HALT mode */
96  cpuMode = IfxCpu_CoreMode_halt;
97  }
98  else
99  {
100  if (dbgsr.B.HALT == (uint32)IfxCpu_DBGST_HALT_run)
101  { /*CPU is in DBG RUNNING mode now check PMCSR status */
102  Ifx_SCU_PMCSR *pmcsr_val;
103 
104  pmcsr_val = (Ifx_SCU_PMCSR *)&MODULE_SCU.PMCSR[index];
105 
106  if (pmcsr_val->B.PMST == (uint32)IfxCpu_PMCSR_PMST_normalMode)
107  { /*Cpu is in normal run mode */
108  cpuMode = IfxCpu_CoreMode_run;
109  }
110  else
111  { /*Cpu is not in run mode */
112  if (pmcsr_val->B.PMST == (uint32)IfxCpu_PMCSR_PMST_idleMode)
113  { /*Cpu is in idle mode */
114  cpuMode = IfxCpu_CoreMode_idle;
115  }
116  }
117  }
118  else
119  {
120  cpuMode = IfxCpu_CoreMode_unknown;
121  }
122  }
123 
124  return cpuMode;
125 }
126 
127 
129 {
130  IfxCpu_ResourceCpu result;
131  uint32 index;
132  result = IfxCpu_ResourceCpu_none;
133 
134  for (index = 0; index < IFXCPU_NUM_MODULES; index++)
135  {
136  if (IfxCpu_cfg_indexMap[index].module == cpu)
137  {
138  result = (IfxCpu_ResourceCpu)IfxCpu_cfg_indexMap[index].index;
139  break;
140  }
141  }
142 
143  return result;
144 }
145 
146 
148 {
149  /*************************************************************************
150  * the choice of a and m is important for a long period of the LCG
151  * with a = 279470273 and
152  * m = 4294967291
153  * a maximum period of 2^32-5 is given
154  * values for a:
155  * 0x5EB0A82F = 1588635695
156  * 0x48E7211F = 1223106847
157  * 0x10a860c1 = 279470273
158  ***************************************************************************/
159  uint32 x = *seed;
160 
161  /* a seed of 0 is not allowed, and therefore will be changed to a valid value */
162  if (x == 0)
163  {
164  x = 42;
165  }
166 
167  uint32 a = 0x10a860c1; // 279470273
168  uint32 m = 0xfffffffb; // 4294967291
169  uint32 result;
170 
171  //__asm(a,m,x,tmp1,tmp2 );
172  //EhEl = a * x;
173  //result = e14 % m;
174  // %0 result
175  // %1 a
176  // %2 x
177  // %3 m
178 /* *INDENT-OFF* */
179 #ifdef __GNUC__
180  __asm(" mul.u %%e14,%1,%2 # d15 = Eh; d14 = El \n"
181  " mov %%d12,%%d14 # e12 = El \n"
182  " mov %%d13, 0 # \n"
183  " madd.u %%e14,%%e12,%%d15, 5 # e14 = El + 5 * d15 \n"
184  " cmp_m: jge.u %%d14,%3,sub_m # \n"
185  " jz %%d15,done # \n"
186  " sub_m: subx %%d14,%%d14,%3 # e12=e12-m \n"
187  " subc %%d15,%%d15,%%d13 # d13=d13-0 \n"
188  " loopu cmp_m # \n"
189  " done: mov %0,%%d14 # \n"
190  : "=d"(result) : "d"(a), "d"(x), "d"(m) : "d12","d13","d14","d15");
191 #elif __TASKING__
192  __asm(" mul.u e14,%1,%2 ; d15 = Eh; d14 = El \n"
193  " mov d12,d14 ; e12 = El \n"
194  " mov d13,#0 ; \n"
195  " madd.u e14,e12,d15,#5 ; e14 = El + 5 * d15 \n"
196  " cmp_m: jge.u d14,%3,sub_m ; \n"
197  " jz d15,done ; \n"
198  " sub_m: subx d14,d14,%3 ; e12=e12-m \n"
199  " subc d15,d15,d13 ; d13=d13-0 \n"
200  " loopu cmp_m ; \n"
201  " done: mov %0,d14 ; \n"
202  : "=d"(result) : "d"(a), "d"(x), "d"(m) : "e14","e12");
203 #else
204  asm(" mul.u %%e14,%1,%2 # d15 = Eh; d14 = El \n"
205  " mov %%d12,%%d14 # e12 = El \n"
206  " mov %%d13, 0 # \n"
207  " madd.u %%e14,%%e12,%%d15, 5 # e14 = El + 5 * d15 \n"
208  " .cmp_m: \n"
209  " jge.u %%d14,%3,.sub_m \n"
210  " jz %%d15,.done # \n"
211  " .sub_m: \n"
212  " subx %%d14,%%d14,%3 # e12=e12-m \n"
213  " subc %%d15,%%d15,%%d13 # d13=d13-0 \n"
214  " loopu .cmp_m # \n"
215  " .done: \n"
216  " mov %0,%%d14 # \n"
217  : "=r"(result) : "r"(a), "r"(x), "r"(m));
218 #endif
219 /* *INDENT-ON* */
220  * seed = result; // to simplify seed passing
221 
222  return result;
223 }
224 
225 
227 {
228  uint32 new_value = IfxCpu_getRandomValue(seed);
229 
230  /* swap min/max if required */
231  if (min > max)
232  {
233  unsigned swap = max;
234  max = min;
235  min = swap;
236  }
237 
238  /* special case */
239  if ((min == 0) && (max == 0xffffffff))
240  {
241  return new_value;
242  }
243 
244  /* return value within range */
245  return (new_value % (max - min + 1)) + min;
246 }
247 
248 
250 {
251  /*Reset the SpinLock*/
252  *lock = 0;
253 }
254 
255 
257 {
258  /*Reset the SpinLock*/
259  *lock = 0;
260 }
261 
262 
263 boolean IfxCpu_setCoreMode(Ifx_CPU *cpu, IfxCpu_CoreMode mode)
264 {
265  // this switch is only temporary required
266  // once the IfxCan driver is generated via lldgen, we will vary the code without #ifdef
267 #ifdef IFX_TC27x
268 /* FIXME Copied from old TC27xA code, check that this is up to date code */
269  IfxCpu_CoreMode cpuMode;
270  boolean RetVal;
271  IfxScu_PMCSR_REQSLP modeSet;
272 
273  RetVal = TRUE;
274 
275  modeSet = IfxScu_PMCSR_REQSLP_Idle;
276 
277  /* Check the mode the CPU is in */
278  cpuMode = IfxCpu_getCoreMode(cpu);
279 
280  /* if requested mode is same as current mode nothing to do */
281  if (cpuMode != mode)
282  {
283  /* transition from halt to Run */
284  if (IfxCpu_CoreMode_halt == cpuMode)
285  {
286  if (IfxCpu_CoreMode_run == mode)
287  {
288  Ifx_CPU_DBGSR dbgsr;
289 
290  if (IfxCpu_getCoreIndex() != IfxCpu_getIndex(cpu))
291  {
292  cpu->DBGSR.B.HALT = 0x2;
293  }
294  else
295  {
296  dbgsr.U = __mfcr(CPU_DBGSR);
297  dbgsr.B.HALT = 0x2;
298  __mtcr(CPU_DBGSR, dbgsr.U);
299  }
300  }
301  else /* cannot go to any other mode e.g. IfxCpu_CoreMode_idle */
302  {
303  RetVal = FALSE;
304  }
305  }
306  /* From Run to Idle or vice versa */
307  else
308  {
309  if (IfxCpu_CoreMode_run == cpuMode)
310  {
311  if (IfxCpu_CoreMode_idle == mode)
312  {
313  modeSet = IfxScu_PMCSR_REQSLP_Idle;
314  }
315  else
316  {
317  RetVal = FALSE;
318  }
319  }
320  /* idle to Run */
321  else if (IfxCpu_CoreMode_idle == cpuMode)
322  {
323  if (IfxCpu_CoreMode_run == mode)
324  {
325  modeSet = IfxScu_PMCSR_REQSLP_Run;
326  }
327  else
328  {
329  RetVal = FALSE;
330  }
331  }
332  else
333  {
334  RetVal = FALSE;
335  }
336 
337  if (TRUE == RetVal)
338  {
339  /* To take care of the Work Around in A step
340  * In A Step the PMCSR is Cpu Endinit protected
341  * in B step it is by safety endinit*/
342  uint16 password;
343  uint32 wdtCon0_Val;
344  Ifx_SCU_WDTCPU *watchdog;
345  watchdog = &MODULE_SCU.WDTCPU[IfxCpu_getCoreIndex()]; /* FIXME access to the watchdog of an other CPU, this might not work! */
347  IfxScuWdt_clearCpuEndinit(password);
348  /* password access */
349  watchdog->CON0.U = (password << 2U) | 0x1U;
350  /* modify access, E=0 */
351  watchdog->CON0.U = (password << 2U) | 0x2U;
352  /* password access in advance */
353  watchdog->CON0.U = (password << 2U) | 0x1U;
354  /* prepare write value */
355  wdtCon0_Val = ((0x0000U) << 16U) | (password << 2U) | (0x3U);
356  MODULE_SCU.PMCSR[(uint32)IfxCpu_getIndex(cpu)].B.REQSLP = modeSet;
357  /* modify access, E=1, reload WDT */
358  watchdog->CON0.U = wdtCon0_Val;
359  IfxScuWdt_setCpuEndinit(password);
360  }
361  }
362  }
363 
364  return RetVal;
365 #else
366  uint8 reqslp;
367  boolean retValue;
368  IfxCpu_ResourceCpu index = IfxCpu_getIndex(cpu);
369 
370  /*Modes such as HALT, SLEEP and STBY are not handled at CPU level */
371  retValue = ((mode == IfxCpu_CoreMode_halt) || (mode == IfxCpu_CoreMode_sleep)
372  || (mode == IfxCpu_CoreMode_stby)) ? FALSE : TRUE;
373 
375 
376  if (retValue == TRUE)
377  {
378  /*Check if the same core is requesting to change the core run mode */
379  if (IfxCpu_getCoreIndex() != index)
380  { /*Request is for the other core */
381  /*To access PMCSR of other CPUs handle the safety EndInit protection */
383  IfxScuWdt_clearSafetyEndinit(safetyWdtPw);
384  MODULE_SCU.PMCSR[(uint32)IfxCpu_getIndex(cpu)].B.REQSLP = reqslp;
385  IfxScuWdt_setSafetyEndinit(safetyWdtPw);
386 
387  cpu->DBGSR.B.HALT = 2; /*reset the HALT bit, if it is already done it is no harm in writing again */
388  }
389  else
390  { /*Request is for self, this request normally only for halt, otherwise the core is already running anyway! */
391  /*To access PMCSR of self handle the cpu EndInit protection */
393  IfxScuWdt_clearCpuEndinit(cpuWdtPw);
394  MODULE_SCU.PMCSR[(uint32)index].B.REQSLP = reqslp;
395  IfxScuWdt_setCpuEndinit(cpuWdtPw);
396  }
397  }
398 
399  return retValue;
400 #endif
401 }
402 
403 
404 boolean IfxCpu_setProgramCounter(Ifx_CPU *cpu, uint32 programCounter)
405 {
406  boolean retVal = TRUE;
407 
409  {
410  retVal = FALSE;
411  }
412  else
413  {
414  cpu->PC.B.PC = programCounter >> 1;
415  }
416 
417  return retVal;
418 }
419 
420 
421 boolean IfxCpu_setSpinLock(IfxCpu_spinLock *lock, uint32 timeoutCount)
422 {
423  boolean retVal;
424  volatile uint32 spinLockVal;
425 
426  retVal = FALSE;
427 
428  do
429  {
430  spinLockVal = 1UL;
431  spinLockVal =
432  (uint32)__cmpAndSwap(((unsigned int *)lock), spinLockVal, 0);
433 
434  /* Check if the SpinLock WAS set before the attempt to acquire spinlock */
435  if (spinLockVal == 0)
436  {
437  retVal = TRUE;
438  }
439  else
440  {
441  timeoutCount--;
442  }
443  } while ((retVal == FALSE) && (timeoutCount > 0));
444 
445  return retVal;
446 }
447 
448 
449 boolean IfxCpu_startCore(Ifx_CPU *cpu, uint32 programCounter)
450 {
451  boolean retVal = TRUE;
452 
453  /* Set the PC for Core 1 */
454  retVal &= IfxCpu_setProgramCounter(cpu, programCounter);
455  /* Get the mode for Core 1 and set it to RUNNING */
456 
457  /* Core not running already */
459  {
460  retVal &= IfxCpu_setCoreMode(cpu, IfxCpu_CoreMode_run);
461  }
462 
463  return retVal;
464 }