sync_on_halt.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /**************************************************************************
  2. ** *
  3. ** FILE : sync_on_halt.c *
  4. ** *
  5. ** DESCRIPTION : *
  6. ** Derivative-specific code that is run, every time the target *
  7. ** halts, to synchronize the target and the debugger. *
  8. ** *
  9. ** This code is linked in by default. At the risk of debugging *
  10. ** problems resulting from e.g. cache incoherence, it can be *
  11. ** left out by right-clicking on the file in the C/C++ Projects *
  12. ** view and selecting "Exclude from build...". *
  13. ** *
  14. ** If a user-defined TriCore processor is being used, this file *
  15. ** may have to be adapted. *
  16. ** *
  17. ** Copyright 1996-2015 Altium BV *
  18. ** *
  19. **************************************************************************/
  20. #include <stddef.h>
  21. /* Code compaction, for example, must be avoided because this creates
  22. * function calls and the CSA chain may not be initialized yet when
  23. * this is run.
  24. *
  25. * Inlining must be avoided because it could make the label
  26. * _sync_on_halt_end disappear. */
  27. #pragma optimize acefgIklmNopRsuvwy
  28. /* Because this code is not part of the application program as such,
  29. * it makes no sense to profile it or runtime error check */
  30. #pragma profiling off
  31. #pragma runtime BCM
  32. #pragma nomisrac
  33. /* This explicit inclusion is used because the file may be compiled
  34. * without SFR inclusion */
  35. #include __SFRFILE__(__CPU__)
  36. /* As above, but for the assembler. */
  37. #define _SYNC_ON_HALT_STRINGIFY1(x) _SYNC_ON_HALT_STRINGIFY2(x)
  38. #define _SYNC_ON_HALT_STRINGIFY2(y) #y
  39. __asm(".include <sfr/reg" _SYNC_ON_HALT_STRINGIFY1(__CPU__) ".def>");
  40. #if defined(_REGTC27X_H) || defined(_REGTC27XB_H) \
  41. || defined(_REGTC27XC_H) || defined(_REGTC27XD_H) \
  42. || defined(_REGTC26X_H) || defined(_REGTC26XB_H) \
  43. || defined(_REGTC29X_H) || defined(_REGTC29XB_H) \
  44. || defined(_REGTC21X_H) || defined(_REGTC22X_H) \
  45. || defined(_REGTC23X_H) || defined(_REGTC23X_ADAS_H) \
  46. || defined(_REGUSERDEF162_H)
  47. #if !defined(__CORE_TC0__) && !defined(__CORE_TC1__) && !defined(__CORE_TC2__)
  48. #define __CLONE __clone
  49. #else
  50. #define __CLONE
  51. #endif
  52. #define __DSPR_SYNC_ON_HALT_LCX __at(0xd0003f80)
  53. #define __DSPR_SYNC_ON_HALT_UCX __at(0xd0003fc0)
  54. #else
  55. #define __CLONE
  56. #define __DSPR_SYNC_ON_HALT_LCX
  57. #define __DSPR_SYNC_ON_HALT_UCX
  58. #endif
  59. unsigned int __near __CLONE __align(64) _sync_on_halt_lcx[16] __DSPR_SYNC_ON_HALT_LCX;
  60. unsigned int __near __CLONE __align(64) _sync_on_halt_ucx[16] __DSPR_SYNC_ON_HALT_UCX;
  61. /* This function should never be called by the target application itself. */
  62. extern void _sync_on_halt_end(void)
  63. {
  64. __nop();
  65. __debug();
  66. }
  67. /* This function should never be called by the target application itself.
  68. * __protect__ is needed to prevent this from being eliminated through
  69. * unreferenced section removal. */
  70. extern void __protect__ _sync_on_halt(void)
  71. {
  72. #if defined(_REGTC1762_H) || defined(_REGTC1764_H) || defined(_REGTC1766_H) || defined(_REGTC1766B_H) \
  73. || defined(_REGTC1792_H) || defined(_REGTC1796_H) || defined(_REGTC1796B_H) \
  74. || defined(_REGTC1164_H) || defined(_REGTC1166_H) \
  75. /* Device has no data cache. */
  76. #elif defined(_REGTC1130_H)
  77. # define _EBU 8
  78. # define _DCACHE_0_ADDRESS 0xc0000000U
  79. # define _DCACHE_0_SIZE 64 /* In kBytes. */
  80. #elif defined(_REGTC1167_H) || defined(_REGTC1197_H) \
  81. || defined(_REGTC1724_H) || defined(_REGTC1728_H) \
  82. || defined(_REGTC1184_H) || defined(_REGTC1784_H) \
  83. || defined(_REGTC1767_H) || defined(_REGTC1768_H) || defined(_REGTC1797_H) \
  84. || defined(_REGTC1782_H) || defined(_REGTC1783_H) || defined(_REGTC1746_H) \
  85. || defined(_REGTC1337_H) || defined(_REGTC1367_H) || defined(_REGTC1387_H)
  86. # if !defined(__CORE_TC131__)
  87. # error Internal inconsistency.
  88. # endif
  89. # define _DCACHE_LINES 256
  90. # define _DCACHE_WAYS 2
  91. # define _DCACHE_LINE_INDEX 4
  92. # define _DCACHE_OFFSET 0x80000000U
  93. #elif defined(_REGTC1736_H) || defined(_REGTC21X_H) || defined(_REGTC22X_H) || defined(_REGTC23X_H) || defined(_REGTC23X_ADAS_H)
  94. /* Device has no data cache, but does have a Data Line or Read Buffer (DLB or DRB). We need
  95. * to execute CACHEI.WI at least once. */
  96. # if !defined(__CORE_TC131__) && !defined(__CORE_TC16X__) && !defined(__CORE_TC162__)
  97. # error Internal inconsistency.
  98. # endif
  99. # define _DCACHE_LINES 1
  100. # define _DCACHE_WAYS 1
  101. # ifdef _REGTC1736_H
  102. # define _DCACHE_LINE_INDEX 4
  103. # else
  104. # define _DCACHE_LINE_INDEX 5
  105. # endif
  106. # define _DCACHE_OFFSET 0x80000000U
  107. #elif defined(_REGTC1798_H) || defined(_REGTC1748_H) || defined(_REGTC1791_H) || defined(_REGTC1793_H)
  108. # ifndef __CORE_TC16__
  109. # error Internal inconsistency.
  110. # endif
  111. # define _DCACHE_LINES 128
  112. # define _DCACHE_WAYS 4
  113. # define _DCACHE_LINE_INDEX 5
  114. # define _DCACHE_OFFSET 0x80000000U
  115. #elif defined(_REGTC27X_H) || defined(_REGTC27XB_H) || defined(_REGTC27XC_H) || defined(_REGTC27XD_H)
  116. # if !defined(__CORE_TC16X__) && !defined(__CORE_TC162__)
  117. # error Internal inconsistency.
  118. # endif
  119. /* Cache way number occupies bits 0 and 1, index number occupies bits 5...10. */
  120. # define _DCACHE_LINES 64
  121. # define _DCACHE_WAYS 4
  122. # define _DCACHE_LINE_INDEX 5
  123. # define _DCACHE_OFFSET 0x80000000U
  124. #elif defined(_REGTC26X_H) || defined(_REGTC26XB_H) || defined(_REGTC29X_H) \
  125. || defined(_REGTC29XB_H) || defined(_REGUSERDEF162_H)
  126. # if !defined(__CORE_TC16X__) && !defined(__CORE_TC162__)
  127. # error Internal inconsistency.
  128. # endif
  129. /* Cache way number occupies bit 0, index number occupies bits 5...11. */
  130. # define _DCACHE_LINES 128
  131. # define _DCACHE_WAYS 2
  132. # define _DCACHE_LINE_INDEX 5
  133. # define _DCACHE_OFFSET 0x80000000U
  134. #else
  135. # error Unknown device. For user-defined devices, this code may have to be adapted.
  136. #endif
  137. #ifdef _DCACHE_LINES
  138. unsigned char * line_addr;
  139. unsigned int line_index;
  140. unsigned int way_index;
  141. #endif
  142. #ifdef _EBU
  143. EBU_ADDRSEL0_type * ebu_addrselx;
  144. ptrdiff_t ebu_addrsel_delta;
  145. int region_index;
  146. unsigned int region_addr_u;
  147. #endif
  148. #if defined(_EBU) || defined(_DCACHE_0_ADDRESS)
  149. unsigned char * line_addr;
  150. unsigned int line_count;
  151. unsigned int line_index;
  152. #endif
  153. /* Determine number of EBU regions. (Note that at the time of this writing at
  154. * least it was not actually possible for there to be 5 or 6, only 4 or 7.) */
  155. #ifndef _EBU
  156. /* (Nothing.) */
  157. #elif defined(EBU_ADDRSEL7) || !defined(EBU_ADDRSEL3)
  158. # error Unexpected number of EBU_ADDRSELx registers.
  159. #elif defined(EBU_ADDRSEL6)
  160. # define _EBU_REGION_COUNT 7
  161. #elif defined(EBU_ADDRSEL5)
  162. # define _EBU_REGION_COUNT 6
  163. #elif defined(EBU_ADDRSEL4)
  164. # define _EBU_REGION_COUNT 5
  165. #else
  166. # define _EBU_REGION_COUNT 4
  167. #endif
  168. /* ***************************************************************************************
  169. * Save PSW and (most of) the address and data registers. (Not all of these will actually
  170. * be used, but that is up to the compiler and cannot be predicted reliably.)
  171. *
  172. * Note that PSW must be saved because of the switch to supervisor mode below, but also
  173. * because the remainder of the code may change the flags.
  174. *
  175. * The st*cx instructions do not affect the CSA list and do not require it to be properly
  176. * initialized (which it might not be at this point). */
  177. __asm("stlcx _sync_on_halt_lcx");
  178. __asm("stucx _sync_on_halt_ucx");
  179. /* Set PSW.IO to 2 (supervisor mode). This is needed for certain operations
  180. * performed below. */
  181. __mtcr(PSW, (int) (((unsigned int) __mfcr(PSW) & 0xfffff3ffU) | 0x800U));
  182. /* ***************************************************************
  183. * Initiate flushing of instruction cache. (Waiting for it to
  184. * complete is done later, i.e. in parallel with the data
  185. * cache flushing.)
  186. */
  187. #if defined(_REGTC1130_H) \
  188. || defined(_REGTC1762_H) || defined(_REGTC1764_H) \
  189. || defined(_REGTC1766_H) || defined(_REGTC1766B_H) \
  190. || defined(_REGTC1164_H) || defined(_REGTC1166_H) \
  191. || defined(_REGTC1792_H) || defined(_REGTC1796_H) || defined(_REGTC1796B_H) \
  192. || defined(_REGUSERDEF162_H)
  193. /* Instruction cache flushing not supported for these devices. */
  194. #elif defined(_REGTC1167_H) || defined(_REGTC1197_H) \
  195. || defined(_REGTC1724_H) || defined(_REGTC1728_H) || defined(_REGTC1736_H) \
  196. || defined(_REGTC1184_H) || defined(_REGTC1784_H) \
  197. || defined(_REGTC1767_H) || defined(_REGTC1768_H) || defined(_REGTC1797_H) \
  198. || defined(_REGTC1782_H) || defined(_REGTC1783_H) || defined(_REGTC1746_H) \
  199. || defined(_REGTC1337_H) || defined(_REGTC1367_H) || defined(_REGTC1387_H)
  200. # define _ICACHE_BIT0 PMI_CON1.B.PCINV
  201. # define _ICACHE_BIT1 PMI_CON1.B.PBINV
  202. #elif defined(_REGTC1798_H) || defined(_REGTC1748_H) || defined(_REGTC1791_H) || defined(_REGTC1793_H) \
  203. || defined(_REGTC21X_H) || defined(_REGTC22X_H) || defined(_REGTC23X_H) || defined(_REGTC23X_ADAS_H) \
  204. || defined(_REGTC27X_H) || defined(_REGTC27XB_H) || defined(_REGTC27XC_H) || defined(_REGTC27XD_H) \
  205. || defined(_REGTC26X_H) || defined(_REGTC26XB_H) || defined(_REGTC29X_H) || defined(_REGTC29XB_H)
  206. # define _ICACHE_BIT0_W(bit_val) \
  207. __mtcr(PCON1, (int) (((unsigned int) __mfcr(PCON1) & 0xfffffffeU) | (bit_val ? 1 : 0)))
  208. # define _ICACHE_BIT1_W(bit_val) \
  209. __mtcr(PCON1, (int) (((unsigned int) __mfcr(PCON1) & 0xfffffffdU) | (bit_val ? 2 : 0)))
  210. # define _ICACHE_BIT0_R \
  211. (((unsigned int) __mfcr(PCON1) & 0x1U)!=0U)
  212. # define _ICACHE_BIT1_R \
  213. (((unsigned int) __mfcr(PCON1) & 0x2U)!=0U)
  214. #else
  215. # error Unknown device.
  216. #endif
  217. #ifdef _ICACHE_BIT0
  218. _ICACHE_BIT0 = 1;
  219. _ICACHE_BIT1 = 1;
  220. #endif
  221. #ifdef _ICACHE_BIT0_W
  222. _ICACHE_BIT0_W(1);
  223. _ICACHE_BIT1_W(1);
  224. #endif
  225. /* **********************************************************
  226. * Flush data cache. This will also flush the data line
  227. * buffer, if there is one. */
  228. #ifdef _EBU
  229. ebu_addrselx = &EBU_ADDRSEL0;
  230. ebu_addrsel_delta = ((EBU_ADDRSEL0_type *) &EBU_ADDRSEL1) - &EBU_ADDRSEL0;
  231. for ( region_index = 0; region_index < _EBU_REGION_COUNT;
  232. region_index++, ebu_addrselx += ebu_addrsel_delta )
  233. {
  234. if (!ebu_addrselx->B.REGENAB)
  235. {
  236. continue;
  237. }
  238. if ( (((ebu_addrselx->B.BASE >> 16) & 0xfU) == _EBU)
  239. || (ebu_addrselx->B.ALTENAB && (ebu_addrselx->B.ALTSEG == _EBU))
  240. )
  241. {
  242. /* EBU region is accessible via segment specified by _EBU. */
  243. /* Calculate start address of region. First, bits 28-31. */
  244. region_addr_u = ((unsigned int) _EBU << 28);
  245. /* Add bits 12-27. */
  246. region_addr_u += ((unsigned int) (ebu_addrselx->B.BASE & 0xffff) << 12)
  247. & (0xffffffffU << (27 - ebu_addrselx->B.MASK));
  248. /* Size measured in 16-byte (128-bit) cache lines.
  249. * For example, when MASK equals 15, the size is
  250. * 4 kBytes, i.e. 256 lines. */
  251. line_count = 1 << (23 - ebu_addrselx->B.MASK);
  252. line_addr = (unsigned char *) region_addr_u;
  253. for (line_index = 0; line_index < line_count; line_index++)
  254. {
  255. __cacheawi(line_addr);
  256. line_addr += 16;
  257. }
  258. }
  259. }
  260. #endif /* #ifdef _EBU */
  261. #ifdef _DCACHE_0_ADDRESS
  262. line_count = (_DCACHE_0_SIZE * 1024) / 16;
  263. line_addr = (unsigned char *) _DCACHE_0_ADDRESS;
  264. for (line_index = 0; line_index < line_count; line_index++)
  265. {
  266. __cacheawi(line_addr);
  267. line_addr += 16;
  268. }
  269. #endif
  270. #ifdef _DCACHE_1_ADDRESS
  271. line_count = (_DCACHE_1_SIZE * 1024) / 16;
  272. line_addr = (unsigned char *) _DCACHE_1_ADDRESS;
  273. for (line_index = 0; line_index < line_count; line_index++)
  274. {
  275. __cacheawi(line_addr);
  276. line_addr += 16;
  277. }
  278. #endif
  279. #ifdef _DCACHE_LINES
  280. /* In the case of a TC1.6E core, there is only a Data Read Buffer (DRB),
  281. * not a real cache, and as a result a single __cacheiwi(...) would
  282. * actually suffice. However, the loop also works. */
  283. line_addr = (unsigned char *) _DCACHE_OFFSET;
  284. for (line_index = 0; line_index < _DCACHE_LINES; line_index++)
  285. {
  286. for (way_index = 0; way_index < _DCACHE_WAYS; way_index++)
  287. {
  288. __cacheiwi( line_addr+way_index );
  289. }
  290. line_addr += (1 << _DCACHE_LINE_INDEX);
  291. }
  292. #endif
  293. /* **********************************************************
  294. * Wait for code cache flushing to complete.
  295. */
  296. #ifdef _ICACHE_BIT0
  297. while (_ICACHE_BIT0 || _ICACHE_BIT1);
  298. #endif
  299. #ifdef _ICACHE_BIT0_R
  300. while (_ICACHE_BIT0_R || _ICACHE_BIT1_R);
  301. #endif
  302. /* ***************************************************************************************
  303. * Restore registers. */
  304. /* If we switched to supervisor mode above, this restores the prior mode
  305. * as well. */
  306. __mtcr(PSW, _sync_on_halt_ucx[1]);
  307. __asm("lducx _sync_on_halt_ucx");
  308. __asm("ldlcx _sync_on_halt_lcx");
  309. /* ***************************************************************************************
  310. * Flush pipeline. */
  311. __dsync(); /* Synchronize data. */
  312. __isync(); /* Synchronize instructions. */
  313. __nop(); /* */
  314. __nop(); /* TC113_CPU9. */
  315. /* No function call should be used here, because the CSA may not have
  316. * been initialized yet. */
  317. __asm("j _sync_on_halt_end");
  318. return;
  319. }