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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [cortexm/] [arch/] [current/] [src/] [vectors.S] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
/*==========================================================================
2
//
3
//      vectors.S
4
//
5
//      Cortex-M exception vectors
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 2008, 2011 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later
16
// version.
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21
// for more details.
22
//
23
// You should have received a copy of the GNU General Public License
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26
//
27
// As a special exception, if other files instantiate templates or use
28
// macros or inline functions from this file, or you compile this file
29
// and link it with other works to produce a work based on this file,
30
// this file does not by itself cause the resulting work to be covered by
31
// the GNU General Public License. However the source code for this file
32
// must still be made available in accordance with section (3) of the GNU
33
// General Public License v2.
34
//
35
// This exception does not invalidate any other reasons why a work based
36
// on this file might be covered by the GNU General Public License.
37
// -------------------------------------------
38
// ####ECOSGPLCOPYRIGHTEND####
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    nickg
43
// Date:         2008-07-30
44
// Description:  This file defines the code placed into the exception
45
//               vectors. It also contains the first level default VSRs
46
//               that save and restore state for both exceptions and
47
//               interrupts.
48
//
49
//####DESCRIPTIONEND####
50
//
51
//========================================================================*/
52
 
53
#include 
54
#include 
55
#ifdef CYGPKG_KERNEL
56
#include 
57
#endif
58
 
59
#include 
60
 
61
//==========================================================================
62
 
63
        .syntax unified
64
        .thumb
65
 
66
//==========================================================================
67
// Initial exception vector table
68
//
69
// This only contains the stack and entry point for reset. The table
70
// to be used at runtime is constructed by code in hal_reset_vsr().
71
 
72
        .section        ".vectors","ax"
73
 
74
        .global         hal_vsr_table
75
hal_vsr_table_init:
76
 
77
        .long           hal_startup_stack               //  0 Reset stack
78
        .long           hal_reset_vsr                   //  1 Reset entry
79
 
80
//==========================================================================
81
 
82
        .text
83
        .thumb
84
 
85
//==========================================================================
86
// Fake entry point.
87
//
88
// The ELF file entry point points here. When loading an executable
89
// via RedBoot/Stubs or via JTAG the PC will be set to this address.
90
// The code here sets up the SP and branches to the reset VSR in
91
// emulation of the hardware reset behaviour.
92
 
93
        .align  2
94
        .global reset_vector
95
        .thumb
96
        .thumb_func
97
        .type   reset_vector, %function
98
reset_vector:
99
 
100
        ldr     sp,=hal_startup_stack
101
        b       hal_reset_vsr
102
 
103
        .pool
104
 
105
#if !defined(CYG_HAL_STARTUP_RAM)
106
//==========================================================================
107
// State switch VSR
108
//
109
// This is called from the init code to switch execution from the main
110
// stack to the process stack. We also take the opportunity to do some
111
// other things that are best done in asm code such as disabling interrupts
112
// and setting the control register.
113
//
114
// The adjustment to MSP by 1/2 interrupt stack size allows code to
115
// throw exceptions without corrupting the execution stack. This is
116
// only necessary for non-kernel configurations (e.g. RedBoot, Stubs)
117
// since kernel configurations will switch to a thread stack before
118
// they should throw an exception.
119
 
120
        .global hal_switch_state_vsr
121
        .thumb
122
        .thumb_func
123
        .type   hal_switch_state_vsr, %function
124
hal_switch_state_vsr:
125
 
126
        mov     r0,#CYGNUM_HAL_CORTEXM_PRIORITY_MAX
127
        msr     basepri,r0
128
 
129
        mov     r0,#2                   // Set CONTROL register to 2
130
        msr     control,r0
131
        isb                             // Insert a barrier
132
 
133
        mov     r0,sp
134
        msr     psp,r0                  // Copy SP to PSP
135
 
136
#if !defined(CYGPKG_KERNEL)
137
        sub     sp,#(CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE/2)
138
#endif
139
 
140
        orr     lr,#0xD                 // Adjust return link
