1/* $NetBSD: locore.S,v 1.11 2002/10/19 12:22:33 bsh 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 adr r1, .Lstart 58 ldmia r1, {r1, r2, sp} /* Set initial stack and */ 59 sub r2, r2, r1 /* get zero init data */ 60 mov r3, #0 61 62.L1: 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 adr r0, .Lmainreturned 81 b _C_LABEL(panic) 82 /* NOTEACHED */ 83 84.Lstart: 85 .word _edata 86 .word _end 87 .word svcstk + INIT_ARM_STACK_SIZE 88 89.Lmainreturned: 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 103.Lcpufuncs: 104 .word _C_LABEL(cpufuncs) 105 106ENTRY_NP(cpu_reset) 107 mrs r2, cpsr 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 mov lr, pc 118 ldr pc, [r0, #CF_IDCACHE_WBINV_ALL] 119 120 /* 121 * Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's 122 * necessary. 123 */ 124 125 ldr r1, .Lcpu_reset_needs_v4_MMU_disable 126 ldr r1, [r1] 127 cmp r1, #0 128 129 /* 130 * MMU & IDC off, 32 bit program & data space 131 * Hurl ourselves into the ROM 132 */ 133 mov r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE) 134 mcr 15, 0, r0, c1, c0, 0 135 mcrne 15, 0, r0, c8, c7, 0 /* nail I+D TLB on ARMv4 and greater */ 136 mov pc, r4 137 138 /* 139 * _cpu_reset_address contains the address to branch to, to complete 140 * the cpu reset after turning the MMU off 141 * This variable is provided by the hardware specific code 142 */ 143.Lcpu_reset_address: 144 .word _C_LABEL(cpu_reset_address) 145 146 /* 147 * cpu_reset_needs_v4_MMU_disable contains a flag that signals if the 148 * v4 MMU disable instruction needs executing... it is an illegal instruction 149 * on f.e. ARM6/7 that locks up the computer in an endless illegal 150 * instruction / data-abort / reset loop. 151 */ 152.Lcpu_reset_needs_v4_MMU_disable: 153 .word _C_LABEL(cpu_reset_needs_v4_MMU_disable) 154 155#endif /* OFW */ 156 157#ifdef IPKDB 158/* 159 * Execute(inst, psr, args, sp) 160 * 161 * Execute INSTruction with PSR and ARGS[0] - ARGS[3] making 162 * available stack at SP for next undefined instruction trap. 163 * 164 * Move the instruction onto the stack and jump to it. 165 */ 166ENTRY_NP(Execute) 167 mov ip, sp 168 stmfd sp!, {r2, r4-r7, fp, ip, lr, pc} 169 sub fp, ip, #4 170 mov ip, r3 171 ldr r7, .Lreturn 172 stmfd sp!, {r0, r7} 173 adr r7, #.LExec 174 mov r5, r1 175 mrs r4, cpsr 176 ldmia r2, {r0-r3} 177 mov r6, sp 178 mov sp, ip 179 msr cpsr_all, r5 180 mov pc, r6 181.LExec: 182 mrs r5, cpsr 183/* XXX Cannot switch thus easily back from user mode */ 184 msr cpsr_all, r4 185 add sp, r6, #8 186 ldmfd sp!, {r6} 187 stmia r6, {r0-r3} 188 mov r0, r5 189 ldmdb fp, {r4-r7, fp, sp, pc} 190.Lreturn: 191 mov pc, r7 192#endif 193 194/* 195 * setjump + longjmp 196 */ 197ENTRY(setjmp) 198 stmia r0, {r4-r14} 199 mov r0, #0x00000000 200 mov pc, lr 201 202ENTRY(longjmp) 203 ldmia r0, {r4-r14} 204 mov r0, #0x00000001 205 mov pc, lr 206 207 .data 208 .global _C_LABEL(esym) 209_C_LABEL(esym): .word _C_LABEL(end) 210 211ENTRY_NP(abort) 212 b _C_LABEL(abort) 213 214 215/* End of locore.S */ 216