locore-v4.S revision 245414
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 245414 2013-01-14 09:11:18Z andrew $"); 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) 80236524Simp mov r9, r0 /* 0 or boot mode from boot2 */ 81236524Simp mov r8, r1 /* Save Machine type */ 82236524Simp mov ip, r2 /* Save meta data */ 83236524Simp mov fp, r3 /* Future expantion */ 84183878Sraj 85193846Smarcel /* Make sure interrupts are disabled. */ 86193846Smarcel mrs r7, cpsr 87193846Smarcel orr r7, r7, #(I32_bit|F32_bit) 88193846Smarcel msr cpsr_c, r7 89193846Smarcel 90166819Scognet#if defined (FLASHADDR) && defined(LOADERRAMADDR) 91166819Scognet /* Check if we're running from flash. */ 92166819Scognet ldr r7, =FLASHADDR 93175983Sraj /* 94166819Scognet * If we're running with MMU disabled, test against the 95166819Scognet * physical address instead. 96166819Scognet */ 97166819Scognet mrc p15, 0, r2, c1, c0, 0 98166819Scognet ands r2, r2, #CPU_CONTROL_MMU_ENABLE 99236524Simp ldreq r6, =PHYSADDR 100236524Simp ldrne r6, =LOADERRAMADDR 101236524Simp cmp r7, r6 102166819Scognet bls flash_lower 103166819Scognet cmp r7, pc 104166819Scognet bhi from_ram 105166819Scognet b do_copy 106166819Scognet 107166819Scognetflash_lower: 108236524Simp cmp r6, pc 109166819Scognet bls from_ram 110166819Scognetdo_copy: 111236524Simp ldr r7, =KERNBASE 112175983Sraj adr r1, _start 113166819Scognet ldr r0, Lreal_start 114166819Scognet ldr r2, Lend 115166819Scognet sub r2, r2, r0 116236524Simp sub r0, r0, r7 117236524Simp add r0, r0, r6 118166819Scognet mov r4, r0 119166819Scognet bl memcpy 120166819Scognet ldr r0, Lram_offset 121166819Scognet add pc, r4, r0 122166819ScognetLram_offset: .word from_ram-_C_LABEL(_start) 123166819Scognetfrom_ram: 124166819Scognet nop 125135640Scognet#endif 126135640Scognet adr r7, Lunmapped 127190602Scognet bic r7, r7, #0xf0000000 128153616Scognet orr r7, r7, #PHYSADDR 129143681Sjmg 130175983Sraj 131166819Scognetdisable_mmu: 132135640Scognet /* Disable MMU for a while */ 133143681Sjmg mrc p15, 0, r2, c1, c0, 0 134153550Scognet bic r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\ 135153550Scognet CPU_CONTROL_WBUF_ENABLE) 136153550Scognet bic r2, r2, #(CPU_CONTROL_IC_ENABLE) 137153550Scognet bic r2, r2, #(CPU_CONTROL_BPRD_ENABLE) 138135640Scognet mcr p15, 0, r2, c1, c0, 0 139129198Scognet 140135640Scognet nop 141135640Scognet nop 142135640Scognet nop 143135640Scognet mov pc, r7 144135640ScognetLunmapped: 145135640Scognet#ifdef STARTUP_PAGETABLE_ADDR 146129198Scognet /* build page table from scratch */ 147129198Scognet ldr r0, Lstartup_pagetable 148129198Scognet adr r4, mmu_init_table 149129198Scognet b 3f 150129198Scognet 151129198Scognet2: 152129198Scognet str r3, [r0, r2] 153129198Scognet add r2, r2, #4 154129198Scognet add r3, r3, #(L1_S_SIZE) 155129198Scognet adds r1, r1, #-1 156129198Scognet bhi 2b 157143681Sjmg3: 158172356Scognet ldmia r4!, {r1,r2,r3} /* # of sections, VA, PA|attr */ 159129198Scognet cmp r1, #0 160140683Scognet adrne r5, 2b 161190602Scognet bicne r5, r5, #0xf0000000 162140683Scognet orrne r5, r5, #PHYSADDR 163140683Scognet movne pc, r5 164129198Scognet 165239268Sgonzo#if defined(SMP) 166239268Sgonzo orr r0, r0, #2 /* Set TTB shared memory flag */ 167239268Sgonzo#endif 168129198Scognet mcr p15, 0, r0, c2, c0, 0 /* Set TTB */ 169129198Scognet mcr p15, 0, r0, c8, c7, 0 /* Flush TLB */ 170129198Scognet 171244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176) || defined(CPU_CORTEXA) || defined(CPU_MV_PJ4B) 172239268Sgonzo mov r0, #0 173239268Sgonzo mcr p15, 0, r0, c13, c0, 1 /* Set ASID to 0 */ 174239268Sgonzo#endif 175239268Sgonzo 176129198Scognet /* Set the Domain Access register. Very important! */ 177143681Sjmg mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT) 178129198Scognet mcr p15, 0, r0, c3, c0, 0 179129198Scognet /* Enable MMU */ 180129198Scognet mrc p15, 0, r0, c1, c0, 0 181244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176) || defined(CPU_CORTEXA) || defined(CPU_MV_PJ4B) 182239268Sgonzo orr r0, r0, #CPU_CONTROL_V6_EXTPAGE 183239268Sgonzo#endif 184243602Sgonzo orr r0, r0, #(CPU_CONTROL_MMU_ENABLE) 185129198Scognet mcr p15, 0, r0, c1, c0, 0 186153550Scognet nop 187153550Scognet nop 188153550Scognet nop 189129198Scognet CPWAIT(r0) 190129198Scognet 191153550Scognet#endif 192129198Scognetmmu_done: 193153550Scognet nop 194129198Scognet adr r1, .Lstart 195129198Scognet ldmia r1, {r1, r2, sp} /* Set initial stack and */ 196129198Scognet sub r2, r2, r1 /* get zero init data */ 197129198Scognet mov r3, #0 198129198Scognet.L1: 199150863Scognet str r3, [r1], #0x0004 /* get zero init data */ 200129198Scognet subs r2, r2, #4 201129198Scognet bgt .L1 202153550Scognet ldr pc, .Lvirt_done 203129198Scognet 204142145Scognetvirt_done: 205236524Simp mov r1, #20 /* loader info size is 20 bytes also second arg */ 206236524Simp subs sp, sp, r1 /* allocate arm_boot_params struct on stack */ 207236524Simp mov r0, sp /* loader info pointer is first arg */ 208236524Simp str r1, [r0] /* Store length of loader info */ 209236524Simp str r9, [r0, #4] /* Store r0 from boot loader */ 210236524Simp str r8, [r0, #8] /* Store r1 from boot loader */ 211236524Simp str ip, [r0, #12] /* store r2 from boot loader */ 212236524Simp str fp, [r0, #16] /* store r3 from boot loader */ 213175983Sraj mov fp, #0 /* trace back starts here */ 214129198Scognet bl _C_LABEL(initarm) /* Off we go */ 215129198Scognet 216129198Scognet /* init arm will return the new stack pointer. */ 217129198Scognet mov sp, r0 218129198Scognet 219129198Scognet bl _C_LABEL(mi_startup) /* call mi_startup()! */ 220129198Scognet 221129198Scognet adr r0, .Lmainreturned 222130164Sphk b _C_LABEL(panic) 223175983Sraj /* NOTREACHED */ 224129198Scognet#ifdef STARTUP_PAGETABLE_ADDR 225129198Scognet#define MMU_INIT(va,pa,n_sec,attr) \ 226129198Scognet .word n_sec ; \ 227129198Scognet .word 4*((va)>>L1_S_SHIFT) ; \ 228129198Scognet .word (pa)|(attr) ; 229129198Scognet 230150863ScognetLvirtaddr: 231150863Scognet .word KERNVIRTADDR 232150863ScognetLphysaddr: 233150863Scognet .word KERNPHYSADDR 234166819ScognetLreal_start: 235166819Scognet .word _start 236166819ScognetLend: 237166819Scognet .word _edata 238129198ScognetLstartup_pagetable: 239129198Scognet .word STARTUP_PAGETABLE_ADDR 240239268Sgonzo#ifdef SMP 241239268SgonzoLstartup_pagetable_secondary: 242239268Sgonzo .word temp_pagetable 243239268Sgonzo#endif 244143681Sjmgmmu_init_table: 245129198Scognet /* fill all table VA==PA */ 246129198Scognet /* map SDRAM VA==PA, WT cacheable */ 247239268Sgonzo#if !defined(SMP) 248135640Scognet MMU_INIT(PHYSADDR, PHYSADDR , 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)) 249135640Scognet /* map VA 0xc0000000..0xc3ffffff to PA */ 250135640Scognet MMU_INIT(KERNBASE, PHYSADDR, 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)) 251239268Sgonzo#else 252239268Sgonzo MMU_INIT(PHYSADDR, PHYSADDR , 64, L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW)) 253239268Sgonzo /* map VA 0xc0000000..0xc3ffffff to PA */ 254239268Sgonzo MMU_INIT(KERNBASE, PHYSADDR, 64, L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW)) 255239268Sgonzo MMU_INIT(0x48000000, 0x48000000, 1, L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW)) 256239268Sgonzo#endif 257129198Scognet .word 0 /* end of table */ 258129198Scognet#endif 259129198Scognet.Lstart: 260129198Scognet .word _edata 261129198Scognet .word _end 262129198Scognet .word svcstk + INIT_ARM_STACK_SIZE 263129198Scognet 264153550Scognet.Lvirt_done: 265153550Scognet .word virt_done 266239268Sgonzo#if defined(SMP) 267239268Sgonzo.Lmpvirt_done: 268239268Sgonzo .word mpvirt_done 269239268Sgonzo#endif 270239268Sgonzo 271129198Scognet.Lmainreturned: 272129198Scognet .asciz "main() returned" 273129198Scognet .align 0 274129198Scognet 275129198Scognet .bss 276129198Scognetsvcstk: 277129198Scognet .space INIT_ARM_STACK_SIZE 278129198Scognet 279129198Scognet .text 280129198Scognet .align 0 281129198Scognet 282143681Sjmg.Lcpufuncs: 283129198Scognet .word _C_LABEL(cpufuncs) 284129198Scognet 285239268Sgonzo#if defined(SMP) 286239268SgonzoLsramaddr: 287239268Sgonzo .word 0xffff0080 288239268Sgonzo 289239268Sgonzo#if 0 290239268Sgonzo#define AP_DEBUG(tmp) \ 291239268Sgonzo mrc p15, 0, r1, c0, c0, 5; \ 292239268Sgonzo ldr r0, Lsramaddr; \ 293239268Sgonzo add r0, r1, lsl #2; \ 294239268Sgonzo mov r1, tmp; \ 295239268Sgonzo str r1, [r0], #0x0000; 296239268Sgonzo#else 297239268Sgonzo#define AP_DEBUG(tmp) 298239268Sgonzo#endif 299239268Sgonzo 300239268Sgonzo 301239268SgonzoASENTRY_NP(mptramp) 302239268Sgonzo mov r0, #0 303239268Sgonzo mcr p15, 0, r0, c7, c7, 0 304239268Sgonzo 305239268Sgonzo AP_DEBUG(#1) 306239268Sgonzo 307239268Sgonzo mrs r3, cpsr_all 308239268Sgonzo bic r3, r3, #(PSR_MODE) 309239268Sgonzo orr r3, r3, #(PSR_SVC32_MODE) 310239268Sgonzo msr cpsr_all, r3 311239268Sgonzo 312239268Sgonzo mrc p15, 0, r0, c0, c0, 5 313239268Sgonzo and r0, #0x0f /* Get CPU ID */ 314239268Sgonzo 315239268Sgonzo /* Read boot address for CPU */ 316239268Sgonzo mov r1, #0x100 317239268Sgonzo mul r2, r0, r1 318239268Sgonzo ldr r1, Lpmureg 319239268Sgonzo add r0, r2, r1 320239268Sgonzo ldr r1, [r0], #0x00 321239268Sgonzo 322239268Sgonzo mov pc, r1 323239268Sgonzo 324239268SgonzoLpmureg: 325239268Sgonzo .word 0xd0022124 326239268Sgonzo 327239268SgonzoASENTRY_NP(mpentry) 328239268Sgonzo 329239268Sgonzo AP_DEBUG(#2) 330239268Sgonzo 331239268Sgonzo /* Make sure interrupts are disabled. */ 332239268Sgonzo mrs r7, cpsr 333239268Sgonzo orr r7, r7, #(I32_bit|F32_bit) 334239268Sgonzo msr cpsr_c, r7 335239268Sgonzo 336239268Sgonzo 337239268Sgonzo adr r7, Ltag 338239268Sgonzo bic r7, r7, #0xf0000000 339239268Sgonzo orr r7, r7, #PHYSADDR 340239268Sgonzo 341239268Sgonzo /* Disable MMU for a while */ 342239268Sgonzo mrc p15, 0, r2, c1, c0, 0 343239268Sgonzo bic r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\ 344239268Sgonzo CPU_CONTROL_WBUF_ENABLE) 345239268Sgonzo bic r2, r2, #(CPU_CONTROL_IC_ENABLE) 346239268Sgonzo bic r2, r2, #(CPU_CONTROL_BPRD_ENABLE) 347239268Sgonzo mcr p15, 0, r2, c1, c0, 0 348239268Sgonzo 349239268Sgonzo nop 350239268Sgonzo nop 351239268Sgonzo nop 352239268Sgonzo 353239268Sgonzo AP_DEBUG(#3) 354239268Sgonzo 355239268SgonzoLtag: 356239268Sgonzo ldr r0, Lstartup_pagetable_secondary 357239268Sgonzo bic r0, r0, #0xf0000000 358239268Sgonzo orr r0, r0, #PHYSADDR 359239268Sgonzo ldr r0, [r0] 360239268Sgonzo#if defined(SMP) 361239268Sgonzo orr r0, r0, #0 /* Set TTB shared memory flag */ 362239268Sgonzo#endif 363239268Sgonzo mcr p15, 0, r0, c2, c0, 0 /* Set TTB */ 364239268Sgonzo mcr p15, 0, r0, c8, c7, 0 /* Flush TLB */ 365239268Sgonzo 366244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176) || defined(CPU_MV_PJ4B) || defined(CPU_CORTEXA) 367239268Sgonzo mov r0, #0 368239268Sgonzo mcr p15, 0, r0, c13, c0, 1 /* Set ASID to 0 */ 369239268Sgonzo#endif 370239268Sgonzo 371239268Sgonzo AP_DEBUG(#4) 372239268Sgonzo 373239268Sgonzo /* Set the Domain Access register. Very important! */ 374239268Sgonzo mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT) 375239268Sgonzo mcr p15, 0, r0, c3, c0, 0 376239268Sgonzo /* Enable MMU */ 377239268Sgonzo mrc p15, 0, r0, c1, c0, 0 378244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176) || defined(CPU_MV_PJ4B) || defined(CPU_CORTEXA) 379239268Sgonzo orr r0, r0, #CPU_CONTROL_V6_EXTPAGE 380239268Sgonzo#endif 381239268Sgonzo orr r0, r0, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE) 382239268Sgonzo mcr p15, 0, r0, c1, c0, 0 383239268Sgonzo nop 384239268Sgonzo nop 385239268Sgonzo nop 386239268Sgonzo CPWAIT(r0) 387239268Sgonzo 388239268Sgonzo adr r1, .Lstart 389239268Sgonzo ldmia r1, {r1, r2, sp} /* Set initial stack and */ 390239268Sgonzo mrc p15, 0, r0, c0, c0, 5 391239268Sgonzo and r0, r0, #15 392239268Sgonzo mov r1, #2048 393239268Sgonzo mul r2, r1, r0 394239268Sgonzo sub sp, sp, r2 395239268Sgonzo str r1, [sp] 396239268Sgonzo ldr pc, .Lmpvirt_done 397239268Sgonzo 398239268Sgonzompvirt_done: 399239268Sgonzo 400239268Sgonzo mov fp, #0 /* trace back starts here */ 401239268Sgonzo bl _C_LABEL(init_secondary) /* Off we go */ 402239268Sgonzo 403239268Sgonzo adr r0, .Lmpreturned 404239268Sgonzo b _C_LABEL(panic) 405239268Sgonzo /* NOTREACHED */ 406239268Sgonzo 407239268Sgonzo.Lmpreturned: 408239268Sgonzo .asciz "main() returned" 409239268Sgonzo .align 0 410239268Sgonzo#endif 411239268Sgonzo 412135640ScognetENTRY_NP(cpu_halt) 413129198Scognet mrs r2, cpsr 414129198Scognet bic r2, r2, #(PSR_MODE) 415129198Scognet orr r2, r2, #(PSR_SVC32_MODE) 416129198Scognet orr r2, r2, #(I32_bit | F32_bit) 417129198Scognet msr cpsr_all, r2 418129198Scognet 419129198Scognet ldr r4, .Lcpu_reset_address 420129198Scognet ldr r4, [r4] 421129198Scognet 422129198Scognet ldr r0, .Lcpufuncs 423129198Scognet mov lr, pc 424129198Scognet ldr pc, [r0, #CF_IDCACHE_WBINV_ALL] 425183839Sraj mov lr, pc 426183839Sraj ldr pc, [r0, #CF_L2CACHE_WBINV_ALL] 427129198Scognet 428129198Scognet /* 429129198Scognet * Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's 430129198Scognet * necessary. 431129198Scognet */ 432129198Scognet 433129198Scognet ldr r1, .Lcpu_reset_needs_v4_MMU_disable 434129198Scognet ldr r1, [r1] 435129198Scognet cmp r1, #0 436129198Scognet mov r2, #0 437129198Scognet 438129198Scognet /* 439175983Sraj * MMU & IDC off, 32 bit program & data space 440129198Scognet * Hurl ourselves into the ROM 441129198Scognet */ 442129198Scognet mov r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE) 443129198Scognet mcr 15, 0, r0, c1, c0, 0 444129198Scognet mcrne 15, 0, r2, c8, c7, 0 /* nail I+D TLB on ARMv4 and greater */ 445129198Scognet mov pc, r4 446129198Scognet 447129198Scognet /* 448129198Scognet * _cpu_reset_address contains the address to branch to, to complete 449129198Scognet * the cpu reset after turning the MMU off 450129198Scognet * This variable is provided by the hardware specific code 451129198Scognet */ 452129198Scognet.Lcpu_reset_address: 453129198Scognet .word _C_LABEL(cpu_reset_address) 454129198Scognet 455129198Scognet /* 456129198Scognet * cpu_reset_needs_v4_MMU_disable contains a flag that signals if the 457129198Scognet * v4 MMU disable instruction needs executing... it is an illegal instruction 458129198Scognet * on f.e. ARM6/7 that locks up the computer in an endless illegal 459129198Scognet * instruction / data-abort / reset loop. 460129198Scognet */ 461129198Scognet.Lcpu_reset_needs_v4_MMU_disable: 462129198Scognet .word _C_LABEL(cpu_reset_needs_v4_MMU_disable) 463129198Scognet 464129198Scognet 465129198Scognet/* 466129198Scognet * setjump + longjmp 467129198Scognet */ 468129198ScognetENTRY(setjmp) 469129198Scognet stmia r0, {r4-r14} 470129198Scognet mov r0, #0x00000000 471137463Scognet RET 472129198Scognet 473129198ScognetENTRY(longjmp) 474129198Scognet ldmia r0, {r4-r14} 475129198Scognet mov r0, #0x00000001 476137463Scognet RET 477129198Scognet 478129198Scognet .data 479129198Scognet .global _C_LABEL(esym) 480129198Scognet_C_LABEL(esym): .word _C_LABEL(end) 481129198Scognet 482129198ScognetENTRY_NP(abort) 483129198Scognet b _C_LABEL(abort) 484129198Scognet 485135640ScognetENTRY_NP(sigcode) 486135640Scognet mov r0, sp 487245414Sandrew 488245414Sandrew /* 489245414Sandrew * Call the sigreturn system call. 490245414Sandrew * 491245414Sandrew * We have to load r7 manually rather than using 492245414Sandrew * "ldr r7, =SYS_sigreturn" to ensure the value of szsigcode is 493245414Sandrew * correct. Using the alternative places esigcode at the address 494245414Sandrew * of the data rather than the address one past the data. 495245414Sandrew */ 496245414Sandrew 497245414Sandrew ldr r7, [pc, #12] /* Load SYS_sigreturn */ 498135640Scognet swi SYS_sigreturn 499135640Scognet 500135640Scognet /* Well if that failed we better exit quick ! */ 501135640Scognet 502245414Sandrew ldr r7, [pc, #8] /* Load SYS_exit */ 503135640Scognet swi SYS_exit 504135640Scognet 505245414Sandrew /* Branch back to retry SYS_sigreturn */ 506245414Sandrew b . - 16 507245414Sandrew 508245414Sandrew .word SYS_sigreturn 509245414Sandrew .word SYS_exit 510245414Sandrew 511135640Scognet .align 0 512135640Scognet .global _C_LABEL(esigcode) 513135640Scognet _C_LABEL(esigcode): 514143681Sjmg 515135640Scognet .data 516135640Scognet .global szsigcode 517135640Scognetszsigcode: 518135640Scognet .long esigcode-sigcode 519129198Scognet/* End of locore.S */ 520