cps-vec.S 12 KB

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