This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Questions about vectors.s


Hi Gary,
Please read the comments below.  Thanks!

--- Gary Thomas <gthomas@redhat.com> wrote:
> >  We are having problems with stack corruption,
> which
> > is somewhat of a mystery.  These two messages
> describe
> > the issue in detail:
> > 
> >
>
http://sources.redhat.com/ml/ecos-discuss/2001-10/msg00196.html
> >
>
http://sources.redhat.com/ml/ecos-discuss/2001-10/msg00352.html
> > 
> > Anyway, regarding the workarounds, below are some
> > solutions that have been tested extensively and
> have
> > been verified:  
> > 
> > -- Increase ARMREG_SIZE (to 256 for example). 
> This is
> > an easy solution, but it really grows the stack. 
> And
> > since the source of the stack corruption is not
> fully
> > understood, it is not guaranteed that "256" is
> > adequate.   
> 
> This is clearly wrong.  The value of ARMREG_SIZE is
> calculated to
> be exactly the size of the saved state frame on the
> stack.  Changing
> it is just masking whatever other problem you are
> having.

Agreed.  
  
> > -- Stay in IRQ mode.  That is, never switch into
> > supervisor mode in the IRQ routine.  This keeps
> the
> > stacks (supervisor and IRQ) separate, but the IRQ
> > stack size should probably be increased.
> 
> While this might work in some cases, it is also not
> correct.
> Depending on how the eCos kernel is configured, it's
> actually
> possible to switch threads in this piece of code. 
> If the
> IRQ handler is running in IRQ mode, that code will
> definitely
> fail.  It also breaks the basic model that all code
> inside
> the eCos kernel+application run in Supervisor mode.

I was under the impression that for ARM at least,
interrupts were not enabled until interrupt_end() is
called and the DSRs are allowed to run -- so this code
would never be interrupted.

It also seems that since the __interrupt_stack (not
__exception_stack, which is used in IRQ mode) is used
while calling cyg_interrupt_call_pending_DSRs, it
wouldn't matter that I never switch to supervisor mode
and use the current supervisor stack (which would be
the __startup_stack for a single-thread example such
as int.c.)  As a footnote, it seems that using the
supervisor stack, as it is used in the IRQ handler,
burdens the thread that gets interrupted with extra
stack size requirements.  It seems that it would be
better to not use the current supervisor stack if it
can be avoided -- but I'm probably just confused.     
  

> > -- When switching to supervisor mode, use a new
> stack,
> > and restore the old stack before mode switching
> back
> > to IRQ mode.  This is a variation on the 2nd
> solution.
> >  It allows the IRQ routine to execute in
> supervisor
> > mode as originally designed, but it is unclear
> that
> > this accomplishes anything. 
> > 
> > It has been entertained (but not verified) that
> the
> > Gameboy has an ARM core tweak, or something
> hardware
> > related that is causing this behavior. 
> > 
> > Note also, the Gameboy Advance has a ROM "BIOS"
> that
> > we have disassembled, but we cannot modify.  It
> > dictates the exception vectors, but provides
> secondary
> > vectors the user can modify.  This has obviously
> > resulted in some modifications of vectors.s.  
> > 
> 
> Can you provide more information here?  My guess is
> that
> the interaction between this BIOS code and the eCos
> handlers
> is where the problem lies.  If you can show me that
> code,
> I might be able to see something.

I fear that providing the code here would probably
bend some copyrights.  But basically, the BIOS IRQ
code (the code  that is pointed to by the IRQ vector)
saves some registers on the IRQ stack before looking
in a specific RAM location for a user vector.  It then
calls the code pointed to by the user vector.  In our
case, this code is at the "IRQ" label.  We modified
the IRQ code to restore the registers from the IRQ
stack upon first entering this code.  This includes
restoring the original LR.  

> > Regarding code integration, it appears that it
> might
> > be cleaner to provide an entirely separate
> vectors.s
> > for the Gameboy instead of polluting the existing
> > vectors.s with messy preprocessor directives and
> > Gameboy specific code.  Your opinion is obviously
> > important here.  
> > 
> 
> Without seeing what you've had to change, I can't
> comment.

I've copied what we have so far below.  Note the ROM
header that is required by the BIOS code for correct
boot-up.

We really appreciate the help!

thanks,
--Bill, Garrick, Rich






//
#========================================================================
// #
// #    vectors.S
// #
// #    ARM exception vectors
// #
//
#========================================================================
// ####COPYRIGHTBEGIN####
//                                                    
                     
// -------------------------------------------        
                     
// The contents of this file are subject to the Red
Hat eCos Public License 
// Version 1.1 (the "License"); you may not use this
file except in         
// compliance with the License.  You may obtain a copy
of the License at    
// http://www.redhat.com/                             
                     
//                                                    
                     
// Software distributed under the License is
distributed on an "AS IS"      
// basis, WITHOUT WARRANTY OF ANY KIND, either express
or implied.  See the 
// License for the specific language governing rights
and limitations under 
// the License.                                       
                     
//                                                    
                     
// The Original Code is eCos - Embedded Configurable
Operating System,      
// released September 30, 1998.                       
                     
//                                                    
                     
// The Initial Developer of the Original Code is Red
Hat.                   
// Portions created by Red Hat are                    
                     
// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.
// All Rights Reserved.                               
                     
// -------------------------------------------        
                     
//                                                    
                     
// ####COPYRIGHTEND####
//
#========================================================================
// ######DESCRIPTIONBEGIN####
// #
// # Author(s):     nickg, gthomas
// # Contributors:  nickg, gthomas
// # Date:          1999-02-20
// # Purpose:       ARM exception vectors
// # Description:   This file defines the code placed
into the exception
// #                vectors. It also contains the
first level default VSRs
// #                that save and restore state for
both exceptions and
// #                interrupts.
// #
// #####DESCRIPTIONEND####
// #
//
#========================================================================

