bl31_data.S 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. /*
  2. * Copyright 2018-2020 NXP
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #include <asm_macros.S>
  8. #include "bl31_data.h"
  9. #include "plat_psci.h"
  10. #include "platform_def.h"
  11. .global _getCoreData
  12. .global _setCoreData
  13. .global _getCoreState
  14. .global _setCoreState
  15. .global _init_global_data
  16. .global _get_global_data
  17. .global _set_global_data
  18. .global _initialize_psci
  19. .global _init_task_flags
  20. .global _set_task1_start
  21. .global _set_task1_done
  22. /* Function returns the specified data field value from the specified cpu
  23. * core data area
  24. * in: x0 = core mask lsb
  25. * x1 = data field name/offset
  26. * out: x0 = data value
  27. * uses x0, x1, x2, [x13, x14, x15]
  28. */
  29. func _getCoreData
  30. /* generate a 0-based core number from the input mask */
  31. clz x2, x0
  32. mov x0, #63
  33. sub x0, x0, x2
  34. /* x0 = core number (0-based) */
  35. /* x1 = field offset */
  36. /* determine if this is bootcore or secondary core */
  37. cbnz x0, 1f
  38. /* get base address for bootcore data */
  39. ldr x2, =BC_PSCI_BASE
  40. add x2, x2, x1
  41. b 2f
  42. 1: /* get base address for secondary core data */
  43. /* x0 = core number (0-based) */
  44. /* x1 = field offset */
  45. /* generate number of regions to offset */
  46. mov x2, #SEC_REGION_SIZE
  47. mul x2, x2, x0
  48. /* x1 = field offset */
  49. /* x2 = region offset */
  50. /* generate the total offset to data element */
  51. sub x1, x2, x1
  52. /* x1 = total offset to data element */
  53. /* get the base address */
  54. ldr x2, =SECONDARY_TOP
  55. /* apply offset to base addr */
  56. sub x2, x2, x1
  57. 2:
  58. /* x2 = data element address */
  59. dc ivac, x2
  60. dsb sy
  61. isb
  62. /* read data */
  63. ldr x0, [x2]
  64. ret
  65. endfunc _getCoreData
  66. /* Function returns the SoC-specific state of the specified cpu
  67. * in: x0 = core mask lsb
  68. * out: x0 = data value
  69. * uses x0, x1, x2, [x13, x14, x15]
  70. */
  71. func _getCoreState
  72. mov x1, #CORE_STATE_DATA
  73. /* generate a 0-based core number from the input mask */
  74. clz x2, x0
  75. mov x0, #63
  76. sub x0, x0, x2
  77. /* x0 = core number (0-based) */
  78. /* x1 = field offset */
  79. /* determine if this is bootcore or secondary core */
  80. cbnz x0, 1f
  81. /* get base address for bootcore data */
  82. ldr x2, =BC_PSCI_BASE
  83. add x2, x2, x1
  84. b 2f
  85. 1: /* get base address for secondary core data */
  86. /* x0 = core number (0-based) */
  87. /* x1 = field offset */
  88. /* generate number of regions to offset */
  89. mov x2, #SEC_REGION_SIZE
  90. mul x2, x2, x0
  91. /* x1 = field offset */
  92. /* x2 = region offset */
  93. /* generate the total offset to data element */
  94. sub x1, x2, x1
  95. /* x1 = total offset to data element */
  96. /* get the base address */
  97. ldr x2, =SECONDARY_TOP
  98. /* apply offset to base addr */
  99. sub x2, x2, x1
  100. 2:
  101. /* x2 = data element address */
  102. dc ivac, x2
  103. dsb sy
  104. isb
  105. /* read data */
  106. ldr x0, [x2]
  107. ret
  108. endfunc _getCoreState
  109. /* Function writes the specified data value into the specified cpu
  110. * core data area
  111. * in: x0 = core mask lsb
  112. * x1 = data field offset
  113. * x2 = data value to write/store
  114. * out: none
  115. * uses x0, x1, x2, x3, [x13, x14, x15]
  116. */
  117. func _setCoreData
  118. /* x0 = core mask */
  119. /* x1 = field offset */
  120. /* x2 = data value */
  121. clz x3, x0
  122. mov x0, #63
  123. sub x0, x0, x3
  124. /* x0 = core number (0-based) */
  125. /* x1 = field offset */
  126. /* x2 = data value */
  127. /* determine if this is bootcore or secondary core */
  128. cbnz x0, 1f
  129. /* get base address for bootcore data */
  130. ldr x3, =BC_PSCI_BASE
  131. add x3, x3, x1
  132. b 2f
  133. 1: /* get base address for secondary core data */
  134. /* x0 = core number (0-based) */
  135. /* x1 = field offset */
  136. /* x2 = data value */
  137. /* generate number of regions to offset */
  138. mov x3, #SEC_REGION_SIZE
  139. mul x3, x3, x0
  140. /* x1 = field offset */
  141. /* x2 = data value */
  142. /* x3 = region offset */
  143. /* generate the total offset to data element */
  144. sub x1, x3, x1
  145. /* x1 = total offset to data element */
  146. /* x2 = data value */
  147. ldr x3, =SECONDARY_TOP
  148. /* apply offset to base addr */
  149. sub x3, x3, x1
  150. 2:
  151. /* x2 = data value */
  152. /* x3 = data element address */
  153. str x2, [x3]
  154. dc cvac, x3
  155. dsb sy
  156. isb
  157. ret
  158. endfunc _setCoreData
  159. /* Function stores the specified core state
  160. * in: x0 = core mask lsb
  161. * x1 = data value to write/store
  162. * out: none
  163. * uses x0, x1, x2, x3, [x13, x14, x15]
  164. */
  165. func _setCoreState
  166. mov x2, #CORE_STATE_DATA
  167. clz x3, x0
  168. mov x0, #63
  169. sub x0, x0, x3
  170. /* x0 = core number (0-based) */
  171. /* x1 = data value */
  172. /* x2 = field offset */
  173. /* determine if this is bootcore or secondary core */
  174. cbnz x0, 1f
  175. /* get base address for bootcore data */
  176. ldr x3, =BC_PSCI_BASE
  177. add x3, x3, x2
  178. b 2f
  179. 1: /* get base address for secondary core data */
  180. /* x0 = core number (0-based) */
  181. /* x1 = data value */
  182. /* x2 = field offset */
  183. /* generate number of regions to offset */
  184. mov x3, #SEC_REGION_SIZE
  185. mul x3, x3, x0
  186. /* x1 = data value */
  187. /* x2 = field offset */
  188. /* x3 = region offset */
  189. /* generate the total offset to data element */
  190. sub x2, x3, x2
  191. /* x1 = data value */
  192. /* x2 = total offset to data element */
  193. ldr x3, =SECONDARY_TOP
  194. /* apply offset to base addr */
  195. sub x3, x3, x2
  196. 2:
  197. /* x1 = data value */
  198. /* x3 = data element address */
  199. str x1, [x3]
  200. dc civac, x3
  201. dsb sy
  202. isb
  203. ret
  204. endfunc _setCoreState
  205. /* Function sets the task1 start
  206. * in: w0 = value to set flag to
  207. * out: none
  208. * uses x0, x1
  209. */
  210. func _set_task1_start
  211. ldr x1, =SMC_TASK1_BASE
  212. add x1, x1, #TSK_START_OFFSET
  213. str w0, [x1]
  214. dc cvac, x1
  215. dsb sy
  216. isb
  217. ret
  218. endfunc _set_task1_start
  219. /* Function sets the state of the task 1 done flag
  220. * in: w0 = value to set flag to
  221. * out: none
  222. * uses x0, x1
  223. */
  224. func _set_task1_done
  225. ldr x1, =SMC_TASK1_BASE
  226. add x1, x1, #TSK_DONE_OFFSET
  227. str w0, [x1]
  228. dc cvac, x1
  229. dsb sy
  230. isb
  231. ret
  232. endfunc _set_task1_done
  233. /* Function initializes the smc global data entries
  234. * Note: the constant LAST_SMC_GLBL_OFFSET must reference the last entry in the
  235. * smc global region
  236. * in: none
  237. * out: none
  238. * uses x0, x1, x2
  239. */
  240. func _init_global_data
  241. ldr x1, =SMC_GLBL_BASE
  242. /* x1 = SMC_GLBL_BASE */
  243. mov x2, #LAST_SMC_GLBL_OFFSET
  244. add x2, x2, x1
  245. 1:
  246. str xzr, [x1]
  247. dc cvac, x1
  248. cmp x2, x1
  249. add x1, x1, #8
  250. b.hi 1b
  251. dsb sy
  252. isb
  253. ret
  254. endfunc _init_global_data
  255. /* Function gets the value of the specified global data element
  256. * in: x0 = offset of data element
  257. * out: x0 = requested data element
  258. * uses x0, x1
  259. */
  260. func _get_global_data
  261. ldr x1, =SMC_GLBL_BASE
  262. add x1, x1, x0
  263. dc ivac, x1
  264. isb
  265. ldr x0, [x1]
  266. ret
  267. endfunc _get_global_data
  268. /* Function sets the value of the specified global data element
  269. * in: x0 = offset of data element
  270. * x1 = value to write
  271. * out: none
  272. * uses x0, x1, x2
  273. */
  274. func _set_global_data
  275. ldr x2, =SMC_GLBL_BASE
  276. add x0, x0, x2
  277. str x1, [x0]
  278. dc cvac, x0
  279. dsb sy
  280. isb
  281. ret
  282. endfunc _set_global_data
  283. /* Function initializes the core data areas
  284. * only executed by the boot core
  285. * in: none
  286. * out: none
  287. * uses: x0, x1, x2, x3, x4, x5, x6, x7, [x13, x14, x15]
  288. */
  289. func _initialize_psci
  290. mov x7, x30
  291. /* initialize the bootcore psci data */
  292. ldr x5, =BC_PSCI_BASE
  293. mov x6, #CORE_RELEASED
  294. str x6, [x5], #8
  295. dc cvac, x5
  296. str xzr, [x5], #8
  297. dc cvac, x5
  298. str xzr, [x5], #8
  299. dc cvac, x5
  300. str xzr, [x5], #8
  301. dc cvac, x5
  302. str xzr, [x5], #8
  303. dc cvac, x5
  304. str xzr, [x5], #8
  305. dc cvac, x5
  306. str xzr, [x5], #8
  307. dc cvac, x5
  308. str xzr, [x5], #8
  309. dc cvac, x5
  310. str xzr, [x5], #8
  311. dc cvac, x5
  312. str xzr, [x5], #8
  313. dc cvac, x5
  314. str xzr, [x5], #8
  315. dc cvac, x5
  316. str xzr, [x5], #8
  317. dc cvac, x5
  318. str xzr, [x5], #8
  319. dc cvac, x5
  320. str xzr, [x5], #8
  321. dc cvac, x5
  322. str xzr, [x5], #8
  323. dc cvac, x5
  324. str xzr, [x5]
  325. dc cvac, x5
  326. dsb sy
  327. isb
  328. /* see if we have any secondary cores */
  329. mov x4, #PLATFORM_CORE_COUNT
  330. sub x4, x4, #1
  331. cbz x4, 3f
  332. /* initialize the secondary core's psci data */
  333. ldr x5, =SECONDARY_TOP
  334. /* core mask lsb for core 1 */
  335. mov x3, #2
  336. sub x5, x5, #SEC_REGION_SIZE
  337. /* x3 = core1 mask lsb */
  338. /* x4 = number of secondary cores */
  339. /* x5 = core1 psci data base address */
  340. 2:
  341. /* set core state in x6 */
  342. mov x0, x3
  343. mov x6, #CORE_IN_RESET
  344. bl _soc_ck_disabled
  345. cbz x0, 1f
  346. mov x6, #CORE_DISABLED
  347. 1:
  348. add x2, x5, #CORE_STATE_DATA
  349. str x6, [x2]
  350. dc cvac, x2
  351. add x2, x5, #SPSR_EL3_DATA
  352. str xzr, [x2]
  353. dc cvac, x2
  354. add x2, x5, #CNTXT_ID_DATA
  355. str xzr, [x2]
  356. dc cvac, x2
  357. add x2, x5, #START_ADDR_DATA
  358. str xzr, [x2]
  359. dc cvac, x2
  360. add x2, x5, #LINK_REG_DATA
  361. str xzr, [x2]
  362. dc cvac, x2
  363. add x2, x5, #GICC_CTLR_DATA
  364. str xzr, [x2]
  365. dc cvac, x2
  366. add x2, x5, #ABORT_FLAG_DATA
  367. str xzr, [x2]
  368. dc cvac, x2
  369. add x2, x5, #SCTLR_DATA
  370. str xzr, [x2]
  371. dc cvac, x2
  372. add x2, x5, #CPUECTLR_DATA
  373. str xzr, [x2]
  374. dc cvac, x2
  375. add x2, x5, #AUX_01_DATA
  376. str xzr, [x2]
  377. dc cvac, x2
  378. add x2, x5, #AUX_02_DATA
  379. str xzr, [x2]
  380. dc cvac, x2
  381. add x2, x5, #AUX_03_DATA
  382. str xzr, [x2]
  383. dc cvac, x2
  384. add x2, x5, #AUX_04_DATA
  385. str xzr, [x2]
  386. dc cvac, x2
  387. add x2, x5, #AUX_05_DATA
  388. str xzr, [x2]
  389. dc cvac, x2
  390. add x2, x5, #SCR_EL3_DATA
  391. str xzr, [x2]
  392. dc cvac, x2
  393. add x2, x5, #HCR_EL2_DATA
  394. str xzr, [x2]
  395. dc cvac, x2
  396. dsb sy
  397. isb
  398. sub x4, x4, #1
  399. cbz x4, 3f
  400. /* generate next core mask */
  401. lsl x3, x3, #1
  402. /* decrement base address to next data area */
  403. sub x5, x5, #SEC_REGION_SIZE
  404. b 2b
  405. 3:
  406. mov x30, x7
  407. ret
  408. endfunc _initialize_psci
  409. /* Function initializes the soc init task flags
  410. * in: none
  411. * out: none
  412. * uses x0, x1, [x13, x14, x15]
  413. */
  414. func _init_task_flags
  415. /* get the base address of the first task structure */
  416. ldr x0, =SMC_TASK1_BASE
  417. /* x0 = task1 base address */
  418. str wzr, [x0, #TSK_START_OFFSET]
  419. str wzr, [x0, #TSK_DONE_OFFSET]
  420. str wzr, [x0, #TSK_CORE_OFFSET]
  421. dc cvac, x0
  422. /* move to task2 structure */
  423. add x0, x0, #SMC_TASK_OFFSET
  424. str wzr, [x0, #TSK_START_OFFSET]
  425. str wzr, [x0, #TSK_DONE_OFFSET]
  426. str wzr, [x0, #TSK_CORE_OFFSET]
  427. dc cvac, x0
  428. /* move to task3 structure */
  429. add x0, x0, #SMC_TASK_OFFSET
  430. str wzr, [x0, #TSK_START_OFFSET]
  431. str wzr, [x0, #TSK_DONE_OFFSET]
  432. str wzr, [x0, #TSK_CORE_OFFSET]
  433. dc cvac, x0
  434. /* move to task4 structure */
  435. add x0, x0, #SMC_TASK_OFFSET
  436. str wzr, [x0, #TSK_START_OFFSET]
  437. str wzr, [x0, #TSK_DONE_OFFSET]
  438. str wzr, [x0, #TSK_CORE_OFFSET]
  439. dc cvac, x0
  440. dsb sy
  441. isb
  442. ret
  443. endfunc _init_task_flags