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