locore-v4.S revision 258845
1129198Scognet/* $NetBSD: locore.S,v 1.14 2003/04/20 16:21:40 thorpej Exp $ */ 2129198Scognet 3139735Simp/*- 4239268Sgonzo * Copyright 2011 Semihalf 5129198Scognet * Copyright (C) 1994-1997 Mark Brinicombe 6129198Scognet * Copyright (C) 1994 Brini 7129198Scognet * All rights reserved. 8129198Scognet * 9129198Scognet * Redistribution and use in source and binary forms, with or without 10129198Scognet * modification, are permitted provided that the following conditions 11129198Scognet * are met: 12129198Scognet * 1. Redistributions of source code must retain the above copyright 13129198Scognet * notice, this list of conditions and the following disclaimer. 14129198Scognet * 2. Redistributions in binary form must reproduce the above copyright 15129198Scognet * notice, this list of conditions and the following disclaimer in the 16129198Scognet * documentation and/or other materials provided with the distribution. 17129198Scognet * 3. All advertising materials mentioning features or use of this software 18129198Scognet * must display the following acknowledgement: 19129198Scognet * This product includes software developed by Brini. 20129198Scognet * 4. The name of Brini may not be used to endorse or promote products 21129198Scognet * derived from this software without specific prior written permission. 22129198Scognet * 23129198Scognet * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR 24129198Scognet * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25129198Scognet * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26129198Scognet * IN NO EVENT SHALL BRINI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27129198Scognet * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28129198Scognet * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 29129198Scognet * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30129198Scognet * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 31129198Scognet * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32129198Scognet * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33129198Scognet * 34129198Scognet */ 35129198Scognet 36129198Scognet#include "assym.s" 37135640Scognet#include <sys/syscall.h> 38129198Scognet#include <machine/asm.h> 39129198Scognet#include <machine/armreg.h> 40129198Scognet#include <machine/pte.h> 41236524Simp 42129198Scognet__FBSDID("$FreeBSD: head/sys/arm/arm/locore.S 258845 2013-12-02 13:09:59Z zbb $"); 43129198Scognet 44159849Simp/* What size should this really be ? It is only used by initarm() */ 45239268Sgonzo#define INIT_ARM_STACK_SIZE (2048 * 4) 46129198Scognet 47129198Scognet#define CPWAIT_BRANCH \ 48129198Scognet sub pc, pc, #4 49129198Scognet 50129198Scognet#define CPWAIT(tmp) \ 51129198Scognet mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\ 52129198Scognet mov tmp, tmp /* wait for it to complete */ ;\ 53129198Scognet CPWAIT_BRANCH /* branch to next insn */ 54129198Scognet 55235277Simp/* 56235277Simp * This is for kvm_mkdb, and should be the address of the beginning 57235277Simp * of the kernel text segment (not necessarily the same as kernbase). 58235277Simp */ 59129198Scognet .text 60129198Scognet .align 0 61129198Scognet.globl kernbase 62129198Scognet.set kernbase,KERNBASE 63150863Scognet.globl physaddr 64150863Scognet.set physaddr,PHYSADDR 65129198Scognet 66183878Sraj/* 67236524Simp * On entry for FreeBSD boot ABI: 68236524Simp * r0 - metadata pointer or 0 (boothowto on AT91's boot2) 69218227Smarcel * r1 - if (r0 == 0) then metadata pointer 70236524Simp * On entry for Linux boot ABI: 71236524Simp * r0 - 0 72236524Simp * r1 - machine type (passed as arg2 to initarm) 73236524Simp * r2 - Pointer to a tagged list or dtb image (phys addr) (passed as arg1 initarm) 74236524Simp * 75236524Simp * For both types of boot we gather up the args, put them in a struct arm_boot_params 76236524Simp * structure and pass that to initarm. 77183878Sraj */ 78236524SimpENTRY_NP(btext) 79218227SmarcelASENTRY_NP(_start) 80250253Sian STOP_UNWINDING /* Can't unwind into the bootloader! */ 81250253Sian 82236524Simp mov r9, r0 /* 0 or boot mode from boot2 */ 83236524Simp mov r8, r1 /* Save Machine type */ 84236524Simp mov ip, r2 /* Save meta data */ 85236524Simp mov fp, r3 /* Future expantion */ 86183878Sraj 87193846Smarcel /* Make sure interrupts are disabled. */ 88193846Smarcel mrs r7, cpsr 89193846Smarcel orr r7, r7, #(I32_bit|F32_bit) 90193846Smarcel msr cpsr_c, r7 91193846Smarcel 92166819Scognet#if defined (FLASHADDR) && defined(LOADERRAMADDR) 93166819Scognet /* Check if we're running from flash. */ 94166819Scognet ldr r7, =FLASHADDR 95175983Sraj /* 96166819Scognet * If we're running with MMU disabled, test against the 97166819Scognet * physical address instead. 98166819Scognet */ 99166819Scognet mrc p15, 0, r2, c1, c0, 0 100166819Scognet ands r2, r2, #CPU_CONTROL_MMU_ENABLE 101236524Simp ldreq r6, =PHYSADDR 102236524Simp ldrne r6, =LOADERRAMADDR 103236524Simp cmp r7, r6 104166819Scognet bls flash_lower 105166819Scognet cmp r7, pc 106166819Scognet bhi from_ram 107166819Scognet b do_copy 108166819Scognet 109166819Scognetflash_lower: 110236524Simp cmp r6, pc 111166819Scognet bls from_ram 112166819Scognetdo_copy: 113236524Simp ldr r7, =KERNBASE 114175983Sraj adr r1, _start 115166819Scognet ldr r0, Lreal_start 116166819Scognet ldr r2, Lend 117166819Scognet sub r2, r2, r0 118236524Simp sub r0, r0, r7 119236524Simp add r0, r0, r6 120166819Scognet mov r4, r0 121166819Scognet bl memcpy 122166819Scognet ldr r0, Lram_offset 123166819Scognet add pc, r4, r0 124166819ScognetLram_offset: .word from_ram-_C_LABEL(_start) 125166819Scognetfrom_ram: 126166819Scognet nop 127135640Scognet#endif 128135640Scognet adr r7, Lunmapped 129190602Scognet bic r7, r7, #0xf0000000 130153616Scognet orr r7, r7, #PHYSADDR 131143681Sjmg 132175983Sraj 133166819Scognetdisable_mmu: 134135640Scognet /* Disable MMU for a while */ 135143681Sjmg mrc p15, 0, r2, c1, c0, 0 136153550Scognet bic r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\ 137153550Scognet CPU_CONTROL_WBUF_ENABLE) 138153550Scognet bic r2, r2, #(CPU_CONTROL_IC_ENABLE) 139153550Scognet bic r2, r2, #(CPU_CONTROL_BPRD_ENABLE) 140135640Scognet mcr p15, 0, r2, c1, c0, 0 141129198Scognet 142135640Scognet nop 143135640Scognet nop 144135640Scognet nop 145135640Scognet mov pc, r7 146135640ScognetLunmapped: 147135640Scognet#ifdef STARTUP_PAGETABLE_ADDR 148129198Scognet /* build page table from scratch */ 149129198Scognet ldr r0, Lstartup_pagetable 150129198Scognet adr r4, mmu_init_table 151129198Scognet b 3f 152129198Scognet 153129198Scognet2: 154129198Scognet str r3, [r0, r2] 155129198Scognet add r2, r2, #4 156129198Scognet add r3, r3, #(L1_S_SIZE) 157129198Scognet adds r1, r1, #-1 158129198Scognet bhi 2b 159143681Sjmg3: 160172356Scognet ldmia r4!, {r1,r2,r3} /* # of sections, VA, PA|attr */ 161129198Scognet cmp r1, #0 162140683Scognet adrne r5, 2b 163190602Scognet bicne r5, r5, #0xf0000000 164140683Scognet orrne r5, r5, #PHYSADDR 165140683Scognet movne pc, r5 166129198Scognet 167239268Sgonzo#if defined(SMP) 168239268Sgonzo orr r0, r0, #2 /* Set TTB shared memory flag */ 169239268Sgonzo#endif 170129198Scognet mcr p15, 0, r0, c2, c0, 0 /* Set TTB */ 171129198Scognet mcr p15, 0, r0, c8, c7, 0 /* Flush TLB */ 172129198Scognet 173244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176) || defined(CPU_CORTEXA) || defined(CPU_MV_PJ4B) 174239268Sgonzo mov r0, #0 175239268Sgonzo mcr p15, 0, r0, c13, c0, 1 /* Set ASID to 0 */ 176239268Sgonzo#endif 177239268Sgonzo 178129198Scognet /* Set the Domain Access register. Very important! */ 179143681Sjmg mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT) 180129198Scognet mcr p15, 0, r0, c3, c0, 0 181248961Sian /* 182248961Sian * Enable MMU. 183248961Sian * On armv6 enable extended page tables, and set alignment checking 184248961Sian * to modulo-4 (CPU_CONTROL_UNAL_ENABLE) for the ldrd/strd 185248961Sian * instructions emitted by clang. 186248961Sian */ 187129198Scognet mrc p15, 0, r0, c1, c0, 0 188248961Sian#ifdef _ARM_ARCH_6 189248961Sian orr r0, r0, #(CPU_CONTROL_V6_EXTPAGE | CPU_CONTROL_UNAL_ENABLE) 190256628Sian orr r0, r0, #(CPU_CONTROL_AFLT_ENABLE) 191250928Sgber orr r0, r0, #(CPU_CONTROL_AF_ENABLE) 192239268Sgonzo#endif 193243602Sgonzo orr r0, r0, #(CPU_CONTROL_MMU_ENABLE) 194129198Scognet mcr p15, 0, r0, c1, c0, 0 195153550Scognet nop 196153550Scognet nop 197153550Scognet nop 198129198Scognet CPWAIT(r0) 199129198Scognet 200153550Scognet#endif 201129198Scognetmmu_done: 202153550Scognet nop 203129198Scognet adr r1, .Lstart 204129198Scognet ldmia r1, {r1, r2, sp} /* Set initial stack and */ 205129198Scognet sub r2, r2, r1 /* get zero init data */ 206129198Scognet mov r3, #0 207129198Scognet.L1: 208150863Scognet str r3, [r1], #0x0004 /* get zero init data */ 209129198Scognet subs r2, r2, #4 210129198Scognet bgt .L1 211153550Scognet ldr pc, .Lvirt_done 212129198Scognet 213142145Scognetvirt_done: 214236524Simp mov r1, #20 /* loader info size is 20 bytes also second arg */ 215236524Simp subs sp, sp, r1 /* allocate arm_boot_params struct on stack */ 216247608Sandrew bic sp, sp, #7 /* align stack to 8 bytes */ 217236524Simp mov r0, sp /* loader info pointer is first arg */ 218236524Simp str r1, [r0] /* Store length of loader info */ 219236524Simp str r9, [r0, #4] /* Store r0 from boot loader */ 220236524Simp str r8, [r0, #8] /* Store r1 from boot loader */ 221236524Simp str ip, [r0, #12] /* store r2 from boot loader */ 222236524Simp str fp, [r0, #16] /* store r3 from boot loader */ 223175983Sraj mov fp, #0 /* trace back starts here */ 224129198Scognet bl _C_LABEL(initarm) /* Off we go */ 225129198Scognet 226129198Scognet /* init arm will return the new stack pointer. */ 227129198Scognet mov sp, r0 228129198Scognet 229129198Scognet bl _C_LABEL(mi_startup) /* call mi_startup()! */ 230129198Scognet 231129198Scognet adr r0, .Lmainreturned 232130164Sphk b _C_LABEL(panic) 233175983Sraj /* NOTREACHED */ 234129198Scognet#ifdef STARTUP_PAGETABLE_ADDR 235129198Scognet#define MMU_INIT(va,pa,n_sec,attr) \ 236129198Scognet .word n_sec ; \ 237129198Scognet .word 4*((va)>>L1_S_SHIFT) ; \ 238129198Scognet .word (pa)|(attr) ; 239129198Scognet 240150863ScognetLvirtaddr: 241150863Scognet .word KERNVIRTADDR 242150863ScognetLphysaddr: 243150863Scognet .word KERNPHYSADDR 244166819ScognetLreal_start: 245166819Scognet .word _start 246166819ScognetLend: 247166819Scognet .word _edata 248129198ScognetLstartup_pagetable: 249129198Scognet .word STARTUP_PAGETABLE_ADDR 250239268Sgonzo#ifdef SMP 251239268SgonzoLstartup_pagetable_secondary: 252239268Sgonzo .word temp_pagetable 253239268Sgonzo#endif 254248361SandrewEND(btext) 255248361SandrewEND(_start) 256248361Sandrew 257143681Sjmgmmu_init_table: 258129198Scognet /* fill all table VA==PA */ 259129198Scognet /* map SDRAM VA==PA, WT cacheable */ 260239268Sgonzo#if !defined(SMP) 261135640Scognet MMU_INIT(PHYSADDR, PHYSADDR , 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)) 262135640Scognet /* map VA 0xc0000000..0xc3ffffff to PA */ 263135640Scognet MMU_INIT(KERNBASE, PHYSADDR, 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)) 264239268Sgonzo#else 265239268Sgonzo MMU_INIT(PHYSADDR, PHYSADDR , 64, L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW)) 266239268Sgonzo /* map VA 0xc0000000..0xc3ffffff to PA */ 267239268Sgonzo MMU_INIT(KERNBASE, PHYSADDR, 64, L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW)) 268239268Sgonzo MMU_INIT(0x48000000, 0x48000000, 1, L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW)) 269250293Sgber#endif /* SMP */ 270129198Scognet .word 0 /* end of table */ 271129198Scognet#endif 272129198Scognet.Lstart: 273129198Scognet .word _edata 274129198Scognet .word _end 275129198Scognet .word svcstk + INIT_ARM_STACK_SIZE 276129198Scognet 277153550Scognet.Lvirt_done: 278153550Scognet .word virt_done 279239268Sgonzo#if defined(SMP) 280239268Sgonzo.Lmpvirt_done: 281239268Sgonzo .word mpvirt_done 282239268Sgonzo#endif 283239268Sgonzo 284129198Scognet.Lmainreturned: 285129198Scognet .asciz "main() returned" 286129198Scognet .align 0 287129198Scognet 288129198Scognet .bss 289129198Scognetsvcstk: 290129198Scognet .space INIT_ARM_STACK_SIZE 291129198Scognet 292129198Scognet .text 293129198Scognet .align 0 294129198Scognet 295143681Sjmg.Lcpufuncs: 296129198Scognet .word _C_LABEL(cpufuncs) 297129198Scognet 298239268Sgonzo#if defined(SMP) 299239268SgonzoLsramaddr: 300239268Sgonzo .word 0xffff0080 301239268Sgonzo 302239268Sgonzo#if 0 303239268Sgonzo#define AP_DEBUG(tmp) \ 304239268Sgonzo mrc p15, 0, r1, c0, c0, 5; \ 305239268Sgonzo ldr r0, Lsramaddr; \ 306239268Sgonzo add r0, r1, lsl #2; \ 307239268Sgonzo mov r1, tmp; \ 308239268Sgonzo str r1, [r0], #0x0000; 309239268Sgonzo#else 310239268Sgonzo#define AP_DEBUG(tmp) 311239268Sgonzo#endif 312239268Sgonzo 313239268Sgonzo 314239268SgonzoASENTRY_NP(mptramp) 315239268Sgonzo mov r0, #0 316239268Sgonzo mcr p15, 0, r0, c7, c7, 0 317239268Sgonzo 318239268Sgonzo AP_DEBUG(#1) 319239268Sgonzo 320239268Sgonzo mrs r3, cpsr_all 321239268Sgonzo bic r3, r3, #(PSR_MODE) 322239268Sgonzo orr r3, r3, #(PSR_SVC32_MODE) 323239268Sgonzo msr cpsr_all, r3 324239268Sgonzo 325239268Sgonzo mrc p15, 0, r0, c0, c0, 5 326239268Sgonzo and r0, #0x0f /* Get CPU ID */ 327239268Sgonzo 328239268Sgonzo /* Read boot address for CPU */ 329239268Sgonzo mov r1, #0x100 330239268Sgonzo mul r2, r0, r1 331239268Sgonzo ldr r1, Lpmureg 332239268Sgonzo add r0, r2, r1 333239268Sgonzo ldr r1, [r0], #0x00 334239268Sgonzo 335239268Sgonzo mov pc, r1 336239268Sgonzo 337239268SgonzoLpmureg: 338239268Sgonzo .word 0xd0022124 339248361SandrewEND(mptramp) 340239268Sgonzo 341239268SgonzoASENTRY_NP(mpentry) 342239268Sgonzo 343239268Sgonzo AP_DEBUG(#2) 344239268Sgonzo 345239268Sgonzo /* Make sure interrupts are disabled. */ 346239268Sgonzo mrs r7, cpsr 347239268Sgonzo orr r7, r7, #(I32_bit|F32_bit) 348239268Sgonzo msr cpsr_c, r7 349239268Sgonzo 350239268Sgonzo 351239268Sgonzo adr r7, Ltag 352239268Sgonzo bic r7, r7, #0xf0000000 353239268Sgonzo orr r7, r7, #PHYSADDR 354239268Sgonzo 355239268Sgonzo /* Disable MMU for a while */ 356239268Sgonzo mrc p15, 0, r2, c1, c0, 0 357239268Sgonzo bic r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\ 358239268Sgonzo CPU_CONTROL_WBUF_ENABLE) 359239268Sgonzo bic r2, r2, #(CPU_CONTROL_IC_ENABLE) 360239268Sgonzo bic r2, r2, #(CPU_CONTROL_BPRD_ENABLE) 361239268Sgonzo mcr p15, 0, r2, c1, c0, 0 362239268Sgonzo 363239268Sgonzo nop 364239268Sgonzo nop 365239268Sgonzo nop 366239268Sgonzo 367239268Sgonzo AP_DEBUG(#3) 368239268Sgonzo 369239268SgonzoLtag: 370239268Sgonzo ldr r0, Lstartup_pagetable_secondary 371239268Sgonzo bic r0, r0, #0xf0000000 372239268Sgonzo orr r0, r0, #PHYSADDR 373239268Sgonzo ldr r0, [r0] 374239268Sgonzo#if defined(SMP) 375239268Sgonzo orr r0, r0, #0 /* Set TTB shared memory flag */ 376239268Sgonzo#endif 377239268Sgonzo mcr p15, 0, r0, c2, c0, 0 /* Set TTB */ 378239268Sgonzo mcr p15, 0, r0, c8, c7, 0 /* Flush TLB */ 379239268Sgonzo 380244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176) || defined(CPU_MV_PJ4B) || defined(CPU_CORTEXA) 381239268Sgonzo mov r0, #0 382239268Sgonzo mcr p15, 0, r0, c13, c0, 1 /* Set ASID to 0 */ 383239268Sgonzo#endif 384239268Sgonzo 385239268Sgonzo AP_DEBUG(#4) 386239268Sgonzo 387239268Sgonzo /* Set the Domain Access register. Very important! */ 388239268Sgonzo mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT) 389239268Sgonzo mcr p15, 0, r0, c3, c0, 0 390239268Sgonzo /* Enable MMU */ 391239268Sgonzo mrc p15, 0, r0, c1, c0, 0 392244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176) || defined(CPU_MV_PJ4B) || defined(CPU_CORTEXA) 393239268Sgonzo orr r0, r0, #CPU_CONTROL_V6_EXTPAGE 394258845Szbb orr r0, r0, #CPU_CONTROL_AF_ENABLE 395239268Sgonzo#endif 396239268Sgonzo orr r0, r0, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE) 397239268Sgonzo mcr p15, 0, r0, c1, c0, 0 398239268Sgonzo nop 399239268Sgonzo nop 400239268Sgonzo nop 401239268Sgonzo CPWAIT(r0) 402239268Sgonzo 403239268Sgonzo adr r1, .Lstart 404239268Sgonzo ldmia r1, {r1, r2, sp} /* Set initial stack and */ 405239268Sgonzo mrc p15, 0, r0, c0, c0, 5 406239268Sgonzo and r0, r0, #15 407239268Sgonzo mov r1, #2048 408239268Sgonzo mul r2, r1, r0 409239268Sgonzo sub sp, sp, r2 410239268Sgonzo str r1, [sp] 411239268Sgonzo ldr pc, .Lmpvirt_done 412239268Sgonzo 413239268Sgonzompvirt_done: 414239268Sgonzo 415239268Sgonzo mov fp, #0 /* trace back starts here */ 416239268Sgonzo bl _C_LABEL(init_secondary) /* Off we go */ 417239268Sgonzo 418239268Sgonzo adr r0, .Lmpreturned 419239268Sgonzo b _C_LABEL(panic) 420239268Sgonzo /* NOTREACHED */ 421239268Sgonzo 422239268Sgonzo.Lmpreturned: 423239268Sgonzo .asciz "main() returned" 424239268Sgonzo .align 0 425248361SandrewEND(mpentry) 426239268Sgonzo#endif 427239268Sgonzo 428135640ScognetENTRY_NP(cpu_halt) 429129198Scognet mrs r2, cpsr 430129198Scognet bic r2, r2, #(PSR_MODE) 431129198Scognet orr r2, r2, #(PSR_SVC32_MODE) 432129198Scognet orr r2, r2, #(I32_bit | F32_bit) 433129198Scognet msr cpsr_all, r2 434129198Scognet 435129198Scognet ldr r4, .Lcpu_reset_address 436129198Scognet ldr r4, [r4] 437129198Scognet 438129198Scognet ldr r0, .Lcpufuncs 439129198Scognet mov lr, pc 440129198Scognet ldr pc, [r0, #CF_IDCACHE_WBINV_ALL] 441183839Sraj mov lr, pc 442183839Sraj ldr pc, [r0, #CF_L2CACHE_WBINV_ALL] 443129198Scognet 444129198Scognet /* 445129198Scognet * Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's 446129198Scognet * necessary. 447129198Scognet */ 448129198Scognet 449129198Scognet ldr r1, .Lcpu_reset_needs_v4_MMU_disable 450129198Scognet ldr r1, [r1] 451129198Scognet cmp r1, #0 452129198Scognet mov r2, #0 453129198Scognet 454129198Scognet /* 455175983Sraj * MMU & IDC off, 32 bit program & data space 456129198Scognet * Hurl ourselves into the ROM 457129198Scognet */ 458129198Scognet mov r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE) 459129198Scognet mcr 15, 0, r0, c1, c0, 0 460129198Scognet mcrne 15, 0, r2, c8, c7, 0 /* nail I+D TLB on ARMv4 and greater */ 461129198Scognet mov pc, r4 462129198Scognet 463129198Scognet /* 464129198Scognet * _cpu_reset_address contains the address to branch to, to complete 465129198Scognet * the cpu reset after turning the MMU off 466129198Scognet * This variable is provided by the hardware specific code 467129198Scognet */ 468129198Scognet.Lcpu_reset_address: 469129198Scognet .word _C_LABEL(cpu_reset_address) 470129198Scognet 471129198Scognet /* 472129198Scognet * cpu_reset_needs_v4_MMU_disable contains a flag that signals if the 473129198Scognet * v4 MMU disable instruction needs executing... it is an illegal instruction 474129198Scognet * on f.e. ARM6/7 that locks up the computer in an endless illegal 475129198Scognet * instruction / data-abort / reset loop. 476129198Scognet */ 477129198Scognet.Lcpu_reset_needs_v4_MMU_disable: 478129198Scognet .word _C_LABEL(cpu_reset_needs_v4_MMU_disable) 479248361SandrewEND(cpu_halt) 480129198Scognet 481129198Scognet 482129198Scognet/* 483129198Scognet * setjump + longjmp 484129198Scognet */ 485129198ScognetENTRY(setjmp) 486129198Scognet stmia r0, {r4-r14} 487129198Scognet mov r0, #0x00000000 488137463Scognet RET 489248361SandrewEND(setjmp) 490129198Scognet 491129198ScognetENTRY(longjmp) 492129198Scognet ldmia r0, {r4-r14} 493129198Scognet mov r0, #0x00000001 494137463Scognet RET 495248361SandrewEND(longjmp) 496129198Scognet 497129198Scognet .data 498129198Scognet .global _C_LABEL(esym) 499129198Scognet_C_LABEL(esym): .word _C_LABEL(end) 500129198Scognet 501129198ScognetENTRY_NP(abort) 502129198Scognet b _C_LABEL(abort) 503248361SandrewEND(abort) 504129198Scognet 505135640ScognetENTRY_NP(sigcode) 506135640Scognet mov r0, sp 507245414Sandrew 508245414Sandrew /* 509245414Sandrew * Call the sigreturn system call. 510245414Sandrew * 511245414Sandrew * We have to load r7 manually rather than using 512245414Sandrew * "ldr r7, =SYS_sigreturn" to ensure the value of szsigcode is 513245414Sandrew * correct. Using the alternative places esigcode at the address 514245414Sandrew * of the data rather than the address one past the data. 515245414Sandrew */ 516245414Sandrew 517245414Sandrew ldr r7, [pc, #12] /* Load SYS_sigreturn */ 518135640Scognet swi SYS_sigreturn 519135640Scognet 520135640Scognet /* Well if that failed we better exit quick ! */ 521135640Scognet 522245414Sandrew ldr r7, [pc, #8] /* Load SYS_exit */ 523135640Scognet swi SYS_exit 524135640Scognet 525245414Sandrew /* Branch back to retry SYS_sigreturn */ 526245414Sandrew b . - 16 527245414Sandrew 528245414Sandrew .word SYS_sigreturn 529245414Sandrew .word SYS_exit 530245414Sandrew 531135640Scognet .align 0 532135640Scognet .global _C_LABEL(esigcode) 533135640Scognet _C_LABEL(esigcode): 534143681Sjmg 535135640Scognet .data 536135640Scognet .global szsigcode 537135640Scognetszsigcode: 538135640Scognet .long esigcode-sigcode 539248361SandrewEND(sigcode) 540129198Scognet/* End of locore.S */ 541