141
        bx      lr                      // Return to init code on PSP now
142
 
143
#endif
144
 
145
//==========================================================================
146
// Default exception VSR
147
//
148
// This is attached to all exception vectors. It saves the entire
149
// machine state and calls into the eCos exception handling code.
150
//
151
// NOTE: At present this implementation does not permit an exception
152
// handler to suspend the faulting thread and enter the scheduler to
153
// switch elsewhere. However, I know of no code that does anything
154
// like this. If there is then this may need treating in the same way
155
// as the interrupt end code.
156
 
157
        .global hal_default_exception_vsr
158
        .thumb
159
        .thumb_func
160
        .type   hal_default_exception_vsr, %function
161
hal_default_exception_vsr:
162
 
163
        mrs     r0,psp                  // Get process stack
164
        sub     r1,r0,#(4*12)           // Make space for saved state
165
        msr     psp,r1                  // Ensure PSP is up to date
166
 
167
        mov     r1,#1                   // R1 = exception state type
168
        mrs     r2,ipsr                 // R2 = vector number
169
        mrs     r3,basepri              // R3 = basepri
170
        stmfd   r0!,{r1-r11,lr}         // Push type, vector, basepri, r4-11
171
 
172
        mov     r4,r0                   // R4 = saved state pointer
173
 
174
        bl      hal_deliver_exception
175
 
176
        mov     r0,r4                   // R0 = state saved across call
177
        ldmfd   r0!,{r1-r11,lr}         // Pop type, vec, basepri, registers and LR
178
        msr     psp,r0                  // Restore PSP
179
        msr     basepri,r3              // Restore basepri
180
 
181
        bx      lr                      // Return
182
 
183
        .pool
184
 
185
//==========================================================================
186
// Default interrupt VSR
187
//
188
// This is a trampoline that translates from the hardware defined entry point
189
// to the ISR defined by eCos. The CPU will switch automatically to the main
190
// (interrupt) stack with the process state saved on the process stack. Apart
191
// from saving a pointer to the interrupt state for Ctrl-C support, and fetching
192
// the vector number, most of the work is actually done in hal_deliver_interrupt().
193
 
194
 
195
        .global hal_default_interrupt_vsr
196
        .thumb
197
        .thumb_func
198
        .type   hal_default_interrupt_vsr, %function
199
hal_default_interrupt_vsr:
200
 
201
        push    {lr}                    // Save return link
202
        sub     sp,#4                   // Realign SP to 8 bytes
203
 
204
#if CYGINT_HAL_COMMON_SAVED_INTERRUPT_STATE_REQUIRED > 0
205
        // If we are supporting Ctrl-C interrupts from GDB, we must squirrel
206
        // away a pointer to the saved interrupt state here so that we can
207
        // plant a breakpoint at some later time.
208
 
209
       .extern  hal_saved_interrupt_state
210
        mrs     r1,psp                  // Get PSP
211
        mov     r0,#3                   // Interrupt state type
212
        stmfd   r1!,{r0}                // Push interrupt type
213
        ldr     r12,=hal_saved_interrupt_state
214
        str     r1,[r12]
215
#endif
216
 
217
        mrs     r0,ipsr                 // R0 = arg0 = vector number
218
        sub     r0,#15                  // Adjust to interrupt range
219
 
220
        bl      hal_deliver_interrupt
221
 
222
        add     sp,#4                   // pop alignment padding
223
        pop     {pc}                    // Pop LR and return
224
 
225
        .pool
226
 
227
//==========================================================================
228
// Pendable SVC VSR
229
//
230
// This is invoked if an interrupt posts a DSR. It calls the DSR
231
// and finalizes interrupt processing by calling interrupt_end(). We want
232
// to run interrupt_end() on the PSP of the current thread. So we push
233
// a fake exception frame onto the PSP which will take us to hal_interrupt_end(),
234
// which will make the call. The return link loaded by that frame takes us
235
// back to hal_interrupt_end_done which will unwind the real exception
236
// frame that is still on the PSP.
237
 
