exception/trap vector handlers

Hi

First of all, if anyone knows that there is a better place for this query, please point me in the right direction.

I got stuck trying to research the internal workings of the BB and thought somebody might help me out. I am following the TI provided OMAP3530 documentation together with the ARM ARM(which includes ARMv7x architectures).

Now for the nice and pretty (and pretty it is!).
From the TI provided OMAP35x Applications Processor Initialization pdf (page 25 onwards) I was researching the ROM memory layout and ROM bootcode. Replacing trap/exception vector handlers with my custom ones is at the moment my intention, but i want to understand everything thoroughly. From the document, the vector lies in ROM, at address 0x14000h.

*ROM exception vectors
*Exceptions are redirected to ROM exception vectors (see Table 1-7). The reset exception is redirected to the public ROM code startup. Other exceptions are redirected to RAM handlers by loading appropriate addresses in the PC register.
/Table 1-7. ROM Exception Vectors
/14000h Reset Branch to the public ROM code startup
14004h Undefined (PC = 4020FFC8h)
14008h Software interrupt (SWI) (PC = 4020FFCCh)
1400Ch Prefetch abort (PC = 4020FFD0h)
14010h Data abort (PC = 4020FFD4h)
14014h Unused (PC = 4020FFD8h)
14018h IRQ (PC = 4020FFDCh)
1401Ch FIQ (PC = 4020FFE0h)

ok so this is simple - instructions at address 0x140xxh to change the PC value to somewhere where the exception handling carries on. To confirm this, i checked my beagleboard.:

OMAP3 beagleboard.org # md 14000 10 produced the following correct results:
00014000: ea00022e ( reset handler: Branch <always> to immediate offset 0x22e)
00014004: e59ff018 ( all the following handlers: load values to PC from [PC + imm])
00014008: e59ff018
0001400c: e59ff018
00014010: e59ff018
00014014: e59ff018
00014018: e59ff018
0001401c: e59ff018
(00014020 seems unused/not interesting, as reset branches to another location)
00014024: 4020ffc8 ( These are the values loaded into PC by each of the LDR PC, [PC + imm] instruction for each trap)
00014028: 4020ffcc
0001402c: 4020ffd0
00014030: 4020ffd4
00014034: 4020ffd8
00014038: 4020ffdc
0001403c: 4020ffe0

All is well so far. Following on with the TI document:
*RAM exception vectors
*The RAM exception vectors provide an easy way to redirect exceptions to the custom handler. Table 1-10 shows the contents of the RAM space reserved for RAM vectors. The first seven addresses are ARM instructions which load into the PC the value located in the next seven addresses. Theses instructions are executed when an exception occurs, since they are called from ROM exception vectors. By default, all exceptions are redirected to the exception dead loops. Users can redirect an exception to other handler by writing its address to the appropriate position from 0x4020FFE4 to 0x4020FFFC, or by overriding instructions between addresses from 0x4020FFC8 to 0x4020FFE0.
Table 1-10. RAM Exception Vectors
0x4020FFC8 Undefined (PC = [0x4020FFE4]) (fantastic! these are the values i found on my bb - previous data table)
0x4020FFCC SWI (PC = [0x4020FFE8])
0x4020FFD0 Pre-fetch abort (PC = [0x4020FFEC])
0x4020FFD4 Data abort (PC = [0x4020FFF0])
0x4020FFD8 Unused (PC = [0x4020FFF4])
0x4020FFDC IRQ (PC = [0x4020FFF8])
0x4020FFE0 FIQ (PC = [0x4020FFFC])

claims.

OMAP3 beagleboard.org # md 4020ffc8 f
4020ffc8: 480022f0 00000001 00000001 00000001 .".H............
4020ffd8: 00000001 000001f4 0000000c 0000010a ................
4020ffe8: 80008890 6d000000 00000003 00000003 .......m........
4020fff8: 80009be4 8000809c

I was able to find the exception vectors built at address 0x4020F800.
Is it an undocumented stuff ? Also how the control comes to 0x4020F800 ?

u-boot v2 is explicitly building exception handlers @ 0x4020F800 for
omap .so, (legacy) u-boot rely on rom-code defaults ?

[BB Trace]

