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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [sparc/] [arch/] [v2_0/] [src/] [vec_xvsr.S] - Rev 174

Compare with Previous | Blame | View Log

/*===========================================================================
//
//      vec_xvsr.S
//
//      SPARC vectors: exception vector service routine
//
//===========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//===========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):    hmt
// Contributors: hmt
// Date:         1999-02-20
// Purpose:      SPARC vector code
// Description:  see vectors.S; this is the default vector service routine
//               for exceptions.
//
//####DESCRIPTIONEND####
//
//=========================================================================*/

!-----------------------------------------------------------------------------

//      .file   "vec_xvsr.S"

!----------------------------------------------------------------------------

#include <pkgconf/system.h>
#include <pkgconf/hal.h>

#ifdef CYGPKG_KERNEL
# include <pkgconf/kernel.h>
#endif

!------------------------------------------------------------------------

#include <cyg/hal/vectors.h>

#define DELAYS_AFTER_WRPSR_SAME_WINDOW
#define DELAYS_AFTER_WRWIM

!------------------------------------------------------------------------

        .text

!---------------------------------------------------------------------------
! default exception handler VSR, which calls the appropriate ISR after
! interrupt masking - much the same as the interrupt VSR but does not lock
! scheduler or call interrupt_end().

        .global hal_default_exception_vsr
hal_default_exception_vsr:
        ! here,locals have been set up as follows:
        ! %l0 = psr (with this CWP/window-level in it)
        ! %l1 = pc
        ! %l2 = npc
        ! %l3 = vector number (16-25 for traps)
        ! and we are in our own register window, though it is likely that
        ! the next one will need to be saved before we can use it:
        ! ie. this one is the invalid register window.

        ! must establish a safe stack before re-enabling interrupts + traps
        and     %l0, __WINBITS, %l7     ! CWP extracted
        ! no inc/dec here, so no need for special measures for not-8-windows
        mov     1, %l6
        sll     %l6, %l7, %l6           ! 1 << CWP
        rd      %wim, %l5
        cmp     %l5, %l6                ! are they the same?
        bne     1f                      ! No, so the stack is OK as is.

        ! now do by hand an overflow trap, effectively
        mov     %g1, %l7                ! (DELAY SLOT)
        srl     %l5, 1, %l5
        sll     %l6, __WINSIZE-1, %l6
        or      %l6, %l5, %g1           ! new WIM in %g1 so we can get it
                                        ! within the save:
        save                            ! Slip into next window
        mov     %g1, %wim               ! Install the new wim
                                        ! (invalidates current window!)
#ifdef DELAYS_AFTER_WRWIM
        nop
        nop
        nop
#endif

        std     %l0, [%sp + 0 * 4]      ! save L & I registers
        std     %l2, [%sp + 2 * 4]
        std     %l4, [%sp + 4 * 4]
        std     %l6, [%sp + 6 * 4]

        std     %i0, [%sp + 8 * 4]
        std     %i2, [%sp + 10 * 4]
        std     %i4, [%sp + 12 * 4]
        std     %i6, [%sp + 14 * 4]

        restore                         ! Go back to trap window.
        mov     %l7, %g1                ! Restore %g1

1:      ! now save away the regs we must preserve
        sub     %fp, 32 * 4, %sp
        ! save a maximal context regardless: see also
        ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
        std     %l0, [%sp + 0 * 4]      ! save L & I registers
        std     %l2, [%sp + 2 * 4]
        std     %l4, [%sp + 4 * 4]
        std     %l6, [%sp + 6 * 4]

        std     %i0, [%sp + 8 * 4]
        std     %i2, [%sp + 10 * 4]
        std     %i4, [%sp + 12 * 4]
        std     %i6, [%sp + 14 * 4]

        st      %g1, [%sp + 17 * 4]     ! save G registers
        std     %g2, [%sp + 18 * 4]
        std     %g4, [%sp + 20 * 4]
        std     %g6, [%sp + 22 * 4]

        ! no point whatsoever in saving O registers

        ! and save the CWP in %g0 save place
        st      %l0, [%sp + 16 * 4]

        sub     %sp, 24 * 4, %sp        ! fresh frame including
                                        ! arg spill area for callees

        ! do not lock the scheduler

        ! HELP_GDB_WITH_BACKTRACE
        mov     %i7, %l5                ! preserve it JIC
        mov     %l1, %i7                ! bogus return link here

        ! and we must preserve the Y register (multiply/divide auxiliary)
        ! over these calls; we will keep it in %l4 which is otherwise unused.
        rd      %y, %l4

        ! Now we can reenable traps (preserving interrupt level)
        or      %l0, 0x0e0, %l7         ! set ET (+S,PS), preserve PIL
        wr      %l7, %psr               ! and enable!
#ifdef DELAYS_AFTER_WRPSR_SAME_WINDOW
        nop
        nop
        nop
