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