#define RICH

#include <pkgconf/hal.h>
#include <pkgconf/hal_arm.h>
#ifdef CYGPKG_KERNEL  // no CDL yet
#include <pkgconf/kernel.h>
#else
# undef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
# undef
CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
#endif
#include <cyg/hal/hal_platform_setup.h>

#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
// The CDL should enforce this
#undef  CYGHWR_HAL_ARM_DUMP_EXCEPTIONS
#endif

#include "arm.inc"

#ifdef __thumb__
// Switch to thumb mode
#define THUMB_MODE(_r_, _l_)                     \
        ldr     _r_,=_l_ ## f+1                 ;\
        bx      _r_                             ;\
        .pool                                   ;\
        .code   16                              ;\
        .thumb_func                             ;\
 _l_:

// Switch to ARM mode
#define ARM_MODE(_r_, _l_)                       \
        ldr     _r_,=_l_ ## f                   ;\
        bx      _r_                             ;\
        .pool                                   ;\
        .code   32                              ;\
 _l_:

// Function definition, start executing body in ARM
mode
#define FUNC_START_ARM(_name_, _r_)              \
        .code   16                              ;\
        .thumb_func                             ;\
        .globl _name_                           ;\
_name_:                                         ;\
        ldr     _r_,=_name_ ## _ARM             ;\
        bx      _r_                             ;\
        .code   32                              ;\
_name_ ## _ARM:

#else

// Switch to thumb mode
#define THUMB_MODE(_r_, _l_)

// Switch to ARM mode
#define ARM_MODE(_r_, _l_)

// Function definition, start executing body in ARM
mode
#define FUNC_START_ARM(_name_, _r_) \
        .globl _name_; \
_name_: 

#endif

        

#define PTR(name)               \
.##name: .word  name

// CYGHWR_HAL_ROM_VADDR is used when compiling for a
different location
// from the base of ROM.  hal_platform_setup.h might
define it.  For
// example, if flash is from 0x50000000 upwards (as on
SA11x0), and we are
// to execute at 0x50040000, then we want the reset
vector to point to
// 0x0004pqrs - the unmapped ROM address of the code -
rather than
// 0x0000pqrs, which is the offset into our flash
block.
// 
// But usually it's not defined, so the behaviour is
the obvious.

#ifndef UNMAPPED        
#ifdef CYGHWR_HAL_ARM_HAS_MMU
# ifndef CYGHWR_HAL_ROM_VADDR
#  define CYGHWR_HAL_ROM_VADDR __exception_handlers
# endif
# define UNMAPPED(x) ((x)-CYGHWR_HAL_ROM_VADDR)
#else
# define UNMAPPED(x) (x)
#endif
#endif        
                                
#define UNMAPPED_PTR(name)              \
.##name: .word  UNMAPPED(name)

        .file   "vectors.S"


// CYGHWR_LED_MACRO can be defined in
hal_platform_setup.h. It's free to
// use r0+r1. Argument is in "\x" - cannot use macro
arguments since the
// macro may contain #-chars and use of arguments
cause these to be 
// interpreted as CPP stringify operators.
// See example in PID hal_platform_setup.h.
#ifndef CYGHWR_LED_MACRO
#define CYGHWR_LED_MACRO
#endif
        
.macro LED x
    CYGHWR_LED_MACRO
.endm

#ifdef RICH
    .GLOBAL     reset_vector
reset_vector:
        .ALIGN
        .CODE 32
        @ Start Vector
rom_header:     b       rom_header_end

        @ Nintendo Logo Character Data (8000004h)
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte   0x00,0x00,0x00,0x00

        @ Software Titles (80000A0h)
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                .byte   0x00,0x00,0x00,0x00

        @ Initial Code (80000ACh)
                .byte   0x00,0x00,0x00,0x00

        @ Maker Code (80000B0h)
                .byte   0x30,0x31

        @ Fixed Value (80000B2h)
                .byte   0x96

        @ Main Unit Code (80000B3h)
                .byte   0x00

        @ Device Type (80000B4h)
                .byte   0x00

        @ Unused Data (7Byte) (80000B5h)
                .byte  
0x00,0x00,0x00,0x00,0x00,0x00,0x00

        @ Software Version No (80000BCh)
                .byte   0x00

        @ Complement Check (80000BDh)
                .byte   0xf0

        @ Check Sum (80000BEh)
                .byte   0x00,0x00

rom_header_end:
        b       start_vector

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ The following reserved bytes are used if the code is
compiled for
@ multiboot mode. The GBA BIOS will auto-patch the
first two bytes
@ with 0x03 and 0x01, respectively, before running any
code.
@
        .byte   0       @ boot method (0=ROM boot,
3=Multiplay boot)
        .byte   0       @ slave # (1=slave#1,
2=slave#2, 3=slave#3)
        .byte   0       @ reserved
        .byte   0       @ reserved
        .word   0       @ reserved
        .word   0       @ reserved
        .word   0       @ reserved
        .word   0       @ reserved
        .word   0       @ reserved
        .word   0       @ reserved
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

#endif

//==========================================================================
// Hardware exception vectors.
//   This entire section will be copied to location
0x0000 at startup time.
//
#ifndef RICH
        .code   32
        .section ".vectors","ax"
#endif

// This macro allows platforms to add their own code
at the very start of
// the image.  This may be required in some
circumstances where eCos ROM 
// based code does not run immediately upon reset
and/or when some sort of
// special header is required at the start of the
image.        
#ifdef PLATFORM_PREAMBLE
        PLATFORM_PREAMBLE
