1/* $NetBSD: start.S,v 1.1.2.3 2004/09/21 13:16:12 skrll Exp $ */
2
3/*
4 * Copyright (c) 2003 Naoto Shimazaki.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY NAOTO SHIMAZAKI AND CONTRIBUTORS ``AS IS''
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE NAOTO OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 * THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * NOTE:
31 * This code assumes some trick described below:
32 *
33 *	- Located at 0x80000000 by linker
34 *	- Placed at 0xbfc00000 (by ROM writer)
35 *	- Executed at 0xbfc00000 by CPU
36 *
37 * So,
38 *
39 *	- You cannot use 'j' and 'jal'.  Instead, you must use 'b'.
40 *	- If you want to jump to absolute address, you must load
41 *	  the target address to a register and jump to it with
42 *	  'jr' or 'jalr'.
43 *	- You never be able to write any memory before
44 *	  the bus configuration completed.
45 *
46 */
47
48#include <sys/cdefs.h>
49#include <sys/errno.h>
50#include <sys/syscall.h>
51
52#include <machine/param.h>
53#include <mips/asm.h>
54#include <mips/cpuregs.h>
55#include <mips/trap.h>
56
57#include "extern.h"
58
59	.text
60	.set	noreorder
61	.align	2
62
63/*
64 * macro ROMICE  - support for Kyoto-micro's PARTNER-ETII ROM-ICE
65 *
66 * PARTNER-ETII by Kyoto-microcomputer is a ROM based emulater.
67 * This ICE initializes by itself the very early configurations of
68 * the target CPU.  This macro skips that configurations.
69 */
70#ifndef ROMICE
71	/*
72	 * exception vector table
73	 */
74	.org	0x0000
75reset_vector:
76	b	start		/* MUST relative jump */
77	nop
78
79	.org	0x0200
80tlb_vector:
81	b	start
82	nop
83
84	.org	0x0280
85xtlb_vector:
86	b	start
87	nop
88
89	.org	0x0380
90exception_vector:
91	b	start
92	nop
93#endif
94
95	.org	0x1000
96	.globl	start
97start:
98#ifndef ROMICE
99	/*
100	 * setup CP0 CONFIG
101	 * EP = 0, AD = 0, K0 = 2
102	 */
103	li	t1, 0x00125482
104	mtc0	t1, $16
105
106	/*
107	 * setup CP0 STATUS
108	 * CU0 = 0, RE = 0, DS:BEV = 0, IM = 0, KX = SX = UX = 0,
109	 * KSU = 0, IE = 0, others = untouch
110	 */
111	mfc0	t1, $12
112	li	t2, 0x00770006
113	and	t1, t1, t2
114	li	t2, 0x00400000
115	or	t1, t1, t2
116	mtc0	t1, $12
117
118	mtc0	zero, $18		/* CP0 Watch Lo */
119	mtc0	zero, $11		/* CP0 compare */
120
121	/*
122	 * setup LED
123	 */
124	li	t0, 0xab000248		/* LEDCNTREG */
125	li	t1, 0x0001
126	sh	t1, (t0)
127
128	/*
129	 * reset HALTimer
130	 */
131	li	t0, 0xab0000a2
132	li	t1, 0x0004
133	sh	t1, (t0)
134
135	/*
136	 * initialize VR4181 bus controller
137	 */
138
139	/*
140	 * setup BCUCNTREG1
141	 * ROMs = 10 (64Mbit), ROMWEN0 = 1, Rtype = 01 (flash)
142	 * RSTOUT = 1 (inactive)
143	 */
144	li	t0, 0xaa000000		/* BCUCNTREG1 */
145	li	t1, 0x8013
146	sh	t1, (t0)
147
148	/*
149	 * setup BCURFCNTREG
150	 * BRF = refresh cycle x 1/TClock
151	 *     = 30.52usec x 32.768MHz
152	 *     = 0x3e8	(1000 TClock)
153	 */
154	li	t0, 0xaa000010		/* BCURFCNTREG */
155	li	t1, 0x03e8
156	sh	t1, (t0)
157
158	/*
159	 * setup BCUSPEEDREG
160	 * WPROM = 111 = 8.5TClock = 259ns
161	 * WROMA = 1000 = 9.5TClock = 290ns
162	 */
163	li	t0, 0xaa00000c		/* BCUSPEEDREG */
164	li	t1, 0x7008
165	sh	t1, (t0)
166
167	/*
168	 * setup SDTIMINGREG
169	 * BIT8 = 1 (always 1)
170	 * TRAS = 01 = 5SDCLK	(forced under 66, 50, 33MHz bus clock)
171	 * TRC  = 01 = 7SDCLK	(forced under 66, 50, 33MHz bus clock)
172	 * TRP  = 10 = 3SDCLK	(forced under 66, 50, 33MHz bus clock)
173	 * TRCP = 01 = 2SDCLK	(forced under 66, 50, 33MHz bus clock)
174	 */
175	li	t0, 0xaa00030c		/* SDTIMINGREG */
176	li	t1, 0x0159
177	sh	t1, (t0)
178
179	/*
180	 * To initialize 64Mbit SDRAM properly, we have to take
181	 * following steps:
182	 *
183	 * 	1. set MEMCFG_REG for 16Mbit SDRAM
184	 * 	2. setup MODE_REG
185	 * 	3. init SDRAM (setting MEMCFG_REG:Init to 1)
186	 * 	4. set MEMCFG_REG for 64Mbit SDRAM
187	 *
188	 * confirm to VR4181 users manual 6.5.2 MEMCFG_REG (page 142).
189	 * (the page number is for Japanese edition.  it might be
190	 *  at another page number for the English edition.)
191	 */
192
193	/*
194	 * first, say MEMCFG_REG that SDRAM is 16Mbit
195	 * Init = 0
196	 * B1Config = 01	(16Mbit)
197	 * Bstreftype = 1	(all raw refresh)
198	 * BstRefr = 0		(not allow burst refresh)
199	 * EDOAsym = 0		(asymetric)
200	 * B0Config = 01	(16Mbit)
201	 * EDO/SDRAM = 1	(SDRAM)
202	 */
203	li	t0, 0xaa000304		/* MEMCFG_REG <- 503 (16Mbit) */
204	li	t1, 0x0503
205	sh	t1, (t0)
206
207	/*
208	 * second, setup MODE_REG
209	 * Bit11 = 0		(always 0)
210	 * Bit10 = 0		(always 0)
211	 * BR-SW = 0		(always 0)
212	 * TE-Ven = 00		(always 00)
213	 * LTMode = 011		(3clock CAS latency)
214	 * WT = 0		(always 0)
215	 * BL = 111		(always 111)
216	 */
217	li	t0, 0xaa000308		/* MODE_REG */
218	li	t1, 0x0037
219	sh	t1, (t0)
220
221	/*
222	 * third, kick SDRAM initialization
223	 * Init = 1
224	 * other = untouched
225	 */
226	li	t0, 0xaa000304		/* MEMCFG_REG:Init <- 1 */
227	li	t1, 0x8503
228	sh	t1, (t0)
229
230	/*
231	 * final, say MEMCFG_REG that SDRAM is 16Mbit
232	 * Init = 0
233	 * B1Config = 10	(64Mbit)
234	 * Bstreftype = 1	(all raw refresh)
235	 * BstRefr = 0		(not allow burst refresh)
236	 * EDOAsym = 0		(asymetric)
237	 * B0Config = 10	(64Mbit)
238	 * EDO/SDRAM = 1	(SDRAM)
239	 */
240	li	t0, 0xaa000304		/* MEMCFG_REG */
241	li	t1, 0x0905
242	sh	t1, (t0)
243
244	/*
245	 * setup XISACTL
246	 * EXTRESULT = 1	(1 is recommended)
247	 * INTRESULT = 0	(0 is recommended)
248	 * EXBUFEN = 0		(use SYSDIR and SYSEN)
249	 * MEMWS = 00		(1.5 SYSCLK)
250	 * IOWS = 10		(2.5 SYSCLK)
251	 * SCLKDIV = 10		(PCLK/6)
252	 */
253	li	t0, 0xab0002c4		/* XISACTL */
254	li	t1, 0x0422
255	sh	t1, (t0)
256	nop
257
258
259	/*
260	 *  enable cache
261	 */
262	mfc0	t0, $16
263	li	t1, 0xfffffff8
264	and	t0, t0, t1
265	or	t0, t0, 0x00000003	/* K0 = 3 */
266	mtc0	t0, $16			/* config */
267	nop
268	nop
269	nop
270
271	/*
272	 * initialize cache
273	 */
274	mtc0	zero, $28		/* TagLo */
275
276	lui	t0, 0x8000		/* vaddr */
277	ori	t1, zero, 0x1000	/* cache size = 4KB */
278cache_clear:
279	.set	push
280	.set	mips3
281	cache	0x00, (t0)		/* Index_Invalidate */
282	cache	0x09, (t0)		/* Index_Store_Tag */
283	.set	pop
284	addiu	t1, t1, -0x10
285	bgtz	t1, cache_clear
286	addiu	t0, t0, 0x10		/* increment of line size */
287
288
289	/* LED3 ON */
290	li	t0, 0xab000306
291	li	t1, 0x0800
292	sh	t1, (t0)
293
294	li	t0, 0xab000308
295	sh	zero, (t0)
296	nop
297	/* LED3 ON */
298
299	/*
300	 * now early bus configuration is done.
301	 */
302
303
304	/*
305	 *  copy bootloader ROM to RAM
306	 */
307	li	t1, LCBOOT_ROMSTARTADDR
308	la	t2, start
309	la	t3, edata
3101:
311	lw	t0, (t1)
312	nop
313	sw	t0, (t2)
314	addu	t2, t2, 4
315	sltu	t0, t2, t3
316	.set	push
317	.set	noreorder
318	.set	nomacro
319	bne	t0, zero, 1b
320	addu	t1, t1, 4
321	.set	pop
322
323
324	/* verify */
325	li	t1, LCBOOT_ROMSTARTADDR
326	la	t2, start
327	la	t3, edata
3281:
329	lw	t0, (t1)
330	lw	t4, (t2)
331	addu	t2, t2, 4
332	bne	t0, t4, 2f
333	sltu	t0, t2, t3
334	.set	push
335	.set	noreorder
336	.set	nomacro
337	bne	t0, zero, 1b
338	addu	t1, t1, 4
339	.set	pop
340	b	4f
341	nop
3422:
343	/* panic. stop LED */
344	li	t0, 0xab000248		/* LEDCNTREG */
345	sh	zero, (t0)
3463:
347	b	3b
348	nop
3494:
350	/* verify done */
351
352
353	/* LED4 ON */
354	li	t0, 0xab000306
355	li	t1, 0x8800
356	sh	t1, (t0)
357
358	li	t0, 0xab000308
359	sh	zero, (t0)
360	/* LED4 ON */
361
362	/*
363	 * now we've got a working RAM with cache.
364	 */
365
366
367#else /* !ROMICE */
368	/*
369	 * enable cache
370	 */
371	mfc0	t0, $16
372	li	t1, 0xfffffff8
373	and	t0, t0, t1
374	or	t0, t0, 0x00000003	/* K0 = 3 */
375	mtc0	t0, $16			/* config */
376	nop
377	nop
378	nop
379#endif /* !ROMICE */
380
381
382	/*
383	 * zero the bss
384	 */
385	la	t1, edata
386	la	t2, end
387	sw	zero, (t1)
3881:
389	addu	t1, t1, 4
390	.set	push
391	.set	mips3
392	.set	noreorder
393	.set	nomacro
394	sltu	t0, t1, t2
395	bnel	t0, zero, 1b
396	sw	zero, (t1)		/* delay slot */
397	.set	pop
398
399
400
401
402#ifdef DEBUG_LED
403	/* LED5 ON */
404	li	t0, 0xab000302
405	li	t1, 0x0002
406	sh	t1, (t0)
407
408	li	t0, 0xab00030a
409	sh	zero, (t0)
410	/* LED5 ON */
411#endif
412
413#ifdef DEBUG_LED
414	/* LED6 ON */
415	li	t0, 0xab000300
416	li	t1, 0x0020
417	sh	t1, (t0)
418
419	li	t0, 0xab00030a
420	sh	zero, (t0)
421	/* LED6 ON */
422#endif
423
424
425
426	/*
427	 * call lcboot main()
428	 */
429	move	a0, zero		/* a0:	argc = 0 */
430	move	a1, zero		/* a1 */
431	move	a2, zero		/* a2 */
432	move	a3, zero		/* a3 */
433	move	k0, zero		/* k0 */
434	move	k1, zero		/* k1 */
435	la	gp, _C_LABEL(_gp)	/* global pointer */
436	la	sp, start		/* stack pointer */
437	la	v0, main
438	jalr	v0
439	nop
440
441	.globl	start_netbsd
442start_netbsd:
443	/*
444	 * all LED OFF
445	 */
446	li	t0, 0xab000248		/* LEDCNTREG */
447	sh	zero, (t0)
448	li	t1, 0xffff
449	li	t0, 0xab000308
450	sh	t1, (t0)
451	li	t0, 0xab00030a
452	sh	t1, (t0)
453
454	/*
455	 * initialize registers
456	 */
457	li	a0, 1			/* a0:	argc = 1 */
458	la	a1, argv0		/* a1:	argv */
459	la	a2, bootinfo		/* a2:	bootinfo */
460	move	a3, zero		/* a3 */
461	move	k0, zero		/* k0 */
462	move	k1, zero		/* k1 */
463	/* no need to set grobal pointer. it set in locore.S */
464	la	sp, NETBSD_STARTADDR	/* stack pointer */
465	/*
466	 * call netbsd
467	 */
468	jr	sp
469	nop
470
471
472/*
473 * arguments for mach_init()
474 */
475	.data
476argv0:
477	.word	argv0c
478argv1:
479	.word	0
480argv0c:
481	.asciiz	"netbsd"
482
483bootinfo:
484	.half	34		/* length */
485	.half	0		/* reserved */
486	.word	0x13536135	/* magic */
487	.word	0		/* fb_addr */
488	.half	0		/* fb_line_bytes */
489	.half	0		/* fb_width */
490	.half	0		/* fb_height */
491	.half	0		/* fb_type */
492	.half	2		/* BI_CNUSE_SERIAL */
493	.half	0		/* padding */
494	.word	0x04104400	/* PLATID_CPU_MIPS_VR_4181 */
495	.word	0x03810100	/* PLATID_MACH_LASER5_L_CARD */
496	.word	0		/* GMT */
497
498/*
499 * End of start.S
500 */
501