1/* $NetBSD: gemini_start.S,v 1.10 2024/11/19 05:00:09 andvar Exp $ */ 2 3/* 4 * Machine dependent startup code for GEMINI boards. 5 * Based on omap_start.S 6 * 7 * Copyright (c) 2002, 2003 Genetec Corporation. All rights reserved. 8 * Written by Hiroyuki Bessho for Genetec Corporation. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of Genetec Corporation may not be used to endorse or 19 * promote products derived from this software without specific prior 20 * written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 * 34 * Copyright (c) 2003 35 * Ichiro FUKUHARA <ichiro@ichiro.org>. 36 * All rights reserved. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 47 * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR 48 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 49 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50 * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR 51 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * SUCH DAMAGE. 58 * 59 * Copyright (c) 2007 Microsoft 60 * All rights reserved. 61 * 62 * Redistribution and use in source and binary forms, with or without 63 * modification, are permitted provided that the following conditions 64 * are met: 65 * 1. Redistributions of source code must retain the above copyright 66 * notice, this list of conditions and the following disclaimer. 67 * 2. Redistributions in binary form must reproduce the above copyright 68 * notice, this list of conditions and the following disclaimer in the 69 * documentation and/or other materials provided with the distribution. 70 * 3. All advertising materials mentioning features or use of this software 71 * must display the following acknowledgement: 72 * This product includes software developed by Microsoft 73 * 74 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 75 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 76 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 77 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT, 78 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 79 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 80 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 81 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 82 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 83 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 84 * SUCH DAMAGE. 85 */ 86 87#include "opt_gemini.h" 88#include "opt_com.h" 89 90#include <machine/asm.h> 91#include <arm/armreg.h> 92#include "assym.h" 93 94RCSID("$NetBSD: gemini_start.S,v 1.10 2024/11/19 05:00:09 andvar Exp $") 95 96 97#if defined(VERBOSE_INIT_ARM) 98# define _PUTCHAR(addr, areg, breg, c) \ 99 ldr areg, addr; \ 1001: \ 101 ldr breg, [areg, #0x14]; /* LSR */ \ 102 tst breg, #0x20; /* TXRDY? */ \ 103 beq 1b; \ 104 mov breg, #(c); /* c */ \ 105 str breg, [areg]; /* TXDATA */ \ 1062: \ 107 ldr breg, [areg, #0x14]; /* LSR */ \ 108 tst breg, #0x40; /* TSRE? */ \ 109 beq 2b; 110#else 111# define _PUTCHAR(addr, areg, breg, c) 112#endif 113 114 115/* 116 * Kernel start routine for GEMINI Eval board. 117 * At this point, this code has been loaded into SDRAM 118 * and the MMU is off 119 */ 120 .section .start,"ax",%progbits 121 122 .global _C_LABEL(gemini_start) 123_C_LABEL(gemini_start): 124 /* Move into supervisor mode and disable IRQs/FIQs. */ 125 mrs r0, cpsr 126 bic r0, r0, #PSR_MODE 127 orr r0, r0, #(I32_bit | F32_bit | PSR_SVC32_MODE) 128 msr cpsr, r0 129 130 _PUTCHAR(Lconsole_pbase, r4, r3, 'a') 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 138 mov r1, r0 /* Save the page table address. */ 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 _PUTCHAR(Lconsole_pbase, r4, r3, 'b') 157 158 /* Now create our entries per the mmu_init_table. */ 159 l1table .req r0 160 va .req r1 161 pa .req r2 162 n_sec .req r3 163 attr .req r4 164 itable .req r5 165 l1sfrm .req r6 166 ldr l1table, Ltemp_l1_table 167 adr itable, mmu_init_table 168 ldr l1sfrm, Ll1_s_frame 169 b 3f 1702: str pa, [l1table, va] 171 add va, va, #4 172 add pa, pa, #(L1_S_SIZE) 173 adds n_sec, n_sec, #-1 174 bhi 2b 1753: ldmia itable!, {va,pa,n_sec,attr} 176 /* Convert va to l1 offset: va = 4 * (va >> L1_S_SHIFT) */ 177 mov va, va, LSR #L1_S_SHIFT 178 mov va, va, LSL #2 179 /* Convert pa to l1 entry: pa = (pa & L1_S_FRAME) | attr */ 180 and pa, pa, l1sfrm 181 orr pa, pa, attr 182 cmp n_sec, #0 183 bne 2b 184 mov r5, r0 /* l1table */ 185 .unreq va 186 .unreq pa 187 .unreq n_sec 188 .unreq attr 189 .unreq itable 190 .unreq l1table 191 .unreq l1sfrm 192 193 _PUTCHAR(Lconsole_pbase, r4, r3, 'c') 194 195 /* 196 * using FA526 -specific cache ops here... 197 */ 198 mov r0, #0 199 mcr p15, 0, r0, c7, c5, 0 /* Invalidate Entire I cache */ 200 mcr p15, 0, r0, c7, c14, 0 /* Clean & Invalidate Entire D cache */ 201 202 ldr r2, Lctl_ID_dis /* Disable I+D caches */ 203 mrc p15, 0, r1, c1, c0, 0 /* " " " */ 204 and r1, r1, r2 /* " " " */ 205 mcr p15, 0, r1, c1, c0, 0 /* " " " */ 206 207 _PUTCHAR(Lconsole_pbase, r4, r3, 'd') 208 209 mcr p15, 0, r0, c7, c5, 6 /* invalidate BTB all */ 210 mcr p15, 0, r0, c7, c10, 4 /* Drain the write buffers. */ 211 mcr p15, 0, r5, c2, c0, 0 /* Set Translation Table Base */ 212 mcr p15, 0, r0, c8, c7, 0 /* Invalidate TLBs */ 213 214 /* Set the Domain Access register */ 215 mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT) 216 mcr p15, 0, r0, c3, c0, 0 217 218 /* 219 * set Extension Control Enable in ECR, so we can use BTB 220 */ 221 ldr r0, Lecr_set 222 mcr p15, 0, r0, c1, c1, 0 223 224 /* 225 * Enable the MMU, etc. 226 */ 227 mrc p15, 0, r0, c1, c0, 0 228 ldr r1, Lcontrol_wax 229 and r0, r0, r1 230 ldr r1, Lcontrol_clr 231 mvn r1, r1 232 and r0, r0, r1 233 ldr r1, Lcontrol_set 234 orr r0, r0, r1 235 mcr p15, 0, r0, c1, c0, 0 236 237 /* 238 * Ensure that the coprocessor has finished turning on the MMU. 239 */ 240 mrc p15, 0, r0, c2, c0, 0 /* Read an arbitrary value. */ 241 mov r0, r0 /* Stall until read completes. */ 242 243 _PUTCHAR(Luart_vbase, r4, r3, 'e') 244 245 /* 246 * Zero .bss 247 */ 248 ldr r0, L_edata 249 ldr r1, L_end 250 mov r2, #0 2511: 252 str r2, [r0], #0x04 /* *r0++ = r2 */ 253 cmp r0, r1 254 bne 1b 255 256#if 0 257 /* 258 * Jump to start in locore.S, which in turn will call initarm and main. 259 */ 260 adr r0, Ltestjmp 261 ldr pc, [r0] 262 nop 263 nop 264 nop 265 nop 266testjmp: 267#endif 268 269 _PUTCHAR(Luart_vbase, r4, r3, 'f') 270 271 adr r0, Lstart 272 ldr pc, [r0] 273 nop 274 nop 275 nop 276 nop 277 278 /* NOTREACHED */ 279 280L_edata: 281 .word _C_LABEL(_edata) 282L_end: 283 .word _C_LABEL(_end) 284 285#if 0 286Ltestjmp: 287 .word testjmp 288#endif 289 290Lstart: 291 .word start 292Ll1_s_frame: 293 .word L1_S_FRAME 294Ltemp_l1_table: 295 /* Put the temporary L1 translation table at the end of SDRAM. */ 296 .word MEMSIZE * 0x100000 - L1_TABLE_SIZE 297 298/* 299 * Coprocessor register initialization values 300 */ 301#if !defined(CPU_ECR_ECE) 302# define CPU_ECR_ECE 1 303#endif 304 /* bits to set in the Extension Control Register */ 305Lecr_set: 306 .word CPU_ECR_ECE 307 308#if !defined(CPU_CONTROL_BTB_ENABLE) 309# define CPU_CONTROL_BTB_ENABLE (1 << 11) 310#endif 311 /* bits to set in the Control Register */ 312 /* bits 6..4 SB1 */ 313Lcontrol_set: 314 .word CPU_CONTROL_MMU_ENABLE | \ 315 CPU_CONTROL_AFLT_ENABLE | \ 316 CPU_CONTROL_DC_ENABLE | \ 317 CPU_CONTROL_WBUF_ENABLE | \ 318 CPU_CONTROL_32BP_ENABLE | \ 319 CPU_CONTROL_32BD_ENABLE | \ 320 CPU_CONTROL_LABT_ENABLE | \ 321 CPU_CONTROL_SYST_ENABLE | \ 322 CPU_CONTROL_IC_ENABLE | \ 323 CPU_CONTROL_DC_ENABLE | \ 324 CPU_CONTROL_BTB_ENABLE 325 326 /* bits to clear in the Control Register */ 327 /* bits 31..14, 10, SBZ */ 328Lcontrol_clr: 329 .word ((~0) << 14) | \ 330 (1 << 10) 331 332 /* bits to "write as existing" in the Control Register */ 333Lcontrol_wax: 334 .word CPU_CONTROL_BEND_ENABLE 335 336 /* bits to disable the caches */ 337Lctl_ID_dis: 338 .word ~(CPU_CONTROL_IC_ENABLE|CPU_CONTROL_DC_ENABLE) 339 340 /* console addressing */ 341Lconsole_pbase: 342#if 0 343 .word CONSADDR 344#else 345 .word GEMINI_UART_BASE 346#endif 347Luart_vbase: 348 .word GEMINI_UART_VBASE 349 350 351/* We'll modify va and pa at run time so we can use relocatable addresses. */ 352#define MMU_INIT(va,pa,n_sec,attr) \ 353 .word va ; \ 354 .word pa ; \ 355 .word n_sec ; \ 356 .word attr ; 357 358mmu_init_table: 359 /* Maintain current 1:1 addressability */ 360 MMU_INIT(KERNEL_BASE_phys, KERNEL_BASE_phys, 361 (MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, 362 L1_S_PROTO | L1_S_AP_KRW | L1_S_B | L1_S_C) 363 364 /* Map Kernel base VA:PA, write-back cacheable */ 365 MMU_INIT(KERNEL_BASE_virt, KERNEL_BASE_phys, 366 (MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, 367 L1_S_PROTO | L1_S_AP_KRW | L1_S_B | L1_S_C) 368 369 /* Map Gemini GLOBAL regs */ 370 MMU_INIT(GEMINI_GLOBAL_VBASE, GEMINI_GLOBAL_BASE, 371 1, 372 L1_S_PROTO | L1_S_AP_KRW) 373 374 /* Map Gemini UART */ 375 MMU_INIT(GEMINI_UART_VBASE, GEMINI_UART_BASE, 376 1, 377 L1_S_PROTO | L1_S_AP_KRW) 378 379 /* Map Gemini LPC Host Controller Space */ 380 MMU_INIT(GEMINI_LPCHC_VBASE, GEMINI_LPCHC_BASE, 381 1, 382 L1_S_PROTO | L1_S_AP_KRW) 383 384 /* Map Gemini LPC IO Space */ 385 MMU_INIT(GEMINI_LPCIO_VBASE, GEMINI_LPCIO_BASE, 386 1, 387 L1_S_PROTO | L1_S_AP_KRW) 388 389 /* Map Gemini DRAM Controller Space */ 390 MMU_INIT(GEMINI_DRAMC_VBASE, GEMINI_DRAMC_BASE, 391 1, 392 L1_S_PROTO | L1_S_AP_KRW) 393 394 /* end of table */ 395 MMU_INIT(0, 0, 0, 0) 396 397