1 /* $NetBSD: viper_start.S,v 1.3.26.1 2007/10/03 19:23:13 garbled Exp $ */
4 * Copyright (c) 2005 Antti Kantee. All Rights Reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
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...
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.
47 #define CPWAIT_BRANCH \
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 */
56 #define SDRAM_START 0xa0000000
58 #define XSCALE_DCACHE_SIZE 0x8000
62 .global _C_LABEL(viper_start)
63 _C_LABEL(viper_start):
65 /* Figure out where we want to jump to when the time comes */
70 * Start playing with the virtual address space mapping
71 * for initial bootstrap.
73 * Load registers, which will remain constant throughout
74 * building the VA mapping.
76 mov r2, #(L1_S_SIZE) /* 1MB chunks */
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)
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 */
102 * Map SDRAM also to VA 0xc00...
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 */
122 * Here come the devices. Map an L1 section for each device
127 mrc p15, 0, r0, c2, c0, 0 /* Get L1 */
128 bic r0, r0, #0xff000000
129 add r0, r0, #(0xfd0 * 4) /* offset to 0xfd000000 */
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))
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))
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))
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))
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))
172 * Cache cleanup. Not needed here? Slight speedup in booting.
174 mov r3, #(XSCALE_DCACHE_SIZE)
177 mcr p15, 0, r3, c7, c10, 2
182 /* Drain write buffer */
183 mcr p15, 0, r6, c7, c10, 4
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.
192 mcr p15, 0, r0, c3, c0, 0
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.
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 */
218 * Now let's clean the cache again to make sure everything
221 * XXX: should this take into account the XScale cache clean bug?
223 mov r3, #(XSCALE_DCACHE_SIZE)
226 mcr p15, 0, r3, c7, c10, 2
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
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?
242 mov pc, r8 /* So be it */
244 /* symbol to use for address calculation in the right VA */
249 * Calculate size of kernel to copy. Don't bother to copy bss,
250 * although I guess the CPU could use the warmup exercise ...
253 .word _edata - _C_LABEL(viper_start)