cps-vec.S 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  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. addi 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. addi 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. addi 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. addi 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 mt
  199. /* Only allow 1 TC per VPE to execute... */
  200. dmt
  201. /* ...and for the moment only 1 VPE */
  202. dvpe
  203. la t1, 1f
  204. jr.hb t1
  205. nop
  206. /* Enter VPE configuration state */
  207. 1: mfc0 t0, CP0_MVPCONTROL
  208. ori t0, t0, MVPCONTROL_VPC
  209. mtc0 t0, CP0_MVPCONTROL
  210. /* Retrieve the number of VPEs within the core */
  211. mfc0 t0, CP0_MVPCONF0
  212. srl t0, t0, MVPCONF0_PVPE_SHIFT
  213. andi t0, t0, (MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT)
  214. addi t7, t0, 1
  215. /* If there's only 1, we're done */
  216. beqz t0, 2f
  217. nop
  218. /* Loop through each VPE within this core */
  219. li t5, 1
  220. 1: /* Operate on the appropriate TC */
  221. mtc0 t5, CP0_VPECONTROL
  222. ehb
  223. /* Bind TC to VPE (1:1 TC:VPE mapping) */
  224. mttc0 t5, CP0_TCBIND
  225. /* Set exclusive TC, non-active, master */
  226. li t0, VPECONF0_MVP
  227. sll t1, t5, VPECONF0_XTC_SHIFT
  228. or t0, t0, t1
  229. mttc0 t0, CP0_VPECONF0
  230. /* Set TC non-active, non-allocatable */
  231. mttc0 zero, CP0_TCSTATUS
  232. /* Set TC halted */
  233. li t0, TCHALT_H
  234. mttc0 t0, CP0_TCHALT
  235. /* Next VPE */
  236. addi t5, t5, 1
  237. slt t0, t5, t7
  238. bnez t0, 1b
  239. nop
  240. /* Leave VPE configuration state */
  241. 2: mfc0 t0, CP0_MVPCONTROL
  242. xori t0, t0, MVPCONTROL_VPC
  243. mtc0 t0, CP0_MVPCONTROL
  244. 3: .set pop
  245. #endif
  246. jr ra
  247. nop
  248. END(mips_cps_core_init)
  249. LEAF(mips_cps_boot_vpes)
  250. /* Retrieve CM base address */
  251. la t0, mips_cm_base
  252. lw t0, 0(t0)
  253. /* Calculate a pointer to this cores struct core_boot_config */
  254. lw t0, GCR_CL_ID_OFS(t0)
  255. li t1, COREBOOTCFG_SIZE
  256. mul t0, t0, t1
  257. la t1, mips_cps_core_bootcfg
  258. lw t1, 0(t1)
  259. addu t0, t0, t1
  260. /* Calculate this VPEs ID. If the core doesn't support MT use 0 */
  261. has_mt t6, 1f
  262. li t9, 0
  263. /* Find the number of VPEs present in the core */
  264. mfc0 t1, CP0_MVPCONF0
  265. srl t1, t1, MVPCONF0_PVPE_SHIFT
  266. andi t1, t1, MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT
  267. addi t1, t1, 1
  268. /* Calculate a mask for the VPE ID from EBase.CPUNum */
  269. clz t1, t1
  270. li t2, 31
  271. subu t1, t2, t1
  272. li t2, 1
  273. sll t1, t2, t1
  274. addiu t1, t1, -1
  275. /* Retrieve the VPE ID from EBase.CPUNum */
  276. mfc0 t9, $15, 1
  277. and t9, t9, t1
  278. 1: /* Calculate a pointer to this VPEs struct vpe_boot_config */
  279. li t1, VPEBOOTCFG_SIZE
  280. mul v0, t9, t1
  281. lw t7, COREBOOTCFG_VPECONFIG(t0)
  282. addu v0, v0, t7
  283. #ifdef CONFIG_MIPS_MT
  284. /* If the core doesn't support MT then return */
  285. bnez t6, 1f
  286. nop
  287. jr ra
  288. nop
  289. .set push
  290. .set mt
  291. 1: /* Enter VPE configuration state */
  292. dvpe
  293. la t1, 1f
  294. jr.hb t1
  295. nop
  296. 1: mfc0 t1, CP0_MVPCONTROL
  297. ori t1, t1, MVPCONTROL_VPC
  298. mtc0 t1, CP0_MVPCONTROL
  299. ehb
  300. /* Loop through each VPE */
  301. lw t6, COREBOOTCFG_VPEMASK(t0)
  302. move t8, t6
  303. li t5, 0
  304. /* Check whether the VPE should be running. If not, skip it */
  305. 1: andi t0, t6, 1
  306. beqz t0, 2f
  307. nop
  308. /* Operate on the appropriate TC */
  309. mfc0 t0, CP0_VPECONTROL
  310. ori t0, t0, VPECONTROL_TARGTC
  311. xori t0, t0, VPECONTROL_TARGTC
  312. or t0, t0, t5
  313. mtc0 t0, CP0_VPECONTROL
  314. ehb
  315. /* Skip the VPE if its TC is not halted */
  316. mftc0 t0, CP0_TCHALT
  317. beqz t0, 2f
  318. nop
  319. /* Calculate a pointer to the VPEs struct vpe_boot_config */
  320. li t0, VPEBOOTCFG_SIZE
  321. mul t0, t0, t5
  322. addu t0, t0, t7
  323. /* Set the TC restart PC */
  324. lw t1, VPEBOOTCFG_PC(t0)
  325. mttc0 t1, CP0_TCRESTART
  326. /* Set the TC stack pointer */
  327. lw t1, VPEBOOTCFG_SP(t0)
  328. mttgpr t1, sp
  329. /* Set the TC global pointer */
  330. lw t1, VPEBOOTCFG_GP(t0)
  331. mttgpr t1, gp
  332. /* Copy config from this VPE */
  333. mfc0 t0, CP0_CONFIG
  334. mttc0 t0, CP0_CONFIG
  335. /* Ensure no software interrupts are pending */
  336. mttc0 zero, CP0_CAUSE
  337. mttc0 zero, CP0_STATUS
  338. /* Set TC active, not interrupt exempt */
  339. mftc0 t0, CP0_TCSTATUS
  340. li t1, ~TCSTATUS_IXMT
  341. and t0, t0, t1
  342. ori t0, t0, TCSTATUS_A
  343. mttc0 t0, CP0_TCSTATUS
  344. /* Clear the TC halt bit */
  345. mttc0 zero, CP0_TCHALT
  346. /* Set VPE active */
  347. mftc0 t0, CP0_VPECONF0
  348. ori t0, t0, VPECONF0_VPA
  349. mttc0 t0, CP0_VPECONF0
  350. /* Next VPE */
  351. 2: srl t6, t6, 1
  352. addi t5, t5, 1
  353. bnez t6, 1b
  354. nop
  355. /* Leave VPE configuration state */
  356. mfc0 t1, CP0_MVPCONTROL
  357. xori t1, t1, MVPCONTROL_VPC
  358. mtc0 t1, CP0_MVPCONTROL
  359. ehb
  360. evpe
  361. /* Check whether this VPE is meant to be running */
  362. li t0, 1
  363. sll t0, t0, t9
  364. and t0, t0, t8
  365. bnez t0, 2f
  366. nop
  367. /* This VPE should be offline, halt the TC */
  368. li t0, TCHALT_H
  369. mtc0 t0, CP0_TCHALT
  370. la t0, 1f
  371. 1: jr.hb t0
  372. nop
  373. 2: .set pop
  374. #endif /* CONFIG_MIPS_MT */
  375. /* Return */
  376. jr ra
  377. nop
  378. END(mips_cps_boot_vpes)
  379. #if defined(CONFIG_MIPS_CPS_PM) && defined(CONFIG_CPU_PM)
  380. /* Calculate a pointer to this CPUs struct mips_static_suspend_state */
  381. .macro psstate dest
  382. .set push
  383. .set noat
  384. lw $1, TI_CPU(gp)
  385. sll $1, $1, LONGLOG
  386. la \dest, __per_cpu_offset
  387. addu $1, $1, \dest
  388. lw $1, 0($1)
  389. la \dest, cps_cpu_state
  390. addu \dest, \dest, $1
  391. .set pop
  392. .endm
  393. LEAF(mips_cps_pm_save)
  394. /* Save CPU state */
  395. SUSPEND_SAVE_REGS
  396. psstate t1
  397. SUSPEND_SAVE_STATIC
  398. jr v0
  399. nop
  400. END(mips_cps_pm_save)
  401. LEAF(mips_cps_pm_restore)
  402. /* Restore CPU state */
  403. psstate t1
  404. RESUME_RESTORE_STATIC
  405. RESUME_RESTORE_REGS_RETURN
  406. END(mips_cps_pm_restore)
  407. #endif /* CONFIG_MIPS_CPS_PM && CONFIG_CPU_PM */