#endif
        ! now call the XSR and so on with the appropriate args:
        ! ie.
        ! isr_retcode = (*(hal_interrupt_handlers[ vector ]))
        !                   ( vector, hal_interrupt_data[ vector ], stackp );

        ! from hal_arch.h
        !// ISR tables
        !CYG_ADDRESS    hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
        !CYG_ADDRWORD   hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
        !CYG_ADDRESS    hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];        

        mov     %l3, %o0
        sll     %l3, 2, %l3             ! %l3 to a word offset
        sethi   %hi(hal_interrupt_data), %l7
        or      %l7, %lo(hal_interrupt_data), %l7
        ld      [ %l7 + %l3 ], %o1      ! data
        add     %sp, 24 * 4, %o2        ! stackpointer of saved regset

        sethi   %hi(hal_interrupt_handlers), %l7
        or      %l7, %lo(hal_interrupt_handlers), %l7
        ld      [ %l7 + %l3 ], %l6
        call    %l6
        nop

        ! do not call _interrupt_end()

        ! restore the Y register having done our callouts to C
        wr      %l4, %y

        ! We can reinstall the original CWP here; even if interrupt_end()
        ! performed a reschedule (ie. yield/resume pair) we will be in the
        ! same window.  The window is preserved by reschedule precisely
        ! because it is impossible atomically to disable traps here without
        ! involving a CWP living in a register for a time when other
        ! interrupts may occur.

        ! disable traps (using the saved psr is fastest way)
        wr      %l0, %psr       ! restores flags, disables traps, same PIL.
#ifdef DELAYS_AFTER_WRPSR_SAME_WINDOW
        nop
        nop
        nop
#endif
        ! HELP_GDB_WITH_BACKTRACE
        mov     %l5, %i7        ! restore (unused) return link

        ! and restore other saved regs
        add     %sp, 24 * 4, %sp        ! undo fresh frame
        ! restore a maximal context regardless: see also
        ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
        ldd     [%sp + 0 * 4], %l0      ! restore L & I registers
        ldd     [%sp + 2 * 4], %l2      ! to support the handler
        ldd     [%sp + 4 * 4], %l4      ! having messed with them.
        ldd     [%sp + 6 * 4], %l6

        ldd     [%sp + 8 * 4], %i0
        ldd     [%sp + 10 * 4], %i2
        ldd     [%sp + 12 * 4], %i4
        ldd     [%sp + 14 * 4], %i6

        ld      [%sp + 17 * 4], %g1     ! and G registers
        ldd     [%sp + 18 * 4], %g2
        ldd     [%sp + 20 * 4], %g4
        ldd     [%sp + 22 * 4], %g6
        ! no point whatsoever in loading back O registers.

        ! Now test for window underflow here and fix up if needs be.
        !
        ! Why?  interrupt_end() might have yielded us, when only
        ! its own frame was restored; its own return to us caused a
        ! window underflow trap, as would our return to interruptee
        ! unless we deal with it now.

        add     %l0, 1, %l7             ! interruptee~s CWP plus noise
        and     %l7, __WINBITS, %l7     ! CWP only
#if 8 == __WINSIZE
        ! it is in range already
#else   // expect 5 or 6 or 7 windows
        cmp     %l7, __WINSIZE
        bge,a   567f                    ! taken: do delay slot, handle overflow
         mov    0, %l7                  ! only if .ge. above
567:    
#endif
        mov     1, %l6
        sll     %l6, %l7, %l6           ! 1 << CWP
        rd      %wim, %l5
        cmp     %l5, %l6                ! are they the same?
        bne     2f                      ! No, so the stack is OK as is.

        ! now do by hand an underflow trap, effectively
        sll     %l5, 1, %l5             ! Rotate wim left
        srl     %l6, __WINSIZE-1, %l6
        wr      %l5, %l6, %wim
#ifdef DELAYS_AFTER_WRWIM
        nop                             ! are these delays needed?
        nop                             ! (following restore uses wim)
        nop
#endif
        restore                         ! Interruptee~s window
        ldd     [%sp + 0 * 4], %l0      ! restore L & I registers
        ldd     [%sp + 2 * 4], %l2
        ldd     [%sp + 4 * 4], %l4
        ldd     [%sp + 6 * 4], %l6

        ldd     [%sp + 8 * 4], %i0
        ldd     [%sp + 10 * 4], %i2
        ldd     [%sp + 12 * 4], %i4
        ldd     [%sp + 14 * 4], %i6
        save                            ! Back to trap window

2:      ! restore the condition codes, PSR and PIL and return from trap.
        wr      %l0, %psr       ! restores flags, disables traps, and old PIL
#ifdef DELAYS_AFTER_WRPSR_SAME_WINDOW
        nop
        nop
        nop
#endif
        jmpl    %l1,  %g0
        rett    %l2


! end of vec_xvsr.S

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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