cps-vec.S 12 KB

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