locore.S revision 1.25
11.25Smatt/* $NetBSD: locore.S,v 1.25 2010/06/19 19:44:57 matt 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 "assym.h" 351.1Schris#include <sys/syscall.h> 361.1Schris#include <sys/errno.h> 371.1Schris#include <machine/asm.h> 381.1Schris#include <machine/cpu.h> 391.1Schris#include <machine/frame.h> 401.1Schris#include <machine/param.h> 411.1Schris 421.1Schris/* What size should this really be ? It is only used by init_arm() */ 431.1Schris#define INIT_ARM_STACK_SIZE 2048 441.1Schris 451.25Smatt RCSID("$NetBSD: locore.S,v 1.25 2010/06/19 19:44:57 matt Exp $") 461.23Smatt 471.1Schris/* 481.1Schris * This is for kvm_mkdb, and should be the address of the beginning 491.1Schris * of the kernel text segment (not necessarily the same as kernbase). 501.1Schris */ 511.1Schris 521.2Sthorpej .text 531.2Sthorpej .align 0 541.5Sthorpej 551.5SthorpejENTRY_NP(kernel_text) 561.2Sthorpej 571.1SchrisASENTRY_NP(start) 581.9Sbjh21 adr r1, .Lstart 591.4Sthorpej ldmia r1, {r1, r2, sp} /* Set initial stack and */ 601.4Sthorpej sub r2, r2, r1 /* get zero init data */ 611.25Smatt 621.25Smatt#ifdef PROCESS_ID_IS_CURCPU 631.25Smatt ldr r3, .Lcpu_info_store 641.25Smatt mcr p15, 0, r3, c13, c0, 4 651.25Smatt#endif 661.25Smatt 671.1Schris mov r3, #0 681.7Sbriggs.L1: 691.4Sthorpej str r3, [r1], #0x0004 /* Zero the bss */ 701.1Schris subs r2, r2, #4 711.7Sbriggs bgt .L1 721.1Schris 731.4Sthorpej mov fp, #0x00000000 /* trace back starts here */ 741.4Sthorpej bl _C_LABEL(initarm) /* Off we go */ 751.1Schris 761.1Schris /* init arm will return the new stack pointer. */ 771.1Schris mov sp, r0 781.1Schris 791.1Schris mov fp, #0x00000000 /* trace back starts here */ 801.1Schris mov ip, sp 811.1Schris stmfd sp!, {fp, ip, lr, pc} 821.1Schris sub fp, ip, #4 831.1Schris 841.4Sthorpej bl _C_LABEL(main) /* call main()! */ 851.1Schris 861.9Sbjh21 adr r0, .Lmainreturned 871.4Sthorpej b _C_LABEL(panic) 881.17Spooka /* NOTREACHED */ 891.1Schris 901.25Smatt#ifdef PROCESS_ID_IS_CURCPU 911.25Smatt.Lcpu_info_store: 921.25Smatt .word _C_LABEL(cpu_info_store) 931.25Smatt#endif 941.25Smatt 951.7Sbriggs.Lstart: 961.1Schris .word _edata 971.1Schris .word _end 981.1Schris .word svcstk + INIT_ARM_STACK_SIZE 991.4Sthorpej 1001.8Sthorpej.Lmainreturned: 1011.4Sthorpej .asciz "main() returned" 1021.4Sthorpej .align 0 1031.1Schris 1041.1Schris .bss 1051.1Schrissvcstk: 1061.1Schris .space INIT_ARM_STACK_SIZE 1071.1Schris 1081.1Schris .text 1091.1Schris .align 0 1101.1Schris 1111.1Schris#ifndef OFW 1121.1Schris /* OFW based systems will used OF_boot() */ 1131.1Schris 1141.8Sthorpej.Lcpufuncs: 1151.1Schris .word _C_LABEL(cpufuncs) 1161.1Schris 1171.1SchrisENTRY_NP(cpu_reset) 1181.7Sbriggs mrs r2, cpsr 1191.1Schris bic r2, r2, #(PSR_MODE) 1201.1Schris orr r2, r2, #(PSR_SVC32_MODE) 1211.24Smatt orr r2, r2, #(IF32_bits) 1221.22Schris msr cpsr_c, r2 1231.1Schris 1241.8Sthorpej ldr r4, .Lcpu_reset_address 1251.1Schris ldr r4, [r4] 1261.1Schris 1271.8Sthorpej ldr r0, .Lcpufuncs 1281.10Sbsh mov lr, pc 1291.3Sthorpej ldr pc, [r0, #CF_IDCACHE_WBINV_ALL] 1301.1Schris 1311.1Schris /* 1321.1Schris * Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's 1331.1Schris * necessary. 1341.1Schris */ 1351.1Schris 1361.8Sthorpej ldr r1, .Lcpu_reset_needs_v4_MMU_disable 1371.1Schris ldr r1, [r1] 1381.1Schris cmp r1, #0 1391.14Sthorpej mov r2, #0 1401.1Schris 1411.1Schris /* 1421.1Schris * MMU & IDC off, 32 bit program & data space 1431.1Schris * Hurl ourselves into the ROM 1441.1Schris */ 1451.13Sthorpej mov r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE) 1461.1Schris mcr 15, 0, r0, c1, c0, 0 1471.14Sthorpej mcrne 15, 0, r2, c8, c7, 0 /* nail I+D TLB on ARMv4 and greater */ 1481.1Schris mov pc, r4 1491.1Schris 1501.1Schris /* 1511.1Schris * _cpu_reset_address contains the address to branch to, to complete 1521.15Swiz * the CPU reset after turning the MMU off 1531.1Schris * This variable is provided by the hardware specific code 1541.1Schris */ 1551.8Sthorpej.Lcpu_reset_address: 1561.1Schris .word _C_LABEL(cpu_reset_address) 1571.1Schris 1581.1Schris /* 1591.1Schris * cpu_reset_needs_v4_MMU_disable contains a flag that signals if the 1601.1Schris * v4 MMU disable instruction needs executing... it is an illegal instruction 1611.1Schris * on f.e. ARM6/7 that locks up the computer in an endless illegal 1621.1Schris * instruction / data-abort / reset loop. 1631.1Schris */ 1641.8Sthorpej.Lcpu_reset_needs_v4_MMU_disable: 1651.1Schris .word _C_LABEL(cpu_reset_needs_v4_MMU_disable) 1661.1Schris 1671.1Schris#endif /* OFW */ 1681.1Schris 1691.1Schris/* 1701.1Schris * setjump + longjmp 1711.1Schris */ 1721.1SchrisENTRY(setjmp) 1731.1Schris stmia r0, {r4-r14} 1741.1Schris mov r0, #0x00000000 1751.1Schris mov pc, lr 1761.1Schris 1771.1SchrisENTRY(longjmp) 1781.1Schris ldmia r0, {r4-r14} 1791.1Schris mov r0, #0x00000001 1801.1Schris mov pc, lr 1811.1Schris 1821.1Schris .data 1831.1Schris .global _C_LABEL(esym) 1841.1Schris_C_LABEL(esym): .word _C_LABEL(end) 1851.1Schris 1861.1SchrisENTRY_NP(abort) 1871.1Schris b _C_LABEL(abort) 1881.1Schris 1891.19Schris/* 1901.21Sskrll * Part of doing a system dump, we need to save a switchframe onto the 1911.21Sskrll * stack, then save the rest of the registers into the dumppcb. 1921.19Schris */ 1931.19SchrisENTRY(dumpsys) 1941.19Schris /* push registers onto stack */ 1951.20Sskrll mov ip, sp 1961.20Sskrll stmfd sp!, {r4-r7, ip, lr} 1971.19Schris 1981.19Schris /* fill in dumppcb */ 1991.19Schris ldr r0, .Ldumppcb 2001.19Schris 2011.19Schris#ifndef __XSCALE__ 2021.19Schris add r2, r0, #(PCB_R8) 2031.19Schris stmia r2, {r8-r13} 2041.19Schris#else 2051.19Schris strd r8, [r0, #(PCB_R8)] 2061.19Schris strd r10, [r0, #(PCB_R10)] 2071.19Schris strd r12, [r0, #(PCB_R12)] 2081.19Schris#endif 2091.19Schris 2101.19Schris bl _C_LABEL(dodumpsys) 2111.19Schris 2121.19Schris /* unwind the stack */ 2131.20Sskrll ldmfd sp, {r4-r7, sp, pc} 2141.19Schris 2151.19Schris.Ldumppcb: 2161.19Schris .word _C_LABEL(dumppcb) 2171.1Schris 2181.1Schris/* End of locore.S */ 219