cps-vec.S 9.1 KB

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