bmips_5xxx_init.S 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2011-2012 by Broadcom Corporation
  7. *
  8. * Init for bmips 5000.
  9. * Used to init second core in dual core 5000's.
  10. */
  11. #include <linux/init.h>
  12. #include <asm/asm.h>
  13. #include <asm/asmmacro.h>
  14. #include <asm/cacheops.h>
  15. #include <asm/regdef.h>
  16. #include <asm/mipsregs.h>
  17. #include <asm/stackframe.h>
  18. #include <asm/addrspace.h>
  19. #include <asm/hazards.h>
  20. #include <asm/bmips.h>
  21. #ifdef CONFIG_CPU_BMIPS5000
  22. #define cacheop(kva, size, linesize, op) \
  23. .set noreorder ; \
  24. addu t1, kva, size ; \
  25. subu t2, linesize, 1 ; \
  26. not t2 ; \
  27. and t0, kva, t2 ; \
  28. addiu t1, t1, -1 ; \
  29. and t1, t2 ; \
  30. 9: cache op, 0(t0) ; \
  31. bne t0, t1, 9b ; \
  32. addu t0, linesize ; \
  33. .set reorder ;
  34. #define IS_SHIFT 22
  35. #define IL_SHIFT 19
  36. #define IA_SHIFT 16
  37. #define DS_SHIFT 13
  38. #define DL_SHIFT 10
  39. #define DA_SHIFT 7
  40. #define IS_MASK 7
  41. #define IL_MASK 7
  42. #define IA_MASK 7
  43. #define DS_MASK 7
  44. #define DL_MASK 7
  45. #define DA_MASK 7
  46. #define ICE_MASK 0x80000000
  47. #define DCE_MASK 0x40000000
  48. #define CP0_BRCM_CONFIG0 $22, 0
  49. #define CP0_BRCM_MODE $22, 1
  50. #define CP0_CONFIG_K0_MASK 7
  51. #define CP0_ICACHE_TAG_LO $28
  52. #define CP0_ICACHE_DATA_LO $28, 1
  53. #define CP0_DCACHE_TAG_LO $28, 2
  54. #define CP0_D_SEC_CACHE_DATA_LO $28, 3
  55. #define CP0_ICACHE_TAG_HI $29
  56. #define CP0_ICACHE_DATA_HI $29, 1
  57. #define CP0_DCACHE_TAG_HI $29, 2
  58. #define CP0_BRCM_MODE_Luc_MASK (1 << 11)
  59. #define CP0_BRCM_CONFIG0_CWF_MASK (1 << 20)
  60. #define CP0_BRCM_CONFIG0_TSE_MASK (1 << 19)
  61. #define CP0_BRCM_MODE_SET_MASK (1 << 7)
  62. #define CP0_BRCM_MODE_ClkRATIO_MASK (7 << 4)
  63. #define CP0_BRCM_MODE_BrPRED_MASK (3 << 24)
  64. #define CP0_BRCM_MODE_BrPRED_SHIFT 24
  65. #define CP0_BRCM_MODE_BrHIST_MASK (0x1f << 20)
  66. #define CP0_BRCM_MODE_BrHIST_SHIFT 20
  67. /* ZSC L2 Cache Register Access Register Definitions */
  68. #define BRCM_ZSC_ALL_REGS_SELECT 0x7 << 24
  69. #define BRCM_ZSC_CONFIG_REG 0 << 3
  70. #define BRCM_ZSC_REQ_BUFFER_REG 2 << 3
  71. #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG0 4 << 3
  72. #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG1 6 << 3
  73. #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG2 8 << 3
  74. #define BRCM_ZSC_SCB0_ADDR_MAPPING_REG0 0xa << 3
  75. #define BRCM_ZSC_SCB0_ADDR_MAPPING_REG1 0xc << 3
  76. #define BRCM_ZSC_SCB1_ADDR_MAPPING_REG0 0xe << 3
  77. #define BRCM_ZSC_SCB1_ADDR_MAPPING_REG1 0x10 << 3
  78. #define BRCM_ZSC_CONFIG_LMB1En 1 << (15)
  79. #define BRCM_ZSC_CONFIG_LMB0En 1 << (14)
  80. /* branch predition values */
  81. #define BRCM_BrPRED_ALL_TAKEN (0x0)
  82. #define BRCM_BrPRED_ALL_NOT_TAKEN (0x1)
  83. #define BRCM_BrPRED_BHT_ENABLE (0x2)
  84. #define BRCM_BrPRED_PREDICT_BACKWARD (0x3)
  85. .align 2
  86. /*
  87. * Function: size_i_cache
  88. * Arguments: None
  89. * Returns: v0 = i cache size, v1 = I cache line size
  90. * Description: compute the I-cache size and I-cache line size
  91. * Trashes: v0, v1, a0, t0
  92. *
  93. * pseudo code:
  94. *
  95. */
  96. LEAF(size_i_cache)
  97. .set noreorder
  98. mfc0 a0, CP0_CONFIG, 1
  99. move t0, a0
  100. /*
  101. * Determine sets per way: IS
  102. *
  103. * This field contains the number of sets (i.e., indices) per way of
  104. * the instruction cache:
  105. * i) 0x0: 64, ii) 0x1: 128, iii) 0x2: 256, iv) 0x3: 512, v) 0x4: 1k
  106. * vi) 0x5 - 0x7: Reserved.
  107. */
  108. srl a0, a0, IS_SHIFT
  109. and a0, a0, IS_MASK
  110. /* sets per way = (64<<IS) */
  111. li v0, 0x40
  112. sllv v0, v0, a0
  113. /*
  114. * Determine line size
  115. *
  116. * This field contains the line size of the instruction cache:
  117. * i) 0x0: No I-cache present, i) 0x3: 16 bytes, ii) 0x4: 32 bytes, iii)
  118. * 0x5: 64 bytes, iv) the rest: Reserved.
  119. */
  120. move a0, t0
  121. srl a0, a0, IL_SHIFT
  122. and a0, a0, IL_MASK
  123. beqz a0, no_i_cache
  124. nop
  125. /* line size = 2 ^ (IL+1) */
  126. addi a0, a0, 1
  127. li v1, 1
  128. sll v1, v1, a0
  129. /* v0 now have sets per way, multiply it by line size now
  130. * that will give the set size
  131. */
  132. sll v0, v0, a0
  133. /*
  134. * Determine set associativity
  135. *
  136. * This field contains the set associativity of the instruction cache.
  137. * i) 0x0: Direct mapped, ii) 0x1: 2-way, iii) 0x2: 3-way, iv) 0x3:
  138. * 4-way, v) 0x4 - 0x7: Reserved.
  139. */
  140. move a0, t0
  141. srl a0, a0, IA_SHIFT
  142. and a0, a0, IA_MASK
  143. addi a0, a0, 0x1
  144. /* v0 has the set size, multiply it by
  145. * set associativiy, to get the cache size
  146. */
  147. multu v0, a0 /*multu is interlocked, so no need to insert nops */
  148. mflo v0
  149. b 1f
  150. nop
  151. no_i_cache:
  152. move v0, zero
  153. move v1, zero
  154. 1:
  155. jr ra
  156. nop
  157. .set reorder
  158. END(size_i_cache)
  159. /*
  160. * Function: size_d_cache
  161. * Arguments: None
  162. * Returns: v0 = d cache size, v1 = d cache line size
  163. * Description: compute the D-cache size and D-cache line size.
  164. * Trashes: v0, v1, a0, t0
  165. *
  166. */
  167. LEAF(size_d_cache)
  168. .set noreorder
  169. mfc0 a0, CP0_CONFIG, 1
  170. move t0, a0
  171. /*
  172. * Determine sets per way: IS
  173. *
  174. * This field contains the number of sets (i.e., indices) per way of
  175. * the instruction cache:
  176. * i) 0x0: 64, ii) 0x1: 128, iii) 0x2: 256, iv) 0x3: 512, v) 0x4: 1k
  177. * vi) 0x5 - 0x7: Reserved.
  178. */
  179. srl a0, a0, DS_SHIFT
  180. and a0, a0, DS_MASK
  181. /* sets per way = (64<<IS) */
  182. li v0, 0x40
  183. sllv v0, v0, a0
  184. /*
  185. * Determine line size
  186. *
  187. * This field contains the line size of the instruction cache:
  188. * i) 0x0: No I-cache present, i) 0x3: 16 bytes, ii) 0x4: 32 bytes, iii)
  189. * 0x5: 64 bytes, iv) the rest: Reserved.
  190. */
  191. move a0, t0
  192. srl a0, a0, DL_SHIFT
  193. and a0, a0, DL_MASK
  194. beqz a0, no_d_cache
  195. nop
  196. /* line size = 2 ^ (IL+1) */
  197. addi a0, a0, 1
  198. li v1, 1
  199. sll v1, v1, a0
  200. /* v0 now have sets per way, multiply it by line size now
  201. * that will give the set size
  202. */
  203. sll v0, v0, a0
  204. /* determine set associativity
  205. *
  206. * This field contains the set associativity of the instruction cache.
  207. * i) 0x0: Direct mapped, ii) 0x1: 2-way, iii) 0x2: 3-way, iv) 0x3:
  208. * 4-way, v) 0x4 - 0x7: Reserved.
  209. */
  210. move a0, t0
  211. srl a0, a0, DA_SHIFT
  212. and a0, a0, DA_MASK
  213. addi a0, a0, 0x1
  214. /* v0 has the set size, multiply it by
  215. * set associativiy, to get the cache size
  216. */
  217. multu v0, a0 /*multu is interlocked, so no need to insert nops */
  218. mflo v0
  219. b 1f
  220. nop
  221. no_d_cache:
  222. move v0, zero
  223. move v1, zero
  224. 1:
  225. jr ra
  226. nop
  227. .set reorder
  228. END(size_d_cache)
  229. /*
  230. * Function: enable_ID
  231. * Arguments: None
  232. * Returns: None
  233. * Description: Enable I and D caches, initialize I and D-caches, also set
  234. * hardware delay for d-cache (TP0).
  235. * Trashes: t0
  236. *
  237. */
  238. .global enable_ID
  239. .ent enable_ID
  240. .set noreorder
  241. enable_ID:
  242. mfc0 t0, CP0_BRCM_CONFIG0
  243. or t0, t0, (ICE_MASK | DCE_MASK)
  244. mtc0 t0, CP0_BRCM_CONFIG0
  245. jr ra
  246. nop
  247. .end enable_ID
  248. .set reorder
  249. /*
  250. * Function: l1_init
  251. * Arguments: None
  252. * Returns: None
  253. * Description: Enable I and D caches, and initialize I and D-caches
  254. * Trashes: a0, v0, v1, t0, t1, t2, t8
  255. *
  256. */
  257. .globl l1_init
  258. .ent l1_init
  259. .set noreorder
  260. l1_init:
  261. /* save return address */
  262. move t8, ra
  263. /* initialize I and D cache Data and Tag registers. */
  264. mtc0 zero, CP0_ICACHE_TAG_LO
  265. mtc0 zero, CP0_ICACHE_TAG_HI
  266. mtc0 zero, CP0_ICACHE_DATA_LO
  267. mtc0 zero, CP0_ICACHE_DATA_HI
  268. mtc0 zero, CP0_DCACHE_TAG_LO
  269. mtc0 zero, CP0_DCACHE_TAG_HI
  270. /* Enable Caches before Clearing. If the caches are disabled
  271. * then the cache operations to clear the cache will be ignored
  272. */
  273. jal enable_ID
  274. nop
  275. jal size_i_cache /* v0 = i-cache size, v1 = i-cache line size */
  276. nop
  277. /* run uncached in kseg 1 */
  278. la k0, 1f
  279. lui k1, 0x2000
  280. or k0, k1, k0
  281. jr k0
  282. nop
  283. 1:
  284. /*
  285. * set K0 cache mode
  286. */
  287. mfc0 t0, CP0_CONFIG
  288. and t0, t0, ~CP0_CONFIG_K0_MASK
  289. or t0, t0, 3 /* Write Back mode */
  290. mtc0 t0, CP0_CONFIG
  291. /*
  292. * Initialize instruction cache.
  293. */
  294. li a0, KSEG0
  295. cacheop(a0, v0, v1, Index_Store_Tag_I)
  296. /*
  297. * Now we can run from I-$, kseg 0
  298. */
  299. la k0, 1f
  300. lui k1, 0x2000
  301. or k0, k1, k0
  302. xor k0, k1, k0
  303. jr k0
  304. nop
  305. 1:
  306. /*
  307. * Initialize data cache.
  308. */
  309. jal size_d_cache /* v0 = d-cache size, v1 = d-cache line size */
  310. nop
  311. li a0, KSEG0
  312. cacheop(a0, v0, v1, Index_Store_Tag_D)
  313. jr t8
  314. nop
  315. .end l1_init
  316. .set reorder
  317. /*
  318. * Function: set_other_config
  319. * Arguments: none
  320. * Returns: None
  321. * Description: initialize other remainder configuration to defaults.
  322. * Trashes: t0, t1
  323. *
  324. * pseudo code:
  325. *
  326. */
  327. LEAF(set_other_config)
  328. .set noreorder
  329. /* enable Bus error for I-fetch */
  330. mfc0 t0, CP0_CACHEERR, 0
  331. li t1, 0x4
  332. or t0, t1
  333. mtc0 t0, CP0_CACHEERR, 0
  334. /* enable Bus error for Load */
  335. mfc0 t0, CP0_CACHEERR, 1
  336. li t1, 0x4
  337. or t0, t1
  338. mtc0 t0, CP0_CACHEERR, 1
  339. /* enable Bus Error for Store */
  340. mfc0 t0, CP0_CACHEERR, 2
  341. li t1, 0x4
  342. or t0, t1
  343. mtc0 t0, CP0_CACHEERR, 2
  344. jr ra
  345. nop
  346. .set reorder
  347. END(set_other_config)
  348. /*
  349. * Function: set_branch_pred
  350. * Arguments: none
  351. * Returns: None
  352. * Description:
  353. * Trashes: t0, t1
  354. *
  355. * pseudo code:
  356. *
  357. */
  358. LEAF(set_branch_pred)
  359. .set noreorder
  360. mfc0 t0, CP0_BRCM_MODE
  361. li t1, ~(CP0_BRCM_MODE_BrPRED_MASK | CP0_BRCM_MODE_BrHIST_MASK )
  362. and t0, t0, t1
  363. /* enable Branch prediction */
  364. li t1, BRCM_BrPRED_BHT_ENABLE
  365. sll t1, CP0_BRCM_MODE_BrPRED_SHIFT
  366. or t0, t0, t1
  367. /* set history count to 8 */
  368. li t1, 8
  369. sll t1, CP0_BRCM_MODE_BrHIST_SHIFT
  370. or t0, t0, t1
  371. mtc0 t0, CP0_BRCM_MODE
  372. jr ra
  373. nop
  374. .set reorder
  375. END(set_branch_pred)
  376. /*
  377. * Function: set_luc
  378. * Arguments: set link uncached.
  379. * Returns: None
  380. * Description:
  381. * Trashes: t0, t1
  382. *
  383. */
  384. LEAF(set_luc)
  385. .set noreorder
  386. mfc0 t0, CP0_BRCM_MODE
  387. li t1, ~(CP0_BRCM_MODE_Luc_MASK)
  388. and t0, t0, t1
  389. /* set Luc */
  390. ori t0, t0, CP0_BRCM_MODE_Luc_MASK
  391. mtc0 t0, CP0_BRCM_MODE
  392. jr ra
  393. nop
  394. .set reorder
  395. END(set_luc)
  396. /*
  397. * Function: set_cwf_tse
  398. * Arguments: set CWF and TSE bits
  399. * Returns: None
  400. * Description:
  401. * Trashes: t0, t1
  402. *
  403. */
  404. LEAF(set_cwf_tse)
  405. .set noreorder
  406. mfc0 t0, CP0_BRCM_CONFIG0
  407. li t1, (CP0_BRCM_CONFIG0_CWF_MASK | CP0_BRCM_CONFIG0_TSE_MASK)
  408. or t0, t0, t1
  409. mtc0 t0, CP0_BRCM_CONFIG0
  410. jr ra
  411. nop
  412. .set reorder
  413. END(set_cwf_tse)
  414. /*
  415. * Function: set_clock_ratio
  416. * Arguments: set clock ratio specified by a0
  417. * Returns: None
  418. * Description:
  419. * Trashes: v0, v1, a0, a1
  420. *
  421. * pseudo code:
  422. *
  423. */
  424. LEAF(set_clock_ratio)
  425. .set noreorder
  426. mfc0 t0, CP0_BRCM_MODE
  427. li t1, ~(CP0_BRCM_MODE_SET_MASK | CP0_BRCM_MODE_ClkRATIO_MASK)
  428. and t0, t0, t1
  429. li t1, CP0_BRCM_MODE_SET_MASK
  430. or t0, t0, t1
  431. or t0, t0, a0
  432. mtc0 t0, CP0_BRCM_MODE
  433. jr ra
  434. nop
  435. .set reorder
  436. END(set_clock_ratio)
  437. /*
  438. * Function: set_zephyr
  439. * Arguments: None
  440. * Returns: None
  441. * Description: Set any zephyr bits
  442. * Trashes: t0 & t1
  443. *
  444. */
  445. LEAF(set_zephyr)
  446. .set noreorder
  447. /* enable read/write of CP0 #22 sel. 8 */
  448. li t0, 0x5a455048
  449. .word 0x4088b00f /* mtc0 t0, $22, 15 */
  450. .word 0x4008b008 /* mfc0 t0, $22, 8 */
  451. li t1, 0x09008000 /* turn off pref, jtb */
  452. or t0, t0, t1
  453. .word 0x4088b008 /* mtc0 t0, $22, 8 */
  454. sync
  455. /* disable read/write of CP0 #22 sel 8 */
  456. li t0, 0x0
  457. .word 0x4088b00f /* mtc0 t0, $22, 15 */
  458. jr ra
  459. nop
  460. .set reorder
  461. END(set_zephyr)
  462. /*
  463. * Function: set_llmb
  464. * Arguments: a0=0 disable llmb, a0=1 enables llmb
  465. * Returns: None
  466. * Description:
  467. * Trashes: t0, t1, t2
  468. *
  469. * pseudo code:
  470. *
  471. */
  472. LEAF(set_llmb)
  473. .set noreorder
  474. li t2, 0x90000000 | BRCM_ZSC_ALL_REGS_SELECT | BRCM_ZSC_CONFIG_REG
  475. sync
  476. cache 0x7, 0x0(t2)
  477. sync
  478. mfc0 t0, CP0_D_SEC_CACHE_DATA_LO
  479. li t1, ~(BRCM_ZSC_CONFIG_LMB1En | BRCM_ZSC_CONFIG_LMB0En)
  480. and t0, t0, t1
  481. beqz a0, svlmb
  482. nop
  483. enable_lmb:
  484. li t1, (BRCM_ZSC_CONFIG_LMB1En | BRCM_ZSC_CONFIG_LMB0En)
  485. or t0, t0, t1
  486. svlmb:
  487. mtc0 t0, CP0_D_SEC_CACHE_DATA_LO
  488. sync
  489. cache 0xb, 0x0(t2)
  490. sync
  491. jr ra
  492. nop
  493. .set reorder
  494. END(set_llmb)
  495. /*
  496. * Function: core_init
  497. * Arguments: none
  498. * Returns: None
  499. * Description: initialize core related configuration
  500. * Trashes: v0,v1,a0,a1,t8
  501. *
  502. * pseudo code:
  503. *
  504. */
  505. .globl core_init
  506. .ent core_init
  507. .set noreorder
  508. core_init:
  509. move t8, ra
  510. /* set Zephyr bits. */
  511. bal set_zephyr
  512. nop
  513. #if ENABLE_FPU==1
  514. /* initialize the Floating point unit (both TPs) */
  515. bal init_fpu
  516. nop
  517. #endif
  518. /* set low latency memory bus */
  519. li a0, 1
  520. bal set_llmb
  521. nop
  522. /* set branch prediction (TP0 only) */
  523. bal set_branch_pred
  524. nop
  525. /* set link uncached */
  526. bal set_luc
  527. nop
  528. /* set CWF and TSE */
  529. bal set_cwf_tse
  530. nop
  531. /*
  532. *set clock ratio by setting 1 to 'set'
  533. * and 0 to ClkRatio, (TP0 only)
  534. */
  535. li a0, 0
  536. bal set_clock_ratio
  537. nop
  538. /* set other configuration to defaults */
  539. bal set_other_config
  540. nop
  541. move ra, t8
  542. jr ra
  543. nop
  544. .set reorder
  545. .end core_init
  546. /*
  547. * Function: clear_jump_target_buffer
  548. * Arguments: None
  549. * Returns: None
  550. * Description:
  551. * Trashes: t0, t1, t2
  552. *
  553. */
  554. #define RESET_CALL_RETURN_STACK_THIS_THREAD (0x06<<16)
  555. #define RESET_JUMP_TARGET_BUFFER_THIS_THREAD (0x04<<16)
  556. #define JTB_CS_CNTL_MASK (0xFF<<16)
  557. .globl clear_jump_target_buffer
  558. .ent clear_jump_target_buffer
  559. .set noreorder
  560. clear_jump_target_buffer:
  561. mfc0 t0, $22, 2
  562. nop
  563. nop
  564. li t1, ~JTB_CS_CNTL_MASK
  565. and t0, t0, t1
  566. li t2, RESET_CALL_RETURN_STACK_THIS_THREAD
  567. or t0, t0, t2
  568. mtc0 t0, $22, 2
  569. nop
  570. nop
  571. and t0, t0, t1
  572. li t2, RESET_JUMP_TARGET_BUFFER_THIS_THREAD
  573. or t0, t0, t2
  574. mtc0 t0, $22, 2
  575. nop
  576. nop
  577. jr ra
  578. nop
  579. .end clear_jump_target_buffer
  580. .set reorder
  581. /*
  582. * Function: bmips_cache_init
  583. * Arguments: None
  584. * Returns: None
  585. * Description: Enable I and D caches, and initialize I and D-caches
  586. * Trashes: v0, v1, t0, t1, t2, t5, t7, t8
  587. *
  588. */
  589. .globl bmips_5xxx_init
  590. .ent bmips_5xxx_init
  591. .set noreorder
  592. bmips_5xxx_init:
  593. /* save return address and A0 */
  594. move t7, ra
  595. move t5, a0
  596. jal l1_init
  597. nop
  598. jal core_init
  599. nop
  600. jal clear_jump_target_buffer
  601. nop
  602. mtc0 zero, CP0_CAUSE
  603. move a0, t5
  604. jr t7
  605. nop
  606. .end bmips_5xxx_init
  607. .set reorder
  608. #endif