#endif
                        
        .global __exception_handlers
__exception_handlers:
#ifdef CYGSEM_HAL_ROM_RESET_USES_JUMP
// Assumption:  ROM code has these vectors at the
hardware reset address.
// A simple jump removes any address-space
dependencies [i.e. safer]
        b       reset_vector                    //
0x00
#else        
        ldr     pc,.reset_vector                //
0x00
#endif        
        ldr     pc,.undefined_instruction       //
0x04
        ldr     pc,.software_interrupt          //
0x08 start && software int
        ldr     pc,.abort_prefetch              //
0x0C
        ldr     pc,.abort_data                  //
0x10
        .word   0                               //
unused
        ldr     pc,.IRQ                         //
0x18
        ldr     pc,.FIQ                         //
0x1C

// The layout of these pointers should match the
vector table above since
// they are copied in pairs.
        .global vectors
vectors:
UNMAPPED_PTR(reset_vector)                      //
0x20
PTR(undefined_instruction)                      //
0x24
PTR(software_interrupt)                         //
0x28
PTR(abort_prefetch)                             //
0x2C
PTR(abort_data)                                 //
0x30
        .word   0                               //
0x34
PTR(IRQ)                                        //
0x38
PTR(FIQ)                                        //
0x3c
#ifdef CYGSEM_HAL_ARM_PID_ANGEL_BOOT         
PTR(start) // This is copied to 0x28 for bootup //
0x40
#endif        
           // location 0x40 is used for storing DRAM
size if known
           // for some platforms.        


//
// "Patch vectors" - used to patch illegal instruction
into debug stub code
//  This code gets mapped to 0x9ffc000 (mirrored at
0x83fc000 for 4mb flash)
//
        .section ".patch_vectors", "ax"
		.code   32

        .globl  hal_patch_vector_code
hal_patch_vector_code:

		// restore registers and return to user code (not
bios, which returns incorrectly)
		ldr		r13, .pv_cl1
		ldmfd	r13!, {r12,r14}
		msr		spsr, r12
		ldmfd	r13!, {r12,r14}

        b		undefined_instruction   

.pv_cl0:
		.word	0x6004000
.pv_cl1:
		.word	0x3007fe0

//
// "Vectors" - fixed location data items
//    This section contains any data which might be
shared between
// an eCos application and any other environment, e.g.
the debug
// ROM.                        
//
        .section ".fixed_vectors"
        // Interrupt/exception VSR pointers
        .globl  hal_vsr_table
hal_vsr_table:
        .rept   8               
        .long   0
        .endr

        .globl  hal_dram_size
hal_dram_size:  
        .long   0
	// what, if anything, hal_dram_type means is up to
the platform
        .globl  hal_dram_type
hal_dram_type:  
        .long   0

        .balign 16        
#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
	// Vectors used to communicate between eCos and ROM
environments
        .globl  hal_virtual_vector_table
hal_virtual_vector_table:
        .rept   CYGNUM_CALL_IF_TABLE_SIZE
        .long   0
        .endr
#endif
        .balign 32
        
// Other vectors - this may include "fixed" locations
#ifdef PLATFORM_VECTORS
        PLATFORM_VECTORS
#endif
                        
        .text   
#ifdef RICH
start_vector:
#else
// Startup code which will get the machine into
supervisor mode
        .global reset_vector
        .type   reset_vector,function
reset_vector:
        PLATFORM_SETUP1         // Early stage
platform initialization
                                // which can set DRAM
size at 0x40
                                // see
<cyg/hal/hal_platform_setup.h>

        // Come here to reset board
warm_reset:                 

#if defined(CYG_HAL_STARTUP_RAM) && \
    !defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
        mrs     r7,cpsr                 // move back
to IRQ mode
        and     r7,r7,#CPSR_MODE_BITS
        cmp     r7,#CPSR_SUPERVISOR_MODE
        beq     start
#endif

        // We cannot access any LED registers until
after PLATFORM_SETUP1
        LED 7

        mov     r0,#0           // move vectors
        ldr     r1,=__exception_handlers
#ifndef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
        // Wait with this if stubs are included (see
