bug in lm32 port

Michael Walle michael at walle.cc
Thu Mar 26 13:51:00 UTC 2009


there is a bug in the lm32 port in the startup routines. There are
immediate branches to the isr handler and main function.

On lm32 the opcode can encode 26bits adresses in an immediate branch,
which permits relative jumps of 64 MiB.

The startup code is divided into a .boot and a .text section. The use of
immediate branches implies, that the 'distance' between these two sections
(and the section that holds the isr handler) must not be greater than

So if, for example, one defines the .boot section in the embedded block
ram to be at 0x00000000 and the .text section in flash/sram (whatever) at
0x40000000, he gets the following error:
(.boot+0xc0): relocation truncated to fit: R_LM32_CALL against symbol
`_ISR_Handler' defined in .text section ...

Proposed fix:
 - move crt0 in libbsp/lm32/shared/start/start.S to .boot
 - use indirect branches

But there is a problem with the ISR handler call: when the cpu jumps to
the interrupt vector, no registers have been saved yet. So we cannot use
indirect jumps. We can't even use register r0 (which is supposed to be
zero) because the "mvhi rX, imm16", which we need for indirect branches,
is just a pseudo operation for "orhi rX, r0, imm16".

Some Thoughts:
 - we could change EBA (which is the exception base address) in the
bootcode and branch to it right after power up/reset. so our 'real'
exception vectors are no longer in the .boot section (well .. that
doesn't resolve the problem, but relocate it)
 - some support code in the .boot section that saves some registers onto
the stack

Any other ideas?


More information about the users mailing list