Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
[cascardo/linux.git] / arch / mips / kernel / cps-vec.S
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
11 #include <asm/addrspace.h>
12 #include <asm/asm.h>
13 #include <asm/asm-offsets.h>
14 #include <asm/asmmacro.h>
15 #include <asm/cacheops.h>
16 #include <asm/mipsregs.h>
17
18 #define GCR_CL_COHERENCE_OFS 0x2008
19
20 .section .text.cps-vec
21 .balign 0x1000
22 .set noreorder
23
24 LEAF(mips_cps_core_entry)
25         /*
26          * These first 8 bytes will be patched by cps_smp_setup to load the
27          * base address of the CM GCRs into register v1.
28          */
29         .quad   0
30
31         /* Check whether we're here due to an NMI */
32         mfc0    k0, CP0_STATUS
33         and     k0, k0, ST0_NMI
34         beqz    k0, not_nmi
35          nop
36
37         /* This is an NMI */
38         la      k0, nmi_handler
39         jr      k0
40          nop
41
42 not_nmi:
43         /* Setup Cause */
44         li      t0, CAUSEF_IV
45         mtc0    t0, CP0_CAUSE
46
47         /* Setup Status */
48         li      t0, ST0_CU1 | ST0_CU0
49         mtc0    t0, CP0_STATUS
50
51         /*
52          * Clear the bits used to index the caches. Note that the architecture
53          * dictates that writing to any of TagLo or TagHi selects 0 or 2 should
54          * be valid for all MIPS32 CPUs, even those for which said writes are
55          * unnecessary.
56          */
57         mtc0    zero, CP0_TAGLO, 0
58         mtc0    zero, CP0_TAGHI, 0
59         mtc0    zero, CP0_TAGLO, 2
60         mtc0    zero, CP0_TAGHI, 2
61         ehb
62
63         /* Primary cache configuration is indicated by Config1 */
64         mfc0    v0, CP0_CONFIG, 1
65
66         /* Detect I-cache line size */
67         _EXT    t0, v0, MIPS_CONF1_IL_SHF, MIPS_CONF1_IL_SZ
68         beqz    t0, icache_done
69          li     t1, 2
70         sllv    t0, t1, t0
71
72         /* Detect I-cache size */
73         _EXT    t1, v0, MIPS_CONF1_IS_SHF, MIPS_CONF1_IS_SZ
74         xori    t2, t1, 0x7
75         beqz    t2, 1f
76          li     t3, 32
77         addi    t1, t1, 1
78         sllv    t1, t3, t1
79 1:      /* At this point t1 == I-cache sets per way */
80         _EXT    t2, v0, MIPS_CONF1_IA_SHF, MIPS_CONF1_IA_SZ
81         addi    t2, t2, 1
82         mul     t1, t1, t0
83         mul     t1, t1, t2
84
85         li      a0, KSEG0
86         add     a1, a0, t1
87 1:      cache   Index_Store_Tag_I, 0(a0)
88         add     a0, a0, t0
89         bne     a0, a1, 1b
90          nop
91 icache_done:
92
93         /* Detect D-cache line size */
94         _EXT    t0, v0, MIPS_CONF1_DL_SHF, MIPS_CONF1_DL_SZ
95         beqz    t0, dcache_done
96          li     t1, 2
97         sllv    t0, t1, t0
98
99         /* Detect D-cache size */
100         _EXT    t1, v0, MIPS_CONF1_DS_SHF, MIPS_CONF1_DS_SZ
101         xori    t2, t1, 0x7
102         beqz    t2, 1f
103          li     t3, 32
104         addi    t1, t1, 1
105         sllv    t1, t3, t1
106 1:      /* At this point t1 == D-cache sets per way */
107         _EXT    t2, v0, MIPS_CONF1_DA_SHF, MIPS_CONF1_DA_SZ
108         addi    t2, t2, 1
109         mul     t1, t1, t0
110         mul     t1, t1, t2
111
112         li      a0, KSEG0
113         addu    a1, a0, t1
114         subu    a1, a1, t0
115 1:      cache   Index_Store_Tag_D, 0(a0)
116         bne     a0, a1, 1b
117          add    a0, a0, t0
118 dcache_done:
119
120         /* Set Kseg0 cacheable, coherent, write-back, write-allocate */
121         mfc0    t0, CP0_CONFIG
122         ori     t0, 0x7
123         xori    t0, 0x2
124         mtc0    t0, CP0_CONFIG
125         ehb
126
127         /* Enter the coherent domain */
128         li      t0, 0xff
129         sw      t0, GCR_CL_COHERENCE_OFS(v1)
130         ehb
131
132         /* Jump to kseg0 */
133         la      t0, 1f
134         jr      t0
135          nop
136
137 1:      /* We're up, cached & coherent */
138
139         /*
140          * TODO: We should check the VPE number we intended to boot here, and
141          *       if non-zero we should start that VPE and stop this one. For
142          *       the moment this doesn't matter since CPUs are brought up
143          *       sequentially and in order, but once hotplug is implemented
144          *       this will need revisiting.
145          */
146
147         /* Off we go! */
148         la      t0, mips_cps_bootcfg
149         lw      t1, BOOTCFG_PC(t0)
150         lw      gp, BOOTCFG_GP(t0)
151         lw      sp, BOOTCFG_SP(t0)
152         jr      t1
153          nop
154         END(mips_cps_core_entry)
155
156 .org 0x200
157 LEAF(excep_tlbfill)
158         b       .
159          nop
160         END(excep_tlbfill)
161
162 .org 0x280
163 LEAF(excep_xtlbfill)
164         b       .
165          nop
166         END(excep_xtlbfill)
167
168 .org 0x300
169 LEAF(excep_cache)
170         b       .
171          nop
172         END(excep_cache)
173
174 .org 0x380
175 LEAF(excep_genex)
176         b       .
177          nop
178         END(excep_genex)
179
180 .org 0x400
181 LEAF(excep_intex)
182         b       .
183          nop
184         END(excep_intex)
185
186 .org 0x480
187 LEAF(excep_ejtag)
188         la      k0, ejtag_debug_handler
189         jr      k0
190          nop
191         END(excep_ejtag)