1/* $NetBSD: locore.S,v 1.1 2001/07/28 15:08:11 chris Exp $ */ 2 3/* 4 * Copyright (C) 1994-1997 Mark Brinicombe 5 * Copyright (C) 1994 Brini 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Brini. 19 * 4. The name of Brini may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL BRINI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34#include "opt_ipkdb.h" 35#include "assym.h" 36#include <sys/syscall.h> 37#include <sys/errno.h> 38#include <machine/asm.h> 39#include <machine/cpu.h> 40#include <machine/frame.h> 41#include <machine/param.h> 42 43/* What size should this really be ? It is only used by init_arm() */ 44#define INIT_ARM_STACK_SIZE 2048 45 46/* 47 * This is for kvm_mkdb, and should be the address of the beginning 48 * of the kernel text segment (not necessarily the same as kernbase). 49 */ 50 51#ifndef netwinder 52ENTRY_NP(kernel_text) 53#endif 54 55ASENTRY_NP(start) 56 add r1, pc, #(Lstart - . - 8) 57 ldmia r1, {r1, r2, sp} /* Set initial stack and */ 58 sub r2, r2, r1 /* get zero init data */ 59 mov r3, #0 60 61L1: 62 str r3, [r1], #0x0004 /* Zero the bss */ 63 subs r2, r2, #4 64 bgt L1 65 66 mov fp, #0x00000000 /* trace back starts here */ 67 bl _C_LABEL(initarm) /* Off we go */ 68 69 /* init arm will return the new stack pointer. */ 70 mov sp, r0 71 72 mov fp, #0x00000000 /* trace back starts here */ 73 mov ip, sp 74 stmfd sp!, {fp, ip, lr, pc} 75 sub fp, ip, #4 76 77 /* Setup an initial trap frame for start_init to use */ 78 79 PUSHFRAME 80 81 mov r0, sp /* parameter to main is trap frame */ 82 83 bl _C_LABEL(main) /* Lets light the flame and start her up */ 84 85 PULLFRAME /* Pull the trap frame, now valid */ 86 87 movs pc, lr /* Exit to user process */ 88 89 /* Never gets here */ 90 91 b . 92 93Lstart: 94 .word _edata 95 .word _end 96 .word svcstk + INIT_ARM_STACK_SIZE 97 98 .bss 99svcstk: 100 .space INIT_ARM_STACK_SIZE 101 102/* 103 * Instructions to copy to the bottom of zero page 104 * These are the entry point to the system exception routines 105 */ 106 107 .text 108 .align 0 109 .global _C_LABEL(page0), _C_LABEL(page0_end) 110_C_LABEL(page0): 111 ldr pc, [pc, #Lreset - . - 8] 112 ldr pc, [pc, #Lundefined - . - 8] 113 ldr pc, [pc, #Lswi - . - 8] 114 ldr pc, [pc, #Labortpre - . - 8] 115 ldr pc, [pc, #Labortdata - . - 8] 116 ldr pc, [pc, #Laddrexc - . - 8] 117 ldr pc, [pc, #Lirq - . - 8] 118 ldr pc, [pc, #Lfiq - . - 8] 119 120Lreset: 121 .word reset_entry 122Lundefined: 123 .word undefined_entry 124Lswi: 125 .word swi_entry 126Labortpre: 127 .word prefetch_abort_entry 128Labortdata: 129 .word data_abort_entry 130Laddrexc: 131 .word addrexc 132Lirq: 133 .word irq_entry 134Lfiq: 135 .word fiq 136_C_LABEL(page0_end) = . 137 138/* vector 0x00000000 - RESET */ 139 140ASENTRY_NP(reset_entry) 141 PUSHFRAME 142 143 mov r0, sp /* Pass the frame to function */ 144 b _C_LABEL(resethandler) /* It's a branch throught zero ! */ 145 146/* vector 0x00000008 - ADDRESS EXCEPTION */ 147 148ASENTRY_NP(addrexc) 149 mrs r1, cpsr_all 150 mrs r2, spsr_all 151 mov r3, lr 152 add r0, pc, #Laddrexcmsg - . - 8 153 bl _C_LABEL(printf) 154 b data_abort_entry 155 156Laddrexcmsg: 157 .asciz "address exception CPSR=%08x SPSR=%08x lr=%08x\n" 158 .align 0 159 160/* vector 0x0000001C - FIQ */ 161 162ASENTRY_NP(fiq) 163 ldr r0, Lfiqmsg 164 b _C_LABEL(panic) 165 166Lfiqmsg: 167 .asciz "fiq" 168 .align 0 169 170#ifndef OFW 171 /* OFW based systems will used OF_boot() */ 172 173Lcpufuncs: 174 .word _C_LABEL(cpufuncs) 175 176ENTRY_NP(cpu_reset) 177 mrs r2, cpsr_all 178 bic r2, r2, #(PSR_MODE) 179 orr r2, r2, #(PSR_SVC32_MODE) 180 orr r2, r2, #(I32_bit | F32_bit) 181 msr cpsr_all, r2 182 183 ldr r4, Lcpu_reset_address 184 ldr r4, [r4] 185 186 ldr r0, Lcpufuncs 187 add lr, pc, #Lboot_cache_purged - . - 8 188 ldr pc, [r0, #CF_CACHE_PURGE_ID] 189 190Lboot_cache_purged: 191 192 /* 193 * Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's 194 * necessary. 195 */ 196 197 ldr r1, Lcpu_reset_needs_v4_MMU_disable 198 ldr r1, [r1] 199 cmp r1, #0 200 201 /* 202 * MMU & IDC off, 32 bit program & data space 203 * Hurl ourselves into the ROM 204 */ 205 mov r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE) 206 mcr 15, 0, r0, c1, c0, 0 207 mcrne 15, 0, r0, c8, c7, 0 /* only when v4 MMU disable is asked for */ 208 mov pc, r4 209 210 /* 211 * _cpu_reset_address contains the address to branch to, to complete 212 * the cpu reset after turning the MMU off 213 * This variable is provided by the hardware specific code 214 */ 215Lcpu_reset_address: 216 .word _C_LABEL(cpu_reset_address) 217 218 /* 219 * cpu_reset_needs_v4_MMU_disable contains a flag that signals if the 220 * v4 MMU disable instruction needs executing... it is an illegal instruction 221 * on f.e. ARM6/7 that locks up the computer in an endless illegal 222 * instruction / data-abort / reset loop. 223 */ 224Lcpu_reset_needs_v4_MMU_disable: 225 .word _C_LABEL(cpu_reset_needs_v4_MMU_disable) 226 227#endif /* OFW */ 228 229#ifdef IPKDB 230#if 0 231/* 232 * ipkdbfbyte and ipkdbsbyte are now in ipkdb_glue.c and do not tweak 233 * the abort handler anymore 234 */ 235ENTRY_NP(ipkdbfbyte) 236 ldr ip, abortp 237 ldr r2, [ip] 238 add r3, pc, #ipkdbfault - . - 8 239 str r3, [ip] 240 ldrb r0, [r0] 241 str r2, [ip] 242 mov pc, lr 243 244ENTRY_NP(ipkdbsbyte) 245 ldr ip, abortp 246 ldr r2, [ip] 247 add r3, pc, #ipkdbfault - . - 8 248 str r3, [ip] 249 strb r1, [r0] 250 sub r0, r0, r0 251 str r2, [ip] 252 mov pc, lr 253 254abortp: 255 .word Labortdata - _C_LABEL(page0) 256ipkdbfault: 257 mov r0, #0xd3 258 msr cpsr_all, r0 259 mvn r0, #0 /* mov r0, #-1 */ 260 str r2, [ip] 261 mov pc, lr 262#endif 263 264/* 265 * Execute(inst, psr, args, sp) 266 * 267 * Execute INSTruction with PSR and ARGS[0] - ARGS[3] making 268 * available stack at SP for next undefined instruction trap. 269 * 270 * Move the instruction onto the stack and jump to it. 271 */ 272ENTRY_NP(Execute) 273 mov ip, sp 274 stmfd sp!, {r2, r4-r7, fp, ip, lr, pc} 275 sub fp, ip, #4 276 mov ip, r3 277 ldr r7, return 278 stmfd sp!, {r0, r7} 279 add r7, pc, #LExec - . - 8 280 mov r5, r1 281 mrs r4, cpsr_all 282 ldmia r2, {r0-r3} 283 mov r6, sp 284 mov sp, ip 285 msr cpsr_all, r5 286 mov pc, r6 287LExec: 288 mrs r5, cpsr_all 289/* XXX Cannot switch thus easily back from user mode */ 290 msr cpsr_all, r4 291 add sp, r6, #8 292 ldmfd sp!, {r6} 293 stmia r6, {r0-r3} 294 mov r0, r5 295 ldmdb fp, {r4-r7, fp, sp, pc} 296return: 297 mov pc, r7 298#endif 299 300/* 301 * setjump + longjmp 302 */ 303ENTRY(setjmp) 304 stmia r0, {r4-r14} 305 mov r0, #0x00000000 306 mov pc, lr 307 308ENTRY(longjmp) 309 ldmia r0, {r4-r14} 310 mov r0, #0x00000001 311 mov pc, lr 312 313 .data 314 .global _C_LABEL(esym) 315_C_LABEL(esym): .word _C_LABEL(end) 316 317ENTRY_NP(abort) 318 b _C_LABEL(abort) 319 320 321/* 322 * Atomic bit set and clear functions 323 */ 324 325ENTRY(atomic_set_bit) 326 mrs r2, cpsr_all 327 orr r3, r2, #(I32_bit) 328 msr cpsr_all, r3 329 330 ldr r3, [r0] 331 orr r3, r3, r1 332 str r3, [r0] 333 334 msr cpsr_all, r2 335 mov pc, lr 336 337 338ENTRY(atomic_clear_bit) 339 mrs r2, cpsr_all 340 orr r3, r2, #(I32_bit) 341 msr cpsr_all, r3 342 343 ldr r3, [r0] 344 bic r3, r3, r1 345 str r3, [r0] 346 347 msr cpsr_all, r2 348 mov pc, lr 349 350/* End of locore.S */ 351