cps-vec.S 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * Copyright (C) 2013 Imagination Technologies
  4. * Author: Paul Burton <paul.burton@mips.com>
  5. */
  6. #include <linux/init.h>
  7. #include <asm/addrspace.h>
  8. #include <asm/asm.h>
  9. #include <asm/asm-offsets.h>
  10. #include <asm/asmmacro.h>
  11. #include <asm/cacheops.h>
  12. #include <asm/eva.h>
  13. #include <asm/mipsregs.h>
  14. #include <asm/mipsmtregs.h>
  15. #include <asm/pm.h>
  16. #include <asm/smp-cps.h>
  17. #define GCR_CPC_BASE_OFS 0x0088
  18. #define GCR_CL_COHERENCE_OFS 0x2008
  19. #define GCR_CL_ID_OFS 0x2028
  20. #define CPC_CL_VC_STOP_OFS 0x2020
  21. #define CPC_CL_VC_RUN_OFS 0x2028
  22. .extern mips_cm_base
  23. .set noreorder
  24. #ifdef CONFIG_64BIT
  25. # define STATUS_BITDEPS ST0_KX
  26. #else
  27. # define STATUS_BITDEPS 0
  28. #endif
  29. #ifdef CONFIG_MIPS_CPS_NS16550
  30. #define DUMP_EXCEP(name) \
  31. PTR_LA a0, 8f; \
  32. jal mips_cps_bev_dump; \
  33. nop; \
  34. TEXT(name)
  35. #else /* !CONFIG_MIPS_CPS_NS16550 */
  36. #define DUMP_EXCEP(name)
  37. #endif /* !CONFIG_MIPS_CPS_NS16550 */
  38. /*
  39. * Set dest to non-zero if the core supports the MT ASE, else zero. If
  40. * MT is not supported then branch to nomt.
  41. */
  42. .macro has_mt dest, nomt
  43. mfc0 \dest, CP0_CONFIG, 1
  44. bgez \dest, \nomt
  45. mfc0 \dest, CP0_CONFIG, 2
  46. bgez \dest, \nomt
  47. mfc0 \dest, CP0_CONFIG, 3
  48. andi \dest, \dest, MIPS_CONF3_MT
  49. beqz \dest, \nomt
  50. nop
  51. .endm
  52. /*
  53. * Set dest to non-zero if the core supports MIPSr6 multithreading
  54. * (ie. VPs), else zero. If MIPSr6 multithreading is not supported then
  55. * branch to nomt.
  56. */
  57. .macro has_vp dest, nomt
  58. mfc0 \dest, CP0_CONFIG, 1
  59. bgez \dest, \nomt
  60. mfc0 \dest, CP0_CONFIG, 2
  61. bgez \dest, \nomt
  62. mfc0 \dest, CP0_CONFIG, 3
  63. bgez \dest, \nomt
  64. mfc0 \dest, CP0_CONFIG, 4
  65. bgez \dest, \nomt
  66. mfc0 \dest, CP0_CONFIG, 5
  67. andi \dest, \dest, MIPS_CONF5_VP
  68. beqz \dest, \nomt
  69. nop
  70. .endm
  71. LEAF(mips_cps_core_boot)
  72. /* Save CCA and GCR base */
  73. move s0, a0
  74. move s1, a1
  75. /* We don't know how to do coherence setup on earlier ISA */
  76. #if MIPS_ISA_REV > 0
  77. /* Skip cache & coherence setup if we're already coherent */
  78. lw s7, GCR_CL_COHERENCE_OFS(s1)
  79. bnez s7, 1f
  80. nop
  81. /* Initialize the L1 caches */
  82. jal mips_cps_cache_init
  83. nop
  84. /* Enter the coherent domain */
  85. li t0, 0xff
  86. sw t0, GCR_CL_COHERENCE_OFS(s1)
  87. ehb
  88. #endif /* MIPS_ISA_REV > 0 */
  89. /* Set Kseg0 CCA to that in s0 */
  90. 1: mfc0 t0, CP0_CONFIG
  91. ori t0, 0x7
  92. xori t0, 0x7
  93. or t0, t0, s0
  94. mtc0 t0, CP0_CONFIG
  95. ehb
  96. /* Jump to kseg0 */
  97. PTR_LA t0, 1f
  98. jr t0
  99. nop
  100. /*
  101. * We're up, cached & coherent. Perform any EVA initialization necessary
  102. * before we access memory.
  103. */
  104. 1: eva_init
  105. /* Retrieve boot configuration pointers */
  106. jal mips_cps_get_bootcfg
  107. nop
  108. /* Skip core-level init if we started up coherent */
  109. bnez s7, 1f
  110. nop
  111. /* Perform any further required core-level initialisation */
  112. jal mips_cps_core_init
  113. nop
  114. /*
  115. * Boot any other VPEs within this core that should be online, and
  116. * deactivate this VPE if it should be offline.
  117. */
  118. move a1, t9
  119. jal mips_cps_boot_vpes
  120. move a0, v0
  121. /* Off we go! */
  122. 1: PTR_L t1, VPEBOOTCFG_PC(v1)
  123. PTR_L gp, VPEBOOTCFG_GP(v1)
  124. PTR_L sp, VPEBOOTCFG_SP(v1)
  125. jr t1
  126. nop
  127. END(mips_cps_core_boot)
  128. __INIT
  129. LEAF(excep_tlbfill)
  130. DUMP_EXCEP("TLB Fill")
  131. b .
  132. nop
  133. END(excep_tlbfill)
  134. LEAF(excep_xtlbfill)
  135. DUMP_EXCEP("XTLB Fill")
  136. b .
  137. nop
  138. END(excep_xtlbfill)
  139. LEAF(excep_cache)
  140. DUMP_EXCEP("Cache")
  141. b .
  142. nop
  143. END(excep_cache)
  144. LEAF(excep_genex)
  145. DUMP_EXCEP("General")
  146. b .
  147. nop
  148. END(excep_genex)
  149. LEAF(excep_intex)
  150. DUMP_EXCEP("Interrupt")
  151. b .
  152. nop
  153. END(excep_intex)
  154. LEAF(excep_ejtag)
  155. PTR_LA k0, ejtag_debug_handler
  156. jr k0
  157. nop
  158. END(excep_ejtag)
  159. __FINIT
  160. LEAF(mips_cps_core_init)
  161. #ifdef CONFIG_MIPS_MT_SMP
  162. /* Check that the core implements the MT ASE */
  163. has_mt t0, 3f
  164. .set push
  165. .set MIPS_ISA_LEVEL_RAW
  166. .set mt
  167. /* Only allow 1 TC per VPE to execute... */
  168. dmt
  169. /* ...and for the moment only 1 VPE */
  170. dvpe
  171. PTR_LA t1, 1f
  172. jr.hb t1
  173. nop
  174. /* Enter VPE configuration state */
  175. 1: mfc0 t0, CP0_MVPCONTROL
  176. ori t0, t0, MVPCONTROL_VPC
  177. mtc0 t0, CP0_MVPCONTROL
  178. /* Retrieve the number of VPEs within the core */
  179. mfc0 t0, CP0_MVPCONF0
  180. srl t0, t0, MVPCONF0_PVPE_SHIFT
  181. andi t0, t0, (MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT)
  182. addiu ta3, t0, 1
  183. /* If there's only 1, we're done */
  184. beqz t0, 2f
  185. nop
  186. /* Loop through each VPE within this core */
  187. li ta1, 1
  188. 1: /* Operate on the appropriate TC */
  189. mtc0 ta1, CP0_VPECONTROL
  190. ehb
  191. /* Bind TC to VPE (1:1 TC:VPE mapping) */
  192. mttc0 ta1, CP0_TCBIND
  193. /* Set exclusive TC, non-active, master */
  194. li t0, VPECONF0_MVP
  195. sll t1, ta1, VPECONF0_XTC_SHIFT
  196. or t0, t0, t1
  197. mttc0 t0, CP0_VPECONF0
  198. /* Set TC non-active, non-allocatable */
  199. mttc0 zero, CP0_TCSTATUS
  200. /* Set TC halted */
  201. li t0, TCHALT_H
  202. mttc0 t0, CP0_TCHALT
  203. /* Next VPE */
  204. addiu ta1, ta1, 1
  205. slt t0, ta1, ta3
  206. bnez t0, 1b
  207. nop
  208. /* Leave VPE configuration state */
  209. 2: mfc0 t0, CP0_MVPCONTROL
  210. xori t0, t0, MVPCONTROL_VPC
  211. mtc0 t0, CP0_MVPCONTROL
  212. 3: .set pop
  213. #endif
  214. jr ra
  215. nop
  216. END(mips_cps_core_init)
  217. /**
  218. * mips_cps_get_bootcfg() - retrieve boot configuration pointers
  219. *
  220. * Returns: pointer to struct core_boot_config in v0, pointer to
  221. * struct vpe_boot_config in v1, VPE ID in t9
  222. */
  223. LEAF(mips_cps_get_bootcfg)
  224. /* Calculate a pointer to this cores struct core_boot_config */
  225. lw t0, GCR_CL_ID_OFS(s1)
  226. li t1, COREBOOTCFG_SIZE
  227. mul t0, t0, t1
  228. PTR_LA t1, mips_cps_core_bootcfg
  229. PTR_L t1, 0(t1)
  230. PTR_ADDU v0, t0, t1
  231. /* Calculate this VPEs ID. If the core doesn't support MT use 0 */
  232. li t9, 0
  233. #if defined(CONFIG_CPU_MIPSR6)
  234. has_vp ta2, 1f
  235. /*
  236. * Assume non-contiguous numbering. Perhaps some day we'll need
  237. * to handle contiguous VP numbering, but no such systems yet
  238. * exist.
  239. */
  240. mfc0 t9, CP0_GLOBALNUMBER
  241. andi t9, t9, MIPS_GLOBALNUMBER_VP
  242. #elif defined(CONFIG_MIPS_MT_SMP)
  243. has_mt ta2, 1f
  244. /* Find the number of VPEs present in the core */
  245. mfc0 t1, CP0_MVPCONF0
  246. srl t1, t1, MVPCONF0_PVPE_SHIFT
  247. andi t1, t1, MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT
  248. addiu t1, t1, 1
  249. /* Calculate a mask for the VPE ID from EBase.CPUNum */
  250. clz t1, t1
  251. li t2, 31
  252. subu t1, t2, t1
  253. li t2, 1
  254. sll t1, t2, t1
  255. addiu t1, t1, -1
  256. /* Retrieve the VPE ID from EBase.CPUNum */
  257. mfc0 t9, $15, 1
  258. and t9, t9, t1
  259. #endif
  260. 1: /* Calculate a pointer to this VPEs struct vpe_boot_config */
  261. li t1, VPEBOOTCFG_SIZE
  262. mul v1, t9, t1
  263. PTR_L ta3, COREBOOTCFG_VPECONFIG(v0)
  264. PTR_ADDU v1, v1, ta3
  265. jr ra
  266. nop
  267. END(mips_cps_get_bootcfg)
  268. LEAF(mips_cps_boot_vpes)
  269. lw ta2, COREBOOTCFG_VPEMASK(a0)
  270. PTR_L ta3, COREBOOTCFG_VPECONFIG(a0)
  271. #if defined(CONFIG_CPU_MIPSR6)
  272. has_vp t0, 5f
  273. /* Find base address of CPC */
  274. PTR_LA t1, mips_gcr_base
  275. PTR_L t1, 0(t1)
  276. PTR_L t1, GCR_CPC_BASE_OFS(t1)
  277. PTR_LI t2, ~0x7fff
  278. and t1, t1, t2
  279. PTR_LI t2, UNCAC_BASE
  280. PTR_ADD t1, t1, t2
  281. /* Start any other VPs that ought to be running */
  282. PTR_S ta2, CPC_CL_VC_RUN_OFS(t1)
  283. /* Ensure this VP stops running if it shouldn't be */
  284. not ta2
  285. PTR_S ta2, CPC_CL_VC_STOP_OFS(t1)
  286. ehb
  287. #elif defined(CONFIG_MIPS_MT)
  288. /* If the core doesn't support MT then return */
  289. has_mt t0, 5f
  290. /* Enter VPE configuration state */
  291. .set push
  292. .set MIPS_ISA_LEVEL_RAW
  293. .set mt
  294. dvpe
  295. .set pop
  296. PTR_LA t1, 1f
  297. jr.hb t1
  298. nop
  299. 1: mfc0 t1, CP0_MVPCONTROL
  300. ori t1, t1, MVPCONTROL_VPC
  301. mtc0 t1, CP0_MVPCONTROL
  302. ehb
  303. /* Loop through each VPE */
  304. move t8, ta2
  305. li ta1, 0
  306. /* Check whether the VPE should be running. If not, skip it */
  307. 1: andi t0, ta2, 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, ta1
  315. mtc0 t0, CP0_VPECONTROL
  316. ehb
  317. .set push
  318. .set MIPS_ISA_LEVEL_RAW
  319. .set mt
  320. /* Skip the VPE if its TC is not halted */
  321. mftc0 t0, CP0_TCHALT
  322. beqz t0, 2f
  323. nop
  324. /* Calculate a pointer to the VPEs struct vpe_boot_config */
  325. li t0, VPEBOOTCFG_SIZE
  326. mul t0, t0, ta1
  327. PTR_ADDU t0, t0, ta3
  328. /* Set the TC restart PC */
  329. lw t1, VPEBOOTCFG_PC(t0)
  330. mttc0 t1, CP0_TCRESTART
  331. /* Set the TC stack pointer */
  332. lw t1, VPEBOOTCFG_SP(t0)
  333. mttgpr t1, sp
  334. /* Set the TC global pointer */
  335. lw t1, VPEBOOTCFG_GP(t0)
  336. mttgpr t1, gp
  337. /* Copy config from this VPE */
  338. mfc0 t0, CP0_CONFIG
  339. mttc0 t0, CP0_CONFIG
  340. /*
  341. * Copy the EVA config from this VPE if the CPU supports it.
  342. * CONFIG3 must exist to be running MT startup - just read it.
  343. */
  344. mfc0 t0, CP0_CONFIG, 3
  345. and t0, t0, MIPS_CONF3_SC
  346. beqz t0, 3f
  347. nop
  348. mfc0 t0, CP0_SEGCTL0
  349. mttc0 t0, CP0_SEGCTL0
  350. mfc0 t0, CP0_SEGCTL1
  351. mttc0 t0, CP0_SEGCTL1
  352. mfc0 t0, CP0_SEGCTL2
  353. mttc0 t0, CP0_SEGCTL2
  354. 3:
  355. /* Ensure no software interrupts are pending */
  356. mttc0 zero, CP0_CAUSE
  357. mttc0 zero, CP0_STATUS
  358. /* Set TC active, not interrupt exempt */
  359. mftc0 t0, CP0_TCSTATUS
  360. li t1, ~TCSTATUS_IXMT
  361. and t0, t0, t1
  362. ori t0, t0, TCSTATUS_A
  363. mttc0 t0, CP0_TCSTATUS
  364. /* Clear the TC halt bit */
  365. mttc0 zero, CP0_TCHALT
  366. /* Set VPE active */
  367. mftc0 t0, CP0_VPECONF0
  368. ori t0, t0, VPECONF0_VPA
  369. mttc0 t0, CP0_VPECONF0
  370. /* Next VPE */
  371. 2: srl ta2, ta2, 1
  372. addiu ta1, ta1, 1
  373. bnez ta2, 1b
  374. nop
  375. /* Leave VPE configuration state */
  376. mfc0 t1, CP0_MVPCONTROL
  377. xori t1, t1, MVPCONTROL_VPC
  378. mtc0 t1, CP0_MVPCONTROL
  379. ehb
  380. evpe
  381. .set pop
  382. /* Check whether this VPE is meant to be running */
  383. li t0, 1
  384. sll t0, t0, a1
  385. and t0, t0, t8
  386. bnez t0, 2f
  387. nop
  388. /* This VPE should be offline, halt the TC */
  389. li t0, TCHALT_H
  390. mtc0 t0, CP0_TCHALT
  391. PTR_LA t0, 1f
  392. 1: jr.hb t0
  393. nop
  394. 2:
  395. #endif /* CONFIG_MIPS_MT_SMP */
  396. /* Return */
  397. 5: jr ra
  398. nop
  399. END(mips_cps_boot_vpes)
  400. #if MIPS_ISA_REV > 0
  401. LEAF(mips_cps_cache_init)
  402. /*
  403. * Clear the bits used to index the caches. Note that the architecture
  404. * dictates that writing to any of TagLo or TagHi selects 0 or 2 should
  405. * be valid for all MIPS32 CPUs, even those for which said writes are
  406. * unnecessary.
  407. */
  408. mtc0 zero, CP0_TAGLO, 0
  409. mtc0 zero, CP0_TAGHI, 0
  410. mtc0 zero, CP0_TAGLO, 2
  411. mtc0 zero, CP0_TAGHI, 2
  412. ehb
  413. /* Primary cache configuration is indicated by Config1 */
  414. mfc0 v0, CP0_CONFIG, 1
  415. /* Detect I-cache line size */
  416. _EXT t0, v0, MIPS_CONF1_IL_SHF, MIPS_CONF1_IL_SZ
  417. beqz t0, icache_done
  418. li t1, 2
  419. sllv t0, t1, t0
  420. /* Detect I-cache size */
  421. _EXT t1, v0, MIPS_CONF1_IS_SHF, MIPS_CONF1_IS_SZ
  422. xori t2, t1, 0x7
  423. beqz t2, 1f
  424. li t3, 32
  425. addiu t1, t1, 1
  426. sllv t1, t3, t1
  427. 1: /* At this point t1 == I-cache sets per way */
  428. _EXT t2, v0, MIPS_CONF1_IA_SHF, MIPS_CONF1_IA_SZ
  429. addiu t2, t2, 1
  430. mul t1, t1, t0
  431. mul t1, t1, t2
  432. li a0, CKSEG0
  433. PTR_ADD a1, a0, t1
  434. 1: cache Index_Store_Tag_I, 0(a0)
  435. PTR_ADD a0, a0, t0
  436. bne a0, a1, 1b
  437. nop
  438. icache_done:
  439. /* Detect D-cache line size */
  440. _EXT t0, v0, MIPS_CONF1_DL_SHF, MIPS_CONF1_DL_SZ
  441. beqz t0, dcache_done
  442. li t1, 2
  443. sllv t0, t1, t0
  444. /* Detect D-cache size */
  445. _EXT t1, v0, MIPS_CONF1_DS_SHF, MIPS_CONF1_DS_SZ
  446. xori t2, t1, 0x7
  447. beqz t2, 1f
  448. li t3, 32
  449. addiu t1, t1, 1
  450. sllv t1, t3, t1
  451. 1: /* At this point t1 == D-cache sets per way */
  452. _EXT t2, v0, MIPS_CONF1_DA_SHF, MIPS_CONF1_DA_SZ
  453. addiu t2, t2, 1
  454. mul t1, t1, t0
  455. mul t1, t1, t2
  456. li a0, CKSEG0
  457. PTR_ADDU a1, a0, t1
  458. PTR_SUBU a1, a1, t0
  459. 1: cache Index_Store_Tag_D, 0(a0)
  460. bne a0, a1, 1b
  461. PTR_ADD a0, a0, t0
  462. dcache_done:
  463. jr ra
  464. nop
  465. END(mips_cps_cache_init)
  466. #endif /* MIPS_ISA_REV > 0 */
  467. #if defined(CONFIG_MIPS_CPS_PM) && defined(CONFIG_CPU_PM)
  468. /* Calculate a pointer to this CPUs struct mips_static_suspend_state */
  469. .macro psstate dest
  470. .set push
  471. .set noat
  472. lw $1, TI_CPU(gp)
  473. sll $1, $1, LONGLOG
  474. PTR_LA \dest, __per_cpu_offset
  475. PTR_ADDU $1, $1, \dest
  476. lw $1, 0($1)
  477. PTR_LA \dest, cps_cpu_state
  478. PTR_ADDU \dest, \dest, $1
  479. .set pop
  480. .endm
  481. LEAF(mips_cps_pm_save)
  482. /* Save CPU state */
  483. SUSPEND_SAVE_REGS
  484. psstate t1
  485. SUSPEND_SAVE_STATIC
  486. jr v0
  487. nop
  488. END(mips_cps_pm_save)
  489. LEAF(mips_cps_pm_restore)
  490. /* Restore CPU state */
  491. psstate t1
  492. RESUME_RESTORE_STATIC
  493. RESUME_RESTORE_REGS_RETURN
  494. END(mips_cps_pm_restore)
  495. #endif /* CONFIG_MIPS_CPS_PM && CONFIG_CPU_PM */