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