Ignore:
Timestamp:
07/17/02 17:17:53 (21 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
f9c74e5
Parents:
3e2f5cc1
Message:

2002-07-17 Jay Monkman <jtm@…>

  • irq/irq_asm.S: Significant rework in attempt to make interrupts work. They appear to be very close to correct but not 100%.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/arm/shared/irq/irq_asm.S

    r3e2f5cc1 rd5136d9  
    33 *  This file contains the implementation of the IRQ handler
    44 *
     5 *  Copyright (c) 2002 Advent Networks, Inc.
     6 *      Jay Monkman <jmonkman@adventnetworks.com>
     7 *
    58 *  CopyRight (C) 2000 Canon Research France SA.
    69 *  Emmanuel Raguet,  mailto:raguet@crf.canon.fr
     10 *
     11 *  Modified Andy Dachs <a.dachs@sstl.co.uk>
     12 *  Copyright (c) 2001 Surrey Satellite Technolgy Limited
    713 *
    814 *  The license and distribution terms for this file may be
     
    1521#include "asm.h"
    1622#define __asm__
    17 #include <registers.h>
     23
     24        .globl _ISR_Handler
     25_ISR_Handler:
     26        stmdb   sp!, {r0, r1, r2, r3}   /* save regs on INT stack */
     27        stmdb   sp!, {lr}               /*    now safe to call C funcs */
     28       
     29
     30/* one nest level deeper */
     31        ldr     r0, =_ISR_Nest_level
     32        ldr     r1, [r0]
     33        add     r1, r1,#1
     34        str     r1, [r0]
     35       
     36/* disable multitasking */
     37        ldr     r0, =_Thread_Dispatch_disable_level         
     38        ldr     r1, [r0]
     39        add     r1, r1,#1
     40        str     r1, [r0]
     41
     42/* BSP specific function to INT handler */
     43        /* FIXME: I'm not sure why I can't save just r12. I'm also  */
     44        /*     not sure which of r1-r3 are important.               */
     45        stmdb   sp!, {r0-r12}               
     46        bl      ExecuteITHandler
     47        ldmia   sp!, {r0-r12}
     48       
     49/* one less nest level  */     
     50        ldr     r0, =_ISR_Nest_level
     51        ldr     r1, [r0]
     52        sub     r1, r1,#1
     53        str     r1, [r0]
     54       
     55/* unnest multitasking */
     56        ldr     r0, =_Thread_Dispatch_disable_level
     57        ldr     r1, [r0]
     58        sub     r1, r1,#1
     59        str     r1, [r0]
     60
     61/* If thread dispatching is disabled, exit */
     62        cmp     r1, #0
     63        bne     exitit
     64
     65/* If a task switch is necessary, call scheduler */
     66        ldr     r0, =_Context_Switch_necessary
     67        ldr     r1, [r0]
     68        cmp     r1, #0
     69       
     70        /* since bframe is going to clear _ISR_Signals_to_thread_executing, */
     71        /*    we need to load it here */
     72        ldr     r0, =_ISR_Signals_to_thread_executing   
     73        ldr     r1, [r0]
     74        bne     bframe
     75       
     76/* If a signals to be sent (_ISR_Signals_to_thread_executing != 0),        */
     77/*  call scheduler */
     78        cmp     r1, #0
     79        beq     exitit
     80       
     81/* _ISR_Signals_to_thread_executing = FALSE */
     82        mov     r1, #0
     83        str     r1, [r0]
     84
     85bframe:
     86
     87/* Now we need to set up the return from this ISR to be _ISR_Dispatch */
     88/* To do that, we need to save the current lr_int and spsr_int on the */
     89/* SVC stack                                                          */
     90        mrs     r0, spsr
     91        ldmia   sp!, {r1}       /* get lr off stack */
     92        stmdb   sp!, {r1}
     93        mrs     r2, cpsr   
     94        orr     r3, r2, #0x1    /* change to SVC mode */
     95        msr     cpsr_c, r3
     96
     97        /* now in SVC mode */
     98        stmdb   sp!, {r0, r1}   /* put spsr_int and lr_int on SVC stack */
     99        msr     cpsr_c, r2      /* change back to INT mode */
     100
     101        /* now in INT mode */
     102
     103        /* replace lr with address of _ISR_Dispatch */
     104        ldr     lr, =_ISR_Dispatch
     105        add     lr, lr, #0x4              /* On entry to an ISR, the lr is */
     106                                          /*    the return address + 4, so */
     107                                          /*    we have to emulate that    */
     108        ldmia   sp!, {r0}                 /* out with the old          */
     109        stmdb   sp!, {lr}                 /*    in with the new (lr) */
     110
     111       
     112        mrs     r0, spsr
     113        orr     r0, r0, #0xc0
     114        msr     spsr, r0
     115                                       
     116exitit:
     117        ldmia   sp!, {lr}                 /* restore regs from INT stack */
     118        ldmia   sp!, {r0, r1, r2, r3}     /* restore regs from INT stack */
     119        subs    pc, lr, #4                /* return */
    18120
    19121
    20 /*
    21  * WARNING :    register r5 is important. If you need to use it,
    22  *              to forget to save it !!!!!!!!!!
    23  */
    24        
    25         .globl _ISR_Handler
    26 _ISR_Handler:   
    27         stmdb   sp!, {r4,r5,lr}                 /* save regs on INT stack */
    28         mrs     r4, cpsr                        /* save current CSPR */
    29         mov     r5, r4                          /* copy CSPR */
    30         orr     r4, r4, #3
    31         msr     cpsr, r4                        /* switch to SVC mode */
    32        
    33         stmdb   sp!, {r0-r3,r12,r14}            /* save scratch regs on SVC stack */
    34122
    35         msr     cpsr, r5                        /* switch back to INT mode */
     123        /* on entry to _ISR_Dispatch, we're in SVC mode */     
     124        .globl _ISR_Dispatch
     125_ISR_Dispatch:
     126        stmdb   sp!, {r0-r12,lr}      /* save regs on SVC stack */
     127                                        /*    (now safe to call C funcs) */
     128                                        /*    we don't save lr, since  */
     129                                        /*    it's just going to get   */
     130                                        /*    overwritten              */
    36131
    37         ldr     r0, =_ISR_Nest_level             /* one nest level deeper */
    38         ldr     r1, [r0]
    39         add     r1, r1,#1
    40         str     r1, [r0]
    41        
    42         ldr     r0, =_Thread_Dispatch_disable_level          /* disable multitasking */
    43         ldr     r1, [r0]
    44         add     r1, r1,#1
    45         str     r1, [r0]
     132        bl      _Thread_Dispatch
     133        ldmia   sp!, {r0-r12, lr}
    46134
    47         b       ExecuteITHandler                /* BSP specific function to INT handler */
     135        stmdb   sp!, {r0-r2}
     136        /* Now we have to screw with the stack */
     137        mov     r0, sp                  /* copy the SVC stack pointer */
     138       
     139        mrs     r1, cpsr   
     140        bic     r2, r1, #0x1            /* change to INT mode */
     141        orr     r2, r2, #0xc0           /* disable interrupts */
     142        msr     cpsr_c, r2
    48143
    49         .globl  ReturnFromHandler
    50 ReturnFromHandler :     
    51         ldr     r0, =_ISR_Nest_level                    /* one less nest level  */
    52         ldr     r1, [r0]
    53         sub     r1, r1,#1
    54         str     r1, [r0]
    55        
    56         ldr     r0, =_Thread_Dispatch_disable_level     /* unnest multitasking */
    57         ldr     r1, [r0]
    58         sub     r1, r1,#1
    59         str     r1, [r0]
     144        /* now in INT mode */
     145        stmdb   sp!, {r4, r5, r6}   /* save temp vars on INT stack */
     146        ldmia   r0!, {r4, r5, r6}   /* Get r0-r3 from SVC stack */
     147        stmdb   sp!, {r4, r5, r6}   /*    and save them on INT stack */
     148       
     149        ldmia   r0!, {r4, r5}           /* get saved values from SVC stack */
     150                                        /*      r4=spsr, r5=lr */
     151        mov     lr,   r5                /* restore lr_int */
     152        msr     spsr, r4                /* restore spsr_int */
    60153
    61         cmp     r1, #0                   /* is dispatch enabled */
    62         bne     exitit                     /* Yes, then exit */
     154        /* switch to SVC mode, update sp, then return to INT mode */
     155        msr     cpsr_c, r1              /* switch to SVC mode */
     156        mov     sp, r0                  /* update sp_svc */
     157        msr     cpsr_c, r2              /* switch back to INT mode */
    63158
    64         ldr     r0, =_Context_Switch_necessary  /* task switch necessary ? */
    65         ldr     r1, [r0]
    66         cmp     r1, #0
    67         bne     schedule                        /* yes, call scheduler */
    68        
    69         ldr     r0, =_ISR_Signals_to_thread_executing   
    70         ldr     r1, [r0]                /* signals sent to Run_thread */
    71         cmp     r1, #0                  /*     while in interrupt handler ? */
    72         beq     exitit                  /* No, exit */
    73        
    74 bframe:
    75         mov     r1, #0       /* _ISR_Signals_to_thread_executing = FALSE */
    76         str     r1, [r0]
    77         /*
    78          * At this point, we need a complete exception context for the
    79          * current thread. We need to complete the interrupt exception
    80          * with the "not-yet-saved" registers
    81          */
    82         /*
    83          * currently exception context = interrupt handler
    84          * it needs to be optimized
    85          */
    86         bl      _ThreadProcessSignalsFromIrq
    87         b       exitit
    88                                
    89 schedule:
    90         /*
    91          * the scratch registers have already been saved and we are already
    92          * back on the thread system stack. So we can call _Thread_Displatch
    93          * directly
    94          */
    95         bl      _Thread_Dispatch
    96         /*
    97          * fall through exit to restore complete contex (scratch registers
    98          * eip, CS, Flags).
    99          */
    100 exitit:
    101         b       AckControler            /* BSP specific function to ack PIC */
     159        /* pop all the registers from the stack */
     160        ldmia   sp!, {r0, r1, r2}
     161        ldmia   sp!, {r4, r5, r6}
    102162
    103         .globl ReturnFromAck
    104 ReturnFromAck :
    105         ldmia   sp!, {r0-r3,r12,r14}    /* restore regs from SVC stack */
    106         msr     cpsr, r5                /* switch back to INT mode */
    107         ldmia   sp!, {r4,r5,lr}         /* restore regs from INT stack */               
    108         subs    pc,r14,#4               /* return */
    109        
     163        /* Finally, we can return to the interrupted task */
     164        subs    pc, lr, #4
     165
     166
     167
     168
     169
Note: See TracChangeset for help on using the changeset viewer.