ST_STM32U5_DisableTZEN.JLinkScript 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. /***********************************************************************
  2. * SEGGER Microcontroller GmbH *
  3. * The Embedded Experts *
  4. ************************************************************************
  5. * *
  6. * (c) SEGGER Microcontroller GmbH *
  7. * All rights reserved *
  8. * www.segger.com *
  9. * *
  10. ************************************************************************
  11. * *
  12. ************************************************************************
  13. * *
  14. * *
  15. * Licensing terms *
  16. * *
  17. * The use in source and binary forms, with or without modification, *
  18. * is permitted for internal use only. The redistribution to any *
  19. * third party is prohibited. *
  20. * *
  21. * *
  22. * THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER "AS IS" AND ANY *
  23. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR *
  25. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE *
  26. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, *
  27. * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
  28. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
  29. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY *
  30. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
  31. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
  32. * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
  33. * DAMAGE. *
  34. * *
  35. ************************************************************************
  36. -------------------------- END-OF-HEADER -----------------------------
  37. Purpose: Implementation of device specific handling for
  38. ST STM32U5xxxx devices
  39. Literature:
  40. [1] J-Link User Guide
  41. [2] ST RM0456 (STM32U5 Reference manual)
  42. Additional information:
  43. [3] ...
  44. */
  45. /*********************************************************************
  46. *
  47. * Constants, fixed
  48. *
  49. **********************************************************************
  50. */
  51. //
  52. // Registers
  53. //
  54. __constant U32 _DHCSR_ADDR = 0xE000EDF0;
  55. __constant U32 _DEMCR_ADDR = 0xE000EDFC; // Debug Exception and Monitor Control Register
  56. __constant U32 _AIRCR_ADDR = 0xE000ED0C; // Application Interrupt and Reset Control Register
  57. __constant U32 _CPUID_ADDR = 0xE000ED00;
  58. //
  59. // Bits
  60. //
  61. __constant U32 _DP_CTRL_STAT_BIT_DBGPWRUPREQ = (1 << 30);
  62. __constant U32 _DP_CTRL_STAT_BIT_SYSPWRUPREQ = (1 << 28);
  63. __constant U32 _DP_CTRL_STAT_BIT_STICKYERR = (1 << 5);
  64. //
  65. // Shifts
  66. //
  67. __constant U32 _BIT_S_HALTED = (1 << 17);
  68. /*********************************************************************
  69. *
  70. * Constants, configurable (might differ between STM32 devices)
  71. *
  72. **********************************************************************
  73. */
  74. //
  75. // Registers
  76. //
  77. __constant U32 _FLASH_BASE = 0x50022000;
  78. __constant U32 _FLASH_BASE_NS = 0x40022000;
  79. __constant U32 _FLASH_NSKEYR = _FLASH_BASE_NS + 0x08;
  80. __constant U32 _FLASH_OPTKEYR = _FLASH_BASE_NS + 0x10;
  81. __constant U32 _FLASH_NSSR = _FLASH_BASE_NS + 0x20;
  82. __constant U32 _FLASH_NSCR = _FLASH_BASE_NS + 0x28;
  83. __constant U32 _FLASH_OPTR = _FLASH_BASE_NS + 0x40;
  84. //
  85. // Shifts & Bits & Masks ...
  86. //
  87. // FLASH_SR
  88. //
  89. __constant U32 _BIT_BSY = 16;
  90. __constant U32 _CLEAR_ERR_SR = 0x000020F8;
  91. //
  92. // FLASH_CR
  93. //
  94. __constant U32 _BIT_OPTSTRT = (1 << 17);
  95. __constant U32 _BIT_OBLLAUNCH = (1 << 27); // Launch option byte loading
  96. __constant U32 _BIT_OPTLOCK = (1 << 30);
  97. __constant U32 _BIT_LOCK = (1 << 31);
  98. //
  99. // FLASH_OPTR
  100. //
  101. __constant U32 _RDP_LVL_0 = (0xAA << 0);
  102. __constant U32 _RDP_LVL_05 = (0x55 << 0);
  103. __constant U32 _RDP_LVL_1 = (0xBB << 0);
  104. __constant U32 _BIT_NSWBOOT0 = (1 << 26);
  105. __constant U32 _BIT_NBOOT0 = (1 << 27);
  106. __constant U32 _BIT_TZEN = (1 << 31);
  107. __constant U32 _MASK_RDP = 0x000000FF;
  108. __constant U32 _MASK_BOOT = 0x0C000000;
  109. __constant U32 _OPTR_FACT_VAL = 0x1FEFF8AA;
  110. //
  111. // Keys
  112. //
  113. __constant U32 _FLASH_KEY1 = 0x45670123;
  114. __constant U32 _FLASH_KEY2 = 0xCDEF89AB;
  115. __constant U32 _OPT_KEY1 = 0x08192A3B;
  116. __constant U32 _OPT_KEY2 = 0x4C5D6E7F;
  117. //
  118. // Misc
  119. //
  120. __constant U32 _DEF_BUSY_TIMEOUT = 500;
  121. /*********************************************************************
  122. *
  123. * Static code
  124. *
  125. **********************************************************************
  126. */
  127. /*********************************************************************
  128. *
  129. * _ConfigureAP()
  130. *
  131. * Function description
  132. * Configures selected AP for debugging.
  133. */
  134. static int _ConfigureAP(U32 Index) {
  135. U32 v;
  136. int r;
  137. //
  138. // Select AP and bank to use
  139. //
  140. v = 0
  141. | (0 << 4) // Select bank 0 (this is default for most casese).
  142. | (Index << 24) // Select AP[Index] (AHB-AP)
  143. ;
  144. JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_SELECT, v);
  145. //
  146. // Initialize DAP for debug use.
  147. //
  148. v = (2 << 0) // Access size: word
  149. | (0 << 4) // NO Auto-increment
  150. | (1 << 25) // Priviledged access
  151. | (0 << 30) // Secure transfer
  152. ;
  153. r = JLINK_CORESIGHT_WriteAP(JLINK_CORESIGHT_AP_REG_CTRL, v);
  154. if (r < 0) {
  155. JLINK_SYS_Report(" Error: Failed to configure AP.");
  156. return -1;
  157. }
  158. return 0;
  159. }
  160. /*********************************************************************
  161. *
  162. * _InitDAP()
  163. *
  164. * Function description
  165. * Initializes DAP, so JLINK_CORESIGHT_ functions can be used.
  166. */
  167. static int _InitDAP(void) {
  168. U32 v;
  169. int r;
  170. int t;
  171. //
  172. // Clear sticky error flags and power up DAP
  173. //
  174. v = _DP_CTRL_STAT_BIT_DBGPWRUPREQ | _DP_CTRL_STAT_BIT_SYSPWRUPREQ;
  175. if (JLINK_ActiveTIF == JLINK_TIF_JTAG) {
  176. v |= _DP_CTRL_STAT_BIT_STICKYERR;
  177. } else {
  178. JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_ABORT, 0x1E);
  179. }
  180. JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_CTRL_STAT, v);
  181. //
  182. // Wait for power up DAP complete
  183. //
  184. r = -1;
  185. t = JLINK_GetTime() + _DEF_BUSY_TIMEOUT;
  186. do {
  187. r = JLINK_CORESIGHT_ReadDP(JLINK_CORESIGHT_DP_REG_CTRL_STAT);
  188. if (r == -1) { // Any error occurred while reading from the DP, we are done
  189. break;
  190. }
  191. v = r;
  192. if (v & (0xF << 28)) { // CSYSPWRUPACK and CDBGPWRUPACK set, so both ports have been completely powered?
  193. r = 0;
  194. break;
  195. }
  196. if ((t - JLINK_GetTime()) <= 0) {
  197. break;
  198. }
  199. } while(1);
  200. if (r < 0) {
  201. JLINK_SYS_Report(" Error: Failed to initialized DAP.");
  202. return -1;
  203. }
  204. r = _ConfigureAP(0); // Finally configure the AP so we can use it.
  205. if (r < 0) {
  206. return -1;
  207. }
  208. return 0;
  209. }
  210. /*********************************************************************
  211. *
  212. * _WaitWhileBusy
  213. *
  214. * Function descripton
  215. * Wait until read value is not busy.
  216. *
  217. * Return value
  218. * 0 O.K.
  219. * < 0 Error
  220. * -1 Timeout reached
  221. * -2 Error reading/writing DAP
  222. */
  223. static int _WaitWhileBusy(U32 Addr, U32 Mask, U32 RefValue, U32 Timeout) {
  224. int r;
  225. int t;
  226. U32 Status;
  227. RefValue &= Mask;
  228. r = -1;
  229. //
  230. // Wait for operation to complete
  231. //
  232. t = JLINK_GetTime() + Timeout;
  233. do {
  234. r = JLINK_MEM_ReadU32(Addr);
  235. //
  236. // Check for error while reading/writing AP.
  237. // We do this because this function might be called after a reset,
  238. // e.g. from _WaitCPUHalted()
  239. //
  240. if (r == -1) { // Connection lost ? => Error.
  241. r = -2;
  242. break;
  243. }
  244. Status = r;
  245. if ((Status & Mask) == RefValue) { // Operation complete? => Done.
  246. r = 0;
  247. break;
  248. }
  249. if ((t - JLINK_GetTime()) < 0) { // Timeout reached? => Error.
  250. r = -1;
  251. break;
  252. }
  253. } while (1);
  254. return r;
  255. }
  256. /*********************************************************************
  257. *
  258. * _WaitWhileFlashBusy
  259. *
  260. * Function descripton
  261. * Wrapper for _WaitWhileBuys, to make Flash wait calls simpler.
  262. */
  263. static int _WaitWhileFlashBusy(U32 Timeout) {
  264. return _WaitWhileBusy(_FLASH_NSSR, _BIT_BSY, ~_BIT_BSY, Timeout);
  265. }
  266. /*********************************************************************
  267. *
  268. * _WaitCPUHalted
  269. *
  270. * Function description
  271. * Wait for DHCSR to signal that the CPU is halted.
  272. *
  273. * Return value
  274. * 0 O.K.
  275. * < 0 Error
  276. */
  277. static int _WaitCPUHalted(void) {
  278. int r;
  279. r = _WaitWhileBusy(_DHCSR_ADDR, _BIT_S_HALTED, _BIT_S_HALTED, _DEF_BUSY_TIMEOUT);
  280. if (r == -1) {
  281. JLINK_SYS_Report(" Timeout while waiting for CPU to halt.");
  282. } else if (r == -2) {
  283. JLINK_SYS_Report(" Error while checking CPU state.");
  284. }
  285. return r;
  286. }
  287. /*********************************************************************
  288. *
  289. * _Reset
  290. *
  291. * Function description
  292. * Reset and wait until CPU is halted.
  293. *
  294. * Return value
  295. * 0 O.K.
  296. * < 0 Error
  297. */
  298. static int _Reset(void) {
  299. int r;
  300. U32 v;
  301. U32 demcr;
  302. r = JLINK_MEM_ReadU32(_DHCSR_ADDR);
  303. if (r < 0) {
  304. return -1;
  305. }
  306. v = r;
  307. v &= 0x3F; // Mask out "debug" bits
  308. v |= (0xA05F << 16); // Debug key to make a write to the DHCSR a valid one
  309. v |= (1 << 1); // Halt the core
  310. v |= (1 << 0); // Enable debug functionalities of the core
  311. JLINK_MEM_WriteU32(_DHCSR_ADDR, v);
  312. demcr = JLINK_MEM_ReadU32(_DEMCR_ADDR);
  313. JLINK_MEM_WriteU32(_DEMCR_ADDR, demcr | (1 << 0)); // Set VC_CORERESET
  314. JLINK_MEM_WriteU32(_AIRCR_ADDR, 0x05FA0004); // SYSRESETREQ
  315. r = _WaitCPUHalted();
  316. if (r < 0) {
  317. return -1;
  318. }
  319. _InitDAP();
  320. return 0;
  321. }
  322. /*********************************************************************
  323. *
  324. * _UnlockOptionbytes
  325. *
  326. * Function description
  327. * Unlock the Flash registers and Optionbytes if not yet unlocked.
  328. *
  329. * Return value
  330. * 0 O.K.
  331. * < 0 Error
  332. */
  333. static void _UnlockOptionbytes(void) {
  334. U32 v;
  335. v = JLINK_MEM_ReadU32(_FLASH_NSCR);
  336. if (v & _BIT_LOCK) {
  337. JLINK_MEM_WriteU32(_FLASH_NSKEYR, _FLASH_KEY1);
  338. JLINK_MEM_WriteU32(_FLASH_NSKEYR, _FLASH_KEY2);
  339. }
  340. if (v & _BIT_OPTLOCK) {
  341. JLINK_MEM_WriteU32(_FLASH_OPTKEYR, _OPT_KEY1);
  342. JLINK_MEM_WriteU32(_FLASH_OPTKEYR, _OPT_KEY2);
  343. }
  344. }
  345. /*********************************************************************
  346. *
  347. * _ProgOptionbytes
  348. *
  349. * Function description
  350. * Triggers option byte programming and launching of the option bytes.
  351. *
  352. * Return value
  353. * 0 O.K.
  354. * < 0 Error
  355. */
  356. static int _ProgOptionbytes(void) {
  357. int r;
  358. U32 v;
  359. JLINK_MEM_WriteU32(_FLASH_NSSR, _CLEAR_ERR_SR); // Reset FLASH_SR error bits
  360. JLINK_MEM_WriteU32(_FLASH_NSCR, _BIT_OPTSTRT);
  361. r = _WaitWhileFlashBusy(30000); // Changing RDP might trigger a mass erase, so we have to give this some time.
  362. if (r < 0) {
  363. return r;
  364. }
  365. //
  366. // Set OBL_LAUNCH bit
  367. // After the OBL_LAUNCH has been set, the device is not responsive until reset,
  368. // so we wait some time and reconnect to the device
  369. //
  370. JLINK_MEM_WriteU32(_FLASH_NSCR, _BIT_OBLLAUNCH);
  371. JLINK_SYS_Sleep(200); // Give OBL_LAUNCH some time
  372. r = _InitDAP(); // CPU has to be reconnected after reset!
  373. return r;
  374. }
  375. /*********************************************************************
  376. *
  377. * _DisableTZENIfActive
  378. *
  379. * Function description
  380. * Disable TrustZone on the device if active.
  381. *
  382. * Return value
  383. * 0 O.K.
  384. * < 0 Error
  385. */
  386. static int _DisableTZENIfActive(void) {
  387. int r;
  388. U32 v;
  389. U32 vOPTR;
  390. vOPTR = JLINK_MEM_ReadU32(_FLASH_OPTR);
  391. if ((vOPTR & _BIT_TZEN) == 0) { // TZEN not set? => Nothing to do.
  392. JLINK_SYS_Report(" TrustZone not enabled (TZEN == 0).");
  393. return 0;
  394. }
  395. JLINK_SYS_Report(" TrustZone enabled (TZEN == 1).");
  396. JLINK_SYS_Report(" Resetting OPTR to factory value...");
  397. //
  398. // Reset device to be in a defined state.
  399. //
  400. r = _Reset();
  401. if (r < 0) {
  402. return -1;
  403. }
  404. //
  405. // Check RDP
  406. //
  407. v = vOPTR & _MASK_RDP;
  408. if ((v == _RDP_LVL_0) || (v == _RDP_LVL_05)) {
  409. //
  410. // Set special boot mode if TZEN is active, but RDP is not Level 1.
  411. // We do this, because when TZEN == 1, we are only able to read/write the flash registers while
  412. // the CPU is executing non-secure code.
  413. // By setting the boot mode while TZEN is set, we force the device to boot RSS, which is then
  414. // executing non-secure code, which enables us to regress from RDP level 1.
  415. //
  416. vOPTR &= ~(_BIT_NSWBOOT0 | _BIT_NBOOT0); // Set bootmode to BTL
  417. vOPTR &= ~_MASK_RDP; // Mask out RDP
  418. vOPTR |= _RDP_LVL_1; // Set RDP level 1
  419. _UnlockOptionbytes();
  420. JLINK_MEM_WriteU32(_FLASH_OPTR, vOPTR);
  421. r = _ProgOptionbytes();
  422. if (r < 0) {
  423. return -1;
  424. }
  425. }
  426. //
  427. // Reset OPTR to factory value
  428. //
  429. _UnlockOptionbytes();
  430. JLINK_MEM_WriteU32(_FLASH_OPTR, _OPTR_FACT_VAL);
  431. r = _ProgOptionbytes();
  432. if (r < 0) {
  433. return -1;
  434. }
  435. v = JLINK_MEM_ReadU32(_FLASH_OPTR);
  436. if (v & _BIT_TZEN) {
  437. JLINK_SYS_Report(" TrustZone still enabled after disable sequence.");
  438. return -1;
  439. }
  440. r = _Reset();
  441. if (r < 0) {
  442. return -1;
  443. }
  444. JLINK_SYS_Report(" TrustZone disabled successfully.");
  445. return 0;
  446. }
  447. /*********************************************************************
  448. *
  449. * Global functions
  450. *
  451. **********************************************************************
  452. */
  453. /*********************************************************************
  454. *
  455. * SetupTarget()
  456. *
  457. * Function description
  458. * If present, called after InitTarget() and after general debug connect sequence
  459. * has been performed by J-Link. Usually used for more high-level CPU debug setup
  460. * like writing certain memory locations, initializing PLL for faster download etc.
  461. *
  462. * Return value
  463. * >= 0: O.K.
  464. * < 0: Error
  465. *
  466. * Notes
  467. * (1) Does not replace any DLL functionality but extends it.
  468. * (2) May use MEM_ API functions
  469. */
  470. int SetupTarget(void) {
  471. int r;
  472. r = _DisableTZENIfActive();
  473. if (r < 0) {
  474. JLINK_SYS_Report(" Disabling TrustZone failed.");
  475. return -1;
  476. }
  477. return 0;
  478. }
  479. /*************************** end of file ****************************/