cps-vec.S 12 KB

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