cps-vec.S 9.3 KB

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