1/* $OpenBSD: locore.S,v 1.23 2022/12/08 01:25:44 guenther Exp $ */ 2/* $NetBSD: locore.S,v 1.14 2003/04/20 16:21:40 thorpej Exp $ */ 3 4/* 5 * Copyright (C) 1994-1997 Mark Brinicombe 6 * Copyright (C) 1994 Brini 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by Brini. 20 * 4. The name of Brini may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL BRINI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 29 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 31 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35#include "assym.h" 36 37#include <sys/syscall.h> 38#include <sys/errno.h> 39 40#include <machine/asm.h> 41#include <machine/frame.h> 42#include <arm/armreg.h> 43#include <arm/sysreg.h> 44#include <arm/pte.h> 45 46/* What size should this really be ? It is only used by init_arm() */ 47#define INIT_ARM_STACK_SIZE 2048 48 49.arch_extension virt 50 51/* 52 * This is for kvm_mkdb, and should be the address of the beginning 53 * of the kernel text segment (not necessarily the same as kernbase). 54 */ 55 56 .text 57 .align 2 58 59ENTRY_NP(kernel_text) 60 61ASENTRY_NP(start) 62 mov r5, r1 63 mov r6, r2 64 mov r7, r3 65 adr r1, .Lstart 66 ldmia r1, {r1, r2, r8, sp} /* Set initial stack and */ 67 68 mcr CP15_TPIDRPRW(r8) /* put curcpu into the TPIDRPRW */ 69 70 sub r2, r2, r1 /* get zero init data */ 71 mov r3, #0 72 73.L1: 74 str r3, [r1], #0x0004 /* Zero the bss */ 75 subs r2, r2, #4 76 bgt .L1 77 78 mov fp, #0x00000000 /* trace back starts here */ 79 mov r1, r5 80 mov r2, r6 81 mov r3, r7 82 bl initarm /* Off we go */ 83 84 /* init arm will return the new stack pointer. */ 85 mov sp, r0 86 87 mov fp, #0x00000000 /* trace back starts here */ 88 mov ip, sp 89 stmfd sp!, {fp, ip, lr, pc} 90 sub fp, ip, #4 91 92 bl main /* call main()! */ 93 94 adr r0, .Lmainreturned 95 b panic 96 /* NOTREACHED */ 97 98.Lstart: 99 .word _edata 100 .word _end 101 .word cpu_info_primary 102 .word svcstk + INIT_ARM_STACK_SIZE 103 104.Lmainreturned: 105 .asciz "main() returned" 106 .align 2 107 108 .globl drop_to_pl1 109drop_to_pl1: 110 /* Drop to PL1 */ 111 mrs r0, cpsr 112 and r0, r0, #(PSR_MODE) 113 teq r0, #(PSR_HYP32_MODE) 114 beq 1f /* If we are not in HYP, we're done */ 115 mov pc, lr 1161: 117 mrs r0, cpsr 118 bic r0, r0, #(PSR_MODE) 119 orr r0, r0, #(PSR_SVC32_MODE) 120 orr r0, r0, #(PSR_I | PSR_F | PSR_A) 121 msr spsr_fsxc, r0 122 msr ELR_hyp, lr 123 eret /* Use the HYP LR to get into SVC */ 124 dsb nsh 125 isb 126 127 .globl start_mmu 128start_mmu: 129 /* Set ASID to zero */ 130 mov r1, #0 131 mcr CP15_CONTEXTIDR(r1) 132 isb 133 134 mcr CP15_TTBR0(r0) /* Set TTB */ 135 mcr CP15_TLBIALL(r0) /* Flush TLB */ 136 137 /* Set the Domain Access register. Very important! */ 138 mov r0, #DOMAIN_CLIENT /* We only use domain 0 */ 139 mcr CP15_DACR(r0) 140 isb 141 142 /* Enable MMU */ 143 mrc CP15_SCTLR(r0) 144 orr r0, r0, #CPU_CONTROL_MMU_ENABLE 145 mcr CP15_SCTLR(r0) 146 isb 147 148 mov pc, lr 149 150#ifdef MULTIPROCESSOR 151 152 .globl cpu_hatch 153cpu_hatch: 154 /* Drop to PL1 */ 155 bl drop_to_pl1 156 157 /* Convert virt -> phys */ 158 mov r9, pc 159 and r9, r9, #0xf0000000 160 161 /* Set up CPU info */ 162 adr r0, .Lcpu_hatch_ci 163 ldr r0, [r0] 164 bic r0, r0, #0xf0000000 165 orr r0, r0, r9 166 ldr r0, [r0] 167 ldr r1, [r0, #CI_SELF] 168 mcr CP15_TPIDRPRW(r1) 169 ldr r8, [r0, #CI_TTBR0] 170 171 /* Enable the mmu */ 172 orr r0, r9, #0x00200000 173 bl start_mmu 174 175 adr r1, .Lcpu_hatch_virt 176 ldr pc, [r1] 177 178cpu_hatch_virt: 179 mcr CP15_TTBR0(r8) /* Set TTB */ 180 mcr CP15_TLBIALL(r8) /* Flush TLB */ 181 182 mrc CP15_TPIDRPRW(r0) 183 ldr r1, [r0, #CI_PL1_STKEND] 184 mov sp, r1 185 186 adr r1, .Lcpu_start_secondary 187 ldr pc, [r1] 188 189 b . 190 191.Lcpu_hatch_virt: 192 .word cpu_hatch_virt 193.Lcpu_start_secondary: 194 .word cpu_start_secondary 195.Lcpu_hatch_ci: 196 .word cpu_hatch_ci 197 198 .data 199 .align 2 200 .global cpu_hatch_ci 201cpu_hatch_ci: 202 .word 0 203 204#endif 205 206 .bss 207 .align 3 208svcstk: 209 .space INIT_ARM_STACK_SIZE 210 211 .text 212 .align 2 213 214#ifndef OFW 215 /* OFW based systems will use OF_boot() */ 216 217.Lcpufuncs: 218 .word cpufuncs 219 220ENTRY_NP(cpu_reset) 221 mrs r2, cpsr 222 bic r2, r2, #(PSR_MODE) 223 orr r2, r2, #(PSR_SVC32_MODE) 224 orr r2, r2, #(PSR_I | PSR_F) 225 msr cpsr_c, r2 226 227 ldr r4, .Lcpu_reset_address 228 ldr r4, [r4] 229 230 ldr r0, .Lcpufuncs 231 mov lr, pc 232 ldr pc, [r0, #CF_IDCACHE_WBINV_ALL] 233 234 /* 235 * MMU & IDC off, 32 bit program & data space 236 * Hurl ourselves into the ROM 237 */ 238 mov r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE) 239 mov r2, #0 240 mcr CP15_SCTLR(r0) 241 mcr CP15_TLBIALL(r2) /* nail I+D TLB */ 242 mov pc, r4 243 244 /* 245 * _cpu_reset_address contains the address to branch to, to complete 246 * the cpu reset after turning the MMU off 247 * This variable is provided by the hardware specific code 248 */ 249.Lcpu_reset_address: 250 .word cpu_reset_address 251 252#endif /* OFW */ 253 254#ifdef DDB 255/* 256 * setjump + longjmp 257 */ 258ENTRY(setjmp) 259 stmia r0, {r4-r14} 260 mov r0, #0x00000000 261 mov pc, lr 262 263ENTRY(longjmp) 264 ldmia r0, {r4-r14} 265 mov r0, #0x00000001 266 mov pc, lr 267#endif /* DDB */ 268 269 .data 270 .align 2 271 .global esym 272esym: .word end 273 274ENTRY_NP(abort) 275 b abort 276