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