]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/fr30/arch/v2_0/src/vectors.S
Initial revision
[karo-tx-redboot.git] / packages / hal / fr30 / arch / v2_0 / src / vectors.S
1 ##=============================================================================
2 ##
3 ##      vectors.S
4 ##
5 ##      fr30 startup code and exception and interrupt vectors
6 ##
7 ##=============================================================================
8 #####ECOSGPLCOPYRIGHTBEGIN####
9 ## -------------------------------------------
10 ## This file is part of eCos, the Embedded Configurable Operating System.
11 ## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 ## Copyright (C) 2007 eCosCentric Ltd.
13 ##
14 ## eCos is free software; you can redistribute it and/or modify it under
15 ## the terms of the GNU General Public License as published by the Free
16 ## Software Foundation; either version 2 or (at your option) any later version.
17 ##
18 ## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 ## 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 along
24 ## with eCos; if not, write to the Free Software Foundation, Inc.,
25 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 ##
27 ## As a special exception, if other files instantiate templates or use macros
28 ## or inline functions from this file, or you compile this file and link it
29 ## with other works to produce a work based on this file, this file does not
30 ## by itself cause the resulting work to be covered by the GNU General Public
31 ## License. However the source code for this file must still be made available
32 ## in accordance with section (3) of the GNU General Public License.
33 ##
34 ## This exception does not invalidate any other reasons why a work based on
35 ## this file might be covered by the GNU General Public License.
36 ##
37 ## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 ## at http://sources.redhat.com/ecos/ecos-license/
39 ## -------------------------------------------
40 #####ECOSGPLCOPYRIGHTEND####
41 ##=============================================================================
42 #######DESCRIPTIONBEGIN####
43 ##
44 ## Author(s):   larsi
45 ## Contributors:larsi
46 ## Date:        2006-06-26
47 ## Purpose:     fr30 exception vectors
48 ## Description: This file defines the code placed into the exception
49 ##              vectors. It also contains the startup code and first
50 ##              level default VSRs that save and restore state for
51 ##              both exceptions and interrupts.
52 ##
53 ######DESCRIPTIONEND####
54 ##
55 ##=============================================================================
56
57
58 #include <pkgconf/system.h>
59 #include <pkgconf/hal.h>
60 #include CYGBLD_HAL_PLATFORM_H
61
62 #ifdef CYGPKG_KERNEL
63 #include <pkgconf/kernel.h>
64 #endif /* CYGPKG_KERNEL */
65
66 #include <cyg/hal/arch.inc>
67
68 #==============================================================================
69
70     .file   "vectors.S"
71
72 #==============================================================================
73 # Real startup code. We jump here from the various reset vectors to set up the
74 # world.
75
76     .text
77     .globl      _start
78
79 _start:
80
81 # disable interrupts and set priority to lowest (=disable)
82     andccr  #0xef
83     stilm   #0x0
84
85     hal_diag_init_led
86 #ifdef CYGPKG_HAL_FR30_FLASH_INIT_DEFINED
87     hal_flash_init
88 #endif
89     hal_cpu_init
90
91 #ifdef CYGPKG_HAL_FR30_MEMC_INIT_DEFINED
92     hal_memc_init
93 #endif
94
95     hal_intc_init
96
97     hal_cache_init
98
99     hal_timer_init
100
101 # Zero the BSS. If the BSS is not a whole number of words
102 # long we will write up to 3 extra bytes at the end.
103 # (This should not be a problem usually).
104     ldi:32  #__bss_end - 8,     r12
105     ldi:32  #__bss_start - 4,   r13
106     eor     r0, r0 ; zero r0
107 2:
108     add     #0x4,   r13
109     cmp     r12,    r13
110     ble:d   2b
111     st      r0,     @r13
112
113 #if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
114
115 # In a ROM booted system, we also need to copy the data section
116 # out to the RAM.
117
118     ldi:32  #__rom_data_start - 4 + CYGPKG_HAL_FR30_LMA_OFFSET,  r11
119     ldi:32  #__ram_data_start - 4,  r9
120     ldi:32  #__ram_data_end - 8,    r10
121 3:
122     add     #0x4,   r11
123     add     #0x4,   r9
124     ld      @r11,   r0
125     cmp     r10,    r9
126     ble:d   3b
127     st      r0,     @r9
128
129 #endif
130
131
132     # Set up the stacks
133     # Begin with interrupt (system) stack
134
135     ldi:32  #__interrupt_stack, r11
136     mov     r11,    ssp
137
138     # and now continue with user stack
139
140     orccr   #0x20
141     ldi:32  #__user_stack,  r11
142     mov     r11,    usp
143
144 #if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
145 # If we are here, initialize the hal_vsr_table. RAM startup
146 # configurations can assume that Redboot has already set it up.
147
148     .extern hal_mon_init
149     ldi:32  #hal_mon_init,  r11
150     call    @r11
151
152 #endif
153
154     .extern hal_variant_init
155     ldi:32  #hal_variant_init,  r11
156     call        @r11
157
158     .extern hal_platform_init
159     ldi:32  #hal_platform_init,  r11
160     call    @r11
161
162 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
163     // This is here so we can debug the constructors.
164     .extern initialize_stub
165     ldi:32  #initialize_stub,   r11
166     call    @r11
167 #endif
168
169     .extern cyg_hal_invoke_constructors
170     ldi:32  #cyg_hal_invoke_constructors,  r11
171     call    @r11
172
173 # TODO integrate into hal_intr.h
174 # set irq 25 priority (for reload timer 1)
175     ldi:20  #0x449,     r4
176     ldi:8   #0x10,      r5
177     stb     r5,         @r4
178
179 #ifdef CYGDBG_HAL_DEBUG_GDB_INITIAL_BREAK
180         .extern breakpoint
181         call breakpoint
182 #endif
183
184
185     .extern cyg_start
186     ldi:32  #cyg_start,  r11
187     call    @r11
188
189 # Hmm.  Not expecting to return from cyg_start, endless nop loop
190 1:  nop
191     call   1b
192
193 #==============================================================================
194 # Default exception VSR
195
196     .align  2, 0xcc
197     .globl  __default_exception_vsr
198 __default_exception_vsr:
199
200     ## We enter here with the CPU state still in the registers and:
201     ##  @(ssp,8)    PS pushed by hardware
202     ##  @(ssp,4)    PC pushed by hardware
203     ##  @(ssp)      old register r0 content pushed by trampoline
204     ##  r0 now contains the vector number
205
206 # at first switch to USP (set bit 5 in CCR in PS)
207     orccr   #0x20
208
209     st      r0,     @-r15
210     st      mdl,    @-r15
211     st      mdh,    @-r15
212
213     mov     r0,     mdh         ; save exception/interrupt number
214     mov     r15,    r0
215     addn    #+12,   r0
216     mov     r0,     mdl         ; save r15 also in mdl
217
218     st      r0,     @-r15       ; store usp
219     mov     ssp,    r0
220     st      r0,     @-r15       ; store ssp (TODO maybe have to sub 12 before)
221     st      rp,     @-r15
222     st      tbr,    @-r15
223     addsp   #-8                 ; skip 2 positions for PS and PC
224     mov     r15,    r0          ; save stack position to later store PS and PC
225
226     st      mdl,    @-r15       ; store original r15 here
227     stm1    (r8, r9, r10, r11, r12, r13, r14)
228     stm0    (r1, r2, r3, r4, r5, r6, r7)
229
230     mov     ssp,    r14
231     ld      @r14,   r1          ; get original r0 content
232     st      r1,     @-r15       ; and store it
233
234     ld      @(r14,4),   r2      ; get hardware pushed PC
235     st      r2,     @r0         ; and store it
236     ld      @(r14,8),   r3      ; get hardware pushed PS
237     addn    #4,     r0          ; and
238     st      r3,     @r0         ; store it
239
240 # we should be finished saving context here
241
242 # Call exception handler
243     .extern hal_default_exception_handler
244
245     ldi:32  #hal_default_exception_handler,  r11
246     mov     r15,    r5          ; pointer to saved state as second argument
247     call:d  @r11
248     mov     mdh,    r4          ; exception number as first argument
249
250 __default_exception_vsr_return:
251
252
253     ## At this point, the user stack (USP) contains:
254     ## @(usp,0x60) trap number
255     ## @(usp,0x5c) mdl
256     ## @(usp,0x58) mdh
257     ## @(usp,0x54) usp
258     ## @(usp,0x50) ssp
259     ## @(usp,0x4c) rp
260     ## @(usp,0x48) tbr
261     ## @(usp,0x44) ps
262     ## @(usp,0x40) pc
263     ## @(usp,0x3c) r15
264     ## @(usp,0x38) r14
265     ## @(usp,0x34) r13
266     ## @(usp,0x30) r12
267     ## @(usp,0x2c) r11
268     ## @(usp,0x28) r10
269     ## @(usp,0x24) r9
270     ## @(usp,0x20) r8
271     ## @(usp,0x1c) r7
272     ## @(usp,0x18) r6
273     ## @(usp,0x14) r5
274     ## @(usp,0x10) r4
275     ## @(usp,0xc)  r3
276     ## @(usp,8)    r2
277     ## @(usp,4)    r1
278     ## @(usp)      r0
279     ##
280     ## and system stack (SSP) contains:
281     ## @(ssp,8) PS
282     ## @(ssp,4) PC
283     ## @(ssp)   old r0 content
284
285 # we can reuse the code from __default_interrupt_vsr
286     ldi:32  #hal_exception_return,  r0
287     jmp    @r0
288
289 #==============================================================================
290 # Default interrupt VSR
291 #
292 #
293
294     .align  2, 0xcc
295     .globl  __default_interrupt_vsr
296 __default_interrupt_vsr:
297
298     ## We enter here with the CPU state still in the registers and:
299     ##  r0          vector number
300     ##  @(ssp)      old register r0 content pushed by trampoline
301     ##  @(ssp,4)    PS pushed by hardware
302     ##  @(ssp,8)    PC pushed by hardware
303
304     # begin to save registers (to USP)
305     orccr   #0x20
306
307     st      mdl,    @-r15
308     st      mdh,    @-r15
309     st      rp,     @-r15
310
311     stm1    (r8, r9, r10, r11, r12, r13)
312     stm0    (r1, r2, r3 , r4 , r5 , r6, r7)
313
314     andccr  #0xdf
315     ld      @r15+,  r8          ; read old r0 content from SSP
316     ld      @r15+,  r9          ; read pc pushed by hardware
317     ld      @r15+,  r10         ; read ps pushed by hardware
318     orccr   #0x20
319
320     st      r8,     @-r15       ; push old r0 content to USP
321
322 # we should be finished saving irq context here
323
324 #if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT)
325 # Increment scheduler lock
326     .extern cyg_scheduler_sched_lock
327     ldi:32  #cyg_scheduler_sched_lock,   r1
328     ld      @r1,    r2
329     addn    #1,     r2
330     st      r2,     @r1
331 #endif
332
333 # Call hal_interrupt_handlers[vector](vector, cyg_hal_interrupt_data[vector])
334     mov     r0,     r8                      ; copy the vector
335     lsl     #2,     r8                      ; multiply vector by 4
336
337     ldi:32  #hal_interrupt_handlers,    r13 ; load handlers table
338     ld      @(r13, r8), r1                  ; current handler
339     ldi:32  #hal_interrupt_data,    r13     ; load data table
340     ld      @(r13, r8), r5                  ; current data, second argument
341     call:d  @r1
342     mov     r0,    r4                      ; exception number as argument
343
344 # At this point:
345 # r15 = stack pointer /*(should be usable as pointer to HAL_SavedRegisters)*/
346 # r4  = ISR return code (returned by call)
347 # r8  = ISR table offset (saved across call)
348 # r0  = vector number (NOT saved across call, but we don't need it)
349
350 /*
351         # If we are returning from the last nested interrupt, move back
352         # to the thread stack. interrupt_end() must be called on the
353         # thread stack since it potentially causes a context switch.
354         
355         hal_from_intstack       
356 */
357
358 #ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
359
360 # Call interrupt_end(return_value, hal_interrupt_objects[vector], regs)
361 # - r4 is the return value from the ISR
362 # - regs points to saved CPU context
363
364     ldi:32  #hal_interrupt_objects,  r13    ; load objects table
365     ld      @(r13, r8), r5                  ; current object, second argument
366     ldi:32  #interrupt_end, r12
367     call:d  @r12
368     mov     r15,    r6                      ; third argument TODO is not in
369                                             ; HAL_Saved_Registers format
370
371 #endif
372
373 ##.globl hal_exception_return
374 hal_exception_return:
375
376 # Now pull saved state from stack and return to
377 # what thread was originally doing.
378
379 # at first store return values to SSP
380     andccr  #0xdf
381     st      r10,    @-r15                   ; store ps
382     st      r9,     @-r15                   ; store pc
383     orccr   #0x20
384
385 # and then restore normal registers from USP
386     ldm0    (r0, r1, r2 , r3 , r4 , r5, r6, r7)
387     ldm1    (r8, r9, r10, r11, r12, r13)
388
389     ld      @r15+,  rp
390     ld      @r15+,  mdh
391     ld      @r15+,  mdl
392
393     andccr  #0xdf
394     reti
395
396
397 #==============================================================================
398 # Exception trampolines
399 # TBR table points to these short code sequences here that push the vector
400 # number on to the stack and then indirect via the VSR table to a handler.
401 # (__default_interrupt_vsr)
402
403     .text
404
405 # macro to create exception handler (no error code)
406
407 .macro  hal_fr30_exception_noerr idx
408     .globl hal_fr30_exception_noerr_\idx
409 hal_fr30_exception_noerr_\idx:
410     st  r0,  @-r15
411     ldi:32  #hal_vsr_table + \idx * 4,  r0
412     ld  @r0,    r0
413     jmp:d   @r0
414     ldi:8   #\idx,    r0
415 .endm
416
417     # Now generate all the default exception VSR trampolines.
418
419 #   hal_fr30_exception_noerr  1 no trampoline needed for reset and mode vector
420     hal_fr30_exception_noerr  2
421     hal_fr30_exception_noerr  3
422     hal_fr30_exception_noerr  4
423     hal_fr30_exception_noerr  5
424     hal_fr30_exception_noerr  6
425     hal_fr30_exception_noerr  7
426     hal_fr30_exception_noerr  8
427     hal_fr30_exception_noerr  9
428     hal_fr30_exception_noerr 10
429     hal_fr30_exception_noerr 11
430     hal_fr30_exception_noerr 12
431     hal_fr30_exception_noerr 13
432     hal_fr30_exception_noerr 14
433
434 #==============================================================================
435 # IRQ handler trampolines
436
437 # macro to create exception handler (no error code)
438
439 .macro  hal_fr30_irq_handler idx
440     .globl hal_fr30_irq_\idx
441 hal_fr30_irq_\idx:
442     st  r0, @-r15
443     ldi:32  #hal_vsr_table + \idx * 4,  r0
444     ld  @r0,    r0
445     jmp:d   @r0
446     ldi:8   #\idx,    r0
447 .endm
448
449     hal_fr30_irq_handler 15
450     hal_fr30_irq_handler 16
451     hal_fr30_irq_handler 17
452     hal_fr30_irq_handler 18
453     hal_fr30_irq_handler 19
454     hal_fr30_irq_handler 20
455     hal_fr30_irq_handler 21
456     hal_fr30_irq_handler 22
457     hal_fr30_irq_handler 23
458     hal_fr30_irq_handler 24
459     hal_fr30_irq_handler 25
460     hal_fr30_irq_handler 26
461     hal_fr30_irq_handler 27
462     hal_fr30_irq_handler 28
463     hal_fr30_irq_handler 29
464     hal_fr30_irq_handler 30
465     hal_fr30_irq_handler 31
466     hal_fr30_irq_handler 32
467     hal_fr30_irq_handler 33
468     hal_fr30_irq_handler 34
469     hal_fr30_irq_handler 35
470     hal_fr30_irq_handler 36
471     hal_fr30_irq_handler 37
472     hal_fr30_irq_handler 38
473     hal_fr30_irq_handler 39
474     hal_fr30_irq_handler 40
475     hal_fr30_irq_handler 41
476     hal_fr30_irq_handler 42
477     hal_fr30_irq_handler 43
478     hal_fr30_irq_handler 44
479     hal_fr30_irq_handler 45
480     hal_fr30_irq_handler 46
481     hal_fr30_irq_handler 47
482     hal_fr30_irq_handler 48
483     hal_fr30_irq_handler 49
484     hal_fr30_irq_handler 50
485     hal_fr30_irq_handler 51
486     hal_fr30_irq_handler 52
487     hal_fr30_irq_handler 53
488     hal_fr30_irq_handler 54
489     hal_fr30_irq_handler 55
490     hal_fr30_irq_handler 56
491     hal_fr30_irq_handler 57
492     hal_fr30_irq_handler 58
493     hal_fr30_irq_handler 59
494     hal_fr30_irq_handler 60
495     hal_fr30_irq_handler 61
496     hal_fr30_irq_handler 62
497     hal_fr30_irq_handler 63
498
499
500     .data
501 //
502 // "Vectors" - fixed location data items
503 // This section contains any data which might be shared between
504 // an eCos application and any other environment, e.g. the debug
505 // ROM.
506 //
507     .section ".fixed_vectors"
508 // Space for the virtual vectors        
509     .balign 4
510 // Vectors used to communicate between eCos and ROM environments
511     .globl  hal_virtual_vector_table
512 hal_virtual_vector_table:
513     .rept   64                  // CYGNUM_CALL_IF_TABLE_SIZE
514     .long   0
515     .endr
516
517     .globl  hal_vsr_table
518 hal_vsr_table:
519     .rept   CYGNUM_HAL_VSR_COUNT            // exceptions & interrupts
520     .long   0
521     .endr
522
523 #==============================================================================
524 # Initial and interrupt stack
525
526     .section ".bss"
527
528     .balign 4
529     .global cyg_interrupt_stack_base
530 cyg_interrupt_stack_base:
531 __interrupt_stack_base:
532     .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
533     .byte 0
534     .endr
535     .balign 4
536     .global cyg_interrupt_stack
537 cyg_interrupt_stack:
538 __interrupt_stack:
539     .long   0,0,0,0,0,0,0,0
540
541
542 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
543     .global __stub_stack_base
544 __stub_stack_base:
545     .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
546     .byte 0
547     .endr
548     .balign 4
549     .global __stub_stack
550 __stub_stack:
551
552     .long   0,0,0,0,0,0,0,0
553 #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
554
555     .balign 4
556 __user_stack_base:
557 //  FIXME TODO import symbolic constant from C-code
558     .rept 4532
559     .byte 0
560     .endr
561     .balign 4
562 __user_stack:
563     .long   0
564
565 #------------------------------------------------------------------------------
566 # end of vectors.S