xref: /openbmc/linux/arch/mips/kernel/cps-vec.S (revision afb46f79)
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
24LEAF(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
42not_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
791:	/* 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
871:	cache	Index_Store_Tag_I, 0(a0)
88	add	a0, a0, t0
89	bne	a0, a1, 1b
90	 nop
91icache_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
1061:	/* 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
1151:	cache	Index_Store_Tag_D, 0(a0)
116	bne	a0, a1, 1b
117	 add	a0, a0, t0
118dcache_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
1371:	/* 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
157LEAF(excep_tlbfill)
158	b	.
159	 nop
160	END(excep_tlbfill)
161
162.org 0x280
163LEAF(excep_xtlbfill)
164	b	.
165	 nop
166	END(excep_xtlbfill)
167
168.org 0x300
169LEAF(excep_cache)
170	b	.
171	 nop
172	END(excep_cache)
173
174.org 0x380
175LEAF(excep_genex)
176	b	.
177	 nop
178	END(excep_genex)
179
180.org 0x400
181LEAF(excep_intex)
182	b	.
183	 nop
184	END(excep_intex)
185
186.org 0x480
187LEAF(excep_ejtag)
188	la	k0, ejtag_debug_handler
189	jr	k0
190	 nop
191	END(excep_ejtag)
192