OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [i386/] [shared/] [irq/] [irq_asm.S] - Blame information for rev 30

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/* irq.c
2
 *
3
 *  This file contains the implementation of the function described in irq.h
4
 *
5
 *  CopyRight (C) 1998 valette@crf.canon.fr
6
 *
7
 *  The license and distribution terms for this file may be
8
 *  found in found in the file LICENSE in this distribution or at
9
 *  http://www.OARcorp.com/rtems/license.html.
10
 *
11
 *  $Id: irq_asm.S,v 1.2 2001-09-27 11:59:49 chris Exp $
12
 */
13
 
14
#include "asm.h"
15
#include 
16
 
17
               BEGIN_CODE
18
 
19
SYM (_ISR_Handler):
20
       /*
21
        *  Before this was point is reached the vectors unique
22
        *  entry point did the following:
23
        *
24
        *     1. saved scratch registers registers eax edx ecx"
25
        *     2. put the vector number in ecx.
26
        *
27
        * BEGINNING OF ESTABLISH SEGMENTS
28
        *
29
        *  WARNING: If an interrupt can occur when the segments are
30
        *           not correct, then this is where we should establish
31
        *           the segments.  In addition to establishing the
32
        *           segments, it may be necessary to establish a stack
33
        *           in the current data area on the outermost interrupt.
34
        *
35
        *  NOTE:  If the previous values of the segment registers are
36
        *         pushed, do not forget to adjust SAVED_REGS.
37
        *
38
        *  NOTE:  Make sure the exit code which restores these
39
        *         when this type of code is needed.
40
        */
41
 
42
       /***** ESTABLISH SEGMENTS CODE GOES HERE  ******/
43
 
44
       /*
45
        * END OF ESTABLISH SEGMENTS
46
        */
47
 
48
        /*
49
         *  Now switch stacks if necessary
50
         */
51
 
52
        movw      SYM (i8259s_cache), ax # move current i8259 interrupt mask in ax
53
        pushl     eax                         # push it on the stack
54
        /*
55
         * compute the new PIC mask:
56
         *
57
         *  =  | irq_mask_or_tbl[]
58
         */
59
        movw      SYM (irq_mask_or_tbl) (,ecx,2), dx
60
        orw       dx, ax
61
        /*
62
         * Install new computed value on the i8259 and update cache
63
         * accordingly
64
         */
65
        movw      ax, SYM (i8259s_cache)
66
        outb      $PIC_MASTER_IMR_IO_PORT
67
        movb      ah, al
68
        outb      $PIC_SLAVE_IMR_IO_PORT
69
 
70
        /*
71
         * acknowledge the interrupt
72
         *
73
         */
74
        movb    $PIC_EOI, al
75
        cmpl    $7, ecx
76
        jbe     .master
77
        outb    $PIC_SLAVE_COMMAND_IO_PORT
78
.master:
79
        outb    $PIC_MASTER_COMMAND_IO_PORT
80
 
81
.check_stack_switch:
82
        pushl     ebp
83
        movl      esp, ebp                  # ebp = previous stack pointer
84
        cmpl      $0, SYM (_ISR_Nest_level) # is this the outermost interrupt?
85
        jne       nested                    # No, then continue
86
        movl      SYM (_CPU_Interrupt_stack_high), esp
87
 
88
        /*
89
         *  We want to insure that the old stack pointer is on the
90
         *  stack we will be on at the end of the ISR when we restore it.
91
         *  By saving it on every interrupt, all we have to do is pop it
92
         *  near the end of every interrupt.
93
         */
94
 
95
nested:
96
        incl      SYM (_ISR_Nest_level)     # one nest level deeper
97
        incl      SYM (_Thread_Dispatch_disable_level) # disable multitasking
98
        /*
99
         * re-enable interrupts at processor level as the current
100
         * interrupt source is now masked via i8259
101
         */
102
        sti
103
 
104
        /*
105
         *  ECX is preloaded with the vector number but it is a scratch register
106
         *  so we must save it again.
107
         */
108
 
109
        pushl     ecx                       # push vector number
110
        mov       SYM (current_irq) (,ecx,4),eax
111
                                            # eax = Users handler
112
        call      *eax                      # invoke user ISR
113
        /*
114
         * disable interrupts_again
115
         */
116
        cli
117
        popl       ecx                       # ecx = vector number
118
        /*
119
         * restore stack
120
         */
121
        movl      ebp, esp
122
        popl      ebp
123
 
124
        /*
125
         * restore the original i8259 masks
126
         */
127
        popl      eax
