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> 40271327Sian#include <machine/cpuconf.h> 41129198Scognet#include <machine/pte.h> 42236524Simp 43129198Scognet__FBSDID("$FreeBSD$"); 44129198Scognet 45159849Simp/* What size should this really be ? It is only used by initarm() */ 46239268Sgonzo#define INIT_ARM_STACK_SIZE (2048 * 4) 47129198Scognet 48129198Scognet#define CPWAIT_BRANCH \ 49129198Scognet sub pc, pc, #4 50129198Scognet 51129198Scognet#define CPWAIT(tmp) \ 52129198Scognet mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\ 53129198Scognet mov tmp, tmp /* wait for it to complete */ ;\ 54129198Scognet CPWAIT_BRANCH /* branch to next insn */ 55129198Scognet 56235277Simp/* 57235277Simp * This is for kvm_mkdb, and should be the address of the beginning 58235277Simp * of the kernel text segment (not necessarily the same as kernbase). 59235277Simp */ 60129198Scognet .text 61129198Scognet .align 0 62129198Scognet.globl kernbase 63129198Scognet.set kernbase,KERNBASE 64150863Scognet.globl physaddr 65150863Scognet.set physaddr,PHYSADDR 66129198Scognet 67183878Sraj/* 68236524Simp * On entry for FreeBSD boot ABI: 69236524Simp * r0 - metadata pointer or 0 (boothowto on AT91's boot2) 70218227Smarcel * r1 - if (r0 == 0) then metadata pointer 71236524Simp * On entry for Linux boot ABI: 72236524Simp * r0 - 0 73236524Simp * r1 - machine type (passed as arg2 to initarm) 74236524Simp * r2 - Pointer to a tagged list or dtb image (phys addr) (passed as arg1 initarm) 75236524Simp * 76236524Simp * For both types of boot we gather up the args, put them in a struct arm_boot_params 77236524Simp * structure and pass that to initarm. 78183878Sraj */ 79269796Sian .globl btext 80269796Sianbtext: 81218227SmarcelASENTRY_NP(_start) 82250253Sian STOP_UNWINDING /* Can't unwind into the bootloader! */ 83250253Sian 84236524Simp mov r9, r0 /* 0 or boot mode from boot2 */ 85236524Simp mov r8, r1 /* Save Machine type */ 86236524Simp mov ip, r2 /* Save meta data */ 87236524Simp mov fp, r3 /* Future expantion */ 88183878Sraj 89193846Smarcel /* Make sure interrupts are disabled. */ 90193846Smarcel mrs r7, cpsr 91193846Smarcel orr r7, r7, #(I32_bit|F32_bit) 92193846Smarcel msr cpsr_c, r7 93193846Smarcel 94166819Scognet#if defined (FLASHADDR) && defined(LOADERRAMADDR) 95166819Scognet /* Check if we're running from flash. */ 96166819Scognet ldr r7, =FLASHADDR 97175983Sraj /* 98166819Scognet * If we're running with MMU disabled, test against the 99166819Scognet * physical address instead. 100166819Scognet */ 101166819Scognet mrc p15, 0, r2, c1, c0, 0 102166819Scognet ands r2, r2, #CPU_CONTROL_MMU_ENABLE 103236524Simp ldreq r6, =PHYSADDR 104236524Simp ldrne r6, =LOADERRAMADDR 105236524Simp cmp r7, r6 106166819Scognet bls flash_lower 107166819Scognet cmp r7, pc 108166819Scognet bhi from_ram 109166819Scognet b do_copy 110166819Scognet 111166819Scognetflash_lower: 112236524Simp cmp r6, pc 113166819Scognet bls from_ram 114166819Scognetdo_copy: 115236524Simp ldr r7, =KERNBASE 116175983Sraj adr r1, _start 117166819Scognet ldr r0, Lreal_start 118166819Scognet ldr r2, Lend 119166819Scognet sub r2, r2, r0 120236524Simp sub r0, r0, r7 121236524Simp add r0, r0, r6 122166819Scognet mov r4, r0 123166819Scognet bl memcpy 124166819Scognet ldr r0, Lram_offset 125166819Scognet add pc, r4, r0 126166819ScognetLram_offset: .word from_ram-_C_LABEL(_start) 127166819Scognetfrom_ram: 128166819Scognet nop 129135640Scognet#endif 130135640Scognet adr r7, Lunmapped 131190602Scognet bic r7, r7, #0xf0000000 132153616Scognet orr r7, r7, #PHYSADDR 133143681Sjmg 134175983Sraj 135166819Scognetdisable_mmu: 136135640Scognet /* Disable MMU for a while */ 137143681Sjmg mrc p15, 0, r2, c1, c0, 0 138153550Scognet bic r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\ 139153550Scognet CPU_CONTROL_WBUF_ENABLE) 140153550Scognet bic r2, r2, #(CPU_CONTROL_IC_ENABLE) 141153550Scognet bic r2, r2, #(CPU_CONTROL_BPRD_ENABLE) 142135640Scognet mcr p15, 0, r2, c1, c0, 0 143129198Scognet 144135640Scognet nop 145135640Scognet nop 146135640Scognet nop 147135640Scognet mov pc, r7 148135640ScognetLunmapped: 149266110Sian /* 150266110Sian * Build page table from scratch. 151266110Sian */ 152266110Sian 153266198Sian /* Find the delta between VA and PA */ 154266198Sian adr r0, Lpagetable 155266198Sian ldr r1, [r0] 156266198Sian sub r2, r1, r0 157266198Sian /* At this point: r2 = VA - PA */ 158266198Sian 159266198Sian /* 160266198Sian * Find the physical address of the table. After these two 161266198Sian * instructions: 162266198Sian * r1 = va(pagetable) 163266198Sian * 164266198Sian * r0 = va(pagetable) - (VA - PA) 165266198Sian * = va(pagetable) - VA + PA 166266198Sian * = pa(pagetable) 167266198Sian */ 168266198Sian ldr r1, [r0, #4] 169266110Sian sub r0, r1, r2 170266110Sian 171266160Sian /* 172266160Sian * Map PA == VA 173266160Sian */ 174266198Sian /* Find the start kernels load address */ 175266198Sian adr r5, _start 176266198Sian ldr r2, =(L1_S_OFFSET) 177266198Sian bic r5, r2 178266160Sian mov r1, r5 179266160Sian mov r2, r5 180266160Sian /* Map 64MiB, preserved over calls to build_pagetables */ 181266160Sian mov r3, #64 182266160Sian bl build_pagetables 183129198Scognet 184266160Sian /* Create the kernel map to jump to */ 185266160Sian mov r1, r5 186266198Sian ldr r2, =(KERNVIRTADDR) 187266160Sian bl build_pagetables 188266160Sian 189266160Sian#if defined(SOCDEV_PA) && defined(SOCDEV_VA) 190266160Sian /* Create the custom map */ 191266196Sian ldr r1, =SOCDEV_PA 192266196Sian ldr r2, =SOCDEV_VA 193266160Sian bl build_pagetables 194266160Sian#endif 195129198Scognet 196239268Sgonzo#if defined(SMP) 197239268Sgonzo orr r0, r0, #2 /* Set TTB shared memory flag */ 198239268Sgonzo#endif 199129198Scognet mcr p15, 0, r0, c2, c0, 0 /* Set TTB */ 200129198Scognet mcr p15, 0, r0, c8, c7, 0 /* Flush TLB */ 201129198Scognet 202266058Sian#if defined(CPU_ARM1136) || defined(CPU_ARM1176) || defined(CPU_CORTEXA) || defined(CPU_MV_PJ4B) || defined(CPU_KRAIT) 203239268Sgonzo mov r0, #0 204239268Sgonzo mcr p15, 0, r0, c13, c0, 1 /* Set ASID to 0 */ 205239268Sgonzo#endif 206239268Sgonzo 207129198Scognet /* Set the Domain Access register. Very important! */ 208143681Sjmg mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT) 209129198Scognet mcr p15, 0, r0, c3, c0, 0 210248961Sian /* 211248961Sian * Enable MMU. 212248961Sian * On armv6 enable extended page tables, and set alignment checking 213248961Sian * to modulo-4 (CPU_CONTROL_UNAL_ENABLE) for the ldrd/strd 214248961Sian * instructions emitted by clang. 215248961Sian */ 216129198Scognet mrc p15, 0, r0, c1, c0, 0 217248961Sian#ifdef _ARM_ARCH_6 218248961Sian orr r0, r0, #(CPU_CONTROL_V6_EXTPAGE | CPU_CONTROL_UNAL_ENABLE) 219259308Sian orr r0, r0, #(CPU_CONTROL_AFLT_ENABLE) 220250928Sgber orr r0, r0, #(CPU_CONTROL_AF_ENABLE) 221239268Sgonzo#endif 222243602Sgonzo orr r0, r0, #(CPU_CONTROL_MMU_ENABLE) 223129198Scognet mcr p15, 0, r0, c1, c0, 0 224153550Scognet nop 225153550Scognet nop 226153550Scognet nop 227129198Scognet CPWAIT(r0) 228129198Scognet 229129198Scognetmmu_done: 230153550Scognet nop 231129198Scognet adr r1, .Lstart 232129198Scognet ldmia r1, {r1, r2, sp} /* Set initial stack and */ 233129198Scognet sub r2, r2, r1 /* get zero init data */ 234129198Scognet mov r3, #0 235129198Scognet.L1: 236150863Scognet str r3, [r1], #0x0004 /* get zero init data */ 237129198Scognet subs r2, r2, #4 238129198Scognet bgt .L1 239153550Scognet ldr pc, .Lvirt_done 240129198Scognet 241142145Scognetvirt_done: 242266194Sian mov r1, #28 /* loader info size is 28 bytes also second arg */ 243236524Simp subs sp, sp, r1 /* allocate arm_boot_params struct on stack */ 244266198Sian mov r0, sp /* loader info pointer is first arg */ 245247608Sandrew bic sp, sp, #7 /* align stack to 8 bytes */ 246236524Simp str r1, [r0] /* Store length of loader info */ 247236524Simp str r9, [r0, #4] /* Store r0 from boot loader */ 248236524Simp str r8, [r0, #8] /* Store r1 from boot loader */ 249236524Simp str ip, [r0, #12] /* store r2 from boot loader */ 250236524Simp str fp, [r0, #16] /* store r3 from boot loader */ 251266160Sian str r5, [r0, #20] /* store the physical address */ 252266198Sian adr r4, Lpagetable /* load the pagetable address */ 253266198Sian ldr r5, [r4, #4] 254266194Sian str r5, [r0, #24] /* store the pagetable address */ 255175983Sraj mov fp, #0 /* trace back starts here */ 256129198Scognet bl _C_LABEL(initarm) /* Off we go */ 257129198Scognet 258129198Scognet /* init arm will return the new stack pointer. */ 259129198Scognet mov sp, r0 260129198Scognet 261129198Scognet bl _C_LABEL(mi_startup) /* call mi_startup()! */ 262129198Scognet 263129198Scognet adr r0, .Lmainreturned 264130164Sphk b _C_LABEL(panic) 265175983Sraj /* NOTREACHED */ 266266160SianEND(_start) 267266160Sian 268266160Sian/* 269266160Sian * Builds the page table 270266160Sian * r0 - The table base address 271266160Sian * r1 - The physical address (trashed) 272266160Sian * r2 - The virtual address (trashed) 273266160Sian * r3 - The number of 1MiB sections 274266160Sian * r4 - Trashed 275266160Sian * 276266160Sian * Addresses must be 1MiB aligned 277266160Sian */ 278266160Sianbuild_pagetables: 279266160Sian /* Set the required page attributed */ 280266160Sian ldr r4, =(L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)) 281266160Sian#if defined(SMP) 282266160Sian orr r4, #(L1_SHARED) 283266160Sian#endif 284266160Sian orr r1, r4 285266160Sian 286266160Sian /* Move the virtual address to the correct bit location */ 287266160Sian lsr r2, #(L1_S_SHIFT - 2) 288266160Sian 289266160Sian mov r4, r3 290266160Sian1: 291266160Sian str r1, [r0, r2] 292266160Sian add r2, r2, #4 293266160Sian add r1, r1, #(L1_S_SIZE) 294266160Sian adds r4, r4, #-1 295266160Sian bhi 1b 296266160Sian 297266160Sian RET 298266160Sian 299266198SianLpagetable: 300266198Sian .word . 301266198Sian .word pagetable 302266198Sian 303150863ScognetLvirtaddr: 304150863Scognet .word KERNVIRTADDR 305150863ScognetLphysaddr: 306150863Scognet .word KERNPHYSADDR 307166819ScognetLreal_start: 308166819Scognet .word _start 309266198SianLend: 310166819Scognet .word _edata 311266198Sian 312129198Scognet.Lstart: 313129198Scognet .word _edata 314266110Sian .word _ebss 315129198Scognet .word svcstk + INIT_ARM_STACK_SIZE 316129198Scognet 317153550Scognet.Lvirt_done: 318153550Scognet .word virt_done 319239268Sgonzo 320129198Scognet.Lmainreturned: 321129198Scognet .asciz "main() returned" 322129198Scognet .align 0 323129198Scognet 324129198Scognet .bss 325129198Scognetsvcstk: 326129198Scognet .space INIT_ARM_STACK_SIZE 327129198Scognet 328266110Sian/* 329266110Sian * Memory for the initial pagetable. We are unable to place this in 330266110Sian * the bss as this will be cleared after the table is loaded. 331266110Sian */ 332266110Sian .section ".init_pagetable" 333266110Sian .align 14 /* 16KiB aligned */ 334266110Sianpagetable: 335266110Sian .space L1_TABLE_SIZE 336266110Sian 337129198Scognet .text 338129198Scognet .align 0 339129198Scognet 340143681Sjmg.Lcpufuncs: 341129198Scognet .word _C_LABEL(cpufuncs) 342129198Scognet 343239268Sgonzo#if defined(SMP) 344239268Sgonzo 345266385Sian.Lmpvirt_done: 346266385Sian .word mpvirt_done 347266385SianLstartup_pagetable_secondary: 348266385Sian .word temp_pagetable 349239268Sgonzo 350239268SgonzoASENTRY_NP(mpentry) 351239268Sgonzo 352239268Sgonzo /* Make sure interrupts are disabled. */ 353239268Sgonzo mrs r7, cpsr 354239268Sgonzo orr r7, r7, #(I32_bit|F32_bit) 355239268Sgonzo msr cpsr_c, r7 356239268Sgonzo 357266385Sian /* Disable MMU. It should be disabled already, but make sure. */ 358239268Sgonzo mrc p15, 0, r2, c1, c0, 0 359239268Sgonzo bic r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\ 360239268Sgonzo CPU_CONTROL_WBUF_ENABLE) 361239268Sgonzo bic r2, r2, #(CPU_CONTROL_IC_ENABLE) 362239268Sgonzo bic r2, r2, #(CPU_CONTROL_BPRD_ENABLE) 363239268Sgonzo mcr p15, 0, r2, c1, c0, 0 364239268Sgonzo nop 365239268Sgonzo nop 366239268Sgonzo nop 367266385Sian CPWAIT(r0) 368239268Sgonzo 369271327Sian#if ARM_MMU_V6 370266385Sian bl armv6_idcache_inv_all /* Modifies r0 only */ 371271327Sian#elif ARM_MMU_V7 372266385Sian bl armv7_idcache_inv_all /* Modifies r0-r3, ip */ 373266385Sian#endif 374239268Sgonzo 375239268Sgonzo ldr r0, Lstartup_pagetable_secondary 376239268Sgonzo bic r0, r0, #0xf0000000 377239268Sgonzo orr r0, r0, #PHYSADDR 378239268Sgonzo ldr r0, [r0] 379266203Sian orr r0, r0, #2 /* Set TTB shared memory flag */ 380239268Sgonzo mcr p15, 0, r0, c2, c0, 0 /* Set TTB */ 381239268Sgonzo mcr p15, 0, r0, c8, c7, 0 /* Flush TLB */ 382239268Sgonzo 383239268Sgonzo mov r0, #0 384239268Sgonzo mcr p15, 0, r0, c13, c0, 1 /* Set ASID to 0 */ 385239268Sgonzo 386239268Sgonzo /* Set the Domain Access register. Very important! */ 387239268Sgonzo mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT) 388239268Sgonzo mcr p15, 0, r0, c3, c0, 0 389239268Sgonzo /* Enable MMU */ 390239268Sgonzo mrc p15, 0, r0, c1, c0, 0 391239268Sgonzo orr r0, r0, #CPU_CONTROL_V6_EXTPAGE 392266058Sian orr r0, r0, #CPU_CONTROL_AF_ENABLE 393266385Sian orr r0, r0, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\ 394266385Sian CPU_CONTROL_WBUF_ENABLE) 395266385Sian orr r0, r0, #(CPU_CONTROL_IC_ENABLE) 396266385Sian orr r0, r0, #(CPU_CONTROL_BPRD_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: 423266385Sian .asciz "init_secondary() 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) 433266144Sian msr cpsr_fsxc, 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 507266274Sian add r0, r0, #SIGF_UC 508245414Sandrew 509245414Sandrew /* 510245414Sandrew * Call the sigreturn system call. 511245414Sandrew * 512245414Sandrew * We have to load r7 manually rather than using 513245414Sandrew * "ldr r7, =SYS_sigreturn" to ensure the value of szsigcode is 514245414Sandrew * correct. Using the alternative places esigcode at the address 515245414Sandrew * of the data rather than the address one past the data. 516245414Sandrew */ 517245414Sandrew 518245414Sandrew ldr r7, [pc, #12] /* Load SYS_sigreturn */ 519135640Scognet swi SYS_sigreturn 520135640Scognet 521135640Scognet /* Well if that failed we better exit quick ! */ 522135640Scognet 523245414Sandrew ldr r7, [pc, #8] /* Load SYS_exit */ 524135640Scognet swi SYS_exit 525135640Scognet 526245414Sandrew /* Branch back to retry SYS_sigreturn */ 527245414Sandrew b . - 16 528269796SianEND(sigcode) 529245414Sandrew .word SYS_sigreturn 530245414Sandrew .word SYS_exit 531245414Sandrew 532135640Scognet .align 0 533135640Scognet .global _C_LABEL(esigcode) 534135640Scognet _C_LABEL(esigcode): 535143681Sjmg 536135640Scognet .data 537135640Scognet .global szsigcode 538135640Scognetszsigcode: 539135640Scognet .long esigcode-sigcode 540269796Sian 541129198Scognet/* End of locore.S */ 542