1 |
30 |
unneback |
/* cpu_asm.s
|
2 |
|
|
*
|
3 |
|
|
* This file contains all assembly code for the MC68020 implementation
|
4 |
|
|
* of RTEMS.
|
5 |
|
|
*
|
6 |
|
|
* ATTENTION: Modified for benchmarks
|
7 |
|
|
*
|
8 |
|
|
* COPYRIGHT (c) 1989-1999.
|
9 |
|
|
* On-Line Applications Research Corporation (OAR).
|
10 |
|
|
*
|
11 |
|
|
* The license and distribution terms for this file may be
|
12 |
|
|
* found in the file LICENSE in this distribution or at
|
13 |
|
|
* http://www.OARcorp.com/rtems/license.html.
|
14 |
|
|
*
|
15 |
|
|
* $Id: Modif_cpu_asm.S,v 1.2 2001-09-27 12:00:07 chris Exp $
|
16 |
|
|
*/
|
17 |
|
|
|
18 |
|
|
|
19 |
|
|
#include
|
20 |
|
|
|
21 |
|
|
.text
|
22 |
|
|
|
23 |
|
|
/*PAGE
|
24 |
|
|
* void _Debug_ISR_Handler_Console()
|
25 |
|
|
*
|
26 |
|
|
* This routine provides the RTEMS interrupt management.
|
27 |
|
|
*
|
28 |
|
|
* NOTE:
|
29 |
|
|
* Upon entry, the master stack will contain an interrupt stack frame
|
30 |
|
|
* back to the interrupted thread and the interrupt stack will contain
|
31 |
|
|
* a throwaway interrupt stack frame. If dispatching is enabled, this
|
32 |
|
|
* is the outer most interrupt, and (a context switch is necessary or
|
33 |
|
|
* the current thread has signals), then set up the master stack to
|
34 |
|
|
* transfer control to the interrupt dispatcher.
|
35 |
|
|
* NOTE:
|
36 |
|
|
* USED TO MESURE THE TIME SPENT IN THE INTERRUPT SUBROUTINE
|
37 |
|
|
* CS5 - CS8 are linked to an oscilloscope so that you can mesure
|
38 |
|
|
* RTEMS overhead (BTW it's very short :) )
|
39 |
|
|
*/
|
40 |
|
|
|
41 |
|
|
/*
|
42 |
|
|
* With this approach, lower priority interrupts may
|
43 |
|
|
* execute twice if a higher priority interrupt is
|
44 |
|
|
* acknowledged before _Thread_Dispatch_disable is
|
45 |
|
|
* increamented and the higher priority interrupt
|
46 |
|
|
* preforms a context switch after executing. The lower
|
47 |
|
|
* priority intterrupt will execute (1) at the end of the
|
48 |
|
|
* higher priority interrupt in the new context if
|
49 |
|
|
* permitted by the new interrupt level mask, and (2) when
|
50 |
|
|
* the original context regains the cpu.
|
51 |
|
|
*/
|
52 |
|
|
|
53 |
|
|
#if ( M68K_HAS_VBR == 1)
|
54 |
|
|
.set SR_OFFSET, 0 | Status register offset
|
55 |
|
|
.set PC_OFFSET, 2 | Program Counter offset
|
56 |
|
|
.set FVO_OFFSET, 6 | Format/vector offset
|
57 |
|
|
#else
|
58 |
|
|
.set SR_OFFSET, 2 | Status register offset
|
59 |
|
|
.set PC_OFFSET, 4 | Program Counter offset
|
60 |
|
|
.set FVO_OFFSET, 0 | Format/vector offset placed in the stack
|
61 |
|
|
#endif /* M68K_HAS_VBR */
|
62 |
|
|
|
63 |
|
|
.set SAVED, 16 | space for saved registers
|
64 |
|
|
|
65 |
|
|
.align 4
|
66 |
|
|
.global SYM (_Debug_ISR_Handler_Console)
|
67 |
|
|
|
68 |
|
|
SYM (_Debug_ISR_Handler_Console):
|
69 |
|
|
|
70 |
|
|
|
|
71 |
|
|
tst.w 0x14000000 | ALLUME CS5
|
72 |
|
|
|
|
73 |
|
|
|
74 |
|
|
addql #1,SYM (_Thread_Dispatch_disable_level) | disable multitasking
|
75 |
|
|
moveml d0-d1/a0-a1,a7@- | save d0-d1,a0-a1
|
76 |
|
|
movew a7@(SAVED+FVO_OFFSET),d0 | d0 = F/VO
|
77 |
|
|
andl #0x0fff,d0 | d0 = vector offset in vbr
|
78 |
|
|
|
79 |
|
|
|
80 |
|
|
#if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == 1 )
|
81 |
|
|
movew sr,d1 | Save status register
|
82 |
|
|
oriw #0x700,sr | Disable interrupts
|
83 |
|
|
tstl SYM (_ISR_Nest_level) | Interrupting an interrupt handler?
|
84 |
|
|
bne 1f | Yes, just skip over stack switch code
|
85 |
|
|
movel SYM(_CPU_Interrupt_stack_high),a0 | End of interrupt stack
|
86 |
|
|
movel a7,a0@- | Save task stack pointer
|
87 |
|
|
movel a0,a7 | Switch to interrupt stack
|
88 |
|
|
1:
|
89 |
|
|
addql #1,SYM(_ISR_Nest_level) | one nest level deeper
|
90 |
|
|
movew d1,sr | Restore status register
|
91 |
|
|
#else
|
92 |
|
|
addql #1,SYM (_ISR_Nest_level) | one nest level deeper
|
93 |
|
|
#endif /* CPU_HAS_SOFTWARE_INTERRUPT_STACK == 1 */
|
94 |
|
|
|
95 |
|
|
#if ( M68K_HAS_PREINDEXING == 1 )
|
96 |
|
|
movel @( SYM (_ISR_Vector_table),d0:w:1),a0| fetch the ISR
|
97 |
|
|
#else
|
98 |
|
|
movel # SYM (_ISR_Vector_table),a0 | a0 = base of RTEMS table
|
99 |
|
|
addal d0,a0 | a0 = address of vector
|
100 |
|
|
movel (a0),a0 | a0 = address of user routine
|
101 |
|
|
#endif
|
102 |
|
|
|
103 |
|
|
lsrl #2,d0 | d0 = vector number
|
104 |
|
|
movel d0,a7@- | push vector number
|
105 |
|
|
|
106 |
|
|
|
|
107 |
|
|
tst.w 0x18000000 | ALLUME CS6
|
108 |
|
|
|
|
109 |
|
|
|
110 |
|
|
jbsr a0@ | invoke the user ISR
|
111 |
|
|
|
112 |
|
|
|
|
113 |
|
|
tst.w 0x18000000 | ALLUME CS6
|
114 |
|
|
|
|
115 |
|
|
|
116 |
|
|
addql #4,a7 | remove vector number
|
117 |
|
|
|
118 |
|
|
#if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == 1 )
|
119 |
|
|
movew sr,d0 | Save status register
|
120 |
|
|
oriw #0x700,sr | Disable interrupts
|
121 |
|
|
subql #1,SYM(_ISR_Nest_level) | Reduce interrupt-nesting count
|
122 |
|
|
bne 1f | Skip if return to interrupt
|
123 |
|
|
movel (a7),a7 | Restore task stack pointer
|
124 |
|
|
1:
|
125 |
|
|
movew d0,sr | Restore status register
|
126 |
|
|
#else
|
127 |
|
|
subql #1,SYM (_ISR_Nest_level) | one less nest level
|
128 |
|
|
#endif /* CPU_HAS_SOFTWARE_INTERRUPT_STACK == 1 */
|
129 |
|
|
|
130 |
|
|
subql #1,SYM (_Thread_Dispatch_disable_level)
|
131 |
|
|
| unnest multitasking
|
132 |
|
|
bne Debug_exit | If dispatch disabled, Debug_exit
|
133 |
|
|
|
134 |
|
|
#if ( M68K_HAS_SEPARATE_STACKS == 1 )
|
135 |
|
|
movew #0xf000,d0 | isolate format nibble
|
136 |
|
|
andw a7@(SAVED+FVO_OFFSET),d0 | get F/VO
|
137 |
|
|
cmpiw #0x1000,d0 | is it a throwaway isf?
|
138 |
|
|
bne Debug_exit | NOT outer level, so branch
|
139 |
|
|
#endif
|
140 |
|
|
|
141 |
|
|
tstl SYM (_Context_Switch_necessary)
|
142 |
|
|
| Is thread switch necessary?
|
143 |
|
|
bne bframe | Yes, invoke dispatcher
|
144 |
|
|
|
145 |
|
|
tstl SYM (_ISR_Signals_to_thread_executing)
|
146 |
|
|
| signals sent to Run_thread
|
147 |
|
|
| while in interrupt handler?
|
148 |
|
|
beq Debug_exit | No, then Debug_exit
|
149 |
|
|
|
150 |
|
|
|
151 |
|
|
bframe: clrl SYM (_ISR_Signals_to_thread_executing)
|
152 |
|
|
| If sent, will be processed
|
153 |
|
|
#if ( M68K_HAS_SEPARATE_STACKS == 1 )
|
154 |
|
|
movec msp,a0 | a0 = master stack pointer
|
155 |
|
|
movew #0,a0@- | push format word
|
156 |
|
|
movel # SYM (_ISR_Dispatch),a0@- | push return addr
|
157 |
|
|
| filter out the trace bit to stop single step debugging breaking
|
158 |
|
|
movew a0@(6+SR_OFFSET),d0
|
159 |
|
|
andw #0x7FFF,d0
|
160 |
|
|
movew d0,a0@- | push thread sr
|
161 |
|
|
movec a0,msp | set master stack pointer
|
162 |
|
|
#else
|
163 |
|
|
|
164 |
|
|
| filter out the trace bit to stop single step debugging breaking
|
165 |
|
|
movew a7@(16+SR_OFFSET),d0
|
166 |
|
|
andw #0x7FFF,d0
|
167 |
|
|
movew d0,sr
|
168 |
|
|
jsr SYM (_Thread_Dispatch)
|
169 |
|
|
#endif
|
170 |
|
|
|
171 |
|
|
Debug_exit: moveml a7@+,d0-d1/a0-a1 | restore d0-d1,a0-a1
|
172 |
|
|
#if ( M68K_HAS_VBR == 0 )
|
173 |
|
|
addql #2,a7 | pop format/id
|
174 |
|
|
#endif /* M68K_HAS_VBR */
|
175 |
|
|
|
176 |
|
|
|
|
177 |
|
|
tst.w 0x1C000000 | ALLUME CS7
|
178 |
|
|
|
|
179 |
|
|
|
180 |
|
|
rte | return to thread
|
181 |
|
|
| OR _Isr_dispatch
|
182 |
|
|
|
183 |
|
|
|