1 ##=============================================================================
5 ## H8/300 exception 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.
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 version.
17 ## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 ## WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 ## You should have received a copy of the GNU General Public License along
23 ## with eCos; if not, write to the Free Software Foundation, Inc.,
24 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 ## As a special exception, if other files instantiate templates or use macros
27 ## or inline functions from this file, or you compile this file and link it
28 ## with other works to produce a work based on this file, this file does not
29 ## by itself cause the resulting work to be covered by the GNU General Public
30 ## License. However the source code for this file must still be made available
31 ## in accordance with section (3) of the GNU General Public License.
33 ## This exception does not invalidate any other reasons why a work based on
34 ## this file might be covered by the GNU General Public License.
36 ## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 ## at http://sources.redhat.com/ecos/ecos-license/
38 ## -------------------------------------------
39 #####ECOSGPLCOPYRIGHTEND####
40 ##=============================================================================
41 #######DESCRIPTIONBEGIN####
43 ## Author(s): Yoshinori Sato
44 ## Contributors: Yoshinori Sato
46 ## Purpose: H8/300 exception vectors
47 ## Description: This file defines the code placed into the exception
48 ## vectors. It also contains the first level default VSRs
49 ## that save and restore state for both exceptions and
52 ######DESCRIPTIONEND####
54 ##=============================================================================
56 #include <pkgconf/hal.h>
59 #include <pkgconf/redboot.h>
64 #include <pkgconf/kernel.h>
68 #include <cyg/hal/arch.inc>
69 #include <cyg/hal/basetype.h>
70 #include <cyg/hal/variant.inc>
73 ##-----------------------------------------------------------------------------
75 #ifdef CYGPKG_HAL_H8300_H8300H
86 #ifdef CYGPKG_HAL_H8300_H8S
97 ##-----------------------------------------------------------------------------
98 ## Macros for Stack handling when running Cygmon
100 .macro hal_cygmon_switch_app_stack
101 #ifdef CYGPKG_HAL_H8300_H8300H
102 ; Switch to interrupt stack to handle exception
104 ; First, save some scratch registers
108 ; Copy the exception frame
109 mov.l #__cygmon_interrupt_stack,er0
113 ; Save the pre-exception sp in the register image
116 ; Actually switch the stack
124 ; Now, restore the scratch registers
125 mov.l @(-4:16,er0),er1
126 mov.l @(-8:16,er0),er0
128 #ifdef CYGPKG_HAL_H8300_H8S
129 ; Switch to interrupt stack to handle exception
131 ; First, save some scratch registers
134 ; Copy the exception frame
135 mov.l #__cygmon_interrupt_stack,er0
136 mov.l @(10,sp:16),er1
141 ; Save the pre-exception sp in the register image
144 ; Actually switch the stack
152 ; Now, restore the scratch registers
153 mov.l @(-4:16,er0),er1
154 mov.l @(-8:16,er0),er0
158 .macro hal_cygmon_restore_app_stack
159 // For cygmon we are switching stacks immediately on exception.
160 // We must wait until the very end before restoring the original stack.
162 #ifdef CYGPKG_HAL_H8300_H8300H
163 ; Save some scratch registers
168 ; We need to restore the application stack pointer, but we also
169 ; need to restore the exception frame.
170 mov.l @(12:16,sp),er0
171 mov.l @(16:16,sp),er1
175 ; Restore the scratch registers
178 mov.l @sp+,sp // Restore the frame-adjusted SP
180 #ifdef CYGPKG_HAL_H8300_H8S
181 ; Save some scratch registers
185 ; We need to restore the application stack pointer, but we also
186 ; need to restore the exception frame.
187 mov.l @(12:16,sp),er0
190 mov.l @(18:16,sp),er1
194 ; Restore the scratch registers
196 mov.l @sp+,sp // Restore the frame-adjusted SP
200 #endif // CYGPKG_CYGMON
202 ##-----------------------------------------------------------------------------
204 #if (defined(CYG_HAL_STARTUP_ROM) || \
205 defined(CYGPKG_HAL_H8300_H8300H_SIM) || \
206 defined(CYGPKG_HAL_H8300_H8S_SIM))
208 .section .vectors,"a"
213 .long CYG_LABEL_DEFN(_start)
214 .long CYG_LABEL_DEFN(_start)
216 .rept CYG_ISR_TABLE_SIZE-2
217 .long interrupt_redirect_table+vector*4
222 #if !defined(CYGSEM_HAL_H8300_VECTOR_HOOK)
223 .section .int_hook_table,"ax"
224 interrupt_redirect_table:
226 .rept CYG_ISR_TABLE_SIZE
231 .section .int_hook_table,"x"
232 interrupt_redirect_table:
233 .space 4*CYG_ISR_TABLE_SIZE
236 ##-----------------------------------------------------------------------------
241 .globl CYG_LABEL_DEFN(_start)
242 CYG_LABEL_DEFN(_start):
245 mov.l #__interrupt_stack,sp
247 ; Initialize hardware
257 #ifdef CYG_HAL_STARTUP_ROM
259 ; Copy data from ROM to RAM
261 mov.l #CYG_LABEL_DEFN(__rom_data_start),er5
262 mov.l #CYG_LABEL_DEFN(__ram_data_start),er6
263 mov.l #CYG_LABEL_DEFN(__ram_data_end),er4
275 #if defined(CYGSEM_HAL_H8300_VECTOR_HOOK)
276 ; Setup Interrupt Vector (virtual)
290 ;; calculate vector address
295 mov.l er0,@__interrupt_table
296 mov.l #0x5e000000+interrupt_entry,er1
297 mov.l #save_vector_table,er3
300 ;; check saved vector
309 cmp.b #CYG_ISR_TABLE_SIZE,r2l
317 mov.l #interrupt_redirect_table,er0
318 mov.l er0,@__interrupt_table
322 mov.l #CYG_LABEL_DEFN(__bss_start),er5
323 mov.l #CYG_LABEL_DEFN(__bss_end),er4
324 sub.l #CYG_LABEL_DEFN(__bss_start),er4
333 ; Call variant and platform HAL
334 ; initialization routines.
336 .extern CYG_LABEL_DEFN(hal_variant_init)
337 jsr @CYG_LABEL_DEFN(hal_variant_init)
339 .extern CYG_LABEL_DEFN(hal_platform_init)
340 jsr @CYG_LABEL_DEFN(hal_platform_init)
344 .extern CYG_LABEL_DEFN(cyg_hal_invoke_constructors)
345 jsr @CYG_LABEL_DEFN(cyg_hal_invoke_constructors)
347 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
348 .extern CYG_LABEL_DEFN(initialize_stub)
349 jsr @CYG_LABEL_DEFN(initialize_stub)
352 #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
353 || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
354 .extern CYG_LABEL_DEFN(hal_ctrlc_isr_init)
355 jsr @CYG_LABEL_DEFN(hal_ctrlc_isr_init)
362 .extern CYG_LABEL_DEFN(cyg_start)
363 jsr @CYG_LABEL_DEFN(cyg_start)
366 bra 9b ; Loop if we return
369 #if defined(CYGSEM_HAL_H8300_SAVE_STUB_VECTOR)
371 #if defined(CYGPKG_HAL_H8300_SAVED_VECTORS)
380 mov.l @(4:16,sp),er0 ; interrupt vector offset
382 mov.l @__interrupt_table,er1
386 mov.l er0,@CYG_LABEL_DEFN(_intvector)
391 hal_cygmon_switch_app_stack
394 h8300_var_interrupt_entry ; load isr address
397 ##-----------------------------------------------------------------------------
398 ## The following macros are defined depending on whether the HAL is configured
399 ## to support the kernel or not.
401 #ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
403 .extern CYG_LABEL_DEFN(cyg_scheduler_sched_lock)
405 ; Increment the scheduler lock
407 .macro increment_sched_lock reg=er0
408 mov.l @CYG_LABEL_DEFN(cyg_scheduler_sched_lock),\reg
410 mov.l \reg,@CYG_LABEL_DEFN(cyg_scheduler_sched_lock)
415 .macro increment_sched_lock reg=er0
420 ##-----------------------------------------------------------------------------
421 ## Default interrupt VSR
424 .globl CYG_LABEL_DEFN(__default_interrupt_vsr)
425 CYG_LABEL_DEFN(__default_interrupt_vsr):
427 ; We come here with all the registers pushed
434 #if defined(CYGPKG_CYGMON)
435 // For Cygmon, we saved this back when we originally switched stacks.
436 mov.l sp,er1 ; A2 = saved thread state
437 #elif defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK)
438 ; Increment interrupt nesting counter
440 mov.l #__interrupt_stack,er0 ; A0 = interrupt stack top
441 cmp.l #__interrupt_stack_base,sp ; compare with base of stack
442 blt 1f ; if lt switch to int stack
443 cmp.l er0,sp ; compare sp with stack top
444 ble 8f ; if le already on istack
446 mov.l er0,sp ; switch to new SP
448 mov.l er1,@-sp ; save old SP
451 mov sp,er1 ; A2 = saved thread state
455 ; Here D3 contains the table byte offset of the vector to
458 #if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR)
460 ; Call cyg_instrument to record that this interrupt is being raised.
462 .extern CYG_LABEL_DEFN(cyg_instrument)
463 mov.l #0x0301,er0 ; type = INTR,RAISE
464 mov.l @CYG_LABEL_DEFN(_intvector),er2 ; arg2 = table offset
465 jsr CYG_LABEL_DEFN(cyg_instrument) ; call instrumentation
469 #ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
471 ; To allow nested interrupts, we set the IE bit. We do
472 ; not touch the IPL bits, so only higher priority interrupts
473 ; will be nested on top of us. Also, new interrupts will not
474 ; be delivered until the ISR calls
475 ; Cyg_Interrupt::acknowledge_interrupt(). At some future point
476 ; we may want to do the ack stuff here to allow immediate nesting.
478 mov.l @CYG_LABEL_DEFN(_intvector),er0
479 mov.b @(CYG_LABEL_DEFN(cyg_hal_level_table),er0),r0l
480 hal_cpu_set_int_level
482 #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) || \
483 defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
485 ; If we have Ctrl-C support enabled, save a pointer to the
486 ; saved CPU state here so we can plant a breakpoint there if
489 .extern CYG_LABEL_DEFN(hal_saved_interrupt_state)
490 mov.l er4,@CYG_LABEL_DEFN(hal_saved_interrupt_state)
493 mov.l @CYG_LABEL_DEFN(_intvector),er0
495 mov.l @(CYG_LABEL_DEFN(hal_interrupt_handlers),er0),er2
497 mov.l @(CYG_LABEL_DEFN(hal_interrupt_data),er0),er1
503 ; on return d0 bit 1 will indicate whether a DSR is
504 ; to be posted. Pass this together with a pointer to
505 ; the interrupt object we have just used to the
506 ; interrupt tidy up routine.
508 ; D3 is defined to be saved across procedure calls, and
509 ; should still contain the vector byte index. Similarly,
510 ; A2 should still point to the saved machine state.
512 #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
513 ; If interrupt was caused by GDB, the ISR call above
514 ; is skipped by jumping here.
518 #if defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK) && !defined(CYGPKG_CYGMON)
520 ; If we are returning from the last nested interrupt, move back
521 ; to the thread stack. interrupt_end() must be called on the
522 ; thread stack since it potentially causes a context switch.
524 mov.l @sp+,sp ; pop old sp
528 #ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
530 ; We only need to call _interrupt_end() when there is a kernel
531 ; present to do any tidying up.
533 ; Using the vector offset in D3, get the interrupt object pointer
535 mov.l @CYG_LABEL_DEFN(_intvector),er1
537 mov.l @(CYG_LABEL_DEFN(hal_interrupt_objects),er1),er1
539 ; Even when this is not the last nested interrupt, we must call
540 ; _interrupt_end() to post the DSR and decrement the scheduler
543 mov.l er3,er2 ; arg3 = saved state.
545 jsr @CYG_LABEL_DEFN(interrupt_end) ; call interrupt end fn
555 hal_cygmon_restore_app_stack
565 .global CYG_LABEL_DEFN(_intvector)
566 CYG_LABEL_DEFN(_intvector):
575 ##-----------------------------------------------------------------------------
576 ## Execute pending DSRs on the interrupt stack with interrupts enabled.
577 ## Note: this can only be called from code running on a thread stack
579 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
580 .extern CYG_LABEL_DEFN(cyg_interrupt_call_pending_DSRs)
581 .global CYG_LABEL_DEFN(hal_interrupt_stack_call_pending_DSRs)
583 CYG_LABEL_DEFN(hal_interrupt_stack_call_pending_DSRs):
584 h8300_var_call_pending_DSR
587 ##-----------------------------------------------------------------------------
591 .globl CYG_LABEL_DEFN(__default_trap_vsr)
592 CYG_LABEL_DEFN(__default_trap_vsr):
594 #ifdef CYG_HAL_DIAG_EXCPT_END
597 mov.l @CYG_LABEL_DEFN(_intvector),er1
598 cmp.l #11,er1 ; Adjust trap entry address
603 jsr @CYG_LABEL_DEFN(cyg_hal_exception_handler)
605 #ifdef CYG_HAL_DIAG_EXCPT_END
610 hal_cygmon_restore_app_stack
614 ##-----------------------------------------------------------------------------
615 ## VSR table. The VSRs pointed to by this table are called from the stubs
616 ## connected to the hardware.
618 #ifndef CYG_HAL_H8300_VSR_TABLE_DEFINED
622 .globl CYG_LABEL_DEFN(hal_vsr_table)
623 CYG_LABEL_DEFN(hal_vsr_table):
624 .long CYG_LABEL_DEFN(__default_trap_vsr)
625 .long CYG_LABEL_DEFN(__default_trap_vsr)
629 .long CYG_LABEL_DEFN(__default_trap_vsr)
630 .long CYG_LABEL_DEFN(__default_trap_vsr)
631 .long CYG_LABEL_DEFN(__default_trap_vsr)
632 .long CYG_LABEL_DEFN(__default_trap_vsr)
633 .long CYG_LABEL_DEFN(__default_trap_vsr)
634 .long CYG_LABEL_DEFN(__default_trap_vsr)
635 .long CYG_LABEL_DEFN(__default_trap_vsr)
637 .rept CYG_ISR_TABLE_SIZE-12
638 .long CYG_LABEL_DEFN(__default_interrupt_vsr)
642 ##-----------------------------------------------------------------------------
647 .extern CYG_LABEL_DEFN(hal_default_isr)
649 .globl CYG_LABEL_DEFN(hal_interrupt_handlers)
650 CYG_LABEL_DEFN(hal_interrupt_handlers):
651 .rept CYG_ISR_TABLE_SIZE
652 .long CYG_LABEL_DEFN(hal_default_isr)
655 .globl CYG_LABEL_DEFN(hal_interrupt_data)
656 CYG_LABEL_DEFN(hal_interrupt_data):
657 .rept CYG_ISR_TABLE_SIZE
661 .globl CYG_LABEL_DEFN(hal_interrupt_objects)
662 CYG_LABEL_DEFN(hal_interrupt_objects):
663 .rept CYG_ISR_TABLE_SIZE
668 ##-----------------------------------------------------------------------------
669 ## Temporary interrupt stack
674 .global _cyg_interrupt_stack_base
675 _cyg_interrupt_stack_base:
676 __interrupt_stack_base:
677 .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
681 .global _cyg_interrupt_stack
682 _cyg_interrupt_stack:
687 .global __cygmon_interrupt_stack_base
688 __cygmon_interrupt_stack_base:
689 .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
693 .global __cygmon_interrupt_stack
694 __cygmon_interrupt_stack:
697 .long 0,0,0,0,0,0,0,0
699 ##-----------------------------------------------------------------------------
705 ##-----------------------------------------------------------------------------