EmbeddedRelated.com
Forums

How to move interrupt vector from 0x0 to some offset

Started by ADNAN January 7, 2010
You cannot change the address of the vectors, but you can **remap** the
address so that the address points to a different area in memory.

For example, it is common to do this (as is done with the SAM7s):
At boot, 0x0 maps to the start of flash. This allows the boot vectors to be in
flash.
Some time after boot you remap the area to RAM. This allows you to write new
values into the vectors.

On Saturday 09 January 2010 03:56:52 ADNAN wrote:
> Hi,
>
> Actually I want to write a bootloader that will download and execute
> another placed in some area of ROM.How it can be possible.?
>
> My idea is to have vector table of bootloader to be at the start of
> the ROM at 0x0 and of my application to be at the start of rom at 0x5000.
> What do you think? I have tried this way bootloader try starting
> application but application dont works.
>
> Regards
> Dani
>
> --- In A..., "Icli, Bekir" wrote:
> > You cannot change the irq and excp vec. addresses.. I told you they are
> > fixed.. 0x0 thru 0x20 What you can do is, let the code run from 0x5000
> > and relocate (simply copy) your vector handlers
> >
> > > __vector:
> > >
> > > LDR PC,Reset_Addr ; Reset
> > > LDR PC,Undefined_Addr ; Undefined instructions
> > > LDR PC,SWI_Addr ; Software interrupt (SWI/SVC)
> > > LDR PC,Prefetch_Addr ; Prefetch abort
> > > LDR PC,Abort_Addr ; Data abort
> > > __vector_0x14:
> > > DCD 0 ; RESERVED
> > > LDR PC,IRQ_Addr ; IRQ
> > > LDR PC,FIQ_Addr ; FIQ
> >
> > to 0x0.. that should solve the problem..
> >
> > Best,
> > Bekir
> >
> > ________________________________
> > From: A... [mailto:A...] On Behalf
> > Of ADNAN Sent: Friday, January 08, 2010 2:47 PM
> > To: A...
> > Subject: [AT91SAM] Re: How to move interrupt vector from 0x0 to some
> > offset
> >
> >
> >
> >
> > Hi,
> >
> > You are right. Now tell me what should i do to change the interrupt
> > vector and exception vector address from 0x0 to 0x5000 or 0x105000 so
> > that my application alos works from there.
> >
> > Regards
> > Dani
> >
> > --- In A..., "Icli,
Bekir" wrote:
> > > Hi Dani,
> > >
> > > It makes perfect sense, that it works when you load it to 0x0 or
> > > 0x100000.. Apparently these two memory locations are mirrored.. (means
> > > they are pointing to the same physical memory).. As I stated in my
> > > former mail, you HAVE TO load your exception vectors (with that I mean
> > > irq and the other exception vectors) to 0x0.. In your case:
> > > __vector:
> > >
> > > LDR PC,Reset_Addr ; Reset
> > > LDR PC,Undefined_Addr ; Undefined instructions
> > > LDR PC,SWI_Addr ; Software interrupt (SWI/SVC)
> > > LDR PC,Prefetch_Addr ; Prefetch abort
> > > LDR PC,Abort_Addr ; Data abort
> > > __vector_0x14:
> > > DCD 0 ; RESERVED
> > > LDR PC,IRQ_Addr ; IRQ
> > > LDR PC,FIQ_Addr ; FIQ
> > > should be placed to 0x0..
> > > Because processor does not know where your handler is, he just jumps to
> > > 0x18 and continues with execution.. If you have a debugger, set a break
> > > point at 0x18 and you'll see what I mean.. and check after that, if
> > > your LDR PC, IRQ_Addr is there.. ;)
> > >
> > > Best,
> > > Bekir
> > >
> > > ________________________________
> > > From: A...
> > > [mailto:A...] On
> > > Behalf Of ADNAN Sent: Friday, January 08, 2010 12:09 PM
> > > To: A...
> > > Subject: [AT91SAM] Re: How to move interrupt vector from 0x0 to some
> > > offset
> > >
> > >
> > >
> > > Hi Bakir,
> > >
> > > Thanks for your reply.
> > >
> > > I am using CMX Rtos for both of my codes, 1, bootloader and other is
> > > the actualy application. The cmx handler for IRQ is as follows, SECTION
> > > .text:CODE:NOROOT:REORDER(2)
> > > ARM
> > > IRQ_Wrapper:
> > > SUB LR,LR,#4 ; adj for proper CMX return
> > > STMFD SP!,{R0-R12,LR} ; save the registers
> > >
> > > ldr r14, =AT91C_BASE_AIC
> > > ldr r0, [r14, #AIC_IVR] ; get vector address
> > > str r14, [r14, #AIC_IVR]
> > >
> > > MRS R9,SPSR ; save the SPSR
> > > STMFD SP!,{R9}
> > > LDR R2,=int_count ; get int_count
> > > MRS R3,CPSR
> > > MOV R4,R3
> > > ORR R4,R4,#Int_Bits ; disable interrupts
> > > MSR CPSR_c,R4
> > > LDRB R1,[R2] ; incr the count
> > > ADD R1,R1,#1
> > > STRB R1,[R2]
> > > MSR CPSR_c,R3 ; restore interrupts
> > >
> > > cmp r0, #0 ; handler available?
> > > beq irq_ack ; no, ack interrupt and exit
> > >
> > > MSR CPSR_c, #SYS_MODE ; SYS mode, interrupts enabled
> > > STMFD sp!,{R0-R12,lr} ; Save registers.
> > > mov lr,pc
> > > BX R0 ; call specified handler
> > > LDMFD SP!,{R0-R12,lr} ; restore registers.
> > > MSR CPSR_c, #IRQ_MODE|I_Bit|F_Bit ; Switch to IRQ mode, no interrupts
> > >
> > > irq_ack
> > > ldr r1, =AT91C_BASE_AIC ; Ack End of Interrupt
> > > str r1, [r1, #AIC_EOICR]
> > >
> > > B K_OS_Intrp_Exit
> > >
> > > This handler works nice when i place intvec at 0x0 or 0x100000, but
> > > stops working when i change address of intvec to 0x5000 or 0x105000 i
> > > dont know why,
> > >
> > > The cStartup is as follows,
> > >
> > > MODULE ?cstartup
> > >
> > > SECTION IRQ_STACK:DATA:NOROOT(3)
> > > SECTION FIQ_STACK:DATA:NOROOT(3)
> > > SECTION UND_STACK:DATA:NOROOT(3)
> > > SECTION ABT_STACK:DATA:NOROOT(3)
> > > SECTION SVC_STACK:DATA:NOROOT(3)
> > > SECTION CSTACK:DATA:NOROOT(3)
> > >
> > > SECTION .intvec:CODE:NOROOT(2)
> > >
> > > PUBLIC __vector
> > > PUBLIC __vector_0x14
> > > PUBLIC __iar_program_start
> > > EXTERN Undef_Wrapper
> > > EXTERN SWI_Wrapper
> > > EXTERN Prefetch_Wrapper
> > > EXTERN Abort_Wrapper
> > > EXTERN IRQ_Wrapper
> > > EXTERN FIQ_Wrapper
> > >
> > > ARM
> > >
> > > ;;====================================================================> > >========= ;; EXECPTION HANDLERS
> > > ; All default exception handlers (except reset) are
> > > ; defined as weak symbol definitions.
> > > ; If a handler is defined by the application it will take precedence.
> > > ;;====================================================================> > >========> > >
> > > __vector:
> > >
> > > LDR PC,Reset_Addr ; Reset
> > > LDR PC,Undefined_Addr ; Undefined instructions
> > > LDR PC,SWI_Addr ; Software interrupt (SWI/SVC)
> > > LDR PC,Prefetch_Addr ; Prefetch abort
> > > LDR PC,Abort_Addr ; Data abort
> > > __vector_0x14:
> > > DCD 0 ; RESERVED
> > > LDR PC,IRQ_Addr ; IRQ
> > > LDR PC,FIQ_Addr ; FIQ
> > >
> > > Reset_Addr: DCD __iar_program_start
> > > Undefined_Addr: DCD Undef_Wrapper
> > > SWI_Addr: DCD SWI_Wrapper
> > > Prefetch_Addr: DCD Prefetch_Wrapper
> > > Abort_Addr: DCD Abort_Wrapper
> > > IRQ_Addr: DCD IRQ_Wrapper
> > > FIQ_Addr: DCD FIQ_Wrapper
> > >
> > > ;;====================================================================> > >========= ;; LOW LEVEL SYSTEM INITIALIZATION
> > > ; After a reset execution starts here, the mode is ARM, supervisor
> > > ; with interrupts disabled.
> > > ;;====================================================================> > >========> > >
> > > SECTION .text:CODE:NOROOT(2)
> > > EXTERN ?main
> > > REQUIRE __vector
> > > EXTERN AT91LowLevelInit
> > > EXTERN at91_spurious_handler
> > >
> > > ARM
> > >
> > > __iar_program_start:
> > > ?cstartup:
> > >
> > > ; Minumum C initialization
> > >
> > > ldr r13,=SFE(SVC_STACK)
> > > ; Call Low level init function
> > > ldr r0,=AT91LowLevelInit
> > > mov lr, pc
> > > bx r0
> > >
> > > ;
> > > ; Add initialization needed before setup of stackpointers here.
> > > ;
> > >
> > > ;
> > > ; Initialize the stack pointers.
> > > ; The pattern below can be used for any of the exception stacks:
> > > ; FIQ, IRQ, SVC, ABT, UND, SYS.
> > > ; The USR mode uses the same stack as SYS.
> > > ; The stack segments must be defined in the linker command file,
> > > ; and be declared above.
> > > ;
> > >
> > > ; --------------------
> > > ; Mode, corresponds to bits 0-5 in CPSR
> > >
> > > MODE_MSK DEFINE 0x1F ; Bit mask for mode bits in CPSR
> > >
> > > USR_MODE DEFINE 0x10 ; User mode
> > > FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode
> > > IRQ_MODE DEFINE 0x12 ; Interrupt Request mode
> > > SVC_MODE DEFINE 0x13 ; Supervisor mode
> > > ABT_MODE DEFINE 0x17 ; Abort mode
> > > UND_MODE DEFINE 0x1B ; Undefined Instruction mode
> > > SYS_MODE DEFINE 0x1F ; System mode
> > >
> > > MRS r0, cpsr ; Original PSR value
> > > ;;====================================================================> > >========= ;; STACK POINTERS SETUP
> > > ;;====================================================================> > >========> > >
> > > ;; Setup the interrupt stack pointer.
> > >
> > > BIC r0, r0, #MODE_MSK ; Clear the mode bits
> > > ORR r0, r0, #IRQ_MODE ; Set IRQ mode bits
> > > MSR cpsr_c, r0 ; Change the mode
> > > LDR sp, =SFE(IRQ_STACK) ; End of IRQ_STACK
> > >
> > > ;; Set up the fast interrupt stack pointer.
> > >
> > > BIC r0, r0, #MODE_MSK ; Clear the mode bits
> > > ORR r0, r0, #FIQ_MODE ; Set FIR mode bits
> > > MSR cpsr_c, r0 ; Change the mode
> > > LDR sp, =SFE(FIQ_STACK) ; End of FIQ_STACK
> > >
> > > bic r0,r0,#MODE_MSK ; Clear the mode bits
> > > orr r0,r0,#UND_MODE ; Set UND mode bits
> > > msr cpsr_c,r0 ; Change the mode
> > > ldr sp,=SFE(UND_STACK) ; End of UND_STACK
> > >
> > > bic r0,r0,#MODE_MSK ; Clear the mode bits
> > > orr r0,r0,#ABT_MODE ; Set ABT mode bits
> > > msr cpsr_c,r0 ; Change the mode
> > > ldr sp,=SFE(ABT_STACK) ; End of ABT_STACK
> > >
> > > bic r0,r0,#MODE_MSK ; Clear the mode bits
> > > orr r0,r0,#SYS_MODE ; Set SYS mode bits
> > > msr cpsr_c,r0 ; Change the mode
> > > ldr sp,=SFE(CSTACK) ; End of CSTACK
> > >
> > > ;; Set up the normal stack pointer.
> > >
> > > BIC r0 ,r0, #MODE_MSK ; Clear the mode bits
> > > ORR r0 ,r0, #SVC_MODE ; Set SVC mode bits
> > > MSR cpsr_c, r0 ; Change the mode
> > > LDR sp, =SFE(SVC_STACK) ; End of SVC_STACK
> > > ; setup spurious interrupt handler
> > > ldr r0,=at91_spurious_handler
> > > ldr r1,=AT91C_BASE_AIC
> > > str r0,[r1, #AIC_SPU]
> > >
> > > #ifdef __ARMVFP__
> > > ;; Enable the VFP coprocessor.
> > >
> > > MOV r0, #0x40000000 ; Set EN bit in VFP
> > > FMXR fpexc, r0 ; FPEXC, clear others.
> > >
> > > ;
> > > ; Disable underflow exceptions by setting flush to zero mode.
> > > ; For full IEEE 754 underflow compliance this code should be removed
> > > ; and the appropriate exception handler installed.
> > > ;
> > >
> > > MOV r0, #0x01000000 ; Set FZ bit in VFP
> > > FMXR fpscr, r0 ; FPSCR, clear others.
> > > #endif
> > >
> > > ;
> > > ; Add more initialization here
> > > ;
> > >
> > > ; Continue to ?main for C-level initialization.
> > >
> > > B ?main
> > >
> > > END
> > > //////////////
> > >
> > > What is wrong. Any views on this.
> > >
> > > Regards
> > > Dani
> > >
> > > --- In
A..., "Icli,
Bekir" wrote:
> > > > Hi Dani,
> > > >
> > > > You should first understand how the interrupts in ARM are handled.
> > > > Wenn the Interrupt Controller asserts the signal, processor loads the
> > > > program counter with the address 0x18. There, you must have a branch
> > > > to your actual IRQ handler.
> > > > It looks pretty much like this:
> > > >
> > > > .section .vectors,"a",%progbits
> > > >
> > > > resetVector:
> > > > b resetHandler /* Reset */
> > > > undefVector:
> > > > b UndefinedException /* Undefined instruction */
> > > > swiVector:
> > > > b SwiException /* Software interrupt !! should not fire!! */
> > > > prefetchAbortVector:
> > > > b PrefetchAbortException /* Prefetch abort */
> > > > dataAbortVector:
> > > > b DataAbortException /* Data abort */
> > > > reservedVector:
> > > > b reservedVector /* Reserved for future use */
> > > > irqVector:
> > > > b irqHandler /* Interrupt */
> > > > fiqVector:
> > > > b fiqVector /* FIQ */
> > > > From there on, it's all up to you, how you deal with the rest in
> > > > "irqHandler".
> > > >
> > > > Good luck,
> > > > Bekir
> > > >
> > > > ________________________________
> > > > From:
> > > > A... > > > >SAM%40yahoogroups.com>
> > > > [mailto:A... > > > >lto:AT91SAM%40yahoogroups.com>] On Behalf Of ADNAN Sent: Thursday,
> > > > January 07, 2010 10:56 PM
> > > > To:
> > > > A... > > > >SAM%40yahoogroups.com> Subject: [AT91SAM] How to move interrupt vector
> > > > from 0x0 to some offset
> > > >
> > > >
> > > >
> > > > Hello all,
> > > >
> > > > I am newbie to Arm and IAR. I have develope an application using
> > > > IAR5.30 and AT91SAM7S128 which has interuupt vector starting from 0x0
> > > > and rom starting from 0x5000 and when i load this application using
> > > > jflash utitlity it is working fine.
> > > >
> > > > On the same configuration(address) i have devloped a bootloader
> > > > application. Now i want to download first application using this
> > > > bootloader application. As the both bootloader application and the
> > > > first application has the same interrupt vector address 0x0 so when i
> > > > download it donot work.
> > > >
> > > > Do i need to move the interrupt vector to some where else, ?
> > > >
> > > > When i moved the interrupt vector of my application to 0x5000 , i.e.
> > > > just in the start of the application, the interrupt are not working.
> > > >
> > > > Kindly send your valuable advise and observation to help solving my
> > > > problem.
> > > >
> > > > Your kind guidence will be highly appricated.
> > > >
> > > > Regards
> > > > Dani