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