mxs40v2_acquire_helpers.cfg 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. #
  2. # Copyright (C) <2019-2021>
  3. # <Cypress Semiconductor Corporation (an Infineon company)>
  4. #
  5. # Acquisition helpers for MXS40v2 family of microcontrollers.
  6. #
  7. if [info exist LOADED_[file rootname [file tail [info script]]]] return
  8. set LOADED_[file rootname [file tail [info script]]] true
  9. source [find target/cympn.cfg]
  10. source [find target/mxs40/cyw20829_status_codes.cfg]
  11. namespace eval mxs40v2 {
  12. variable CYBOOT_ID_MASK 0xFFF00000
  13. variable CYBOOT_ID_FAIL 0xBAF00000
  14. variable CYBOOT_ID_SUCCESS 0x0D500000
  15. variable CYAPP_ID_MASK 0xFFF00000
  16. variable CYAPP_ID_FAIL 0x45000000
  17. variable CYAPP_ID_SUCCESS 0xF2A00000
  18. variable ACQUIRE_TIMEOUT 2500
  19. variable EFUSE_BOOTROW_ADDR 0x40810180
  20. variable EFUSE_CTRL_ADDR 0x40810000
  21. variable EFUSE_DEVICE_ID_ADDR 0x40810878
  22. variable EFUSE_SI_REV_ID_ADDR 0x4081087C
  23. variable NVIC_VTOR_ADDR 0xE000ED08
  24. variable RAM_BOOT_BUILD_ADDR 0x20000008
  25. variable RAM_BOOT_STATUS_ADDR 0x20000000
  26. variable RAM_BOOT_VERSION_ADDR 0x20000004
  27. variable SRSS_RES_SOFT_CTL_ADDR 0x40200410
  28. variable SRSS_RES_SOFT_CTL_RESET_MASK 0x00000001
  29. variable SRSS_TST_DEBUG_CTL_ADDR 0x40200404
  30. variable SRSS_TST_DEBUG_CTL_WFA_MASK 0x80000000
  31. variable SRSS_TST_DEBUG_CTL_WFA_REQ 0x00000001
  32. variable SRSS_TST_DEBUG_STATUS_ADDR 0x40200408
  33. variable SRSS_TST_MODE_ADDR 0x40200400
  34. variable SRSS_TST_MODE_MASK 0x80000000
  35. namespace eval priv {
  36. variable push_count 0
  37. variable pushed_log_level 0
  38. proc push_log_settings {} {
  39. variable push_count
  40. variable pushed_log_level
  41. if { $push_count == 0 } {
  42. local_echo off
  43. scan [debug_level] "debug_level: %d" pushed_log_level
  44. debug_level -1
  45. }
  46. incr push_count
  47. }
  48. proc pop_log_settings {} {
  49. variable push_count
  50. variable pushed_log_level
  51. if { $push_count == 0 } {
  52. puts stderr "push/pop log settings mismatch"
  53. } else {
  54. incr push_count -1
  55. }
  56. if { $push_count == 0 } {
  57. debug_level $pushed_log_level
  58. local_echo on
  59. }
  60. }
  61. proc default_dap_ap { dap_name ap_num } {
  62. upvar $dap_name dap
  63. upvar $ap_num ap
  64. set target [target current]
  65. set dap [expr {$dap ne {} ? $dap : [$target cget -dap]}]
  66. set ap [expr {$ap ne {} ? $ap : [$target cget -ap-num]}]
  67. }
  68. proc read32 { dap ap address } {
  69. push_log_settings
  70. catch {
  71. $dap apreg $ap 0x00 0xAB000002
  72. $dap apreg $ap 0x04 $address
  73. $dap apreg $ap 0x0C
  74. } result options
  75. pop_log_settings
  76. return {*}$options [string trim $result]
  77. }
  78. proc write32 { dap ap address val } {
  79. $dap apreg $ap 0x00 0xAB000002
  80. $dap apreg $ap 0x04 $address
  81. $dap apreg $ap 0x0C $val
  82. }
  83. proc is_idle_loop { dap ap } {
  84. variable [namespace parent]::CYBOOT_ID_FAIL
  85. variable [namespace parent]::CYBOOT_ID_MASK
  86. variable [namespace parent]::CYBOOT_ID_SUCCESS
  87. variable [namespace parent]::CYBOOT_NEXT_APP_LAUNCHED
  88. variable [namespace parent]::CYBOOT_WFA_POLLING
  89. variable [namespace parent]::RAM_BOOT_STATUS_ADDR
  90. variable [namespace parent]::SRSS_TST_DEBUG_CTL_ADDR
  91. variable [namespace parent]::SRSS_TST_DEBUG_CTL_WFA_MASK
  92. variable [namespace parent]::SRSS_TST_DEBUG_STATUS_ADDR
  93. if [catch {read32 $dap $ap $SRSS_TST_DEBUG_STATUS_ADDR} mmio_status] {
  94. return 0
  95. }
  96. if [catch {read32 $dap $ap $SRSS_TST_DEBUG_CTL_ADDR} debug_status] {
  97. return 0
  98. }
  99. # CYBOOT_ID_FAIL in SRSS_TST_DEBUG_CTL_ADDR means device is CORRUPTED
  100. # Return BREAK status to exit outer polling loop
  101. if { [expr {$mmio_status & $CYBOOT_ID_MASK}] == $CYBOOT_ID_FAIL } {
  102. return -code break
  103. }
  104. if {$mmio_status == $CYBOOT_WFA_POLLING &&
  105. [expr {$debug_status & $SRSS_TST_DEBUG_CTL_WFA_MASK}]} {
  106. return 1
  107. }
  108. if [catch {read32 $dap $ap $RAM_BOOT_STATUS_ADDR} ram_status] {
  109. return 0
  110. }
  111. if { [expr {$ram_status & $CYBOOT_ID_MASK}] == $CYBOOT_ID_FAIL ||
  112. [expr {$ram_status & $CYBOOT_ID_MASK}] == $CYBOOT_ID_SUCCESS &&
  113. $ram_status != $CYBOOT_NEXT_APP_LAUNCHED } {
  114. return 1
  115. }
  116. # CYBOOT_NEXT_APP_LAUNCHED means we've missed listen window
  117. # Return BREAK status to exit outer polling loop
  118. if {$ram_status == $CYBOOT_NEXT_APP_LAUNCHED} {
  119. return -code break
  120. }
  121. return 0
  122. }
  123. proc do_reset { reset_mode dap ap } {
  124. variable [namespace parent]::SRSS_RES_SOFT_CTL_ADDR
  125. variable [namespace parent]::SRSS_RES_SOFT_CTL_RESET_MASK
  126. if { $reset_mode > 2 } {
  127. return 0
  128. }
  129. set RESET_METHODS { 0 "XRES pin" 1 "DP.CDBGRSTREQ" 2 "SRSS_RES_SOFT_CTL" }
  130. echo "** Reset using $RESET_METHODS($reset_mode)"
  131. if { $reset_mode == 0 } {
  132. adapter assert srst
  133. adapter deassert srst
  134. } elseif { $reset_mode == 1 } {
  135. catch {$dap dpreg 4 0xF4000040}
  136. } elseif { $reset_mode == 2 } {
  137. catch {write32 $dap $ap $SRSS_RES_SOFT_CTL_ADDR $SRSS_RES_SOFT_CTL_RESET_MASK}
  138. }
  139. return 1
  140. }
  141. # namespace eval priv
  142. }
  143. #####################################################################################################################
  144. #
  145. #####################################################################################################################
  146. proc wait_for_idle_loop { {dap {}} {ap {}} } {
  147. variable ACQUIRE_TIMEOUT
  148. priv::default_dap_ap dap ap
  149. priv::push_log_settings
  150. scan [poll status] "background polling: %s" poll_status
  151. poll off
  152. priv::pop_log_settings
  153. set ret 0
  154. set t_end [expr {[clock milliseconds] + $ACQUIRE_TIMEOUT}]
  155. while {[clock milliseconds] < $t_end} {
  156. if [priv::is_idle_loop $dap $ap] {
  157. set ret 1
  158. break
  159. }
  160. }
  161. priv::push_log_settings
  162. eval poll $poll_status
  163. priv::pop_log_settings
  164. return $ret
  165. }
  166. #####################################################################################################################
  167. #
  168. #####################################################################################################################
  169. proc is_ap_open { {dap {}} {ap {}} } {
  170. priv::default_dap_ap dap ap
  171. priv::push_log_settings
  172. scan [poll status] "background polling: %s" poll_status
  173. poll off
  174. set ret 0
  175. # read location of the ROM Table to check if AP is opened
  176. if ![catch {
  177. set dbg_base [string trim [$dap apreg $ap 0xF8]]
  178. priv::read32 $dap $ap $dbg_base
  179. }] {
  180. set ret 1
  181. }
  182. eval poll $poll_status
  183. priv::pop_log_settings
  184. return $ret
  185. }
  186. #####################################################################################################################
  187. #
  188. #####################################################################################################################
  189. proc wait_for_ap_open { {dap {}} {ap {}} } {
  190. variable ACQUIRE_TIMEOUT
  191. priv::default_dap_ap dap ap
  192. set ret 0
  193. set t_end [expr {[clock milliseconds] + $ACQUIRE_TIMEOUT}]
  194. while {[clock milliseconds] < $t_end} {
  195. if {[is_ap_open $dap $ap]} {
  196. set ret 1
  197. break
  198. }
  199. }
  200. return $ret
  201. }
  202. #####################################################################################################################
  203. #
  204. #####################################################################################################################
  205. proc decode_lcs { bootrow } {
  206. if { $bootrow == 0x00 } { return "VIRGIN" }
  207. if { $bootrow == 0x29 } { return "SORT" }
  208. if { [expr {$bootrow & 0x3F}] != 0x29 } { return "CORRUPTED" }
  209. set tmp $bootrow
  210. set tmp [expr {(($tmp >> 1 ) ^ $tmp ) & 0x00005540}]
  211. if { $tmp != 0 } { return "CORRUPTED" }
  212. set bootrow [expr {$bootrow & 0x0000FFC0}]
  213. set lcs_table {
  214. { "PROVISIONED" 0x00C0 }
  215. { "NORMAL" 0xC000 }
  216. { "NORMAL_NO_SECURE" 0xCC00 }
  217. { "NORMAL_PROVISIONED" 0xC0C0 }
  218. { "SECURE" 0xC3C0 }
  219. { "RMA" 0xF000 }
  220. { "RMA" 0xFC00 }
  221. { "RMA" 0xF3C0 }
  222. }
  223. foreach lcs $lcs_table {
  224. if { $bootrow == [lindex $lcs 1] } { return [lindex $lcs 0] }
  225. }
  226. return "CORRUPTED"
  227. }
  228. #####################################################################################################################
  229. #
  230. #####################################################################################################################
  231. proc decode_boot_status { status } {
  232. foreach val $::mxs40v2::cyw20829_boot_status_codes {
  233. if { $status == [lindex $val 1] } { return [lindex $val 0] }
  234. }
  235. foreach val $::mxs40v2::cyw20829_app_status_codes {
  236. if { $status == [lindex $val 1] } { return [lindex $val 0] }
  237. }
  238. return "None/Unknown ([format 0x%08X $status])"
  239. }
  240. #####################################################################################################################
  241. #
  242. #####################################################################################################################
  243. proc display_chip_info { chipname {force no} {dap {}} {ap {}} } {
  244. # Run info command inly once for each particular chip, unless forced
  245. global ${chipname}::info_runned
  246. if { [info exists ${chipname}::info_runned] && $force != "force" } return
  247. set ${chipname}::info_runned 1
  248. variable CYBOOT_ID_FAIL
  249. variable CYBOOT_ID_MASK
  250. variable CYBOOT_SERVICE_APP_NOT_LAUNCHED
  251. variable EFUSE_BOOTROW_ADDR
  252. variable EFUSE_CTRL_ADDR
  253. variable EFUSE_DEVICE_ID_ADDR
  254. variable EFUSE_SI_REV_ID_ADDR
  255. variable RAM_BOOT_BUILD_ADDR
  256. variable RAM_BOOT_STATUS_ADDR
  257. variable RAM_BOOT_VERSION_ADDR
  258. variable SRSS_TST_DEBUG_STATUS_ADDR
  259. priv::default_dap_ap dap ap
  260. priv::push_log_settings
  261. scan [poll status] "background polling: %s" poll_status
  262. poll off
  263. set efuse_ctl 0
  264. catch {priv::read32 $dap $ap $EFUSE_CTRL_ADDR} efuse_ctl
  265. catch {priv::write32 $dap $ap $EFUSE_CTRL_ADDR [expr {$efuse_ctl | 0x80000000}]}
  266. echo "***************************************"
  267. set display_str "** "
  268. if ![catch {priv::read32 $dap $ap $EFUSE_DEVICE_ID_ADDR} dev_id] {
  269. set siid [format "%04X" [expr {$dev_id & 0xFFFF}]]
  270. set family [format "%03X" [expr {($dev_id >> 16) & 0xFFF}]]
  271. append display_str "Silicon: 0x$siid, Family: 0x$family"
  272. }
  273. if ![catch {priv::read32 $dap $ap $EFUSE_SI_REV_ID_ADDR} rev_id] {
  274. set revision [format "%02X" [expr {$rev_id & 0xFF}]]
  275. set rev_major "0x0[string index $revision 0]"
  276. set rev_major_str [expr {$rev_major == 0 ? "?" : [format %c [expr {$rev_major + 0x40}]]}]
  277. set rev_minor "0x0[string index $revision 1]"
  278. set rev_minor_str [expr {$rev_minor == 0 ? "?" : [expr {$rev_minor - 1} ]}]
  279. if {$display_str ne "** "} { append display_str ", " }
  280. append display_str "Rev.: 0x$revision (${rev_major_str}${rev_minor_str})"
  281. }
  282. if {$display_str ne "** "} {
  283. echo $display_str
  284. }
  285. if { [info exists siid] && [dict exists $::MPN $siid] } {
  286. echo "** Detected Device: [lindex $::MPN($siid) 0]"
  287. } else {
  288. echo "** Device is not present in the UDD"
  289. }
  290. set lcs {}
  291. if ![catch {priv::read32 $dap $ap $EFUSE_BOOTROW_ADDR} bootrow] {
  292. set lcs [decode_lcs $bootrow]
  293. echo "** Life Cycle : $lcs"
  294. }
  295. set is_corrupted 0
  296. if ![catch {priv::read32 $dap $ap $SRSS_TST_DEBUG_STATUS_ADDR} mmio_status] {
  297. if { [expr {$mmio_status & $CYBOOT_ID_MASK}] == $CYBOOT_ID_FAIL } {
  298. echo "** Boot Status : [decode_boot_status $mmio_status]"
  299. echo "** Reached CORRUPTED branch"
  300. set is_corrupted 1
  301. }
  302. }
  303. if { !$is_corrupted } {
  304. if { ![catch {priv::read32 $dap $ap $RAM_BOOT_VERSION_ADDR} boot_version] &&
  305. ![catch {priv::read32 $dap $ap $RAM_BOOT_BUILD_ADDR} boot_build] } {
  306. set major [expr {($boot_version & 0xFF0000) >> 16}]
  307. set minor [expr {($boot_version & 0x00FF00) >> 8}]
  308. set patch [expr {$boot_version & 0x0000FF}]
  309. echo [format "** Boot version: %d.%d.%d.%d" $major $minor $patch $boot_build]
  310. }
  311. if { ![catch {priv::read32 $dap $ap $RAM_BOOT_STATUS_ADDR} boot_status] } {
  312. echo "** Boot Status : [decode_boot_status $boot_status]"
  313. if { [expr {$boot_status & $CYBOOT_ID_MASK}] == $CYBOOT_ID_FAIL} {
  314. echo "** Reached DEAD branch"
  315. }
  316. }
  317. }
  318. echo "***************************************"
  319. if { $lcs eq "NORMAL" } {
  320. puts stderr "**** WARNING ******************************************************************"
  321. puts stderr "* The detected device is in NORMAL Life Cycle. Programmed application"
  322. puts stderr "* will not start until the device is moved to NORMAL_SECURE or NORMAL_NO_SECURE"
  323. puts stderr "* state. Please refer to the README.md in the device BSP for more information."
  324. puts stderr "*******************************************************************************"
  325. }
  326. catch {priv::write32 $dap $ap $EFUSE_CTRL_ADDR $efuse_ctl}
  327. eval poll $poll_status
  328. priv::pop_log_settings
  329. }
  330. #####################################################################################################################
  331. #
  332. #####################################################################################################################
  333. proc acquire_wfa { {request {}} {dap {}} {ap {}} } {
  334. variable SRSS_RES_SOFT_CTL_ADDR
  335. variable SRSS_RES_SOFT_CTL_RESET_MASK
  336. variable SRSS_TST_DEBUG_CTL_ADDR
  337. variable SRSS_TST_DEBUG_CTL_WFA_MASK
  338. variable SRSS_TST_DEBUG_CTL_WFA_REQ
  339. priv::default_dap_ap dap ap
  340. priv::push_log_settings
  341. scan [poll status] "background polling: %s" poll_status
  342. poll off
  343. priv::pop_log_settings
  344. set request [expr {$request ne {} ? $request : $SRSS_TST_DEBUG_CTL_WFA_REQ}]
  345. if [expr {[priv::read32 $dap $ap $SRSS_TST_DEBUG_CTL_ADDR] & $SRSS_TST_DEBUG_CTL_WFA_MASK}] {
  346. catch {
  347. priv::write32 $dap $ap $SRSS_TST_DEBUG_CTL_ADDR $SRSS_TST_DEBUG_CTL_WFA_MASK
  348. priv::write32 $dap $ap $SRSS_RES_SOFT_CTL_ADDR $SRSS_RES_SOFT_CTL_RESET_MASK
  349. }
  350. }
  351. if ![wait_for_ap_open $dap $ap] {
  352. puts stderr "** Timed out waiting for AP #$ap to open!"
  353. }
  354. catch {
  355. priv::write32 $dap $ap $SRSS_TST_DEBUG_CTL_ADDR $request
  356. priv::write32 $dap $ap $SRSS_RES_SOFT_CTL_ADDR $SRSS_RES_SOFT_CTL_RESET_MASK
  357. }
  358. set result [wait_for_idle_loop $dap $ap]
  359. if {$result} {
  360. echo "** Target acquired in FWA mode (req: [format 0x%02X $request])"
  361. } else {
  362. puts stderr "** Acquisition in WFA mode FAILED!"
  363. }
  364. priv::push_log_settings
  365. eval poll $poll_status
  366. priv::pop_log_settings
  367. return $result
  368. }
  369. #####################################################################################################################
  370. #
  371. #####################################################################################################################
  372. proc launch_service_app { {dap {}} {ap {}} } {
  373. variable ACQUIRE_TIMEOUT
  374. variable CYAPP_APP_RUNNING
  375. variable CYAPP_ID_FAIL
  376. variable CYAPP_ID_MASK
  377. variable CYAPP_SUCCESS
  378. variable CYBOOT_SERVICE_APP_LAUNCHED
  379. variable CYBOOT_SERVICE_APP_NOT_LAUNCHED
  380. variable SRSS_TST_DEBUG_CTL_ADDR
  381. variable SRSS_TST_DEBUG_STATUS_ADDR
  382. priv::default_dap_ap dap ap
  383. priv::push_log_settings
  384. scan [poll status] "background polling: %s" poll_status
  385. poll off
  386. priv::pop_log_settings
  387. catch {priv::write32 $dap $ap $SRSS_TST_DEBUG_CTL_ADDR 0}
  388. set result 0
  389. set t_end [expr {[clock milliseconds] + $ACQUIRE_TIMEOUT}]
  390. while {[clock milliseconds] < $t_end} {
  391. if [catch {priv::read32 $dap $ap $SRSS_TST_DEBUG_STATUS_ADDR} mmio_status] continue
  392. if {$mmio_status == $CYAPP_APP_RUNNING} {
  393. echo "** Service application launched!"
  394. set result 1
  395. break
  396. }
  397. if {$mmio_status == $CYBOOT_SERVICE_APP_NOT_LAUNCHED} {
  398. puts stderr "** Service application was not launched by the Boot!"
  399. set result 0
  400. break
  401. }
  402. }
  403. if {$result} {
  404. echo "** Waiting for service application to complete..."
  405. set result 0
  406. set t_end [expr {[clock milliseconds] + $ACQUIRE_TIMEOUT}]
  407. while {[clock milliseconds] < $t_end} {
  408. if [catch {priv::read32 $dap $ap $SRSS_TST_DEBUG_STATUS_ADDR} mmio_status] continue
  409. if {$mmio_status == $CYAPP_APP_RUNNING} continue
  410. if {$mmio_status == $CYAPP_SUCCESS} {
  411. echo "** Service application completed successfully!"
  412. set result 1
  413. break
  414. }
  415. if {[expr {$mmio_status & $CYAPP_ID_MASK}] == $CYAPP_ID_FAIL} {
  416. puts stderr "** Service application failed! Status: [decode_boot_status $mmio_status]"
  417. set result 0
  418. break
  419. }
  420. }
  421. }
  422. priv::push_log_settings
  423. eval poll $poll_status
  424. priv::pop_log_settings
  425. return $result
  426. }
  427. if { [adapter name] eq "kitprog3" && ![using_jtag]} {
  428. # Configure KitProg3/MiniProg4 parameters for CYW20829 device acquisition:
  429. # target_type == 4 (CY20829); mode == 0 (Reset); attempts == 2
  430. kitprog3 acquire_config off 4 0 2
  431. }
  432. #####################################################################################################################
  433. #
  434. #####################################################################################################################
  435. proc toggle_xres { {dap {}} {ap {}} } {
  436. variable ACQUIRE_TIMEOUT
  437. variable SRSS_TST_MODE_ADDR
  438. variable SRSS_TST_MODE_MASK
  439. priv::default_dap_ap dap ap
  440. priv::push_log_settings
  441. set reset_cfg [reset_config]
  442. reset_config srst_only
  443. scan [poll status] "background polling: %s" poll_status
  444. poll off
  445. set reset_mode 0
  446. while { 1 } {
  447. set t_end [expr {[clock milliseconds] + $ACQUIRE_TIMEOUT}]
  448. while {[clock milliseconds] < $t_end} {
  449. if ![catch {priv::write32 $dap $ap $SRSS_TST_MODE_ADDR $SRSS_TST_MODE_MASK}] break
  450. }
  451. if { [priv::do_reset $reset_mode $dap $ap] == 0 } {
  452. puts stderr "** Failed to reset the device"
  453. break
  454. }
  455. set tst_mode 0xDEADBEEF
  456. while {[clock milliseconds] < $t_end} {
  457. if ![catch {set tst_mode [priv::read32 $dap $ap $SRSS_TST_MODE_ADDR]}] break
  458. }
  459. if { $tst_mode == 0 } break
  460. incr reset_mode
  461. }
  462. eval poll $poll_status
  463. eval [concat reset_config $reset_cfg]
  464. priv::pop_log_settings
  465. }
  466. #####################################################################################################################
  467. #
  468. #####################################################################################################################
  469. proc acquire_xres { {dap {}} {ap {}} } {
  470. variable ACQUIRE_TIMEOUT
  471. variable SRSS_TST_MODE_ADDR
  472. variable SRSS_TST_MODE_MASK
  473. variable SRSS_RES_SOFT_CTL_ADDR
  474. variable SRSS_RES_SOFT_CTL_RESET_MASK
  475. priv::default_dap_ap dap ap
  476. priv::push_log_settings
  477. scan [poll status] "background polling: %s" poll_status
  478. poll off
  479. priv::pop_log_settings
  480. local_echo off
  481. scan [adapter srst delay] "adapter srst delay: %d" srst_delay
  482. set reset_cfg [reset_config]
  483. adapter srst delay 0
  484. reset_config srst_only
  485. set result 0
  486. if { [adapter name] eq "kitprog3" && ![using_jtag]} {
  487. kitprog3 acquire_psoc
  488. set result [wait_for_idle_loop $dap $ap]
  489. }
  490. if {$result == 0} {
  491. for {set i 0} {$i < 3} {incr i} {
  492. set t_end [expr {[clock milliseconds] + $ACQUIRE_TIMEOUT}]
  493. priv::do_reset $i $dap $ap
  494. while {[clock milliseconds] < $t_end} {
  495. if ![catch {priv::write32 $dap $ap $SRSS_TST_MODE_ADDR $SRSS_TST_MODE_MASK}] break
  496. }
  497. set result [wait_for_idle_loop $dap $ap]
  498. if {$result} break
  499. }
  500. }
  501. local_echo off
  502. adapter srst delay $srst_delay
  503. eval [concat reset_config $reset_cfg]
  504. local_echo on
  505. if {$result} {
  506. echo "** Target acquired in Test Mode"
  507. } else {
  508. puts stderr "** Acquisition in Test Mode FAILED!"
  509. }
  510. priv::push_log_settings
  511. eval poll $poll_status
  512. priv::pop_log_settings
  513. return $result
  514. }
  515. #####################################################################################################################
  516. #
  517. #####################################################################################################################
  518. proc reset_wait_halt { target } {
  519. variable ACQUIRE_TIMEOUT
  520. variable CYBOOT_IDLE_BRANCH_REACHED
  521. variable CYBOOT_ID_FAIL
  522. variable CYBOOT_ID_MASK
  523. variable CYBOOT_NEXT_APP_LAUNCHED
  524. variable RAM_BOOT_STATUS_ADDR
  525. set app_launched 0
  526. set t_end [expr {[clock milliseconds] + $ACQUIRE_TIMEOUT}]
  527. while {[clock milliseconds] < $t_end} {
  528. $target arp_examine
  529. $target arp_poll
  530. $target arp_poll
  531. set boot_status [mrw $RAM_BOOT_STATUS_ADDR]
  532. if [expr {($boot_status & $CYBOOT_ID_MASK) == $CYBOOT_ID_FAIL}] break
  533. if {$boot_status == $CYBOOT_IDLE_BRANCH_REACHED} break
  534. if {$boot_status == $CYBOOT_NEXT_APP_LAUNCHED} {
  535. set app_launched 1
  536. break
  537. }
  538. }
  539. set ret_val 1
  540. if {$app_launched} {
  541. if [catch {$target arp_waitstate halted 1000}] {
  542. set ret_val 0
  543. }
  544. } else {
  545. puts stderr "** Application was not launched, boot status: [decode_boot_status $boot_status]"
  546. $target arp_halt
  547. $target arp_waitstate halted 1000
  548. }
  549. return $ret_val
  550. }
  551. #####################################################################################################################
  552. #
  553. #####################################################################################################################
  554. proc reset_halt_breakpoint { target use_certificate } {
  555. variable NVIC_VTOR_ADDR
  556. priv::push_log_settings
  557. scan [poll status] "background polling: %s" poll_status
  558. poll off
  559. priv::pop_log_settings
  560. set vtbl_addr [mrw $NVIC_VTOR_ADDR]
  561. if { !($vtbl_addr >= 0x20000000 && $vtbl_addr < 0x20020000) &&
  562. !($vtbl_addr >= 0x04000000 && $vtbl_addr < 0x04020000) &&
  563. !($vtbl_addr >= 0x60000000 && $vtbl_addr < 0x68000000) &&
  564. !($vtbl_addr >= 0x08000000 && $vtbl_addr < 0x10000000) } {
  565. puts stderr "** Vector Table address invalid ([format 0x%08X $vtbl_addr]), using predefined address (0x20004000)"
  566. set vtbl_addr 0x20004000
  567. }
  568. set entry_addr [mrw [expr {$vtbl_addr + 4}]]
  569. if { !($entry_addr >= 0x20000000 && $entry_addr < 0x20020000) &&
  570. !($entry_addr >= 0x04000000 && $entry_addr < 0x04020000) &&
  571. !($entry_addr >= 0x60000000 && $entry_addr < 0x68000000) &&
  572. !($entry_addr >= 0x08000000 && $entry_addr < 0x10000000) } {
  573. puts stderr "** Entry Point address invalid ([format 0x%08X $entry_addr])"
  574. eval poll $poll_status
  575. return
  576. }
  577. echo "** Entry Point found at ([format 0x%08X $entry_addr])"
  578. priv::push_log_settings
  579. bp $entry_addr 2 hw
  580. if {$use_certificate} {
  581. send_certificate
  582. } else {
  583. catch {mww 0xE000ED0C 0x05FA0004}
  584. }
  585. priv::pop_log_settings
  586. wait_for_ap_open
  587. set ret_val [reset_wait_halt $target]
  588. # Remove all breakpoints
  589. rbp all
  590. eval poll $poll_status
  591. return $ret_val
  592. }
  593. #####################################################################################################################
  594. #
  595. #####################################################################################################################
  596. proc reset_halt_vector_catch { target use_certificate } {
  597. priv::push_log_settings
  598. scan [poll status] "background polling: %s" poll_status
  599. poll off
  600. # Setup VectorCatch
  601. set prev_demcr [mrw 0xE000EDFC]
  602. mww 0xE000EDFC 0x01000001
  603. if {$use_certificate} {
  604. send_certificate
  605. } else {
  606. catch {mww 0xE000ED0C 0x05FA0004}
  607. }
  608. priv::pop_log_settings
  609. wait_for_ap_open
  610. set ret_val [reset_wait_halt $target]
  611. # Clear VectorCatch
  612. mww 0xE000EDFC $prev_demcr
  613. eval poll $poll_status
  614. return $ret_val
  615. }
  616. #####################################################################################################################
  617. #
  618. #####################################################################################################################
  619. proc reset_halt { target {use_certificate 0}} {
  620. if ![reset_halt_vector_catch $target $use_certificate] {
  621. puts stderr "** VectorCatch acquisition failed, falling back to BKPT method"
  622. if ![reset_halt_breakpoint $target $use_certificate] {
  623. puts stderr "** BKPT acquisition also failed, giving up"
  624. }
  625. }
  626. }
  627. # namespace eval mxs40v2
  628. }
  629. #####################################################################################################################
  630. #
  631. #####################################################################################################################
  632. proc provision_no_secure {service_app params {service_app_addr 0x20004000} {params_addr 0x2000D000}} {
  633. if {[command mode] == "exec"} {
  634. puts stderr "** The 'provision_no_secure' can only be called before 'init'"
  635. return
  636. }
  637. set tgt [target current]
  638. set sep [string last "." $tgt]
  639. set cm33_target [string range $tgt 0 [expr {$sep - 1}]].cm33
  640. set sysap_target [string range $tgt 0 [expr {$sep - 1}]].sysap
  641. $cm33_target configure -defer-examine
  642. targets $sysap_target
  643. init
  644. mxs40v2::acquire_xres
  645. set lcs [mxs40v2::decode_lcs [mrw $::mxs40v2::EFUSE_BOOTROW_ADDR]]
  646. echo "** Current Life Cycle: $lcs"
  647. if {$lcs ne "NORMAL"} {
  648. puts stderr "** Transition to NORMAL_NO_SECURE can only be done when device is in NORMAL Life Cycle"
  649. return
  650. }
  651. mxs40v2::acquire_wfa 1
  652. load_image $service_app $service_app_addr
  653. load_image $params $params_addr
  654. mxs40v2::launch_service_app
  655. mxs40v2::acquire_xres
  656. set lcs [mxs40v2::decode_lcs [mrw $::mxs40v2::EFUSE_BOOTROW_ADDR]]
  657. echo "** Current Life Cycle: $lcs"
  658. }