1 ##=============================================================================
5 ## fr30 startup code and exception and interrupt vectors
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.
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.
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
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.
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.
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.
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####
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.
53 ######DESCRIPTIONEND####
55 ##=============================================================================
58 #include <pkgconf/system.h>
59 #include <pkgconf/hal.h>
60 #include CYGBLD_HAL_PLATFORM_H
63 #include <pkgconf/kernel.h>
64 #endif /* CYGPKG_KERNEL */
66 #include <cyg/hal/arch.inc>
68 #==============================================================================
72 #==============================================================================
73 # Real startup code. We jump here from the various reset vectors to set up the
81 # disable interrupts and set priority to lowest (=disable)
86 #ifdef CYGPKG_HAL_FR30_FLASH_INIT_DEFINED
91 #ifdef CYGPKG_HAL_FR30_MEMC_INIT_DEFINED
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
113 #if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
115 # In a ROM booted system, we also need to copy the data section
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
133 # Begin with interrupt (system) stack
135 ldi:32 #__interrupt_stack, r11
138 # and now continue with user stack
141 ldi:32 #__user_stack, r11
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.
149 ldi:32 #hal_mon_init, r11
154 .extern hal_variant_init
155 ldi:32 #hal_variant_init, r11
158 .extern hal_platform_init
159 ldi:32 #hal_platform_init, r11
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
169 .extern cyg_hal_invoke_constructors
170 ldi:32 #cyg_hal_invoke_constructors, r11
173 # TODO integrate into hal_intr.h
174 # set irq 25 priority (for reload timer 1)
179 #ifdef CYGDBG_HAL_DEBUG_GDB_INITIAL_BREAK
186 ldi:32 #cyg_start, r11
189 # Hmm. Not expecting to return from cyg_start, endless nop loop
193 #==============================================================================
194 # Default exception VSR
197 .globl __default_exception_vsr
198 __default_exception_vsr:
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
206 # at first switch to USP (set bit 5 in CCR in PS)
213 mov r0, mdh ; save exception/interrupt number
216 mov r0, mdl ; save r15 also in mdl
218 st r0, @-r15 ; store usp
220 st r0, @-r15 ; store ssp (TODO maybe have to sub 12 before)
223 addsp #-8 ; skip 2 positions for PS and PC
224 mov r15, r0 ; save stack position to later store PS and PC
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)
231 ld @r14, r1 ; get original r0 content
232 st r1, @-r15 ; and store it
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
238 st r3, @r0 ; store it
240 # we should be finished saving context here
242 # Call exception handler
243 .extern hal_default_exception_handler
245 ldi:32 #hal_default_exception_handler, r11
246 mov r15, r5 ; pointer to saved state as second argument
248 mov mdh, r4 ; exception number as first argument
250 __default_exception_vsr_return:
253 ## At this point, the user stack (USP) contains:
254 ## @(usp,0x60) trap number
280 ## and system stack (SSP) contains:
283 ## @(ssp) old r0 content
285 # we can reuse the code from __default_interrupt_vsr
286 ldi:32 #hal_exception_return, r0
289 #==============================================================================
290 # Default interrupt VSR
295 .globl __default_interrupt_vsr
296 __default_interrupt_vsr:
298 ## We enter here with the CPU state still in the registers and:
300 ## @(ssp) old register r0 content pushed by trampoline
301 ## @(ssp,4) PS pushed by hardware
302 ## @(ssp,8) PC pushed by hardware
304 # begin to save registers (to USP)
311 stm1 (r8, r9, r10, r11, r12, r13)
312 stm0 (r1, r2, r3 , r4 , r5 , r6, r7)
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
320 st r8, @-r15 ; push old r0 content to USP
322 # we should be finished saving irq context here
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
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
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
342 mov r0, r4 ; exception number as argument
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)
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.
358 #ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
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
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
368 mov r15, r6 ; third argument TODO is not in
369 ; HAL_Saved_Registers format
373 ##.globl hal_exception_return
374 hal_exception_return:
376 # Now pull saved state from stack and return to
377 # what thread was originally doing.
379 # at first store return values to SSP
381 st r10, @-r15 ; store ps
382 st r9, @-r15 ; store pc
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)
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)
405 # macro to create exception handler (no error code)
407 .macro hal_fr30_exception_noerr idx
408 .globl hal_fr30_exception_noerr_\idx
409 hal_fr30_exception_noerr_\idx:
411 ldi:32 #hal_vsr_table + \idx * 4, r0
417 # Now generate all the default exception VSR trampolines.
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
434 #==============================================================================
435 # IRQ handler trampolines
437 # macro to create exception handler (no error code)
439 .macro hal_fr30_irq_handler idx
440 .globl hal_fr30_irq_\idx
443 ldi:32 #hal_vsr_table + \idx * 4, r0
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
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
507 .section ".fixed_vectors"
508 // Space for the virtual vectors
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
519 .rept CYGNUM_HAL_VSR_COUNT // exceptions & interrupts
523 #==============================================================================
524 # Initial and interrupt stack
529 .global cyg_interrupt_stack_base
530 cyg_interrupt_stack_base:
531 __interrupt_stack_base:
532 .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
536 .global cyg_interrupt_stack
539 .long 0,0,0,0,0,0,0,0
542 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
543 .global __stub_stack_base
545 .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
552 .long 0,0,0,0,0,0,0,0
553 #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
557 // FIXME TODO import symbolic constant from C-code
565 #------------------------------------------------------------------------------