I'm having an issue/misunderstanding on remapping the vector table for an A9 core in a bare metal (flat mapped) application. I assumed I could create a vector table in some arbitrary location in RAM, load that location into the vbar register:
ldr r0, =vector_tbl mcr p15, 0, r0, c12, c0, 0 //write VBAR register
and when an interrupt occurred (via the gic/IRQ), control would pass to the IRQ handler. This isn't happening. Control actually passes to the svc handler with the cpu in IRQ mode. I'm pretty sure this is a result of not remapping the vector table correctly. Any guidance on this?
Check the value of vector_tbl and the alignment.
The address of the vector table I'm trying to use is shown in the attached listing, line 289 which is at location 0x009005B0 (OCRAM). The exceptions are in the correct order. As the listing shows, 0x009005B0 is loaded into the VTOR register via function set_vbar (line 201). The problem I have is that when the interrupt occurs from the local timer (as mentioned above), execution jumps to line 230 instead of line 270. Interestingly, the mode is switched to IRQ mode. I put a breakpoint at line 230 to see if the vector table somehow got corrupted - it did not. I can set the next instruction to line 296 and it executes the "jump" to line 270 showing that the table is fine. Are there some other rules to setting the VTOR register that I'm overlooking?
194 195 ASM_PUBLIC_BEGIN(_set_vbar) 196 ASM_PUBLIC_FUNC(_set_vbar) 197 198 /************************************************************************ 199 * Set the location of the hardware vector table into the VBAR reg 200 ***********************************************************************/ 201 set_vbar 202 000000EC 44009FE5 ldr r0, =vector_tbl 203 000000F0 100F0CEE mcr p15, 0, r0, c12, c0, 0 //write VBAR register 204 205 // SCTLR bit V - location of exception vectors 206 000000F4 100F11EE mrc p15, 0, r0, c1, c0, 0 //read SCTLR 207 000000F8 800DC0E3 bic r0, r0, #0x2000 //clear V bit 208 000000FC 100F01EE mcr p15, 0, r0, c1, c0, 0 //write SCTLR 209 210 00000100 1EFF2FE1 bx lr //return 211 212 ASM_PUBLIC_END(_set_vbar) 213 214 215 216 ASM_PUBLIC_BEGIN(undef_isr) 217 ASM_PUBLIC_FUNC(undef_isr) 218 219 undef_isr 220 00000104 FEFFFFEA b . 221 222 ASM_PUBLIC_END(undef_isr) 223 224 225 226 ASM_PUBLIC_BEGIN(svc_isr) 227 ASM_PUBLIC_FUNC(svc_isr) 228 229 svc_isr 230 00000108 FEFFFFEA b . 231 232 ASM_PUBLIC_END(svc_isr) 233 234 235 236 ASM_PUBLIC_BEGIN(prefetch_isr) 237 ASM_PUBLIC_FUNC(prefetch_isr) 238 239 prefetch_isr 240 0000010C FEFFFFEA b . 241 242 ASM_PUBLIC_END(prefetch_isr) 243 244 245 246 ASM_PUBLIC_BEGIN(abort_isr) 247 ASM_PUBLIC_FUNC(abort_isr) 248 249 abort_isr 250 00000110 FEFFFFEA b . 251 ASM_PUBLIC_END(abort_isr) 252 253 254 255 ASM_PUBLIC_BEGIN(fiq_isr) 256 ASM_PUBLIC_FUNC(fiq_isr) 257 258 fiq_isr 259 00000114 FEFFFFEA b . 260 261 ASM_PUBLIC_END(fiq_isr) 262 263 264 265 ASM_PUBLIC_BEGIN(irq_isr) 266 ASM_PUBLIC_FUNC(irq_isr) 267 268 irq_isr 269 // Save registers 270 00000118 FF5F2DE9 push {r0-r12, lr} 271 272 // Call the IRQ Exception handler 273 0000011C 18009FE5 ldr r0, =irq_hnlr //make sure bit0 is 0 274 00000120 30FF2FE1 blx r0 275 276 // Return to normal program flow 277 00000124 FF5FBDE8 pop {r0-r12, lr} 278 00000128 04F05EE2 subs pc, lr, #4 279 280 ASM_PUBLIC_END(irq_isr) 281 282 283 284 285 ASM_CODE_SECTION(vector_ram) 286 287 // This is the actual hardware exception table, the address of which is loaded 288 // into the VBAR. This section must be aligned on a 4-byte boundary (VBAR) 289 vector_tbl 290 00000000 18F09FE5 ldr pc, =__boot 291 00000004 18F09FE5 ldr pc, =undef_isr 292 00000008 18F09FE5 ldr pc, =svc_isr 293 0000000C 18F09FE5 ldr pc, =prefetch_isr 294 00000010 18F09FE5 ldr pc, =abort_isr 295 00000014 00F020E3 nop // reserved 296 00000018 14F09FE5 ldr pc, =irq_isr 297 0000001C 14F09FE5 ldr pc, =fiq_isr 298
Vbar must be aligned on 32byte boundary!
I saw some illusions to that, but could never find where it was documented. Thanks for the help. That solved the problem.
ARMv7AR Manual:
B4.1.156 VBAR, Vector Base Address Register, Security Extensions
...
Vector_Base_Address, bits[31:5] Bits[31:5] of the base address of the low exception vectors. Bits[4:0] of an exception vector is the exception offset, see Table B1-3 on page B1-1166.Bits[4:0] Reserved, UNK/SBZP.