1/* $NetBSD: locore.S,v 1.6 2002/04/25 23:23:23 thorpej 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 .text 52 .align 0 53 54ENTRY_NP(kernel_text) 55 56ASENTRY_NP(start) 57 add r1, pc, #(Lstart - . - 8) 58 ldmia r1, {r1, r2, sp} /* Set initial stack and */ 59 sub r2, r2, r1 /* get zero init data */ 60 mov r3, #0 61 62L1: 63 str r3, [r1], #0x0004 /* Zero the bss */ 64 subs r2, r2, #4 65 bgt L1 66 67 mov fp, #0x00000000 /* trace back starts here */ 68 bl _C_LABEL(initarm) /* Off we go */ 69 70 /* init arm will return the new stack pointer. */ 71 mov sp, r0 72 73 mov fp, #0x00000000 /* trace back starts here */ 74 mov ip, sp 75 stmfd sp!, {fp, ip, lr, pc} 76 sub fp, ip, #4 77 78 bl _C_LABEL(main) /* call main()! */ 79 80 add r0, pc, #Lmainreturned - . - 8 81 b _C_LABEL(panic) 82 /* NOTEACHED */ 83 84Lstart: 85 .word _edata 86 .word _end 87 .word svcstk + INIT_ARM_STACK_SIZE 88 89Lmainreturned: 90 .asciz "main() returned" 91 .align 0 92 93 .bss 94svcstk: 95 .space INIT_ARM_STACK_SIZE 96 97 .text 98 .align 0 99 100#ifndef OFW 101 /* OFW based systems will used OF_boot() */ 102 103Lcpufuncs: 104 .word _C_LABEL(cpufuncs) 105 106ENTRY_NP(cpu_reset) 107 mrs r2, cpsr_all 108 bic r2, r2, #(PSR_MODE) 109 orr r2, r2, #(PSR_SVC32_MODE) 110 orr r2, r2, #(I32_bit | F32_bit) 111 msr cpsr_all, r2 112 113 ldr r4, Lcpu_reset_address 114 ldr r4, [r4] 115 116 ldr r0, Lcpufuncs 117 add lr, pc, #Lboot_cache_purged - . - 8 118 ldr pc, [r0, #CF_IDCACHE_WBINV_ALL] 119 120Lboot_cache_purged: 121 122 /* 123 * Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's 124 * necessary. 125 */ 126 127 ldr r1, Lcpu_reset_needs_v4_MMU_disable 128 ldr r1, [r1] 129 cmp r1, #0 130 131 /* 132 * MMU & IDC off, 32 bit program & data space 133 * Hurl ourselves into the ROM 134 */ 135 mov r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE) 136 mcr 15, 0, r0, c1, c0, 0 137 mcrne 15, 0, r0, c8, c7, 0 /* nail I+D TLB on ARMv4 and greater */ 138 mov pc, r4 139 140 /* 141 * _cpu_reset_address contains the address to branch to, to complete 142 * the cpu reset after turning the MMU off 143 * This variable is provided by the hardware specific code 144 */ 145Lcpu_reset_address: 146 .word _C_LABEL(cpu_reset_address) 147 148 /* 149 * cpu_reset_needs_v4_MMU_disable contains a flag that signals if the 150 * v4 MMU disable instruction needs executing... it is an illegal instruction 151 * on f.e. ARM6/7 that locks up the computer in an endless illegal 152 * instruction / data-abort / reset loop. 153 */ 154Lcpu_reset_needs_v4_MMU_disable: 155 .word _C_LABEL(cpu_reset_needs_v4_MMU_disable) 156 157#endif /* OFW */ 158 159#ifdef IPKDB 160/* 161 * Execute(inst, psr, args, sp) 162 * 163 * Execute INSTruction with PSR and ARGS[0] - ARGS[3] making 164 * available stack at SP for next undefined instruction trap. 165 * 166 * Move the instruction onto the stack and jump to it. 167 */ 168ENTRY_NP(Execute) 169 mov ip, sp 170 stmfd sp!, {r2, r4-r7, fp, ip, lr, pc} 171 sub fp, ip, #4 172 mov ip, r3 173 ldr r7, return 174 stmfd sp!, {r0, r7} 175 add r7, pc, #LExec - . - 8 176 mov r5, r1 177 mrs r4, cpsr_all 178 ldmia r2, {r0-r3} 179 mov r6, sp 180 mov sp, ip 181 msr cpsr_all, r5 182 mov pc, r6 183LExec: 184 mrs r5, cpsr_all 185/* XXX Cannot switch thus easily back from user mode */ 186 msr cpsr_all, r4 187 add sp, r6, #8 188 ldmfd sp!, {r6} 189 stmia r6, {r0-r3} 190 mov r0, r5 191 ldmdb fp, {r4-r7, fp, sp, pc} 192return: 193 mov pc, r7 194#endif 195 196/* 197 * setjump + longjmp 198 */ 199ENTRY(setjmp) 200 stmia r0, {r4-r14} 201 mov r0, #0x00000000 202 mov pc, lr 203 204ENTRY(longjmp) 205 ldmia r0, {r4-r14} 206 mov r0, #0x00000001 207 mov pc, lr 208 209 .data 210 .global _C_LABEL(esym) 211_C_LABEL(esym): .word _C_LABEL(end) 212 213ENTRY_NP(abort) 214 b _C_LABEL(abort) 215 216 217/* 218 * Atomic bit set and clear functions 219 */ 220 221ENTRY(atomic_set_bit) 222 mrs r2, cpsr_all 223 orr r3, r2, #(I32_bit) 224 msr cpsr_all, r3 225 226 ldr r3, [r0] 227 orr r3, r3, r1 228 str r3, [r0] 229 230 msr cpsr_all, r2 231 mov pc, lr 232 233 234ENTRY(atomic_clear_bit) 235 mrs r2, cpsr_all 236 orr r3, r2, #(I32_bit) 237 msr cpsr_all, r3 238 239 ldr r3, [r0] 240 bic r3, r3, r1 241 str r3, [r0] 242 243 msr cpsr_all, r2 244 mov pc, lr 245 246/* End of locore.S */ 247