Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / evbarm / viper / viper_start.S
blob90fd49608c237e7da569e4b6251a8306e8c9bbe6
1 /*      $NetBSD: viper_start.S,v 1.3.26.1 2007/10/03 19:23:13 garbled Exp $     */
3 /*
4  * Copyright (c) 2005 Antti Kantee.  All Rights Reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the company nor the name of the author may be used to
15  *    endorse or promote products derived from this software without specific
16  *    prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
31 #include <machine/asm.h>
32 #include <arm/armreg.h>
33 #include <arm/arm32/pmap.h>
34 #include <arm/arm32/pte.h>
37  * We start out with RAM mapped to the bottom 64MB.  We are jogging
38  * happily there with the MMU on.  Our mission: map some important
39  * bootstrap devices (such as console port) in addition to mapping
40  * the physical RAM to 0xc0...
41  *
42  * If I try to create a mapping from scratch, something important gets
43  * wiped out (never could figure out exactly what), so we do this with
44  * the MMU on adding to the existing translation table.
45  */
47 #define CPWAIT_BRANCH                                                    \
48         sub     pc, pc, #4
50 #define CPWAIT(tmp)                                                      \
51         mrc     p15, 0, tmp, c2, c0, 0  /* arbitrary read of CP15 */    ;\
52         mov     tmp, tmp                /* wait for it to complete */   ;\
53         CPWAIT_BRANCH                   /* branch to next insn */
55 #ifndef SDRAM_START
56 #define SDRAM_START 0xa0000000
57 #endif
58 #define XSCALE_DCACHE_SIZE 0x8000
60         .text
62         .global _C_LABEL(viper_start)
63 _C_LABEL(viper_start):
65         /* Figure out where we want to jump to when the time comes */
66         adr     r8, .Linva
67         ldr     r8, [r8]
69         /*
70          * Start playing with the virtual address space mapping
71          * for initial bootstrap.
72          *
73          * Load registers, which will remain constant throughout
74          * building the VA mapping.
75          */
76         mov     r2, #(L1_S_SIZE)                /* 1MB chunks */
78         /*
79          * First map SDRAM VA == PA.  This enables us to cut&waste
80          * some existing initarm() code without modification
81          * (and, if, god forbid, someone would like to unify them
82          * some day, this'll make that job easier)
83          */
84         mrc     p15, 0, r0, c2, c0, 0           /* Get L1 */
85         bic     r0, r0, #0xff000000
86         add     r0, r0, #(0xa00 * 4)            /* offset to 0xa0.. */
88         mov     r3, #SDRAM_START                /* map to 0xa00.. */
89         orr     r3, r3, #(L1_S_AP(AP_KRW))      /* the usual perms & stuff */
90         orr     r3, r3, #(L1_TYPE_S)
91         orr     r3, r3, #(L1_S_DOM(PMAP_DOMAIN_KERNEL))
92         mov     r1, #0x40                       /* 64 1MB entries */
95         /* and looplooploop */
96         str     r3, [r0], #4
97         add     r3, r3, r2
98         subs    r1, r1, #1
99         bgt     1b
101         /*
102          * Map SDRAM also to VA 0xc00...
103          */
104         mrc     p15, 0, r0, c2, c0, 0           /* Get L1 */
105         bic     r0, r0, #0xff000000
106         add     r0, r0, #(0xc00 * 4)            /* start from 0xc00.. */
108         mov     r3, #SDRAM_START                /* map to 0xa00.. */
109         orr     r3, r3, #(L1_S_AP(AP_KRW))      /* the usual perms & stuff */
110         orr     r3, r3, #(L1_TYPE_S)
111         orr     r3, r3, #(L1_S_DOM(PMAP_DOMAIN_KERNEL))
112         mov     r1, #0x40                       /* 64 1MB entries */
115         /* and looplooploop */
116         str     r3, [r0], #4
117         add     r3, r3, r2
118         subs    r1, r1, #1
119         bgt     1b
121         /*
122          * Here come the devices.  Map an L1 section for each device
123          * to make this easy.
124          */
126         /* INTCTL */
127         mrc     p15, 0, r0, c2, c0, 0           /* Get L1 */
128         bic     r0, r0, #0xff000000
129         add     r0, r0, #(0xfd0 * 4)            /* offset to 0xfd000000 */
131         mov     r3,     #0x40000000     
132         orr     r3, r3, #0x00d00000     
133         orr     r3, r3, #(L1_S_AP(AP_KRW))
134         orr     r3, r3, #(L1_TYPE_S)
135         orr     r3, r3, #(L1_S_DOM(PMAP_DOMAIN_KERNEL))
136         str     r3, [r0], #4
138         /* GPIO */
139         mov     r3,     #0x40000000     
140         orr     r3, r3, #0x00e00000     
141         orr     r3, r3, #(L1_S_AP(AP_KRW))
142         orr     r3, r3, #(L1_TYPE_S)
143         orr     r3, r3, #(L1_S_DOM(PMAP_DOMAIN_KERNEL))
144         str     r3, [r0], #4
146         /* CLKMAN */
147         mov     r3,     #0x41000000     
148         orr     r3, r3, #0x00300000     
149         orr     r3, r3, #(L1_S_AP(AP_KRW))
150         orr     r3, r3, #(L1_TYPE_S)
151         orr     r3, r3, #(L1_S_DOM(PMAP_DOMAIN_KERNEL))
152         str     r3, [r0], #4
154         /* FFUART */
155         mov     r3,     #0x40000000     
156         orr     r3, r3, #0x00100000     
157         orr     r3, r3, #(L1_S_AP(AP_KRW))
158         orr     r3, r3, #(L1_TYPE_S)
159         orr     r3, r3, #(L1_S_DOM(PMAP_DOMAIN_KERNEL))
160         str     r3, [r0], #4
162         /* BTUART */
163         mov     r3,     #0x40000000     
164         orr     r3, r3, #0x00200000     
165         orr     r3, r3, #(L1_S_AP(AP_KRW))
166         orr     r3, r3, #(L1_TYPE_S)
167         orr     r3, r3, #(L1_S_DOM(PMAP_DOMAIN_KERNEL))
168         str     r3, [r0], #4
170 #if 0
171         /*
172          * Cache cleanup.  Not needed here?  Slight speedup in booting.
173          */
174         mov     r3, #(XSCALE_DCACHE_SIZE)
175         subs    r3, r3, #32
177         mcr     p15, 0, r3, c7, c10, 2
178         subs    r3, r3, #32
179         bne     1b
180         CPWAIT(r3)
182         /* Drain write buffer */
183         mcr     p15, 0, r6, c7, c10, 4
184 #endif
186         /*
187          * Make domain control go ful fart.
188          * We probably could be slightly more sensible about this,
189          * but it'll be replaced soon anyway, so why bother.
190          */
191         mov     r0, #0xffffffff
192         mcr     p15, 0, r0, c3, c0, 0
194         /*
195          * Relocate the kernel to where we want it, not where Redboot
196          * let's us load it.  Don't bother jumping after this stage,
197          * we'll do that soon enough anyway, and to the correct virtual
198          * address space region I might add.
199          */
200         adr     r0, _C_LABEL(viper_start)       /* start copy from here */
201         add     r0, r0, #SDRAM_START            /* offset to SDRAM mapping */
203         ldr     r1, .Lcopy_size                 /* copy this much (bytes) */
204         add     r1, r1, #3                      /* prepare for roundup */
205         mov     r1, r1, LSR #2                  /* make it words */
207         mov     r2, #SDRAM_START                /* target address, */
208         add     r2, r2, #0x00200000             /* kernel offsets by 2megs */
210         /* after this it's just a load-store-loop */
212         ldr     r3, [r0], #4
213         str     r3, [r2], #4
214         subs    r1, r1, #1
215         bgt     1b
217         /*
218          * Now let's clean the cache again to make sure everything
219          * is in place.
220          *
221          * XXX: should this take into account the XScale cache clean bug?
222          */
223         mov     r3, #(XSCALE_DCACHE_SIZE)
224         subs    r3, r3, #32
226         mcr     p15, 0, r3, c7, c10, 2
227         subs    r3, r3, #32
228         bne     1b
229         CPWAIT(r3)
231         /* Drain write buffer */
232         mcr     p15, 0, r6, c7, c10, 4
234         /* Invalidate TLBs just to be sure */
235         mcr     p15, 0, r0, c8, c7, 0
237         /*
238          * You are standing at the gate to NetBSD. --More--
239          * Unspeakable cruelty and harm lurk down there. --More--
240          * Are you sure you want to enter?
241          */
242         mov     pc, r8                          /* So be it */
244 /* symbol to use for address calculation in the right VA */
245 .Linva:
246         .word   start
249  * Calculate size of kernel to copy.  Don't bother to copy bss,
250  * although I guess the CPU could use the warmup exercise ...
251  */
252 .Lcopy_size:
253         .word _edata - _C_LABEL(viper_start)