Home | History | Annotate | Line # | Download | only in arm32
exception.S revision 1.1.8.2
      1  1.1.8.2  nathanw /*	$NetBSD: exception.S,v 1.1.8.2 2002/01/08 00:23:08 nathanw Exp $	*/
      2  1.1.8.2  nathanw 
      3  1.1.8.2  nathanw /*
      4  1.1.8.2  nathanw  * Copyright (c) 1994-1997 Mark Brinicombe.
      5  1.1.8.2  nathanw  * Copyright (c) 1994 Brini.
      6  1.1.8.2  nathanw  * All rights reserved.
      7  1.1.8.2  nathanw  *
      8  1.1.8.2  nathanw  * This code is derived from software written for Brini by Mark Brinicombe
      9  1.1.8.2  nathanw  *
     10  1.1.8.2  nathanw  * Redistribution and use in source and binary forms, with or without
     11  1.1.8.2  nathanw  * modification, are permitted provided that the following conditions
     12  1.1.8.2  nathanw  * are met:
     13  1.1.8.2  nathanw  * 1. Redistributions of source code must retain the above copyright
     14  1.1.8.2  nathanw  *    notice, this list of conditions and the following disclaimer.
     15  1.1.8.2  nathanw  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1.8.2  nathanw  *    notice, this list of conditions and the following disclaimer in the
     17  1.1.8.2  nathanw  *    documentation and/or other materials provided with the distribution.
     18  1.1.8.2  nathanw  * 3. All advertising materials mentioning features or use of this software
     19  1.1.8.2  nathanw  *    must display the following acknowledgement:
     20  1.1.8.2  nathanw  *	This product includes software developed by Brini.
     21  1.1.8.2  nathanw  * 4. The name of the company nor the name of the author may be used to
     22  1.1.8.2  nathanw  *    endorse or promote products derived from this software without specific
     23  1.1.8.2  nathanw  *    prior written permission.
     24  1.1.8.2  nathanw  *
     25  1.1.8.2  nathanw  * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
     26  1.1.8.2  nathanw  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     27  1.1.8.2  nathanw  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     28  1.1.8.2  nathanw  * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     29  1.1.8.2  nathanw  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     30  1.1.8.2  nathanw  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     31  1.1.8.2  nathanw  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     32  1.1.8.2  nathanw  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33  1.1.8.2  nathanw  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     34  1.1.8.2  nathanw  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     35  1.1.8.2  nathanw  * SUCH DAMAGE.
     36  1.1.8.2  nathanw  *
     37  1.1.8.2  nathanw  * RiscBSD kernel project
     38  1.1.8.2  nathanw  *
     39  1.1.8.2  nathanw  * exception.S
     40  1.1.8.2  nathanw  *
     41  1.1.8.2  nathanw  * Low level handlers for exception vectors
     42  1.1.8.2  nathanw  *
     43  1.1.8.2  nathanw  * Created      : 24/09/94
     44  1.1.8.2  nathanw  *
     45  1.1.8.2  nathanw  * Based on kate/display/abort.s
     46  1.1.8.2  nathanw  */
     47  1.1.8.2  nathanw 
     48  1.1.8.2  nathanw #include "opt_ipkdb.h"
     49  1.1.8.2  nathanw #include <machine/asm.h>
     50  1.1.8.2  nathanw #include <machine/cpu.h>
     51  1.1.8.2  nathanw #include <machine/frame.h>
     52  1.1.8.2  nathanw #include "assym.h"
     53  1.1.8.2  nathanw 
     54  1.1.8.2  nathanw 	.text
     55  1.1.8.2  nathanw 	.align	0
     56  1.1.8.2  nathanw 
     57  1.1.8.2  nathanw Lastpending:
     58  1.1.8.2  nathanw         .word   _C_LABEL(astpending)
     59  1.1.8.2  nathanw 
     60  1.1.8.2  nathanw /*
     61  1.1.8.2  nathanw  * General exception exit handler
     62  1.1.8.2  nathanw  *
     63  1.1.8.2  nathanw  * It exits straight away if not returning to USR mode.
     64  1.1.8.2  nathanw  * This loops around delivering any pending ASTs.
     65  1.1.8.2  nathanw  * Interrupts are disabled at suitable points to avoid ASTs
     66  1.1.8.2  nathanw  * being posted between testing and exit to user mode.
     67  1.1.8.2  nathanw  *
     68  1.1.8.2  nathanw  * This function uses PULLFRAMEFROMSVCANDEXIT thus should
     69  1.1.8.2  nathanw  * only be called if the exception handler used PUSHFRAMEINSVC
     70  1.1.8.2  nathanw  */
     71  1.1.8.2  nathanw 
     72  1.1.8.2  nathanw exception_exit:
     73  1.1.8.2  nathanw 	mrs     r4, cpsr_all		/* Get CPSR */
     74  1.1.8.2  nathanw 
     75  1.1.8.2  nathanw 	ldr	r0, [sp]		/* Get the SPSR from stack */
     76  1.1.8.2  nathanw 	and	r0, r0, #(PSR_MODE)	/* Test for USR32 mode before the AST */
     77  1.1.8.2  nathanw 	teq	r0, #(PSR_USR32_MODE)
     78  1.1.8.2  nathanw 	bne	do_exit			/* Not USR mode so no AST delivery */
     79  1.1.8.2  nathanw 
     80  1.1.8.2  nathanw 	ldr	r5, Lastpending		/* Get address of astpending */
     81  1.1.8.2  nathanw 
     82  1.1.8.2  nathanw Lexception_exit_loop:
     83  1.1.8.2  nathanw 	orr     r0, r4, #(I32_bit)	/* Block IRQs */
     84  1.1.8.2  nathanw 	msr     cpsr_all, r0
     85  1.1.8.2  nathanw 
     86  1.1.8.2  nathanw 	ldr	r1, [r5]		/* Do we have an AST pending */
     87  1.1.8.2  nathanw 	teq	r1, #0x00000000
     88  1.1.8.2  nathanw 	bne	do_ast
     89  1.1.8.2  nathanw 
     90  1.1.8.2  nathanw 	PULLFRAMEFROMSVCANDEXIT		/* No AST so exit */
     91  1.1.8.2  nathanw 
     92  1.1.8.2  nathanw do_ast:
     93  1.1.8.2  nathanw 	mov	r1, #0x00000000		/* Clear ast pending */
     94  1.1.8.2  nathanw 	str	r1, [r5]
     95  1.1.8.2  nathanw 
     96  1.1.8.2  nathanw 	msr     cpsr_all, r4		/* Restore interrupts */
     97  1.1.8.2  nathanw 
     98  1.1.8.2  nathanw 	mov	r0, sp			/* arg 0 = trap frame */
     99  1.1.8.2  nathanw 	bl	_C_LABEL(ast)		/* call the AST handler */
    100  1.1.8.2  nathanw 	b	Lexception_exit_loop	/* Try and exit again */
    101  1.1.8.2  nathanw 
    102  1.1.8.2  nathanw do_exit:
    103  1.1.8.2  nathanw 	orr     r0, r4, #(I32_bit)	/* Disable interupts */
    104  1.1.8.2  nathanw 	msr     cpsr_all, r0
    105  1.1.8.2  nathanw 
    106  1.1.8.2  nathanw 	PULLFRAMEFROMSVCANDEXIT		/* Restore the trap frame and exit */
    107  1.1.8.2  nathanw 
    108  1.1.8.2  nathanw /*
    109  1.1.8.2  nathanw  * reset_entry:
    110  1.1.8.2  nathanw  *
    111  1.1.8.2  nathanw  *	Handler for Reset exception.
    112  1.1.8.2  nathanw  */
    113  1.1.8.2  nathanw ASENTRY_NP(reset_entry)
    114  1.1.8.2  nathanw 	adr	r0, Lreset_panicmsg
    115  1.1.8.2  nathanw 	mov	r1, lr
    116  1.1.8.2  nathanw 	bl	_C_LABEL(panic)
    117  1.1.8.2  nathanw 	/* NOTREACHED */
    118  1.1.8.2  nathanw Lreset_panicmsg:
    119  1.1.8.2  nathanw 	.asciz	"Reset vector called, LR = 0x%08x"
    120  1.1.8.2  nathanw 	.balign	4
    121  1.1.8.2  nathanw 
    122  1.1.8.2  nathanw /*
    123  1.1.8.2  nathanw  * swi_entry
    124  1.1.8.2  nathanw  *
    125  1.1.8.2  nathanw  *	Handler for the Software Interrupt exception.
    126  1.1.8.2  nathanw  */
    127  1.1.8.2  nathanw ASENTRY_NP(swi_entry)
    128  1.1.8.2  nathanw 	PUSHFRAME
    129  1.1.8.2  nathanw 
    130  1.1.8.2  nathanw  	sub	r0, lr, #0x00000004	/* Get the address of the SWI */
    131  1.1.8.2  nathanw 	ldr	r4, [r0]		/* Get the instruction */
    132  1.1.8.2  nathanw 
    133  1.1.8.2  nathanw 	bic	r1, r4, #0xff000000	/* Extract the comment field */
    134  1.1.8.2  nathanw 
    135  1.1.8.2  nathanw 	mov	r0, sp			/* Pass the frame to any function */
    136  1.1.8.2  nathanw 
    137  1.1.8.2  nathanw 	bl	_C_LABEL(syscall)	/* It's a syscall ! */
    138  1.1.8.2  nathanw 
    139  1.1.8.2  nathanw 	ldr	r5, Lastpending		/* Get address of astpending */
    140  1.1.8.2  nathanw 	mrs     r4, cpsr_all		/* Get CPSR */
    141  1.1.8.2  nathanw 
    142  1.1.8.2  nathanw swi_exit_loop:
    143  1.1.8.2  nathanw 	orr     r0, r4, #(I32_bit)	/* Disable IRQs */
    144  1.1.8.2  nathanw 	msr     cpsr_all, r0
    145  1.1.8.2  nathanw 
    146  1.1.8.2  nathanw 	ldr	r1, [r5]		/* Do we have an AST pending */
    147  1.1.8.2  nathanw 	teq	r1, #0x00000000
    148  1.1.8.2  nathanw 	bne	do_swi_ast
    149  1.1.8.2  nathanw 
    150  1.1.8.2  nathanw 	PULLFRAME
    151  1.1.8.2  nathanw 	movs	pc, lr			/* Exit */
    152  1.1.8.2  nathanw 
    153  1.1.8.2  nathanw do_swi_ast:
    154  1.1.8.2  nathanw 	mov	r1, #0x00000000		/* Clear ast pending */
    155  1.1.8.2  nathanw 	str	r1, [r5]
    156  1.1.8.2  nathanw 
    157  1.1.8.2  nathanw 	msr     cpsr_all, r4		/* Restore interrupts */
    158  1.1.8.2  nathanw 
    159  1.1.8.2  nathanw 	mov	r0, sp			/* arg 0 = trap frame */
    160  1.1.8.2  nathanw 	bl	_C_LABEL(ast)		/* call the AST handler */
    161  1.1.8.2  nathanw 	b	swi_exit_loop		/* Try and exit again */
    162  1.1.8.2  nathanw 
    163  1.1.8.2  nathanw /*
    164  1.1.8.2  nathanw  * prefetch_abort_entry:
    165  1.1.8.2  nathanw  *
    166  1.1.8.2  nathanw  *	Handler for the Prefetch Abort exception.
    167  1.1.8.2  nathanw  */
    168  1.1.8.2  nathanw ASENTRY_NP(prefetch_abort_entry)
    169  1.1.8.2  nathanw         sub     lr, lr, #0x00000004     /* Adjust the lr */
    170  1.1.8.2  nathanw 
    171  1.1.8.2  nathanw 	PUSHFRAMEINSVC
    172  1.1.8.2  nathanw 
    173  1.1.8.2  nathanw  	mov	r0, sp			/* pass the stack pointer as r0 */
    174  1.1.8.2  nathanw 
    175  1.1.8.2  nathanw 	add	lr, pc, #exception_exit - . - 8
    176  1.1.8.2  nathanw 	ldr	r1, Lprefetch_abort_handler_address
    177  1.1.8.2  nathanw 	ldr	pc, [r1]
    178  1.1.8.2  nathanw 
    179  1.1.8.2  nathanw Lprefetch_abort_handler_address:
    180  1.1.8.2  nathanw 	.word	_C_LABEL(prefetch_abort_handler_address)
    181  1.1.8.2  nathanw 
    182  1.1.8.2  nathanw 	.data
    183  1.1.8.2  nathanw 	.global	_C_LABEL(prefetch_abort_handler_address)
    184  1.1.8.2  nathanw 
    185  1.1.8.2  nathanw _C_LABEL(prefetch_abort_handler_address):
    186  1.1.8.2  nathanw 	.word	abortprefetch
    187  1.1.8.2  nathanw 
    188  1.1.8.2  nathanw 	.text
    189  1.1.8.2  nathanw abortprefetch:
    190  1.1.8.2  nathanw         add     r0, pc, #abortprefetchmsg - . - 8
    191  1.1.8.2  nathanw 	b	_C_LABEL(panic)
    192  1.1.8.2  nathanw 
    193  1.1.8.2  nathanw abortprefetchmsg:
    194  1.1.8.2  nathanw         .asciz  "abortprefetch"
    195  1.1.8.2  nathanw         .align  0
    196  1.1.8.2  nathanw 
    197  1.1.8.2  nathanw /*
    198  1.1.8.2  nathanw  * data_abort_entry:
    199  1.1.8.2  nathanw  *
    200  1.1.8.2  nathanw  *	Handler for the Data Abort exception.
    201  1.1.8.2  nathanw  */
    202  1.1.8.2  nathanw ASENTRY_NP(data_abort_entry)
    203  1.1.8.2  nathanw         sub     lr, lr, #0x00000008     /* Adjust the lr */
    204  1.1.8.2  nathanw 
    205  1.1.8.2  nathanw 	PUSHFRAMEINSVC			/* Push trap frame and switch */
    206  1.1.8.2  nathanw 					/* to SVC32 mode */
    207  1.1.8.2  nathanw 
    208  1.1.8.2  nathanw 	mov	r0, sp			/* pass the stack pointer as r0 */
    209  1.1.8.2  nathanw 
    210  1.1.8.2  nathanw 	add	lr, pc, #exception_exit - . - 8
    211  1.1.8.2  nathanw 	ldr	r1, Ldata_abort_handler_address
    212  1.1.8.2  nathanw 	ldr	pc, [r1]
    213  1.1.8.2  nathanw 
    214  1.1.8.2  nathanw Ldata_abort_handler_address:
    215  1.1.8.2  nathanw 	.word	_C_LABEL(data_abort_handler_address)
    216  1.1.8.2  nathanw 
    217  1.1.8.2  nathanw 	.data
    218  1.1.8.2  nathanw 	.global	_C_LABEL(data_abort_handler_address)
    219  1.1.8.2  nathanw _C_LABEL(data_abort_handler_address):
    220  1.1.8.2  nathanw 	.word	abortdata
    221  1.1.8.2  nathanw 
    222  1.1.8.2  nathanw 	.text
    223  1.1.8.2  nathanw abortdata:
    224  1.1.8.2  nathanw         add     r0, pc, #abortdatamsg - . - 8
    225  1.1.8.2  nathanw 	b	_C_LABEL(panic)
    226  1.1.8.2  nathanw 
    227  1.1.8.2  nathanw abortdatamsg:
    228  1.1.8.2  nathanw         .asciz  "abortdata"
    229  1.1.8.2  nathanw         .align  0
    230  1.1.8.2  nathanw 
    231  1.1.8.2  nathanw /*
    232  1.1.8.2  nathanw  * address_exception_entry:
    233  1.1.8.2  nathanw  *
    234  1.1.8.2  nathanw  *	Handler for the Address Exception exception.
    235  1.1.8.2  nathanw  *
    236  1.1.8.2  nathanw  *	NOTE: This exception isn't really used on arm32.  We
    237  1.1.8.2  nathanw  *	print a warning message to the console and then treat
    238  1.1.8.2  nathanw  *	it like a Data Abort.
    239  1.1.8.2  nathanw  */
    240  1.1.8.2  nathanw ASENTRY_NP(address_exception_entry)
    241  1.1.8.2  nathanw 	mrs	r1, cpsr_all
    242  1.1.8.2  nathanw 	mrs	r2, spsr_all
    243  1.1.8.2  nathanw 	mov	r3, lr
    244  1.1.8.2  nathanw 	adr	r0, Laddress_exception_msg
    245  1.1.8.2  nathanw 	bl	_C_LABEL(printf)	/* XXX CLOBBERS LR!! */
    246  1.1.8.2  nathanw 	b	data_abort_entry
    247  1.1.8.2  nathanw Laddress_exception_msg:
    248  1.1.8.2  nathanw 	.asciz	"Address Exception CPSR=0x%08x SPSR=0x%08x LR=0x%08x\n"
    249  1.1.8.2  nathanw 	.balign	4
    250  1.1.8.2  nathanw 
    251  1.1.8.2  nathanw /*
    252  1.1.8.2  nathanw  * undefined_entry:
    253  1.1.8.2  nathanw  *
    254  1.1.8.2  nathanw  *	Handler for the Undefined Instruction exception.
    255  1.1.8.2  nathanw  *
    256  1.1.8.2  nathanw  *	We indirect the undefined vector via the handler address
    257  1.1.8.2  nathanw  *	in the data area.  Entry to the undefined handler must
    258  1.1.8.2  nathanw  *	look like direct entry from the vector.
    259  1.1.8.2  nathanw  */
    260  1.1.8.2  nathanw ASENTRY_NP(undefined_entry)
    261  1.1.8.2  nathanw #ifdef IPKDB
    262  1.1.8.2  nathanw /*
    263  1.1.8.2  nathanw  * IPKDB must be hooked in at the earliest possible entry point.
    264  1.1.8.2  nathanw  *
    265  1.1.8.2  nathanw  */
    266  1.1.8.2  nathanw /*
    267  1.1.8.2  nathanw  * Make room for all registers saving real r0-r7 and r15.
    268  1.1.8.2  nathanw  * The remaining registers are updated later.
    269  1.1.8.2  nathanw  */
    270  1.1.8.2  nathanw 	stmfd	sp!, {r0,r1}		/* psr & spsr */
    271  1.1.8.2  nathanw 	stmfd	sp!, {lr}		/* pc */
    272  1.1.8.2  nathanw 	stmfd	sp!, {r0-r14}		/* r0-r7, r8-r14 */
    273  1.1.8.2  nathanw /*
    274  1.1.8.2  nathanw  * Get previous psr.
    275  1.1.8.2  nathanw  */
    276  1.1.8.2  nathanw 	mrs	r7, cpsr_all
    277  1.1.8.2  nathanw 	mrs	r0, spsr_all
    278  1.1.8.2  nathanw 	str	r0, [sp, #(16*4)]
    279  1.1.8.2  nathanw /*
    280  1.1.8.2  nathanw  * Test for user mode.
    281  1.1.8.2  nathanw  */
    282  1.1.8.2  nathanw 	tst	r0, #0xf
    283  1.1.8.2  nathanw 	bne	Lprenotuser_push
    284  1.1.8.2  nathanw 	add	r1, sp, #(8*4)
    285  1.1.8.2  nathanw 	stmia	r1,{r8-r14}^		/* store user mode r8-r14*/
    286  1.1.8.2  nathanw 	b	Lgoipkdb
    287  1.1.8.2  nathanw /*
    288  1.1.8.2  nathanw  * Switch to previous mode to get r8-r13.
    289  1.1.8.2  nathanw  */
    290  1.1.8.2  nathanw Lprenotuser_push:
    291  1.1.8.2  nathanw 	orr	r0, r0, #(I32_bit) /* disable interrupts */
    292  1.1.8.2  nathanw 	msr	cpsr_all, r0
    293  1.1.8.2  nathanw 	mov	r1, r8
    294  1.1.8.2  nathanw 	mov	r2, r9
    295  1.1.8.2  nathanw 	mov	r3, r10
    296  1.1.8.2  nathanw 	mov	r4, r11
    297  1.1.8.2  nathanw 	mov	r5, r12
    298  1.1.8.2  nathanw 	mov	r6, r13
    299  1.1.8.2  nathanw 	msr	cpsr_all, r7		/* back to undefined mode */
    300  1.1.8.2  nathanw 	add	r8, sp, #(8*4)
    301  1.1.8.2  nathanw 	stmia	r8, {r1-r6}		/* r8-r13 */
    302  1.1.8.2  nathanw /*
    303  1.1.8.2  nathanw  * Now back to previous mode to get r14 and spsr.
    304  1.1.8.2  nathanw  */
    305  1.1.8.2  nathanw 	msr	cpsr_all, r0
    306  1.1.8.2  nathanw 	mov	r1, r14
    307  1.1.8.2  nathanw 	mrs	r2, spsr
    308  1.1.8.2  nathanw 	msr	cpsr_all, r7		/* back to undefined mode */
    309  1.1.8.2  nathanw 	str	r1, [sp, #(14*4)]	/* r14 */
    310  1.1.8.2  nathanw 	str	r2, [sp, #(17*4)]	/* spsr */
    311  1.1.8.2  nathanw /*
    312  1.1.8.2  nathanw  * Now to IPKDB.
    313  1.1.8.2  nathanw  */
    314  1.1.8.2  nathanw Lgoipkdb:
    315  1.1.8.2  nathanw 	mov	r0, sp
    316  1.1.8.2  nathanw 	bl	_C_LABEL(ipkdb_trap_glue)
    317  1.1.8.2  nathanw 	ldr	r1, Lipkdb_trap_return
    318  1.1.8.2  nathanw 	str	r0,[r1]
    319  1.1.8.2  nathanw /*
    320  1.1.8.2  nathanw  * Have to load all registers from the stack.
    321  1.1.8.2  nathanw  *
    322  1.1.8.2  nathanw  * Start with spsr and pc.
    323  1.1.8.2  nathanw  */
    324  1.1.8.2  nathanw 	ldr	r0, [sp, #(16*4)]	/* spsr */
    325  1.1.8.2  nathanw 	ldr	r1, [sp, #(15*4)]	/* r15 */
    326  1.1.8.2  nathanw 	msr	spsr_all, r0
    327  1.1.8.2  nathanw 	mov	r14, r1
    328  1.1.8.2  nathanw /*
    329  1.1.8.2  nathanw  * Test for user mode.
    330  1.1.8.2  nathanw  */
    331  1.1.8.2  nathanw 	tst	r0, #0xf
    332  1.1.8.2  nathanw 	bne	Lprenotuser_pull
    333  1.1.8.2  nathanw 	add	r1, sp, #(8*4)
    334  1.1.8.2  nathanw 	ldmia	r1, {r8-r14}^		/* load user mode r8-r14 */
    335  1.1.8.2  nathanw 	b	Lpull_r0r7
    336  1.1.8.2  nathanw Lprenotuser_pull:
    337  1.1.8.2  nathanw /*
    338  1.1.8.2  nathanw  * Now previous mode spsr and r14.
    339  1.1.8.2  nathanw  */
    340  1.1.8.2  nathanw 	ldr	r1, [sp, #(17*4)]		/* spsr */
    341  1.1.8.2  nathanw 	ldr	r2, [sp, #(14*4)]		/* r14 */
    342  1.1.8.2  nathanw 	orr	r0, r0, #(I32_bit)
    343  1.1.8.2  nathanw 	msr	cpsr_all, r0			/* switch to previous mode */
    344  1.1.8.2  nathanw 	msr	spsr_all, r1
    345  1.1.8.2  nathanw 	mov	r14, r2
    346  1.1.8.2  nathanw 	msr	cpsr_all, r7			/* back to undefined mode */
    347  1.1.8.2  nathanw /*
    348  1.1.8.2  nathanw  * Now r8-r13.
    349  1.1.8.2  nathanw  */
    350  1.1.8.2  nathanw 	add	r8, sp, #(8*4)
    351  1.1.8.2  nathanw 	ldmia	r8, {r1-r6}		/* r8-r13 */
    352  1.1.8.2  nathanw 	msr	cpsr_all, r0
    353  1.1.8.2  nathanw 	mov	r8, r1
    354  1.1.8.2  nathanw 	mov	r9, r2
    355  1.1.8.2  nathanw 	mov	r10, r3
    356  1.1.8.2  nathanw 	mov	r11, r4
    357  1.1.8.2  nathanw 	mov	r12, r5
    358  1.1.8.2  nathanw 	mov	r13, r6
    359  1.1.8.2  nathanw 	msr	cpsr_all, r7
    360  1.1.8.2  nathanw Lpull_r0r7:
    361  1.1.8.2  nathanw /*
    362  1.1.8.2  nathanw  * Now the rest of the registers.
    363  1.1.8.2  nathanw  */
    364  1.1.8.2  nathanw 	ldr	r1,Lipkdb_trap_return
    365  1.1.8.2  nathanw 	ldr	r0,[r1]
    366  1.1.8.2  nathanw 	tst	r0,r0
    367  1.1.8.2  nathanw 	ldmfd	sp!, {r0-r7}		/* r0-r7 */
    368  1.1.8.2  nathanw 	add	sp, sp, #(10*4)		/* adjust sp */
    369  1.1.8.2  nathanw 
    370  1.1.8.2  nathanw /*
    371  1.1.8.2  nathanw  * Did IPKDB handle it?
    372  1.1.8.2  nathanw  */
    373  1.1.8.2  nathanw 	movnes	pc, lr			/* return */
    374  1.1.8.2  nathanw 
    375  1.1.8.2  nathanw #endif
    376  1.1.8.2  nathanw 	stmfd	sp!, {r0, r1}
    377  1.1.8.2  nathanw 	ldr	r0, Lundefined_handler_indirection
    378  1.1.8.2  nathanw 	ldr	r1, [sp], #0x0004
    379  1.1.8.2  nathanw 	str	r1, [r0, #0x0000]
    380  1.1.8.2  nathanw 	ldr	r1, [sp], #0x0004
    381  1.1.8.2  nathanw 	str	r1, [r0, #0x0004]
    382  1.1.8.2  nathanw 	ldmia	r0, {r0, r1, pc}
    383  1.1.8.2  nathanw 
    384  1.1.8.2  nathanw #ifdef IPKDB
    385  1.1.8.2  nathanw Lipkdb_trap_return:
    386  1.1.8.2  nathanw 	.word	Lipkdb_trap_return_data
    387  1.1.8.2  nathanw #endif
    388  1.1.8.2  nathanw 
    389  1.1.8.2  nathanw Lundefined_handler_indirection:
    390  1.1.8.2  nathanw 	.word	Lundefined_handler_indirection_data
    391  1.1.8.2  nathanw 
    392  1.1.8.2  nathanw /*
    393  1.1.8.2  nathanw  * assembly bounce code for calling the kernel
    394  1.1.8.2  nathanw  * undefined instruction handler. This uses
    395  1.1.8.2  nathanw  * a standard trap frame and is called in SVC mode.
    396  1.1.8.2  nathanw  */
    397  1.1.8.2  nathanw 
    398  1.1.8.2  nathanw ENTRY_NP(undefinedinstruction_bounce)
    399  1.1.8.2  nathanw 	PUSHFRAMEINSVC
    400  1.1.8.2  nathanw 	mov	r0, sp
    401  1.1.8.2  nathanw 	bl	_C_LABEL(undefinedinstruction)
    402  1.1.8.2  nathanw 
    403  1.1.8.2  nathanw 	b	exception_exit
    404  1.1.8.2  nathanw 
    405  1.1.8.2  nathanw 	.data
    406  1.1.8.2  nathanw 	.align	0
    407  1.1.8.2  nathanw 
    408  1.1.8.2  nathanw #ifdef IPKDB
    409  1.1.8.2  nathanw Lipkdb_trap_return_data:
    410  1.1.8.2  nathanw 	.word	0
    411  1.1.8.2  nathanw #endif
    412  1.1.8.2  nathanw 
    413  1.1.8.2  nathanw /*
    414  1.1.8.2  nathanw  * Indirection data
    415  1.1.8.2  nathanw  * 2 words use for preserving r0 and r1
    416  1.1.8.2  nathanw  * 3rd word contains the undefined handler address.
    417  1.1.8.2  nathanw  */
    418  1.1.8.2  nathanw 
    419  1.1.8.2  nathanw Lundefined_handler_indirection_data:
    420  1.1.8.2  nathanw 	.word	0
    421  1.1.8.2  nathanw 	.word	0
    422  1.1.8.2  nathanw 
    423  1.1.8.2  nathanw 	.global	_C_LABEL(undefined_handler_address)
    424  1.1.8.2  nathanw _C_LABEL(undefined_handler_address):
    425  1.1.8.2  nathanw 	.word	_C_LABEL(undefinedinstruction_bounce)
    426