further down).
        ldr     r2,[r1,#0x04]   // undefined
instruction
        str     r2,[r0,#0x04]
        ldr     r2,[r1,#0x24]   
        str     r2,[r0,#0x24]
#endif
        ldr     r2,[r1,#0x08]   // software interrupt
        str     r2,[r0,#0x08]


#if defined(CYGSEM_HAL_ARM_PID_ANGEL_BOOT)
// Ugly hack to get into supervisor mode
        ldr     r2,[r1,#0x40]
        str     r2,[r0,#0x28]

        LED 6
                
        swi                     // switch to
supervisor mode
#endif        

//
=========================================================================
// Real startup code. We jump here from the reset
vector to set up the world.
        .globl  start
start:  

        LED 5

#if defined(CYG_HAL_STARTUP_RAM) && \
    !defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
// If we get restarted, hang here to avoid corrupting
memory
        ldr     r0,.init_flag
        ldr     r1,[r0]
1:      cmp     r1,#0
        bne     1b
        ldr     r1,init_done
        str     r1,[r0]
#endif

        // Reset software interrupt pointer
        mov     r0,#0           // move vectors
        ldr     r1,.__exception_handlers
#if defined(CYG_HAL_STARTUP_RAM) && \
    !defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
        cmp     r7,#CPSR_SUPERVISOR_MODE
        beq     10f
#endif
        ldr     r2,[r1,#0x28]   // software interrupt
        str     r2,[r0,#0x28]
10:
        ldr     r2,[r1,#0x18]   // IRQ
        str     r2,[r0,#0x18]
        ldr     r2,[r1,#0x38]
        str     r2,[r0,#0x38]
        ldr     r2,[r1,#0x1C]   // FIQ
        str     r2,[r0,#0x1C]
        ldr     r2,[r1,#0x3C]
        str     r2,[r0,#0x3C]
        ldr     r2,[r1,#0x0C]   // abort (prefetch)
        str     r2,[r0,#0x0C]
        ldr     r2,[r1,#0x2C]   
        str     r2,[r0,#0x2C]
        ldr     r2,[r1,#0x10]   // abort (data)
        str     r2,[r0,#0x10]
        ldr     r2,[r1,#0x30]
        str     r2,[r0,#0x30]

        LED 4
#endif
#if defined(CYG_HAL_STARTUP_ROM) ||
defined(CYG_HAL_STARTUP_ROMRAM)
#ifndef RICH
        // Set up reset vector
        mov     r0,#0
        ldr     r1,.__exception_handlers
        ldr     r2,[r1,#0x00]    // reset vector
intstruction
        str     r2,[r0,#0x00]
        ldr     r2,=warm_reset
        str     r2,[r0,#0x20]
#endif
        // Relocate [copy] data from ROM to RAM
        ldr     r3,.__rom_data_start
        ldr     r4,.__ram_data_start
        ldr     r5,.__ram_data_end
        cmp     r4,r5           // jump if no data to
move
        beq     2f
        sub     r3,r3,#4        // loop adjustments
        sub     r4,r4,#4
1:      ldr     r0,[r3,#4]!     // copy info
        str     r0,[r4,#4]!
        cmp     r4,r5
        bne     1b
2:
#endif

        // initialize interrupt/exception environments
        ldr     sp,.__startup_stack
        mov    
r0,#(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_IRQ_MODE)
        msr     cpsr,r0
        ldr     sp,.__exception_stack
        mov    
r0,#(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_UNDEF_MODE)
        msr     cpsr,r0
        ldr     sp,.__exception_stack

        // initialize CPSR (machine state register)
        mov    
r0,#(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SUPERVISOR_MODE)
        msr     cpsr,r0

        // Note: some functions in LIBGCC1 will cause
a "restore from SPSR"!!
        msr     spsr,r0

        // initialize stack
        ldr     sp,.__startup_stack

        // clear BSS
        ldr     r1,.__bss_start
        ldr     r2,.__bss_end
        mov     r0,#0
        cmp     r1,r2
        beq     2f
1:      str     r0,[r1],#4
        cmp     r1,r2
        bne     1b
2:

        // Run kernel + application in THUMB mode
        THUMB_MODE(r1,10)

		// setup agb interrupt address
        ldr     r1, int_addr					  
        adr     r0, IRQ
        str     r0, [r1]

        LED 3
        
		bl		TDInit

        // Call platform specific hardware
initialization
        bl      hal_hardware_init

#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
        bl      initialize_stub

        // Now that stub is initialized, change
vector. It is possible
        // to single-step through most of the init
code, except the below.
        // Put a breakpoint at the call to
cyg_hal_invoke_constructors to
        // pass over this bit (s-s depends on internal
state in the stub).
#endif

#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) || \
    defined(CYGIMP_HAL_PROCESS_ALL_EXCEPTIONS)
        mov     r0,#0           // move vectors
        ldr     r1,=__exception_handlers
        ldr     r2,[r1,#0x04]   // undefined
instruction
        str     r2,[r0,#0x04]
        ldr     r2,[r1,#0x24]   
        str     r2,[r0,#0x24]
#endif

#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
        .extern hal_ctrlc_isr_init
        bl      hal_ctrlc_isr_init
#endif

        LED 2
        
        // Run through static constructors
        bl      cyg_hal_invoke_constructors

        LED 1
        
        // This starts up the eCos kernel
        bl      cyg_start
_start_hang:
        b       _start_hang
        .code   32
        
        .global reset_platform
        .type   reset_platform,function
reset_platform:         
#ifdef CYGSEM_HAL_ROM_MONITOR
        // initialize CPSR (machine state register)
        mov    
r0,#(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SUPERVISOR_MODE)
        msr     cpsr,r0
        b       start_vector
#else
        mov     r0,#0
        mov     pc,r0           // Jump to reset
vector        
#endif                   
		
init_done:
        .long   0xDEADB00B
int_addr:
		.long	0x3007ffc

//
// Exception handlers
// Assumption: get here from a Supervisor context
[mode]
//
        .code   32
undefined_instruction:
        ldr     sp,.__undef_exception_stack     // get
good stack
        stmfd   sp!,{r0,fp,ip,lr}               
        mrs     r0,spsr
        stmfd   sp!,{r0}
        mov     ip,sp                   // save SP
which will vanish with
                                        //   mode
switch
        mrs     r0,cpsr                 // switch to
Supervisor Mode
        bic     r0,r0,#CPSR_MODE_BITS
        orr     r0,r0,#CPSR_SUPERVISOR_MODE
        msr     cpsr,r0                 // sp,lr are
now old values
        mov     fp,sp
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
        ldr     sp,.__GDB_stack
        cmp     fp,sp                   // already on
GDB stack?
        bhi     10f     
        ldr     r0,.__GDB_stack_base            
        cmp     fp,r0
        bls     10f                     // no - switch
to GDB stack
                                        //     
(already in sp)
        mov     sp,fp                   // yes - no
switch
10:
#endif
        sub     sp,sp,#ARMREG_SIZE      // make space
for frame
        stmea   sp,{r0-r10,fp}          // save
immediately visible registers
        ldmfd   ip,{r0-r4}              // saved
registers
        // Adjust PC according to CPU mode
        tst     r0,#CPSR_THUMB_ENABLE
        subeq   r4,r4,#4                // PC at time
of interrupt (ARM)
        subne   r4,r4,#2                // PC at time
of interrupt (thumb)
        str     r0,[sp,#armreg_cpsr]    // CPSR at
time of interrupt
        str     r1,[sp,#armreg_r0]      // saved R0
        str     r2,[sp,#armreg_fp]      // saved FP
        str     r3,[sp,#armreg_ip]      // saved IP
        str     r4,[sp,#armreg_pc]      // PC at time
of interrupt
        str     lr,[sp,#armreg_lr]      // LR at time
of interrupt
        add     r0,ip,#ARMREG_SIZE
        str     fp,[sp,#armreg_sp]      // SP at time
of interrupt
#ifdef  CYGHWR_HAL_ARM_DUMP_EXCEPTIONS
        mov     r0,sp
        bl      cyg_hal_report_undefined_instruction
#endif
        mov    
v1,#CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION
        b       call_exception_handler

        .code   32
software_interrupt:
        sub     sp,sp,#ARMREG_SIZE+16   // make space
for frame
        stmea   sp,{r0-r10,fp}          // save
immediately visible registers
        mrs     r0,spsr
        // Adjust PC according to CPU mode
        tst     r0,#CPSR_THUMB_ENABLE
        subeq   r3,lr,#4                // PC at time
of interrupt (ARM)
        subne   r3,lr,#2                // PC at time
of interrupt (thumb)
        str     r0,[sp,#armreg_cpsr]    // CPSR at
time of interrupt
        str     ip,[sp,#armreg_ip]      // saved IP
        str     r3,[sp,#armreg_pc]      // PC at time
of interrupt
        str     lr,[sp,#armreg_lr]      // LR at time
of interrupt
        add     r0,sp,#ARMREG_SIZE+16
        str     r0,[sp,#armreg_sp]      // SP at time
of interrupt
#ifdef  CYGHWR_HAL_ARM_DUMP_EXCEPTIONS
        mov     r0,sp
        bl      cyg_hal_report_software_interrupt
#endif
        mov     v1,#CYGNUM_HAL_EXCEPTION_INTERRUPT
        b       call_exception_handler

        .code   32
abort_prefetch:
        ldr     sp,.__undef_exception_stack     // get
good stack
        sub     lr,lr,#4                // PC at time
of interrupt
        stmfd   sp!,{r0,fp,ip,lr}               
        mrs     r0,spsr
        stmfd   sp!,{r0}
        mov     ip,sp                   // save SP
which will vanish with
                                        //   mode
switch
        mrs     r0,cpsr                 // switch to
Supervisor Mode
        bic     r0,r0,#CPSR_MODE_BITS
        orr     r0,r0,#CPSR_SUPERVISOR_MODE
        msr     cpsr,r0                 // sp,lr are
now old values
        mov     fp,sp
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
        ldr     sp,.__GDB_stack
        cmp     fp,sp                   // already on
GDB stack?
        bhi     10f     
        ldr     r0,.__GDB_stack_base            
        cmp     fp,r0
        bls     10f                     // no - switch
to GDB stack
                                        //     
(already in sp)
        mov     sp,fp                   // yes - no
switch
10:
#endif
        sub     sp,sp,#ARMREG_SIZE      // make space
for frame
        stmea   sp,{r0-r10,fp}          // save
immediately visible registers
        ldmfd   ip,{r0-r4}              // saved
registers
        str     r0,[sp,#armreg_cpsr]    // CPSR at
time of interrupt
        str     r1,[sp,#armreg_r0]      // saved R0
        str     r2,[sp,#armreg_fp]      // saved FP
        str     r3,[sp,#armreg_ip]      // saved IP
        str     r4,[sp,#armreg_pc]      // PC at time
of interrupt
        str     lr,[sp,#armreg_lr]      // LR at time
of interrupt
        add     r0,ip,#ARMREG_SIZE
        str     fp,[sp,#armreg_sp]      // SP at time
of interrupt
#ifdef  CYGHWR_HAL_ARM_DUMP_EXCEPTIONS
        mov     r0,sp
        bl      cyg_hal_report_abort_prefetch
#endif
        mov     v1,#CYGNUM_HAL_EXCEPTION_CODE_ACCESS
        b       call_exception_handler

        .code   32
abort_data:
        ldr     sp,.__undef_exception_stack     // get
good stack
        sub     lr,lr,#4                // PC at time
of interrupt
        stmfd   sp!,{r0,fp,ip,lr}               
        mrs     r0,spsr
        stmfd   sp!,{r0}
        mov     ip,sp                   // save SP
which will vanish with
                                        //   mode
switch
        mrs     r0,cpsr                 // switch to
Supervisor Mode
        bic     r0,r0,#CPSR_MODE_BITS
        orr     r0,r0,#CPSR_SUPERVISOR_MODE
        msr     cpsr,r0                 // sp,lr are
now old values
        mov     fp,sp
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
        ldr     sp,.__GDB_stack
        cmp     fp,sp                   // already on
GDB stack?
        bhi     10f     
        ldr     r0,.__GDB_stack_base            
        cmp     fp,r0
        bls     10f                     // no - switch
to GDB stack
                                        //     
(already in sp)
        mov     sp,fp                   // yes - no
switch
10:
#endif
        sub     sp,sp,#ARMREG_SIZE      // make space
for frame
        stmea   sp,{r0-r10,fp}          // save
immediately visible registers
        ldmfd   ip,{r0-r4}              // saved
registers
        str     r0,[sp,#armreg_cpsr]    // CPSR at
time of interrupt
        str     r1,[sp,#armreg_r0]      // saved R0
        str     r2,[sp,#armreg_fp]      // saved FP
        str     r3,[sp,#armreg_ip]      // saved IP
        str     r4,[sp,#armreg_pc]      // PC at time
of interrupt
        str     lr,[sp,#armreg_lr]      // LR at time
of interrupt
        add     r0,ip,#ARMREG_SIZE
        str     fp,[sp,#armreg_sp]      // SP at time
of interrupt
#ifdef  CYGHWR_HAL_ARM_DUMP_EXCEPTIONS
        mov     r0,sp
        bl      cyg_hal_report_abort_data
#endif
        mov     v1,#CYGNUM_HAL_EXCEPTION_DATA_ACCESS
        b       call_exception_handler

        
//
// Dispatch an exception handler.

        .code   32
call_exception_handler:
        str     v1,[sp,#armreg_vector]
        mov     r0,sp

        THUMB_MODE(r9,10)

        bl      exception_handler
#ifdef  CYGHWR_HAL_ARM_DUMP_EXCEPTIONS
        mov     r0,sp
        bl     
cyg_hal_report_exception_handler_returned
#endif

        ARM_MODE(r1,10)

// Restore [interrupted] context
        mov     ip,sp                   // get stack
pointer

        mrs     r0,cpsr                 // move back
to IRQ mode
        orr    
r0,r0,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE
        msr     cpsr,r0
        nop
        nop

        ldr     lr,[ip,#armreg_lr]
        ldr     sp,[sp,#armreg_sp]
                        
        bic     r0,r0,#CPSR_MODE_BITS
        orr     r0,r0,#CPSR_IRQ_MODE
        msr     cpsr,r0

        mov     sp,ip
        ldr     lr,[sp,#armreg_pc]
        ldr     r0,[sp,#armreg_cpsr]
        ldr     ip,[sp,#armreg_ip]
        msr     spsr,r0
        ldmfd   sp,{r0-r10,fp}

        movs    pc,lr                   // restore PC
from LR, CPSR from SPSR

// Handle device interrupts
// This is slightly more complicated than the other
exception handlers because
// it needs to interface with the kernel (if present).

        .code   32
FIQ:
        // We can get here from supervisor mode or
from IRQ mode.
        mrs     r8,spsr                 // CPSR at
time of interrupt
        and     r9,r8,#CPSR_MODE_BITS   // isolate
pre-interrupt mode
        cmp	r9,#CPSR_IRQ_MODE
        bne	1f
        // If FIQ interrupted IRQ mode, just return
with FIQ disabled.
        // The common interrupt handling takes care of
the rest.
        orr	r8,r8,#CPSR_FIQ_DISABLE
        msr	spsr,r8
        subs	pc,lr,#4
    1:
        // If FIQ interrupted supervisor mode, switch
to IRQ mode and
        // fall through to IRQ handler.
        ldr     sp,.__exception_stack   // get good
stack to save lr and spsr
        stmdb   sp,{r8,lr}
        mov    
r8,#CPSR_IRQ_MODE|CPSR_FIQ_DISABLE|CPSR_IRQ_DISABLE
        msr     cpsr,r8			// switch to IRQ mode
        ldr     sp,.__exception_stack   // get regs
saved in FIQ mode
        ldmdb	sp,{sp,lr}
        msr     spsr,sp

        // now it looks like we got an IRQ instead of
an FIQ except that
        // FIQ is disabled so we don't recurse.

//#define MODE_SWITCH

IRQ:
		// This restores registers and stack from GBA bios
		ldmfd   r13!,{r0-r3,r12,r14}
	
        // Note: I use this exception stack while
saving the context because
        // the current SP does not seem to be always
valid in this CPU mode.
        ldr     sp,.__exception_stack   // get good
stack
        sub     lr,lr,#4                // PC at time
of interrupt
        stmfd   sp!,{r0,fp,ip,lr}               
        mrs     r0,spsr
        stmfd   sp!,{r0}

handle_IRQ_or_FIQ:              
        mov     ip,sp                   // save SP
which will vanish with
                                        //   mode
switch
#ifdef MODE_SWITCH
        mrs     r0,cpsr                 // switch to
Supervisor Mode
        bic     r0,r0,#CPSR_MODE_BITS
        orr    
r0,r0,#CPSR_SUPERVISOR_MODE|CPSR_FIQ_DISABLE|CPSR_IRQ_DISABLE
        msr     cpsr,r0                 // sp,lr are
now old values
#endif
        mov     fp,sp                   // save old SP
        sub     sp,sp,#ARMREG_SIZE      // make space
for frame
        stmea   sp,{r0-r10,fp}          // save
immediately visible registers
        ldmfd   ip,{r0-r4}              // saved
registers
        str     r0,[sp,#armreg_cpsr]    // CPSR at
time of interrupt
        str     r1,[sp,#armreg_r0]      // saved R0
        str     r2,[sp,#armreg_fp]      // saved FP
        str     r3,[sp,#armreg_ip]      // saved IP
        str     r4,[sp,#armreg_pc]      // PC at time
of interrupt
        str     lr,[sp,#armreg_lr]      // LR at time
of interrupt
        str     fp,[sp,#armreg_sp]      // SP at time
of interrupt
        mov     r0,#CYGNUM_HAL_VECTOR_IRQ       //
FIXME: we don't distinguish
        str     r0,[sp,#armreg_vector]          // FIQ
and IRQ here
        mov     v6,sp                   // Save
pointer to register frame

//      mov     r0,sp
//      bl      _show_frame_in

#ifdef
CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
        // Switch to interrupt stack
        ldr     r2,.irq_level           // current
number of nested interrupts
        ldr     r0,[r2]
        add     r1,r0,#1
        str     r1,[r2]                 // if was
zero, switch stacks
        cmp     r0,#0
        moveq   r1,sp                   // save old
stack pointer
        ldreq   sp,.__interrupt_stack
        stmeqfd sp!,{r1}
10:
#endif

        // The entire CPU state is now stashed on the
stack,
        // increment the scheduler lock and handle the
interrupt

#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT               
 
        .extern cyg_scheduler_sched_lock
        ldr     r3,.cyg_scheduler_sched_lock
        ldr     r4,[r3]
        add     r4,r4,#1
        str     r4,[r3]
#endif

        THUMB_MODE(r3,10)

        mov     r0,v6
        bl      hal_IRQ_handler         // determine
interrupt source
        mov     v1,r0                   // returned
vector #

#if defined(CYGPKG_KERNEL_INSTRUMENT) && \
    defined(CYGDBG_KERNEL_INSTRUMENT_INTR)
        ldr     r0,=RAISE_INTR          // arg0 = type
= INTR,RAISE
        mov     r1,v1                   // arg1 =
vector
        mov     r2,#0                   // arg2 = 0
        bl      cyg_instrument          // call
instrument function
#endif

        ARM_MODE(r0,10)

        mov     r0,v1                   // vector #

#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
        // If we are supporting Ctrl-C interrupts from
GDB, we must squirrel
        // away a pointer to the save interrupt state
here so that we can
        // plant a breakpoint at some later time.

       .extern  hal_saved_interrupt_state
        ldr     r2,=hal_saved_interrupt_state
        str     v6,[r2]
#endif

        cmp     r0,#CYGNUM_HAL_INTERRUPT_NONE   //
spurious interrupt
        bne     10f
#ifndef CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS
        mov     r0,v6                   // register
frame
        bl      hal_spurious_IRQ
#endif // CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS
        b       spurious_IRQ
        
10:     ldr     r1,.hal_interrupt_data
        ldr     r1,[r1,v1,lsl #2]       // handler
data
        ldr     r2,.hal_interrupt_handlers
        ldr     v3,[r2,v1,lsl #2]       // handler
(indexed by vector #)
        mov     r2,v6                   // register
frame (this is necessary
                                        // for the ISR
too, for ^C detection)

#ifdef __thumb__
        ldr     lr,=10f
        bx      v3                      // invoke
handler (thumb mode)
        .pool
        .code   16
        .thumb_func
IRQ_10T:
10:     ldr     r2,=15f
        bx      r2                      // switch back
to ARM mode
        .pool
        .code   32
15:
IRQ_15A:
#else
        mov     lr,pc                   // invoke
handler (call indirect
        mov     pc,v3                   // thru v3)
#endif

spurious_IRQ:           

#ifdef
CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
        // If we are returning from the last nested
interrupt, move back
        // to the thread stack. interrupt_end() must
be called on the
        // thread stack since it potentially causes a
context switch.
        ldr     r2,.irq_level
        ldr     r3,[r2]
        subs    r1,r3,#1
        str     r1,[r2]
        ldreq   sp,[sp]         // This should be the
saved stack pointer
#endif
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
        // The return value from the handler (in r0)
will indicate whether a 
        // DSR is to be posted. Pass this together
with a pointer to the
        // interrupt object we have just used to the
interrupt tidy up routine.

                              // don't run this for
spurious interrupts!
        cmp     v1,#CYGNUM_HAL_INTERRUPT_NONE
        beq     17f
        ldr     r1,.hal_interrupt_objects
        ldr     r1,[r1,v1,lsl #2]
        mov     r2,v6           // register frame

        THUMB_MODE(r3,10)

        bl      interrupt_end   // post any bottom
layer handler
                                // threads and call
scheduler
        ARM_MODE(r1,10)
17:
#endif

//      mov     r0,sp
//      bl      show_frame_out

        mov     ip,sp                   // get stack
pointer

#ifdef MODE_SWITCH
        mrs     r0,cpsr                 // move back
to IRQ mode
        orr    
r0,r0,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE
        msr     cpsr,r0
        nop
        nop
#endif

        ldr     lr,[ip,#armreg_lr]
        ldr     sp,[sp,#armreg_sp]
                        
#ifdef MODE_SWITCH
        bic     r0,r0,#CPSR_MODE_BITS
        orr     r0,r0,#CPSR_IRQ_MODE
        msr     cpsr,r0
#endif

        mov     sp,ip
        ldr     lr,[sp,#armreg_pc]
        ldr     r0,[sp,#armreg_cpsr]
        ldr     ip,[sp,#armreg_ip]
        msr     spsr,r0
        ldmfd   sp,{r0-r10,fp}
        movs    pc,lr                   // restore PC
from LR, CPSR from SPSR

#ifdef
CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
// Execute pending DSRs the interrupt stack
// Note: this can only be called from code running on
a thread stack
FUNC_START_ARM(hal_interrupt_stack_call_pending_DSRs,
r1)
        stmfd   sp!,{r4,r5,lr}
        // Disable interrupts
        mrs     r4,cpsr                 // disable
IRQ's
        orr    
r2,r4,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE
        bic    
r5,r4,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE
        msr     cpsr,r2
        // Switch to interrupt stack
        mov     r3,sp                   // save old
stack pointer
        ldr     sp,.__interrupt_stack
        stmfd   sp!,{r3}                // stored at
top of interrupt stack
        ldr     r2,.irq_level           // current
number of nested interrupts
        ldr     r3,[r2]
        add     r3,r3,#1                // bump
nesting level
        str     r3,[r2]
        msr     cpsr,r5                 // enable
interrupts

        THUMB_MODE(r1,20)

        bl      cyg_interrupt_call_pending_DSRs


        ARM_MODE(r1,22)

        // Disable interrupts
        mrs     r1,cpsr                 // disable
IRQ's
        orr    
r2,r1,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE
        msr     cpsr,r2

        // Move back to the thread stack.
        ldr     r2,.irq_level
        ldr     r3,[r2]
        sub     r3,r3,#1                // decrement
nesting level
        str     r3,[r2]
        ldr     sp,[sp]                 // This should
be the saved stack pointer
        msr     cpsr,r4                 // restore
interrupts to original state

#ifdef __thumb__
        ldmfd   sp!,{r4,r5,lr}          // return
        bx      lr
#else
        ldmfd   sp!,{r4,r5,pc}          // return
#endif // __thumb__
#endif //
CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
        
// Thumb-only support functions
#ifdef __thumb__

FUNC_START_ARM(hal_disable_interrupts, r1)
        mrs     r0,cpsr                 // current
state
        orr     r1,r0,#0xC0             // mask both
FIQ and IRQ
        msr     cpsr,r1
        bx      lr                      // exit, _old_
in r0        

FUNC_START_ARM(hal_enable_interrupts, r1)
        mrs     r0,cpsr                 // current
state
        bic     r1,r0,#0xC0             // mask both
FIQ and IRQ
        msr     cpsr,r1
        bx      lr                      // exit
        
FUNC_START_ARM(hal_restore_interrupts, r1)
        mrs     r1,cpsr                 // current
state
        bic     r1,r1,#0xC0             // mask out
FIQ/IRQ bits
        and     r0,r0,#0xC0             // keep only
FIQ/IRQ
        orr     r1,r1,r0                // mask both
FIQ and IRQ
        msr     cpsr,r1
        bx      lr                      // exit       


FUNC_START_ARM(hal_query_interrupts, r1)
        mrs     r0,cpsr                 // current
state
        bx      lr                      // exit, state
in r0

#endif // __thumb__

// Dummy/support functions

        .global __gccmain
        .global _psr
        .global _sp

#ifdef __thumb__
        .code   16
        .thumb_func
__gccmain:
        bx      lr

        .code   16
        .thumb_func
_psr:
        ARM_MODE(r1,10)
        mrs     r0,cpsr
        bx      lr

        .code   16
        .thumb_func
_sp:
        mov     r0,sp
        bx      lr
#else
__gccmain:
        mov     pc,lr   

_psr:
        mrs     r0,cpsr
        mov     pc,lr

_sp:
        mov     r0,sp
        mov     pc,lr
#endif                


//
// Pointers to various objects.
//
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
PTR(__GDB_stack_base)
PTR(__GDB_stack)
#endif
PTR(__startup_stack)
PTR(__exception_stack)
PTR(__undef_exception_stack)
PTR(__bss_start)
PTR(__bss_end)
PTR(_end)
PTR(__rom_data_start)
PTR(__ram_data_start)
PTR(__ram_data_end)
PTR(hal_interrupt_handlers)
PTR(hal_interrupt_data)
PTR(hal_interrupt_objects)
PTR(__exception_handlers)
PTR(init_flag)
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
PTR(cyg_scheduler_sched_lock)
#endif
#ifdef
CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
PTR(irq_level)
PTR(__interrupt_stack)
#endif
PTR(hal_patch_vector_code)

//
// Identification - useful to find out when a system
was configured
_eCos_id:
        .asciz  "eCos : " __DATE__


//
-------------------------------------------------------------------------
// Interrupt vector tables.
// These tables contain the isr, data and object
pointers used to deliver
// interrupts to user code.

// Despite appearances, their sizes are not #defines,
but .equ symbols
// generated by magic without proper dependencies in
arm.inc
// Recompiling will not DTRT without manual
intervention.

        .data

init_flag:
        .balign 4
        .long   0

        .extern hal_default_isr

        .globl  hal_interrupt_handlers
hal_interrupt_handlers:
        .rept   CYGNUM_HAL_ISR_COUNT
        .long   hal_default_isr
        .endr

        .globl  hal_interrupt_data
hal_interrupt_data:
        .rept   CYGNUM_HAL_ISR_COUNT
        .long   0
        .endr

        .globl  hal_interrupt_objects
hal_interrupt_objects:
        .rept   CYGNUM_HAL_ISR_COUNT
        .long   0
        .endr

//
-------------------------------------------------------------------------
// Temporary interrupt stack
        
        .section ".bss"

// Small stacks, only used for saving information
between CPU modes
__exception_stack_base: 
        .rept   32
        .long   0
        .endr
__exception_stack:
        .rept   32
        .long   0
        .endr
__undef_exception_stack:

// Runtime stack used during all interrupt processing
#ifndef CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
#define CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE 4096
#endif
#ifdef
CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
        .balign 16
        .global cyg_interrupt_stack_base
cyg_interrupt_stack_base:
__interrupt_stack_base:
        .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
        .byte 0
        .endr
        .balign 16
        .global cyg_interrupt_stack
cyg_interrupt_stack:
__interrupt_stack:
irq_level:
        .long   0
#endif

#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
        .balign 16
__GDB_stack_base:
        .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
// rather than 1k
        .byte 0
        .endr
__GDB_stack:
#endif
        .balign 16
__startup_stack_base:
#ifdef
CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
        .rept 4096
#else
        .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
#endif
        .byte 0
        .endr
        .balign 16
__startup_stack:

#ifdef PLATFORM_EXTRAS
#include PLATFORM_EXTRAS
#endif                                

//
--------------------------------------------------------------------------
//  end of vectors.S


__________________________________________________
Do You Yahoo!?
Make a great connection at Yahoo! Personals.
http://personals.yahoo.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]