[BACK]Return to exception.S CVS log [TXT][DIR] Up to [local] / sys / arch / arm / arm

Annotation of sys/arch/arm/arm/exception.S, Revision 1.1

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

CVSweb