4020f800: e59ff014 e59ff014 e59ff014 e59ff014 ................
4020f810: e59ff014 e59ff014 e59ff014 80e80140 ............@...
4020f820: 80e801a0 80e80200 80e80260 80e802c0 ........`.......
4020f830: 80e80320 80e80380 12345678 80e80000 .......xV4.....

Regards,
Shankar

What am i missing/misunderstanding?
Can anyone explain me / give me pointers how to solve the mistery of the
missing exception handlers?

U-Boot defines the following under include/asm-arm/arch-omap3/omap3.h.

Can someone help us to understand from where this 0x4020F800 is derived ?

[include/asm-arm/arch-omap3/omap3.h]
......
/* base address for indirect vectors (internal boot mode) */
#define SRAM_OFFSET0 0x40000000
#define SRAM_OFFSET1 0x00200000
#define SRAM_OFFSET2 0x0000F800
#define SRAM_VECT_CODE
(SRAM_OFFSET0|SRAM_OFFSET1|SRAM_OFFSET2)

Regards,
Shankar

The TI documentation is correct, but the exception vector tables are
overwritten by u-boot (and x-load) that incorrectly initialise a stack
at the top of RAM which soon over-writes the table contents, rather
than at the place reserved by TI for stacks (Public stack
4020F000..0x4020FCB0).

omap3.h:

#define LOW_LEVEL_SRAM_STACK 0x4020FFFC // ooops this will soon
overwrite the vector table.

See spruf98b p3377, Figure 25-7. 64KB RAM Memory Map of GP Devices,
Public Stack.

This suggests it should be changed to

#define LOW_LEVEL_SRAM_STACK 0x4020FCAC

If this is done in x-load and u-boot, exceptions (in u-boot) then
actually work.

Peter

The TI documentation is correct, but the exception vector tables are
overwritten by u-boot (and x-load) that incorrectly initialise a stack
at the top of RAM which soon over-writes the table contents, rather
than at the place reserved by TI for stacks (Public stack
4020F000..0x4020FCB0).

omap3.h:

#define LOW_LEVEL_SRAM_STACK 0x4020FFFC // ooops this will soon
overwrite the vector table.

See spruf98b p3377, Figure 25-7. 64KB RAM Memory Map of GP Devices,
Public Stack.
  

It doesnt seem that revision B or the TRM is available anywhere. TI now
only give spruf98c (rev C). Could not find such a figure in revision C.
If you are aware of a place where revB is still hosted, i'd be grateful
if you shared it.

> See spruf98b p3377, Figure 25-7. 64KB RAM Memory Map of GP Devices,
> Public Stack.

Ok, in spruf98c.pdf...

page 3467,
Chapter 26 Initialization
Sec 1.4.2.2 RAM memory map,
Figure 1-7. 64KB RAM Memory Map of GP Devices.

Peter

Why wouldn't you use

#define LOW_LEVEL_SRAM_STACK 0x4020FCB0 since that is where the public
stack starts in the TI documentation? (assuming a descending stack)

Further aren't SRAM_OFFSET0, SRAM_OFFSET1, SRAM_OFFSET2 wrong? Shouldn't
they sum to 0x4020FFC8 instead of 0x4020F800?

Regards,

Brad Badke

Hemisphere GPS
8444 N 90th St #130
Scottsdale, AZ 85258
Direct: 480-348-6323
Fax: 480-348-6370
bbadke@hemispheregps.com
www.hemispheregps.com

Why wouldn't you use

#define LOW_LEVEL_SRAM_STACK 0x4020FCB0 since that is where the public
stack starts in the TI documentation? (assuming a descending stack)

I think 0x4020FCB0 is the first address of the Reserved area and
therefore unsuitable. Perhaps I should have said the stack memory
space goes from 0x4020F000 to 0x4020FCB0 *non-inclusive*. That is my
interpretation but the Diagram is not very clear. [aside: If the
values were all say ...0000 and ...FFFF then you could reasonably
expect the expected.
But with ...FCB0 - Better to err on the side of caution.]

Also, I don't know for certain if the ARM architecture when doing a
push performs a "store then decrement" or "decrement then store".
"Store then decrement" is the safer assumption, therefore the SP
should be set to 0x4020FCAC. This is consistent also with the original
setting of 0x4020FFFC. (Also assuming max 32-bit write before
decrement).

Really my intent was to explain what caused the OP reported behavior,
rather than exactly what should be done to correct it, so my first
post might lack for a bit of rigour I'm afraid.

Further aren't SRAM_OFFSET0, SRAM_OFFSET1, SRAM_OFFSET2 wrong? Shouldn't
they sum to 0x4020FFC8 instead of 0x4020F800?

Technically I think you are right, but I don't like to encourage this
kind of code-thinking.

The assembler may also have trouble, try it.

Best,

Peter.

OK Peter, I believe you are correct about the 0x4020FCA8 (=0x4020FCB0
- 8 for Daniel's code).

As far as the SRAM_OFFSETS are concerned, I think I am correct. As far
as me trying it, I am busy porting my own proprietary RTOS to the OMAP
and don't have the time (maybe in a couple of months when I have spare
time I will play with x-loader, u-boot and Linux). Hopefully Daniel has
it all figured out by then.

Regards,

Brad Badke

Hemisphere GPS
8444 N 90th St #130
Scottsdale, AZ 85258
Direct: 480-348-6323
Fax: 480-348-6370
bbadke@hemispheregps.com
www.hemispheregps.com

current status seems pretty good.

...
OMAP3 beagleboard.org # md 0 00000000:data abort pc : [<80e96980>] lr : [<80e96960>] sp : 80e3fdf0 ip : fffffffe fp : 00000000 r10: 00000040 r9 : 00000000 r8 : 80e3ffe0 r7 : 00000004 r6 : 00000000 r5 : 00000004 r4 : 00000000 r3 : 00000000 r2 : 00000002 r1 : 00000003 r0 : 80ea521a Flags: nZCv IRQs off FIQs off Mode SVC_32 Resetting CPU ...
                                                                                
resetting ...
                                                                                
Texas Instruments X-Loader 1.4.2 (Feb 19 2009 - 12:01:24) Reading boot sector Loading u-boot.bin from mmc
                                                                                
U-Boot 2009.08-00343-g14abfe3-dirty (Oct 16 2009 - 18:31:43)

... and so on. this is the default exception handler of uboot in action.
OMAP3 beagleboard.org # md 4020ffc8 e 4020ffc8: e59ff014 e59ff014 e59ff014 e59ff014 ................ 4020ffd8: e59ff014 e59ff014 e59ff014 80e80160 ............`... 4020ffe8: 80e801c0 80e80220 80e80280 80e802e0 .... ........... 4020fff8: 80e80340 80e803a0
... looks correct.

