cps-vec.S 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. /*
  2. * Copyright (C) 2013 Imagination Technologies
  3. * Author: Paul Burton <paul.burton@imgtec.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2 of the License, or (at your
  8. * option) any later version.
  9. */
  10. #include <asm/addrspace.h>
  11. #include <asm/asm.h>
  12. #include <asm/asm-offsets.h>
  13. #include <asm/asmmacro.h>
  14. #include <asm/cacheops.h>
  15. #include <asm/mipsregs.h>
  16. #include <asm/mipsmtregs.h>
  17. #include <asm/pm.h>
  18. #define GCR_CL_COHERENCE_OFS 0x2008
  19. #define GCR_CL_ID_OFS 0x2028
  20. .extern mips_cm_base
  21. .set noreorder
  22. /*
  23. * Set dest to non-zero if the core supports the MT ASE, else zero. If
  24. * MT is not supported then branch to nomt.
  25. */
  26. .macro has_mt dest, nomt
  27. mfc0 \dest, CP0_CONFIG
  28. bgez \dest, \nomt
  29. mfc0 \dest, CP0_CONFIG, 1
  30. bgez \dest, \nomt
  31. mfc0 \dest, CP0_CONFIG, 2
  32. bgez \dest, \nomt
  33. mfc0 \dest, CP0_CONFIG, 3
  34. andi \dest, \dest, MIPS_CONF3_MT
  35. beqz \dest, \nomt
  36. .endm
  37. .section .text.cps-vec
  38. .balign 0x1000
  39. LEAF(mips_cps_core_entry)
  40. /*
  41. * These first 12 bytes will be patched by cps_smp_setup to load the
  42. * base address of the CM GCRs into register v1 and the CCA to use into
  43. * register s0.
  44. */
  45. .quad 0
  46. .word 0
  47. /* Check whether we're here due to an NMI */
  48. mfc0 k0, CP0_STATUS
  49. and k0, k0, ST0_NMI
  50. beqz k0, not_nmi
  51. nop
  52. /* This is an NMI */
  53. la k0, nmi_handler
  54. jr k0
  55. nop
  56. not_nmi:
  57. /* Setup Cause */
  58. li t0, CAUSEF_IV
  59. mtc0 t0, CP0_CAUSE
  60. /* Setup Status */
  61. li t0, ST0_CU1 | ST0_CU0
  62. mtc0 t0, CP0_STATUS
  63. /*
  64. * Clear the bits used to index the caches. Note that the architecture
  65. * dictates that writing to any of TagLo or TagHi selects 0 or 2 should
  66. * be valid for all MIPS32 CPUs, even those for which said writes are
  67. * unnecessary.
  68. */
  69. mtc0 zero, CP0_TAGLO, 0
  70. mtc0 zero, CP0_TAGHI, 0
  71. mtc0 zero, CP0_TAGLO, 2
  72. mtc0 zero, CP0_TAGHI, 2
  73. ehb
  74. /* Primary cache configuration is indicated by Config1 */
  75. mfc0 v0, CP0_CONFIG, 1
  76. /* Detect I-cache line size */
  77. _EXT t0, v0, MIPS_CONF1_IL_SHF, MIPS_CONF1_IL_SZ
  78. beqz t0, icache_done
  79. li t1, 2
  80. sllv t0, t1, t0
  81. /* Detect I-cache size */
  82. _EXT t1, v0, MIPS_CONF1_IS_SHF, MIPS_CONF1_IS_SZ
  83. xori t2, t1, 0x7
  84. beqz t2, 1f
  85. li t3, 32
  86. addi t1, t1, 1
  87. sllv t1, t3, t1
  88. 1: /* At this point t1 == I-cache sets per way */
  89. _EXT t2, v0, MIPS_CONF1_IA_SHF, MIPS_CONF1_IA_SZ
  90. addi t2, t2, 1
  91. mul t1, t1, t0
  92. mul t1, t1, t2
  93. li a0, KSEG0
  94. add a1, a0, t1
  95. 1: cache Index_Store_Tag_I, 0(a0)
  96. add a0, a0, t0
  97. bne a0, a1, 1b
  98. nop
  99. icache_done:
  100. /* Detect D-cache line size */
  101. _EXT t0, v0, MIPS_CONF1_DL_SHF, MIPS_CONF1_DL_SZ
  102. beqz t0, dcache_done
  103. li t1, 2
  104. sllv t0, t1, t0
  105. /* Detect D-cache size */
  106. _EXT t1, v0, MIPS_CONF1_DS_SHF, MIPS_CONF1_DS_SZ
  107. xori t2, t1, 0x7
  108. beqz t2, 1f
  109. li t3, 32
  110. addi t1, t1, 1
  111. sllv t1, t3, t1
  112. 1: /* At this point t1 == D-cache sets per way */
  113. _EXT t2, v0, MIPS_CONF1_DA_SHF, MIPS_CONF1_DA_SZ
  114. addi t2, t2, 1
  115. mul t1, t1, t0
  116. mul t1, t1, t2
  117. li a0, KSEG0
  118. addu a1, a0, t1
  119. subu a1, a1, t0
  120. 1: cache Index_Store_Tag_D, 0(a0)
  121. bne a0, a1, 1b
  122. add a0, a0, t0
  123. dcache_done:
  124. /* Set Kseg0 CCA to that in s0 */
  125. mfc0 t0, CP0_CONFIG
  126. ori t0, 0x7
  127. xori t0, 0x7
  128. or t0, t0, s0
  129. mtc0 t0, CP0_CONFIG
  130. ehb
  131. /* Enter the coherent domain */
  132. li t0, 0xff
  133. sw t0, GCR_CL_COHERENCE_OFS(v1)
  134. ehb
  135. /* Jump to kseg0 */
  136. la t0, 1f
  137. jr t0
  138. nop
  139. /*
  140. * We're up, cached & coherent. Perform any further required core-level
  141. * initialisation.
  142. */
  143. 1: jal mips_cps_core_init
  144. nop
  145. /*
  146. * Boot any other VPEs within this core that should be online, and
  147. * deactivate this VPE if it should be offline.
  148. */
  149. jal mips_cps_boot_vpes
  150. nop
  151. /* Off we go! */
  152. lw t1, VPEBOOTCFG_PC(v0)
  153. lw gp, VPEBOOTCFG_GP(v0)
  154. lw sp, VPEBOOTCFG_SP(v0)
  155. jr t1
  156. nop
  157. END(mips_cps_core_entry)
  158. .org 0x200
  159. LEAF(excep_tlbfill)
  160. b .
  161. nop
  162. END(excep_tlbfill)
  163. .org 0x280
  164. LEAF(excep_xtlbfill)
  165. b .
  166. nop
  167. END(excep_xtlbfill)
  168. .org 0x300
  169. LEAF(excep_cache)
  170. b .
  171. nop
  172. END(excep_cache)
  173. .org 0x380
  174. LEAF(excep_genex)
  175. b .
  176. nop
  177. END(excep_genex)
  178. .org 0x400
  179. LEAF(excep_intex)
  180. b .
  181. nop
  182. END(excep_intex)
  183. .org 0x480
  184. LEAF(excep_ejtag)
  185. la k0, ejtag_debug_handler
  186. jr k0
  187. nop
  188. END(excep_ejtag)
  189. LEAF(mips_cps_core_init)
  190. #ifdef CONFIG_MIPS_MT
  191. /* Check that the core implements the MT ASE */
  192. has_mt t0, 3f
  193. nop
  194. .set push
  195. .set mt
  196. /* Only allow 1 TC per VPE to execute... */
  197. dmt
  198. /* ...and for the moment only 1 VPE */
  199. dvpe
  200. la t1, 1f
  201. jr.hb t1
  202. nop
  203. /* Enter VPE configuration state */
  204. 1: mfc0 t0, CP0_MVPCONTROL
  205. ori t0, t0, MVPCONTROL_VPC
  206. mtc0 t0, CP0_MVPCONTROL
  207. /* Retrieve the number of VPEs within the core */
  208. mfc0 t0, CP0_MVPCONF0
  209. srl t0, t0, MVPCONF0_PVPE_SHIFT
  210. andi t0, t0, (MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT)
  211. addi t7, t0, 1
  212. /* If there's only 1, we're done */
  213. beqz t0, 2f
  214. nop
  215. /* Loop through each VPE within this core */
  216. li t5, 1
  217. 1: /* Operate on the appropriate TC */
  218. mtc0 t5, CP0_VPECONTROL
  219. ehb
  220. /* Bind TC to VPE (1:1 TC:VPE mapping) */
  221. mttc0 t5, CP0_TCBIND
  222. /* Set exclusive TC, non-active, master */
  223. li t0, VPECONF0_MVP
  224. sll t1, t5, VPECONF0_XTC_SHIFT
  225. or t0, t0, t1
  226. mttc0 t0, CP0_VPECONF0
  227. /* Set TC non-active, non-allocatable */
  228. mttc0 zero, CP0_TCSTATUS
  229. /* Set TC halted */
  230. li t0, TCHALT_H
  231. mttc0 t0, CP0_TCHALT
  232. /* Next VPE */
  233. addi t5, t5, 1
  234. slt t0, t5, t7
  235. bnez t0, 1b
  236. nop
  237. /* Leave VPE configuration state */
  238. 2: mfc0 t0, CP0_MVPCONTROL
  239. xori t0, t0, MVPCONTROL_VPC
  240. mtc0 t0, CP0_MVPCONTROL
  241. 3: .set pop
  242. #endif
  243. jr ra
  244. nop
  245. END(mips_cps_core_init)
  246. LEAF(mips_cps_boot_vpes)
  247. /* Retrieve CM base address */
  248. la t0, mips_cm_base
  249. lw t0, 0(t0)
  250. /* Calculate a pointer to this cores struct core_boot_config */
  251. lw t0, GCR_CL_ID_OFS(t0)
  252. li t1, COREBOOTCFG_SIZE
  253. mul t0, t0, t1
  254. la t1, mips_cps_core_bootcfg
  255. lw t1, 0(t1)
  256. addu t0, t0, t1
  257. /* Calculate this VPEs ID. If the core doesn't support MT use 0 */
  258. has_mt t6, 1f
  259. li t9, 0
  260. /* Find the number of VPEs present in the core */
  261. mfc0 t1, CP0_MVPCONF0
  262. srl t1, t1, MVPCONF0_PVPE_SHIFT
  263. andi t1, t1, MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT
  264. addi t1, t1, 1
  265. /* Calculate a mask for the VPE ID from EBase.CPUNum */
  266. clz t1, t1
  267. li t2, 31
  268. subu t1, t2, t1
  269. li t2, 1
  270. sll t1, t2, t1
  271. addiu t1, t1, -1
  272. /* Retrieve the VPE ID from EBase.CPUNum */
  273. mfc0 t9, $15, 1
  274. and t9, t9, t1
  275. 1: /* Calculate a pointer to this VPEs struct vpe_boot_config */
  276. li t1, VPEBOOTCFG_SIZE
  277. mul v0, t9, t1
  278. lw t7, COREBOOTCFG_VPECONFIG(t0)
  279. addu v0, v0, t7
  280. #ifdef CONFIG_MIPS_MT
  281. /* If the core doesn't support MT then return */
  282. bnez t6, 1f
  283. nop
  284. jr ra
  285. nop
  286. .set push
  287. .set mt
  288. 1: /* Enter VPE configuration state */
  289. dvpe
  290. la t1, 1f
  291. jr.hb t1
  292. nop
  293. 1: mfc0 t1, CP0_MVPCONTROL
  294. ori t1, t1, MVPCONTROL_VPC
  295. mtc0 t1, CP0_MVPCONTROL
  296. ehb
  297. /* Loop through each VPE */
  298. lw t6, COREBOOTCFG_VPEMASK(t0)
  299. move t8, t6
  300. li t5, 0
  301. /* Check whether the VPE should be running. If not, skip it */
  302. 1: andi t0, t6, 1
  303. beqz t0, 2f
  304. nop
  305. /* Operate on the appropriate TC */
  306. mfc0 t0, CP0_VPECONTROL
  307. ori t0, t0, VPECONTROL_TARGTC
  308. xori t0, t0, VPECONTROL_TARGTC
  309. or t0, t0, t5
  310. mtc0 t0, CP0_VPECONTROL
  311. ehb
  312. /* Skip the VPE if its TC is not halted */
  313. mftc0 t0, CP0_TCHALT
  314. beqz t0, 2f
  315. nop
  316. /* Calculate a pointer to the VPEs struct vpe_boot_config */
  317. li t0, VPEBOOTCFG_SIZE
  318. mul t0, t0, t5
  319. addu t0, t0, t7
  320. /* Set the TC restart PC */
  321. lw t1, VPEBOOTCFG_PC(t0)
  322. mttc0 t1, CP0_TCRESTART
  323. /* Set the TC stack pointer */
  324. lw t1, VPEBOOTCFG_SP(t0)
  325. mttgpr t1, sp
  326. /* Set the TC global pointer */
  327. lw t1, VPEBOOTCFG_GP(t0)
  328. mttgpr t1, gp
  329. /* Copy config from this VPE */
  330. mfc0 t0, CP0_CONFIG
  331. mttc0 t0, CP0_CONFIG
  332. /* Ensure no software interrupts are pending */
  333. mttc0 zero, CP0_CAUSE
  334. mttc0 zero, CP0_STATUS
  335. /* Set TC active, not interrupt exempt */
  336. mftc0 t0, CP0_TCSTATUS
  337. li t1, ~TCSTATUS_IXMT
  338. and t0, t0, t1
  339. ori t0, t0, TCSTATUS_A
  340. mttc0 t0, CP0_TCSTATUS
  341. /* Clear the TC halt bit */
  342. mttc0 zero, CP0_TCHALT
  343. /* Set VPE active */
  344. mftc0 t0, CP0_VPECONF0
  345. ori t0, t0, VPECONF0_VPA
  346. mttc0 t0, CP0_VPECONF0
  347. /* Next VPE */
  348. 2: srl t6, t6, 1
  349. addi t5, t5, 1
  350. bnez t6, 1b
  351. nop
  352. /* Leave VPE configuration state */
  353. mfc0 t1, CP0_MVPCONTROL
  354. xori t1, t1, MVPCONTROL_VPC
  355. mtc0 t1, CP0_MVPCONTROL
  356. ehb
  357. evpe
  358. /* Check whether this VPE is meant to be running */
  359. li t0, 1
  360. sll t0, t0, t9
  361. and t0, t0, t8
  362. bnez t0, 2f
  363. nop
  364. /* This VPE should be offline, halt the TC */
  365. li t0, TCHALT_H
  366. mtc0 t0, CP0_TCHALT
  367. la t0, 1f
  368. 1: jr.hb t0
  369. nop
  370. 2: .set pop
  371. #endif /* CONFIG_MIPS_MT */
  372. /* Return */
  373. jr ra
  374. nop
  375. END(mips_cps_boot_vpes)
  376. #if defined(CONFIG_MIPS_CPS_PM) && defined(CONFIG_CPU_PM)
  377. /* Calculate a pointer to this CPUs struct mips_static_suspend_state */
  378. .macro psstate dest
  379. .set push
  380. .set noat
  381. lw $1, TI_CPU(gp)
  382. sll $1, $1, LONGLOG
  383. la \dest, __per_cpu_offset
  384. addu $1, $1, \dest
  385. lw $1, 0($1)
  386. la \dest, cps_cpu_state
  387. addu \dest, \dest, $1
  388. .set pop
  389. .endm
  390. LEAF(mips_cps_pm_save)
  391. /* Save CPU state */
  392. SUSPEND_SAVE_REGS
  393. psstate t1
  394. SUSPEND_SAVE_STATIC
  395. jr v0
  396. nop
  397. END(mips_cps_pm_save)
  398. LEAF(mips_cps_pm_restore)
  399. /* Restore CPU state */
  400. psstate t1
  401. RESUME_RESTORE_STATIC
  402. RESUME_RESTORE_REGS_RETURN
  403. END(mips_cps_pm_restore)
  404. #endif /* CONFIG_MIPS_CPS_PM && CONFIG_CPU_PM */