No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / hpcmips / stand / lcboot / start.S
blob1a8158b37843c3bcb5d29784dba1e240ff9c8774
1 /* $NetBSD: start.S,v 1.1.2.3 2004/09/21 13:16:12 skrll Exp $ */
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  */
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  */
48 #include <sys/cdefs.h>
49 #include <sys/errno.h>
50 #include <sys/syscall.h>
52 #include <machine/param.h>
53 #include <mips/asm.h>
54 #include <mips/cpuregs.h>
55 #include <mips/trap.h>
57 #include "extern.h"
59         .text
60         .set    noreorder
61         .align  2
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
75 reset_vector:
76         b       start           /* MUST relative jump */
77         nop
79         .org    0x0200
80 tlb_vector:
81         b       start
82         nop
84         .org    0x0280
85 xtlb_vector:
86         b       start
87         nop
88         
89         .org    0x0380
90 exception_vector:
91         b       start
92         nop
93 #endif
95         .org    0x1000
96         .globl  start
97 start:
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
118         mtc0    zero, $18               /* CP0 Watch Lo */
119         mtc0    zero, $11               /* CP0 compare */
121         /*
122          * setup LED
123          */
124         li      t0, 0xab000248          /* LEDCNTREG */
125         li      t1, 0x0001
126         sh      t1, (t0)
128         /*
129          * reset HALTimer
130          */
131         li      t0, 0xab0000a2
132         li      t1, 0x0004
133         sh      t1, (t0)
135         /*
136          * initialize VR4181 bus controller
137          */
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)
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)
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)
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)
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          */
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)
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)
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)
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)
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
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
271         /*
272          * initialize cache
273          */
274         mtc0    zero, $28               /* TagLo */
276         lui     t0, 0x8000              /* vaddr */
277         ori     t1, zero, 0x1000        /* cache size = 4KB */
278 cache_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 */
289         /* LED3 ON */
290         li      t0, 0xab000306
291         li      t1, 0x0800
292         sh      t1, (t0)
294         li      t0, 0xab000308
295         sh      zero, (t0)
296         nop
297         /* LED3 ON */
299         /*
300          * now early bus configuration is done.
301          */
304         /*
305          *  copy bootloader ROM to RAM
306          */
307         li      t1, LCBOOT_ROMSTARTADDR
308         la      t2, start
309         la      t3, edata
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         
324         /* verify */
325         li      t1, LCBOOT_ROMSTARTADDR
326         la      t2, start
327         la      t3, edata
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
343         /* panic. stop LED */
344         li      t0, 0xab000248          /* LEDCNTREG */
345         sh      zero, (t0)
347         b       3b
348         nop
349 4:      
350         /* verify done */
351                 
353         /* LED4 ON */
354         li      t0, 0xab000306
355         li      t1, 0x8800
356         sh      t1, (t0)
358         li      t0, 0xab000308
359         sh      zero, (t0)
360         /* LED4 ON */
362         /*
363          * now we've got a working RAM with cache.
364          */
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 */
382         /*
383          * zero the bss
384          */
385         la      t1, edata
386         la      t2, end
387         sw      zero, (t1)
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
402 #ifdef DEBUG_LED
403         /* LED5 ON */
404         li      t0, 0xab000302
405         li      t1, 0x0002
406         sh      t1, (t0)
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)
419         li      t0, 0xab00030a
420         sh      zero, (t0)
421         /* LED6 ON */
422 #endif
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
441         .globl  start_netbsd
442 start_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)
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
473  * arguments for mach_init()
474  */
475         .data
476 argv0:
477         .word   argv0c
478 argv1:
479         .word   0
480 argv0c:
481         .asciiz "netbsd"
483 bootinfo:
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 */
499  * End of start.S
500  */