although I found another bug, this time in the SWI handler, which in the end is pretty obvious to spot:

start.S
...
    str lr, [r0] @ save caller lr in position 0
                        @ of saved stack
    mrs r0, spsr @ get the spsr
    str lr, [r0, #4] @ save spsr in position 1 of
                        @ saved stack
...

r0 holds the address of stack that is calculated. but is overwritten before being used for the second time.you can clearly see they meant to save spsr in lr, and store lr in stack. so i fixed that and got SWI working as well.

OMAP3 beagleboard.org # go 80300000 ## Starting application at 0x80300000 ... software interrupt pc : [<8030008c>] lr : [<200001d0>] sp : 80e3fe58 ip : fffffffe fp : 80e3fe5c r10: 00000000 r9 : 80e61580 r8 : 80e3ffe0 r7 : 00000000 r6 : 00000002 r5 : 80e61634 r4 : 80300000 r3 : 0000000a r2 : 0000000a r1 : 80e61634 r0 : 200001d0 Flags: nzCv IRQs off FIQs off Mode USER_32 Resetting CPU ...
                                                                                
resetting ... ... etc.

so all seems fixed. now just need to restore the original value of LR, and of course the code is ugly, and before making any kind of a 'patch' i should clean it up from all garbage. but the actual fix code is pretty small, only required a lot of reading to figure out whats happening where.

Daniel K.

Brad Badke wrote:

so all seems fixed. now just need to restore the original value of LR, and of course the code is ugly, and before making any kind of a 'patch' i should clean it up from all garbage. but the actual fix code is pretty small,

    Hi Daniel,

    I tried to do the same thing as you did. That's allocate vector table correctly in U-boot.
       It seems that you've figured this out. Would you mind to share your patch?
    Thanks a lot.

    Cheers,
    Matt