Hi Epis,
> How to place this inteupt serivece routine after .org 0x20 ?
There are several techniques you can use. I'm assuming that you're not using the HAL.
One technique is to place your startup code at the beginning of your application, and
place the exception handler entry point at offset 0x20 from the start. This is the technique
used by u-boot. For example, the file cpu/nios2/start.S:
<div class='quotetop'>QUOTE </div>
--- Quote Start ---
.text
.global _start
_start:
/* ICACHE INIT -- only the icache line at the reset address
* is invalidated at reset. So the init must stay within
* the cache line size (8 words). If GERMS is used, we'll
* just be invalidating the cache a second time. If cache
* is not implemented initi behaves as nop.
*/
ori r4, r0, %lo(CFG_ICACHELINE_SIZE)
movhi r5, %hi(CFG_ICACHE_SIZE)
ori r5, r5, %lo(CFG_ICACHE_SIZE)
mov r6, r0
0: initi r6
add r6, r6, r4
bltu r6, r5, 0b
br _except_end /* Skip the tramp */
/* EXCEPTION TRAMPOLINE -- the following gets copied
* to the exception address (below), but is otherwise at the
* default exception vector offset (0x0020).
*/
. = _start + 0x20 _except_start:
movhi et, %hi(_exception)
ori et, et, %lo(_exception)
jmp et
_except_end:[/b]
--- Quote End ---
Your linker script must account for this by specifying the specific object module first:
<div class='quotetop'>QUOTE </div>
--- Quote Start ---
SECTIONS
{
.text :
{
cpu/nios2/start.o (.text) *(.text)
*(.text.*)
*(.gnu.linkonce.t*)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
}[/b]
--- Quote End ---
This is convenient if you need to relocate the exception entry point (and other sections at
run time) -- i.e. moving the code from flash to SDRAM without regard to the current
location:
<div class='quotetop'>QUOTE </div>
--- Quote Start ---
/* RELOCATE CODE, DATA & COMMAND TABLE -- the following code
* assumes code, data and the command table are all
* contiguous. This lets us relocate everything as a single
* block. Make sure the linker script matches this ;-)
*/
nextpc r4
_cur: movhi r5, %hi(_cur - _start)
ori r5, r5, %lo(_cur - _start)
sub r4, r4, r5 /* r4 <- cur _start */
mov r8, r4
movhi r5, %hi(_start)
ori r5, r5, %lo(_start) /* r5 <- linked _start */
beq r4, r5, 3f
movhi r6, %hi(_edata)
ori r6, r6, %lo(_edata)
2: ldwio r7, 0(r4)
addi r4, r4, 4
stwio r7, 0(r5)
addi r5, r5, 4
bne r5, r6, 2b
3:
/* ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent
* and between __bss_start and _end.
*/
movhi r5, %hi(__bss_start)
ori r5, r5, %lo(__bss_start)
movhi r6, %hi(_end)
ori r6, r6, %lo(_end)
beq r5, r6, 5f
4: stwio r0, 0(r5)
addi r5, r5, 4
bne r5, r6, 4b
5:
/* GLOBAL POINTER -- the global pointer is used to reference
* "small data" (see -G switch). The linker script must
* provide the gp address.
*/
movhi gp, %hi(_gp)
ori gp, gp, %lo(_gp)
/* JUMP TO RELOC ADDR */
movhi r4, %hi(_reloc)
ori r4, r4, %lo(_reloc)
jmp r4
_reloc:
/* COPY EXCEPTION TRAMPOLINE -- copy the tramp to the
* exception address. Define CONFIG_ROM_STUBS to prevent
* the copy (e.g. exception in flash or in other
* softare/firmware component).
*/
movhi r4, %hi(_except_start)
ori r4, r4, %lo(_except_start)
movhi r5, %hi(_except_end)
ori r5, r5, %lo(_except_end)
movhi r6, %hi(CFG_EXCEPTION_ADDR)
ori r6, r6, %lo(CFG_EXCEPTION_ADDR)
beq r4, r6, 7f /* Skip if at proper addr */
6: ldwio r7, 0(r4)
stwio r7, 0(r6)
addi r4, r4, 4
addi r6, r6, 4
bne r4, r5, 6b
7:[/b]
--- Quote End ---
Another technique you can use is to place the exception entry point in its own section,
then let the linker (and linker script) locate it where you want. You can play with the
load memory address of the section if you need to relocate it at run time.
Regards,
--Scott
PS -- You can download the u-boot source code if you want to dig into details:
http://www.psyent.com/download (
http://www.psyent.com/download)