1/* $NetBSD: rpi_start.S,v 1.7 2012/09/23 15:56:32 skrll Exp $ */ 2 3/* 4 * Copyright (c) 2002, 2003 Genetec Corporation. All rights reserved. 5 * Written by Hiroyuki Bessho for Genetec Corporation. 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 * 3. The name of Genetec Corporation may not be used to endorse or 16 * promote products derived from this software without specific prior 17 * written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 * Copyright (c) 2003 32 * Ichiro FUKUHARA <ichiro@ichiro.org>. 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 44 * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR 45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 46 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 47 * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR 48 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 54 * SUCH DAMAGE. 55 * 56 * Copyright (c) 2007 Microsoft 57 * All rights reserved. 58 * 59 * Redistribution and use in source and binary forms, with or without 60 * modification, are permitted provided that the following conditions 61 * are met: 62 * 1. Redistributions of source code must retain the above copyright 63 * notice, this list of conditions and the following disclaimer. 64 * 2. Redistributions in binary form must reproduce the above copyright 65 * notice, this list of conditions and the following disclaimer in the 66 * documentation and/or other materials provided with the distribution. 67 * 3. All advertising materials mentioning features or use of this software 68 * must display the following acknowledgement: 69 * This product includes software developed by Microsoft 70 * 71 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 72 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 73 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 74 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT, 75 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 76 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 77 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 78 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 79 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 80 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 81 * SUCH DAMAGE. 82 */ 83 84#include "opt_cputypes.h" 85 86#include <machine/asm.h> 87#include <arm/armreg.h> 88#include "assym.h" 89 90RCSID("$NetBSD: rpi_start.S,v 1.2.2.3 2012/11/19 19:13:01 riz Exp $") 91 92/* 93 * Workaround Erratum 411920 94 * 95 * - value of arg 'reg' Should Be Zero 96 */ 97#define Invalidate_I_cache(reg) \ 98 .p2align 5; \ 99 mcr p15, 0, reg, c7, c5, 0; /* Invalidate Entire I cache */ \ 100 mcr p15, 0, reg, c7, c5, 0; /* Invalidate Entire I cache */ \ 101 mcr p15, 0, reg, c7, c5, 0; /* Invalidate Entire I cache */ \ 102 mcr p15, 0, reg, c7, c5, 0; /* Invalidate Entire I cache */ \ 103 nop; \ 104 nop; \ 105 nop; \ 106 nop; \ 107 nop; \ 108 nop; \ 109 nop; \ 110 nop; \ 111 nop; \ 112 nop; \ 113 nop; 114 115/* 116 * Kernel start routine for RPI boards. 117 * At this point, this code has been loaded into SDRAM 118 * and the MMU is off 119 */ 120 .text 121 122 .global _C_LABEL(rpi_start) 123_C_LABEL(rpi_start): 124 adr r8, rpi_boot_regs 125 stmia r8!, {r0-r3} 126 127 mrs r0, cpsr 128 bic r0, r0, #PSR_MODE 129 orr r0, r0, #(I32_bit | F32_bit | PSR_SVC32_MODE) 130 msr cpsr, r0 131 132 /* 133 * Set up a preliminary mapping in the MMU to allow us to run 134 * at KERNEL_BASE with caches on. 135 */ 136 /* Build page table from scratch */ 137 ldr r0, Ltemp_l1_table /* The page table address - entered into TTB later */ 138 mov r1, r0 /* Start address to clear memory. */ 139 /* Zero the entire table so all virtual addresses are invalid. */ 140 mov r2, #L1_TABLE_SIZE /* in bytes */ 141 mov r3, #0 142 mov r4, r3 143 mov r5, r3 144 mov r6, r3 145 mov r7, r3 146 mov r8, r3 147 mov r10, r3 148 mov r11, r3 1491: stmia r1!, {r3-r8,r10-r11} 150 stmia r1!, {r3-r8,r10-r11} 151 stmia r1!, {r3-r8,r10-r11} 152 stmia r1!, {r3-r8,r10-r11} 153 subs r2, r2, #(4 * 4 * 8) /* bytes per loop */ 154 bne 1b 155 156 /* Now create our entries per the mmu_init_table. */ 157 l1table .req r0 158 va .req r1 159 pa .req r2 160 n_sec .req r3 161 attr .req r4 162 itable .req r5 163 l1sfrm .req r6 164 165 adr itable, mmu_init_table 166 ldr l1sfrm, Ll1_s_frame 167 b 3f 168 1692: str pa, [l1table, va] 170 add va, va, #4 171 add pa, pa, #(L1_S_SIZE) 172 adds n_sec, n_sec, #-1 173 bhi 2b 174 1753: ldmia itable!, {va,pa,n_sec,attr} 176 mov n_sec, n_sec, lsr #L1_S_SHIFT 177 /* Convert va to l1 offset: va = 4 * (va >> L1_S_SHIFT) */ 178 mov va, va, LSR #L1_S_SHIFT 179 mov va, va, LSL #2 180 /* Convert pa to l1 entry: pa = (pa & L1_S_FRAME) | attr */ 181 and pa, pa, l1sfrm 182 orr pa, pa, attr 183 cmp n_sec, #0 184 bne 2b 185 186 .unreq va 187 .unreq pa 188 .unreq n_sec 189 .unreq attr 190 .unreq itable 191 .unreq l1table 192 .unreq l1sfrm 193 194 /* 195 * In theory, because the MMU is off, we shouldn't need all of this, 196 * but let's not take any chances and do a typical sequence to set 197 * the Translation Table Base. 198 */ 199 mov r0, #0 /* SBZ */ 200 Invalidate_I_cache(r0) 201 202 mcr p15, 0, r0, c7, c14, 0 /* Clean and Invalidate Entire Data Cache */ 203 204 ldr r2, Lctl_ID_dis /* Disable I+D caches */ 205 mrc p15, 0, r1, c1, c0, 0 /* " " " */ 206 and r1, r1, r2 /* " " " */ 207 mcr p15, 0, r1, c1, c0, 0 /* " " " */ 208 209 mcr p15, 0, r0, c7, c10, 4 /* Drain the write buffers. */ 210 211 ldr r0, Ltemp_l1_table /* The page table address */ 212 mcr p15, 0, r0, c2, c0, 0 /* Set Translation Table Base */ 213 214 mov r0, #0 215 mcr p15, 0, r0, c8, c7, 0 /* Invalidate TLBs */ 216 217 /* Set the Domain Access register. Very important! */ 218 mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT) 219 mcr p15, 0, r0, c3, c0, 0 220 221 /* 222 * Enable the MMU, etc. 223 */ 224 mrc p15, 0, r0, c1, c0, 0 225 226 ldr r1, Lcontrol_wax 227 and r0, r0, r1 228 ldr r1, Lcontrol_clr 229 bic r0, r0, r1 230 ldr r1, Lcontrol_set 231 orr r0, r0, r1 232 ldr lr, Lstart 233 234 .align 5 235 @ turn mmu on! 236 mov r0, r0 237 mcr p15, 0, r0, c1, c0, 0 238 239 /* 240 * Ensure that the coprocessor has finished turning on the MMU. 241 */ 242 mrc p15, 0, r0, c0, c0, 0 /* Read an arbitrary value. */ 243 mov r0, r0 /* Stall until read completes. */ 244 245 /* 246 * Jump to start in locore.S, which in turn will call initarm and main. 247 */ 248 mov pc, lr 249 nop 250 nop 251 nop 252 nop 253 254 /* NOTREACHED */ 255Ll1_s_frame: 256 .word L1_S_FRAME 257 258Ltemp_l1_table: 259 /* Put the temporary L1 translation table just below the kernel. */ 260 .word 0x4000 261 262Lstart: 263 .word start 264/* 265 * Coprocessor register initialization values 266 */ 267 268 /* bits to set in the Control Register */ 269Lcontrol_set: 270 .word CPU_CONTROL_MMU_ENABLE | \ 271 CPU_CONTROL_AFLT_ENABLE | \ 272 CPU_CONTROL_DC_ENABLE | \ 273 CPU_CONTROL_WBUF_ENABLE | /* not defined in 1176 */ \ 274 CPU_CONTROL_32BP_ENABLE | \ 275 CPU_CONTROL_32BD_ENABLE | \ 276 CPU_CONTROL_LABT_ENABLE | \ 277 CPU_CONTROL_SYST_ENABLE | \ 278 (1 << 16) | /* SBO - Global enable for data tcm */ \ 279 (1 << 18) | /* SBO - Global enable for insn tcm */ \ 280 CPU_CONTROL_IC_ENABLE 281 282 283 /* bits to clear in the Control Register */ 284Lcontrol_clr: 285 .word 0 286 287 /* bits to "write as existing" in the Control Register */ 288Lcontrol_wax: 289 .word (3 << 30) | \ 290 (1 << 29) | \ 291 (1 << 28) | \ 292 (3 << 26) | \ 293 (3 << 19) | \ 294 (1 << 17) | \ 295 (1 << 10) 296 297 /* bits to disable the caches */ 298Lctl_ID_dis: 299 .word ~(CPU_CONTROL_IC_ENABLE|CPU_CONTROL_DC_ENABLE) 300 301/* We'll modify va and pa at run time so we can use relocatable addresses. */ 302#define MMU_INIT(va,pa,n_sec,attr) \ 303 .word va ; \ 304 .word pa ; \ 305 .word n_sec ; \ 306 .word attr ; 307 308mmu_init_table: 309 /* Add 1MB of VA==PA at 0x00000000 so we can keep the kernel going */ 310 MMU_INIT(0x0, 0x0, 311 (_end - KERNEL_BASE + 2 * L1_S_SIZE - 1), 312 L1_S_PROTO | L1_S_AP_KRW) 313 314 MMU_INIT(KERNEL_BASE, 0x0, 315 (_end - KERNEL_BASE + 2 * L1_S_SIZE - 1), 316 L1_S_PROTO | L1_S_AP_KRW | L1_S_B | L1_S_C) 317 318 /* Map the 16MB of peripherals */ 319 MMU_INIT(RPI_KERNEL_IO_VBASE, RPI_KERNEL_IO_PBASE, 320 (RPI_KERNEL_IO_VSIZE + L1_S_SIZE - 1), 321 L1_S_PROTO | L1_S_AP_KRW) 322 323 /* end of table */ 324 MMU_INIT(0, 0, 0, 0) 325 326 .globl _C_LABEL(rpi_boot_regs) 327rpi_boot_regs: 328 .space 4 * 4 329