1/*
2 * init_vpe1.S
3 *
4 *  Created on: Jan 13, 2011
5 *  Author: MIPS TECHNOLOGIES, INC
6 *  Initialize the second vpe and additional TCs
7*/
8/*
9Unpublished work (c) MIPS Technologies, Inc.  All rights reserved.  Unpublished rights reserved
10under the copyright laws of the United States of America and other countries.
11
12This code is confidential and proprietary to MIPS Technologies, Inc. ("MIPS Technologies") and
13may be disclosed only as permitted in writing by MIPS Technologies or an authorized third party.
14Any copying, reproducing, modifying, use or disclosure of this code (in whole or in part) that is
15not expressly permitted in writing by MIPS Technologies or an authorized third party is strictly
16prohibited. At a minimum, this code is protected under trade secret, unfair competition, and
17copyright laws. Violations thereof may result in criminal penalties and fines.
18
19MIPS Technologies reserves the right to change this code to improve function, design or
20otherwise. MIPS Technologies does not assume any liability arising out of the application or use
21of this code, or of any error or omission in such code.  Any warranties, whether express, statutory,
22implied or otherwise, including but not limited to the implied warranties of merchantability or
23fitness for a particular purpose, are excluded.  Except as expressly provided in any written license
24agreement from MIPS Technologies or an authorized third party, the furnishing of this code does
25not give recipient any license to any intellectual property rights, including any patent rights, that
26cover this code.
27
28This code shall not be exported, reexported, transferred, or released, directly or indirectly, in
29violation of the law of any country or international law, regulation, treaty, Executive Order,
30statute, amendments or supplements thereto.  Should a conflict arise regarding the export,
31reexport, transfer, or release of this code, the laws of the United States of America shall be
32the governing law.
33
34This code may only be disclosed to the United States government ("Government"), or to
35Government users, with prior written consent from MIPS Technologies or an authorized third
36party.  This code constitutes one or more of the following: commercial computer software,
37commercial computer software documentation or other commercial items.  If the user of this
38code, or any related documentation of any kind, including related technical data or manuals, is an
39agency, department, or other entity of the Government, the use, duplication, reproduction, release,
40modification, disclosure, or transfer of this code, or any related documentation of any kind, is
41restricted in accordance with Federal Acquisition Regulation 12.212 for civilian agencies and
42Defense Federal Acquisition Regulation Supplement 227.7202 for military agencies.  The use of
43this code by the Government is further restricted in accordance with the terms of the license
44agreement(s) and/or applicable contract terms and conditions covering this code from MIPS
45Technologies or an authorized third party.
46*/
47
48#include <boot.h>
49#include <regdef.h>
50#include <m32c0.h>
51
52// defines not yet in m32c0.h
53#define C0_MVPCTL $0, 1
54#define C0_MVPCONF0 $0, 2
55#define C0_VPECTL $1, 1
56#define C0_VPECONF0 $1, 2
57#define C0_TCSTATUS $2, 1
58#define C0_TCBIND $2, 2
59#define C0_TCRESTART $2, 3
60#define C0_TCHALT $2, 4
61
62	.set	noreorder           // Don't allow the assembler to reorder instructions.
63	.set	noat                // Don't allow the assembler to use r1(at) for synthetic instr.
64/**************************************************************************************
65**************************************************************************************/
66LEAF(init_vpe1)
67
68   // Each vpe will need to set up additional TC bound to it. (No rebinding.)
69
70    beqz    r21_more_tcs, done_init_vpe1   // If there is no .
71    nop
72    beqz    r20_more_vpes, done_init_vpe1   // If there is no vpe1 then skip init_vpe1.
73    nop
74
75	// This is executing on TC0 bound to VPE0.  Therefore VPEConf0.MVP is set.
76	// Enter config mode
77	mfc0	v0, C0_MVPCTL	// read C0_MVPCtl
78	or		v0, (1 << 1)		// set VPC
79	mtc0	v0, C0_MVPCTL	// write C0_MVPCtl
80	ehb
81
82#define a0_NTCS	a0
83#define a2_NVPES	a2
84#define a3_TC	a3
85
86	// Get number of a3_TC's and VPE's
87	mfc0	v0, C0_MVPCONF0	// read C0_MVPCONF0
88	ext		a0_NTCS, v0, 0, 8	// extract PTC
89	ext		a2_NVPES, v0, 10, 4	// extract PVPE
90
91	// Initialise a3_TC's/VPE's
92	move	a3_TC, zero
93nexttc:
94	// Select TCn
95	mfc0	v0, C0_VPECTL	// read C0_VPECTL
96	ins		v0, a3_TC, 0, 8		// insert TargTC
97	mtc0	v0, C0_VPECTL	// write C0_VPECTL
98	ehb
99
100	// Bind a3_TC to next VPE
101	beqz	a3_TC, nextvpe	// Don't rebind TC0
102	nop
103
104	// Halt a3_TC being configured
105	li		v0, 1			    // set Halt bit
106	mttc0	v0, C0_TCHALT	// write C0_TCHALT
107	ehb
108
109	move    v1, a3_TC
110	// Bind TC to a VPE
111	mftc0   v0, C0_TCBIND	// Read C0_TCBind
112	ins     v0, v1, 0, 4	// change S_TCBindCurVPE
113	mttc0   v0, C0_TCBIND	// write C0_TCBind
114
115	// This code checks to see if the a3_TC mumber is
116	// less than the VPE number. This ensures
117	// in a system with more than 1 VPE and TCs each
118	// VPE will have at least one a3_TC bound to it
119	// and any TCs left over will be bound to the last a3_TC
120	slt		v1, a2_NVPES, a3_TC
121	bnez	v1, 2f			// Bind spare a3_TC's to VPElast
122	move	v1, a2_NVPES
123
124	// Set XTC for active a3_TC's
125	mftc0	v0, C0_VPECONF0	// read C0_VPECONF0
126	ins		v0, a3_TC, 21, 8 // insert XTC
127	mttc0	v0, C0_VPECONF0	// write C0_VPECONF0
128
129	move	v1, a3_TC
1302:
131	// Bind a3_TC to a VPE
132	mftc0	v0, C0_TCBIND	// read C0_TCBIND
133	ins		v0, v1, 0, 4	// insert VPE
134	mttc0	v0, C0_TCBIND	// write C0_TCBIND
135
136	// Set up TCStatus register:
137	// Disable Coprocessor Usable bits
138	// Disable MDMX/DSP ASE
139	// Clear Dirty a3_TC
140	// not dynamically allocatable
141	// not allocated
142	// Kernel mode
143	// interrupt exempt
144	// ASID 0
145	li		v0, (1 << 10)	// set IXMT
146	mttc0	v0, C0_TCSTATUS	// write C0_TCSTATUS
147
148	// Initialize the a3_TC's register file
149	li v0, 0xdeadbeef
150	mttgpr	v0, $1
151	mttgpr	v0, $2
152	mttgpr	v0, $3
153	mttgpr	v0, $4
154	mttgpr	v0, $5
155	mttgpr	v0, $6
156	mttgpr	v0, $7
157	mttgpr	v0, $8
158	mttgpr	v0, $9
159	mttgpr	v0, $10
160	mttgpr	v0, $11
161	mttgpr	v0, $12
162	mttgpr	v0, $13
163	mttgpr	v0, $14
164	mttgpr	v0, $15
165	mttgpr	v0, $16
166	mttgpr	v0, $17
167	mttgpr	v0, $18
168	mttgpr	v0, $19
169	mttgpr	v0, $20
170	mttgpr	v0, $21
171	mttgpr	v0, $22
172	mttgpr	v0, $23
173	mttgpr	v0, $24
174	mttgpr	v0, $25
175	mttgpr	v0, $26
176	mttgpr	v0, $27
177	mttgpr	v0, $28
178	mttgpr	v0, $29
179	mttgpr	v0, $30
180	mttgpr	v0, $31
181
182nextvpe:
183	slt		v1, a2_NVPES, a3_TC
184	bnez	v1, donevpe		// No more VPE's
185	nop
186
187	// Disable multi-threading with a3_TC's
188	mftc0	v0, C0_VPECTL	// read C0_VPECTL
189	ins		v0, zero, 15, 1	// clear TE
190	mttc0	v0, C0_VPECTL	// write C0_VPECTL
191
192	beqz	a3_TC, 1f
193	nop
194
195	// For VPE1..n
196	// Clear VPA and set master VPE
197	mftc0	v0, C0_VPECONF0	// read C0_VPECONF0
198	ins		v0, zero, 0, 1	// insert VPA
199	or		v0, (1 << 1)	// set MVP
200	mttc0	v0, C0_VPECONF0	// write C0_VPECONF0
201
202	mfc0	v0, C0_STATUS	// read vpe0 C0_STATUS
203	mttc0	v0, C0_STATUS	// write vpe1 C0_Status
204
205	li		v0, 0x12345678
206	mttc0	v0, C0_EPC		// write C0_EPC
207
208	// RAMHACK: vpe0.Cause -> vpe1.Cause (Cause.IV == 1)
209	mfc0	v0, C0_CAUSE	// read vpe0 C0_CAUSE
210	mttc0	v0, C0_CAUSE	// write vpe1 C0_CAUSE
211
212	mfc0	v0, C0_CONFIG	// read vpe0 C0_CONFIG
213	mttc0	v0, C0_CONFIG	// write vpe1 C0_CONFIG
214
215	mftc0	v0, C0_EBASE	// read C0_EBASE
216	ext		v0, v0, 0, 10	// extract CPUNum
217	mttgpr	v0, r23_cpu_num
218
219	// vpe1 of each core can execute cached as it's L1 I$ has already been initialized.
220	// and the L2$ has been initialized or "disabled" via CCA override.
221	// RAMHACK: Move entry point to _start.
222	// la		a1, __reset_vector
223	la		a1, _start
224	ins     a1, zero, 29, 1 // Convert to cached kseg0 address in case we linked to kseg1.
225	mttc0   a1, C0_TCRESTART // write C0_TCRESTART
226
227	// Yes.. this is undoing all of the work done above... :)
228	mftc0	v0, C0_TCSTATUS	// read C0_TCSTATUS
229	ins	    v0, zero, 10, 1	// insert IXMT
230	ori	    v0, (1 << 13)	// set A
231	mttc0	v0, C0_TCSTATUS	// write C0_TCSTATUS
232
233	mttc0	zero, C0_TCHALT	// write C0_TCHALT
234
235	mftc0	v0, C0_VPECONF0	// read C0_VPECONF0
236	ori	    v0, 1		    // set VPA
237	mttc0	v0, C0_VPECONF0	// write C0_VPECONF0
2381:
239
240donevpe:
241	addu	a3_TC, 1
242	sltu	v1, a0_NTCS, a3_TC
243	beqz	v1, nexttc
244	nop
245
246	// Exit config mode
247	mfc0	v0, C0_MVPCTL	// read C0_MVPCtl
248    ori     v0, 1           // set EVP will enable execution by vpe1
249	ins	    v0, zero, 1, 1	// insert VPC
250	mtc0	v0, C0_MVPCTL	// write C0_MVPCtl
251	ehb
252
253#undef a0_NTCS
254#undef a2_NVPES
255#undef a3_TC
256
257done_init_vpe1:
258
259    jr   ra
260    nop
261END(init_vpe1)
262
263