128
        movw      ax, SYM (i8259s_cache)
129
        outb      $PIC_MASTER_IMR_IO_PORT
130
        movb      ah, al
131
        outb      $PIC_SLAVE_IMR_IO_PORT
132
 
133
 
134
        decl      SYM (_ISR_Nest_level)     # one less ISR nest level
135
                                            # If interrupts are nested,
136
                                            #   then dispatching is disabled
137
 
138
        decl      SYM (_Thread_Dispatch_disable_level)
139
                                            # unnest multitasking
140
                                            # Is dispatch disabled
141
        jne       .exit                     # Yes, then exit
142
 
143
        cmpl      $0, SYM (_Context_Switch_necessary)
144
                                            # Is task switch necessary?
145
        jne       .schedule                 # Yes, then call the scheduler
146
 
147
        cmpl      $0, SYM (_ISR_Signals_to_thread_executing)
148
                                            # signals sent to Run_thread
149
                                            #   while in interrupt handler?
150
        je        .exit                     # No, exit
151
 
152
 
153
.bframe:
154
        movl      $0, SYM (_ISR_Signals_to_thread_executing)
155
        /*
156
         * This code is the less critical path. In order to have a single
157
         * Thread Context, we take the same frame than the one pushed on
158
         * exceptions. This makes sense because Signal is a software
159
         * exception.
160
         */
161
        popl    edx
162
        popl    ecx
163
        popl    eax
164
 
165
        pushl   $0      # fake fault code
166
        pushl   $0      # fake exception number
167
 
168
        pusha
169
        pushl   esp
170
        call    _ThreadProcessSignalsFromIrq
171
        addl    $4, esp
172
        popa
173
        addl    $8, esp
174
        iret
175
 
176
.schedule:
177
        /*
178
         * the scratch registers have already been saved and we are already
179
         * back on the thread system stack. So we can call _Thread_Displatch
180
         * directly
181
         */
182
        call _Thread_Dispatch
183
        /*
184
         * fall through exit to restore complete contex (scratch registers
185
         * eip, CS, Flags).
186
         */
187
.exit:
188
       /*
189
        * BEGINNING OF DE-ESTABLISH SEGMENTS
190
        *
191
        *  NOTE:  Make sure there is code here if code is added to
192
        *         load the segment registers.
193
        *
194
        */
195
 
196
       /******* DE-ESTABLISH SEGMENTS CODE GOES HERE ********/
197
 
198
       /*
199
        * END OF DE-ESTABLISH SEGMENTS
200
        */
201
        popl    edx
202
        popl    ecx
203
        popl    eax
204
        iret
205
 
206
 
207
#define DISTINCT_INTERRUPT_ENTRY(_vector) \
208
        .p2align 4                         ; \
209
        PUBLIC (rtems_irq_prologue_ ## _vector ) ; \
210
SYM (rtems_irq_prologue_ ## _vector ):             \
211
        pushl   eax             ; \
212
        pushl   ecx             ; \
213
        pushl   edx             ; \
214
        movl    $ _vector, ecx  ; \
215
        jmp   SYM (_ISR_Handler) ;
216
 
217
DISTINCT_INTERRUPT_ENTRY(0)
218
DISTINCT_INTERRUPT_ENTRY(1)
219
DISTINCT_INTERRUPT_ENTRY(2)
220
DISTINCT_INTERRUPT_ENTRY(3)
221
DISTINCT_INTERRUPT_ENTRY(4)
222
DISTINCT_INTERRUPT_ENTRY(5)
223
DISTINCT_INTERRUPT_ENTRY(6)
224
DISTINCT_INTERRUPT_ENTRY(7)
225
DISTINCT_INTERRUPT_ENTRY(8)
226
DISTINCT_INTERRUPT_ENTRY(9)
227
DISTINCT_INTERRUPT_ENTRY(10)
228
DISTINCT_INTERRUPT_ENTRY(11)
229
DISTINCT_INTERRUPT_ENTRY(12)
230
DISTINCT_INTERRUPT_ENTRY(13)
231
DISTINCT_INTERRUPT_ENTRY(14)
232
DISTINCT_INTERRUPT_ENTRY(15)
233
 
234
        /*
235
         * routine used to initialize the IDT by default
236
         */
237
 
238
PUBLIC (default_raw_idt_handler)
239
PUBLIC (raw_idt_notify)
240
 
241
SYM (default_raw_idt_handler):
242
        pusha
243
        cld
244
        call    raw_idt_notify
245
        popa
246
        iret
247
 
248
END_CODE
249
 
250
END

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.