238
 
239
        .global hal_pendable_svc_vsr
240
        .thumb
241
        .thumb_func
242
        .type   hal_pendable_svc_vsr, %function
243
hal_pendable_svc_vsr:
244
 
245
        mrs     r12,psp                 // R12 = thread's PSP
246
        sub     r0,r12,#0x20            // Make space for frame
247
        msr     psp,r0                  // Put it back
248
 
249
        ldr     r3,=0x01000000          // R3 = PSR = thumb bit set
250
        ldr     r2,=hal_interrupt_end   // R2 = PC = interrupt end entry point
251
        ldr     r1,=hal_interrupt_end_done // R1 = LR = restore code
252
        stmfd   r12!,{r0-r3}            // Save fake R12, LR, PC, PSR
253
        stmfd   r12!,{r0-r3}            // Save fake R0-R3
254
 
255
        bx      lr                      // Return to hal_interrupt_end
256
 
257
        .pool
258
 
259
//==========================================================================
260
// Interrupt end done
261
//
262
// After calling interrupt end a thread returns here to unstack the
263
// exception frame used to enter hal_pendable_svc_vsr. We can only
264
// successfully unstack a frame by doing a proper exception return
265
// from handler mode, so we use a SWI which will discard its own
266
// frame and restore the saved one.
267
 
268
 
269
        .global hal_interrupt_end_done
270
        .thumb
271
        .thumb_func
272
        .type   hal_interrupt_end_done, %function
273
hal_interrupt_end_done:
274
 
275
        ldr     r3,=hal_interrupt_end_vsr
276
        swi 0
277
 
278
//==========================================================================
279
// Interrupt end VSR
280
//
281
// This is the SVC VSR invoked by hal_interrupt_end_done to restore the
282
// original exception frame from a pendable SVC entry. It does this
283
// by discarding its own frame and using the one below it on the
284
// stack to return.
285
 
286
        .global hal_interrupt_end_vsr
287
        .thumb
288
        .thumb_func
289
        .type   hal_interrupt_end_vsr, %function
290
hal_interrupt_end_vsr:
291
 
292
        mrs     r12,psp                 // R12 = thread's PSP
293
        add     r12,#32                 // Skip our saved state
294
        msr     psp,r12                 // Restore thread's PSP
295
 
296
        bx      lr                      // And return
297
 
298
//==========================================================================
299
// Run DSRs VSR
300
//
301
// This is invoked from the kernel via a SWI to run DSRs on the
302
// interrupt/main stack. It merely branches to
303
// cyg_interrupt_call_pending_DSRs() which will then directly return
304
// from the SVC exception.
305
 
306
        .global hal_call_dsrs_vsr
307
        .thumb
308
        .thumb_func
309
        .type   hal_call_dsrs_vsr, %function
310
 
311
hal_call_dsrs_vsr:
312
 
313
        .extern cyg_interrupt_call_pending_DSRs
314
        b       cyg_interrupt_call_pending_DSRs
315
 
316
//==========================================================================
317
// SVC VSR
318
//
319
// The SVC VSR is used as a general-purpose mechanism for running code
320
// in handler mode. R3 contains the address of a piece of code to run,
321
// R0-R2 contain any arguments. Once entered the code is responsible for
322
// handling the system state and returning to thread mode.
323
//
324
// Note that R0-R3 must be explicitly restored from their stacked
325
// copies since a late arriving interrupt can preempt the SVC entry
326
// and corrupt these registers before we get here.
327
 
328
        .global hal_default_svc_vsr
329
        .thumb
330
        .thumb_func
331
        .type   hal_default_svc_vsr, %function
332
hal_default_svc_vsr:
333
 
334
        mrs     r12,psp
335
        ldmfd   r12,{r0-r3}
336
        bx      r3                      // Jump to routine in R3
337
 
338
        .pool
339
 
340
//==========================================================================
341
// end of vectors.S

powered by: WebSVN 2.1.0

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