0
votes

My question would be based on this code. This is a startup code for arm-based board (rpi2). I am mostly interested in part related to vector table setup. The vector table looks like this:

// Vector table
.align 4
.globl vec_table
vec_table:
ldr pc,add_handler_00
ldr pc,add_handler_04
ldr pc,add_handler_08
ldr pc,add_handler_0C
ldr pc,add_handler_10
ldr pc,add_handler_14
ldr pc,add_handler_18
ldr pc,add_handler_1C
add_handler_00: .word _start
add_handler_04: .word handler_04
add_handler_08: .word handler_08
add_handler_0C: .word handler_0C
add_handler_10: .word handler_10
add_handler_14: .word handler_14
add_handler_18: .word handler_18
add_handler_1C: .word handler_1C

// Low-level vector table handlers
.macro vec_handler num
handler_\num:
    mov r0,#0x\num
    ldr r3,=exception_handler
    bx r3
.endm

vec_handler 04
vec_handler 08
vec_handler 0C
vec_handler 10
vec_handler 14
vec_handler 18
vec_handler 1C

further, when the boot code will jump to kernel_main

// Call kernel_main
ldr r3, =kernel_main

the main function would call vector table setup like this:

extern uint32_t vec_table;
void install_vector_table()
{
    asm volatile("mcr p15, 0, %[r], c12, c0, 0": :[r]"r" (&vec_table):);
}

When I have tested if this exception really occur, I noticed that if i add some .word blocks at the beginning of the boot.S file the exception logic stops to work. For example if i move this data

und_stack: .word 0xc0026000
dab_stack: .word 0xc0028000
svc_stack: .word 0xc0032000

from the end of the file to the beginning the exceptions stop working. I mean - for example instead of calling data abort exception handler it constantly spinning to reset.

What i have discovered:

It looks like alignment or absolute addressing issue, something is breaks down when i add more data to beginning. When i add two words and it looks like following:

periph_base: .word 0x3f200000
virtual_base: .word 0xc0000000
und_stack: .word 0xc0026000
dab_stack: .word 0xc0028000

it works fine, if i add one more word - it breaks down. I have analayzed objdump address of every jump in a way of exception call and i see no critical difference between them in bad and good cases. Can anybody suggest what is this?

1

1 Answers

3
votes

It looks like alignment or absolute addressing issue

It is.

Your vector table is 16-byte aligned:

.align 4
.globl vec_table
vec_table:

but the architecture requires it to be 32-byte aligned (i.e. to its total size) - note that the bottom 5 bits of VBAR are reserved.

Say that your 16-byte-aligned table winds up at 0x12340010, VBAR will likely just ignore bits 0-4, taking the effective value 0x12340000, and a subsequent data abort taken to offset 0x10 from that address will indeed happen to land in your reset handler.