locore.S revision 1.1
11.1Schris/* $NetBSD: locore.S,v 1.1 2001/07/28 15:08:11 chris Exp $ */ 21.1Schris 31.1Schris/* 41.1Schris * Copyright (C) 1994-1997 Mark Brinicombe 51.1Schris * Copyright (C) 1994 Brini 61.1Schris * All rights reserved. 71.1Schris * 81.1Schris * Redistribution and use in source and binary forms, with or without 91.1Schris * modification, are permitted provided that the following conditions 101.1Schris * are met: 111.1Schris * 1. Redistributions of source code must retain the above copyright 121.1Schris * notice, this list of conditions and the following disclaimer. 131.1Schris * 2. Redistributions in binary form must reproduce the above copyright 141.1Schris * notice, this list of conditions and the following disclaimer in the 151.1Schris * documentation and/or other materials provided with the distribution. 161.1Schris * 3. All advertising materials mentioning features or use of this software 171.1Schris * must display the following acknowledgement: 181.1Schris * This product includes software developed by Brini. 191.1Schris * 4. The name of Brini may not be used to endorse or promote products 201.1Schris * derived from this software without specific prior written permission. 211.1Schris * 221.1Schris * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR 231.1Schris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 241.1Schris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 251.1Schris * IN NO EVENT SHALL BRINI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 261.1Schris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 271.1Schris * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 281.1Schris * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 291.1Schris * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 301.1Schris * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 311.1Schris * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 321.1Schris */ 331.1Schris 341.1Schris#include "opt_ipkdb.h" 351.1Schris#include "assym.h" 361.1Schris#include <sys/syscall.h> 371.1Schris#include <sys/errno.h> 381.1Schris#include <machine/asm.h> 391.1Schris#include <machine/cpu.h> 401.1Schris#include <machine/frame.h> 411.1Schris#include <machine/param.h> 421.1Schris 431.1Schris/* What size should this really be ? It is only used by init_arm() */ 441.1Schris#define INIT_ARM_STACK_SIZE 2048 451.1Schris 461.1Schris/* 471.1Schris * This is for kvm_mkdb, and should be the address of the beginning 481.1Schris * of the kernel text segment (not necessarily the same as kernbase). 491.1Schris */ 501.1Schris 511.1Schris#ifndef netwinder 521.1SchrisENTRY_NP(kernel_text) 531.1Schris#endif 541.1Schris 551.1SchrisASENTRY_NP(start) 561.1Schris add r1, pc, #(Lstart - . - 8) 571.1Schris ldmia r1, {r1, r2, sp} /* Set initial stack and */ 581.1Schris sub r2, r2, r1 /* get zero init data */ 591.1Schris mov r3, #0 601.1Schris 611.1SchrisL1: 621.1Schris str r3, [r1], #0x0004 /* Zero the bss */ 631.1Schris subs r2, r2, #4 641.1Schris bgt L1 651.1Schris 661.1Schris mov fp, #0x00000000 /* trace back starts here */ 671.1Schris bl _C_LABEL(initarm) /* Off we go */ 681.1Schris 691.1Schris /* init arm will return the new stack pointer. */ 701.1Schris mov sp, r0 711.1Schris 721.1Schris mov fp, #0x00000000 /* trace back starts here */ 731.1Schris mov ip, sp 741.1Schris stmfd sp!, {fp, ip, lr, pc} 751.1Schris sub fp, ip, #4 761.1Schris 771.1Schris /* Setup an initial trap frame for start_init to use */ 781.1Schris 791.1Schris PUSHFRAME 801.1Schris 811.1Schris mov r0, sp /* parameter to main is trap frame */ 821.1Schris 831.1Schris bl _C_LABEL(main) /* Lets light the flame and start her up */ 841.1Schris 851.1Schris PULLFRAME /* Pull the trap frame, now valid */ 861.1Schris 871.1Schris movs pc, lr /* Exit to user process */ 881.1Schris 891.1Schris /* Never gets here */ 901.1Schris 911.1Schris b . 921.1Schris 931.1SchrisLstart: 941.1Schris .word _edata 951.1Schris .word _end 961.1Schris .word svcstk + INIT_ARM_STACK_SIZE 971.1Schris 981.1Schris .bss 991.1Schrissvcstk: 1001.1Schris .space INIT_ARM_STACK_SIZE 1011.1Schris 1021.1Schris/* 1031.1Schris * Instructions to copy to the bottom of zero page 1041.1Schris * These are the entry point to the system exception routines 1051.1Schris */ 1061.1Schris 1071.1Schris .text 1081.1Schris .align 0 1091.1Schris .global _C_LABEL(page0), _C_LABEL(page0_end) 1101.1Schris_C_LABEL(page0): 1111.1Schris ldr pc, [pc, #Lreset - . - 8] 1121.1Schris ldr pc, [pc, #Lundefined - . - 8] 1131.1Schris ldr pc, [pc, #Lswi - . - 8] 1141.1Schris ldr pc, [pc, #Labortpre - . - 8] 1151.1Schris ldr pc, [pc, #Labortdata - . - 8] 1161.1Schris ldr pc, [pc, #Laddrexc - . - 8] 1171.1Schris ldr pc, [pc, #Lirq - . - 8] 1181.1Schris ldr pc, [pc, #Lfiq - . - 8] 1191.1Schris 1201.1SchrisLreset: 1211.1Schris .word reset_entry 1221.1SchrisLundefined: 1231.1Schris .word undefined_entry 1241.1SchrisLswi: 1251.1Schris .word swi_entry 1261.1SchrisLabortpre: 1271.1Schris .word prefetch_abort_entry 1281.1SchrisLabortdata: 1291.1Schris .word data_abort_entry 1301.1SchrisLaddrexc: 1311.1Schris .word addrexc 1321.1SchrisLirq: 1331.1Schris .word irq_entry 1341.1SchrisLfiq: 1351.1Schris .word fiq 1361.1Schris_C_LABEL(page0_end) = . 1371.1Schris 1381.1Schris/* vector 0x00000000 - RESET */ 1391.1Schris 1401.1SchrisASENTRY_NP(reset_entry) 1411.1Schris PUSHFRAME 1421.1Schris 1431.1Schris mov r0, sp /* Pass the frame to function */ 1441.1Schris b _C_LABEL(resethandler) /* It's a branch throught zero ! */ 1451.1Schris 1461.1Schris/* vector 0x00000008 - ADDRESS EXCEPTION */ 1471.1Schris 1481.1SchrisASENTRY_NP(addrexc) 1491.1Schris mrs r1, cpsr_all 1501.1Schris mrs r2, spsr_all 1511.1Schris mov r3, lr 1521.1Schris add r0, pc, #Laddrexcmsg - . - 8 1531.1Schris bl _C_LABEL(printf) 1541.1Schris b data_abort_entry 1551.1Schris 1561.1SchrisLaddrexcmsg: 1571.1Schris .asciz "address exception CPSR=%08x SPSR=%08x lr=%08x\n" 1581.1Schris .align 0 1591.1Schris 1601.1Schris/* vector 0x0000001C - FIQ */ 1611.1Schris 1621.1SchrisASENTRY_NP(fiq) 1631.1Schris ldr r0, Lfiqmsg 1641.1Schris b _C_LABEL(panic) 1651.1Schris 1661.1SchrisLfiqmsg: 1671.1Schris .asciz "fiq" 1681.1Schris .align 0 1691.1Schris 1701.1Schris#ifndef OFW 1711.1Schris /* OFW based systems will used OF_boot() */ 1721.1Schris 1731.1SchrisLcpufuncs: 1741.1Schris .word _C_LABEL(cpufuncs) 1751.1Schris 1761.1SchrisENTRY_NP(cpu_reset) 1771.1Schris mrs r2, cpsr_all 1781.1Schris bic r2, r2, #(PSR_MODE) 1791.1Schris orr r2, r2, #(PSR_SVC32_MODE) 1801.1Schris orr r2, r2, #(I32_bit | F32_bit) 1811.1Schris msr cpsr_all, r2 1821.1Schris 1831.1Schris ldr r4, Lcpu_reset_address 1841.1Schris ldr r4, [r4] 1851.1Schris 1861.1Schris ldr r0, Lcpufuncs 1871.1Schris add lr, pc, #Lboot_cache_purged - . - 8 1881.1Schris ldr pc, [r0, #CF_CACHE_PURGE_ID] 1891.1Schris 1901.1SchrisLboot_cache_purged: 1911.1Schris 1921.1Schris /* 1931.1Schris * Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's 1941.1Schris * necessary. 1951.1Schris */ 1961.1Schris 1971.1Schris ldr r1, Lcpu_reset_needs_v4_MMU_disable 1981.1Schris ldr r1, [r1] 1991.1Schris cmp r1, #0 2001.1Schris 2011.1Schris /* 2021.1Schris * MMU & IDC off, 32 bit program & data space 2031.1Schris * Hurl ourselves into the ROM 2041.1Schris */ 2051.1Schris mov r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE) 2061.1Schris mcr 15, 0, r0, c1, c0, 0 2071.1Schris mcrne 15, 0, r0, c8, c7, 0 /* only when v4 MMU disable is asked for */ 2081.1Schris mov pc, r4 2091.1Schris 2101.1Schris /* 2111.1Schris * _cpu_reset_address contains the address to branch to, to complete 2121.1Schris * the cpu reset after turning the MMU off 2131.1Schris * This variable is provided by the hardware specific code 2141.1Schris */ 2151.1SchrisLcpu_reset_address: 2161.1Schris .word _C_LABEL(cpu_reset_address) 2171.1Schris 2181.1Schris /* 2191.1Schris * cpu_reset_needs_v4_MMU_disable contains a flag that signals if the 2201.1Schris * v4 MMU disable instruction needs executing... it is an illegal instruction 2211.1Schris * on f.e. ARM6/7 that locks up the computer in an endless illegal 2221.1Schris * instruction / data-abort / reset loop. 2231.1Schris */ 2241.1SchrisLcpu_reset_needs_v4_MMU_disable: 2251.1Schris .word _C_LABEL(cpu_reset_needs_v4_MMU_disable) 2261.1Schris 2271.1Schris#endif /* OFW */ 2281.1Schris 2291.1Schris#ifdef IPKDB 2301.1Schris#if 0 2311.1Schris/* 2321.1Schris * ipkdbfbyte and ipkdbsbyte are now in ipkdb_glue.c and do not tweak 2331.1Schris * the abort handler anymore 2341.1Schris */ 2351.1SchrisENTRY_NP(ipkdbfbyte) 2361.1Schris ldr ip, abortp 2371.1Schris ldr r2, [ip] 2381.1Schris add r3, pc, #ipkdbfault - . - 8 2391.1Schris str r3, [ip] 2401.1Schris ldrb r0, [r0] 2411.1Schris str r2, [ip] 2421.1Schris mov pc, lr 2431.1Schris 2441.1SchrisENTRY_NP(ipkdbsbyte) 2451.1Schris ldr ip, abortp 2461.1Schris ldr r2, [ip] 2471.1Schris add r3, pc, #ipkdbfault - . - 8 2481.1Schris str r3, [ip] 2491.1Schris strb r1, [r0] 2501.1Schris sub r0, r0, r0 2511.1Schris str r2, [ip] 2521.1Schris mov pc, lr 2531.1Schris 2541.1Schrisabortp: 2551.1Schris .word Labortdata - _C_LABEL(page0) 2561.1Schrisipkdbfault: 2571.1Schris mov r0, #0xd3 2581.1Schris msr cpsr_all, r0 2591.1Schris mvn r0, #0 /* mov r0, #-1 */ 2601.1Schris str r2, [ip] 2611.1Schris mov pc, lr 2621.1Schris#endif 2631.1Schris 2641.1Schris/* 2651.1Schris * Execute(inst, psr, args, sp) 2661.1Schris * 2671.1Schris * Execute INSTruction with PSR and ARGS[0] - ARGS[3] making 2681.1Schris * available stack at SP for next undefined instruction trap. 2691.1Schris * 2701.1Schris * Move the instruction onto the stack and jump to it. 2711.1Schris */ 2721.1SchrisENTRY_NP(Execute) 2731.1Schris mov ip, sp 2741.1Schris stmfd sp!, {r2, r4-r7, fp, ip, lr, pc} 2751.1Schris sub fp, ip, #4 2761.1Schris mov ip, r3 2771.1Schris ldr r7, return 2781.1Schris stmfd sp!, {r0, r7} 2791.1Schris add r7, pc, #LExec - . - 8 2801.1Schris mov r5, r1 2811.1Schris mrs r4, cpsr_all 2821.1Schris ldmia r2, {r0-r3} 2831.1Schris mov r6, sp 2841.1Schris mov sp, ip 2851.1Schris msr cpsr_all, r5 2861.1Schris mov pc, r6 2871.1SchrisLExec: 2881.1Schris mrs r5, cpsr_all 2891.1Schris/* XXX Cannot switch thus easily back from user mode */ 2901.1Schris msr cpsr_all, r4 2911.1Schris add sp, r6, #8 2921.1Schris ldmfd sp!, {r6} 2931.1Schris stmia r6, {r0-r3} 2941.1Schris mov r0, r5 2951.1Schris ldmdb fp, {r4-r7, fp, sp, pc} 2961.1Schrisreturn: 2971.1Schris mov pc, r7 2981.1Schris#endif 2991.1Schris 3001.1Schris/* 3011.1Schris * setjump + longjmp 3021.1Schris */ 3031.1SchrisENTRY(setjmp) 3041.1Schris stmia r0, {r4-r14} 3051.1Schris mov r0, #0x00000000 3061.1Schris mov pc, lr 3071.1Schris 3081.1SchrisENTRY(longjmp) 3091.1Schris ldmia r0, {r4-r14} 3101.1Schris mov r0, #0x00000001 3111.1Schris mov pc, lr 3121.1Schris 3131.1Schris .data 3141.1Schris .global _C_LABEL(esym) 3151.1Schris_C_LABEL(esym): .word _C_LABEL(end) 3161.1Schris 3171.1SchrisENTRY_NP(abort) 3181.1Schris b _C_LABEL(abort) 3191.1Schris 3201.1Schris 3211.1Schris/* 3221.1Schris * Atomic bit set and clear functions 3231.1Schris */ 3241.1Schris 3251.1SchrisENTRY(atomic_set_bit) 3261.1Schris mrs r2, cpsr_all 3271.1Schris orr r3, r2, #(I32_bit) 3281.1Schris msr cpsr_all, r3 3291.1Schris 3301.1Schris ldr r3, [r0] 3311.1Schris orr r3, r3, r1 3321.1Schris str r3, [r0] 3331.1Schris 3341.1Schris msr cpsr_all, r2 3351.1Schris mov pc, lr 3361.1Schris 3371.1Schris 3381.1SchrisENTRY(atomic_clear_bit) 3391.1Schris mrs r2, cpsr_all 3401.1Schris orr r3, r2, #(I32_bit) 3411.1Schris msr cpsr_all, r3 3421.1Schris 3431.1Schris ldr r3, [r0] 3441.1Schris bic r3, r3, r1 3451.1Schris str r3, [r0] 3461.1Schris 3471.1Schris msr cpsr_all, r2 3481.1Schris mov pc, lr 3491.1Schris 3501.1Schris/* End of locore.S */ 351