[#4698] Crash when trying to execute from L1 text

Document created by Aaronwu Employee on Sep 25, 2013
Version 1Show Document
  • View in full screen mode

[#4698] Crash when trying to execute from L1 text

Submitted By: Phil Wilshire

Open Date

2008-12-05 14:34:40     Close Date

2008-12-05 14:39:34


Medium     Assignee:

Mike Frysinger


N/A     Fixed In Release:


Found In Release:

2008R1.5     Status:



STAMP     Processor:


Silicon Revision:



Is the bug repeatable?:


Summary: Crash when trying to execute from L1 text



Given the following code example


int l1_test_code(void) __attribute__ ((l1_text));


int l1_test_code(void)


  return 23;



int do_l1_test(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])


        int val;

        printf ("l1_test_addr   = %08x\n", l1_test_code);

        if ( argc > 1 ) {

          val = l1_test_code();

          printf ("l1_test_val   = %d\n", val);


        return 0;


U_BOOT_CMD(l1_test, 3, 1, do_l1_test,

           "l1_test - tests l1_test address\n",

           "l1_test x - runs l1_test code\n"




This shows the address of the function

but I get an error when trying to run the code.


  first test just get the address


bfin_1205> l1_test

l1_test_addr   = ffa00034


  second test get address then execute code..

bfin_1205> l1_test 1

l1_test_addr   = ffa00034




Ack! Something bad happened to the Blackfin!



SEQSTAT: 00002021  IPEND: 3fc00bc  SYSCFG: 0032


  EXCAUSE   : 0x21

  physical IVG7 asserted : <0x03fc0744> { _evt_default + 0x0 }

RETE: <0x00000000> /* Maybe null pointer? */

RETN: <0x008c0000> /* unknown address */

RETX: <0x03a00034> /* unknown address */

RETS: <0x03fd4358> { _do_l1_test + 0x24 }

PC  : <0x03fc00bc> { _start + 0xbc }

DCPLB_FAULT_ADDR: <0x03f5bb8c> /* unknown address */

ICPLB_FAULT_ADDR: <0x03a00034> /* unknown address */




CPLBINFO shows the area set up


bfin> cplbinfo

Instruction CPLB table [0000100f]:

      Address     Data   Size  Valid  Locked

  1 0xffa00000  0x20007   1M     Y      Y

  2 0x03c00000  0x31007   4M     Y      Y

  3 0x04000000  0x31007   4M     Y      Y

  4 0x20000000  0x30005   4M     Y      N

  5 0x00000000  0x31005   4M     Y      N

  6 0x00400000  0x31005   4M     Y      N

  7 0x00800000  0x31005   4M     Y      N


The objdump of u-boot shows this


0034 <_l1_test_code>(-6291404) */

3fd434c:       ff e3 8a f3     CALL 0x3fd2a60 <_printf>;

3fd4350:       0f 0d           CC = R7 <= 0x1;

3fd4352:       0a 18           IF CC JUMP 0x3fd4366 <_do_l1_test+0x32>;

3fd4354:       d1 e3 70 5e     CALL 0x3a00034 <env_offset+0x39fc034>;

3fd4358:       08 30           R1 = R0;

3fd435a:       40 e1 fe 03     R0.H = 0x3fe;           /* (1022)       R0=0x3fe

09cc(66980300) */

3fd435e:       00 e1 e4 09     R0.L = 0x9e4;           /* (2532)       R0=0x3fe

09e4(66980324) */



And the actual code memory shows this



03fd4330: 00100538 01670578 03fee140 ffa0e141    8...x.g.@...A...

03fd4340: 6fa6303a 09cce100 0034e101 f38ae3ff    :0.o......4.....

03fd4350: 180a0d0f 5e70e3d1 e1403008 e10003fe    ......p^.0@.....

03fd4360: e3ff09e4 6c66f37f 60000127 00100538    ......fl'..`8...

03fd4370: 014b0560 0167014c 318e6fa6 03fee14a    `.K.L.g..o.1J...



So it looks like some kind of linking error

for code in L1_text or have I done something wrong here ??


Any thoughts


  Phil Wilshire




--- Mike Frysinger                                           2008-12-05 14:39:34

read cpu/blackfin/reset.c ... since i dont plan on changing u-boot, we'll mark

this a dupe of linker relaxation bug


--- Phil Wilshire                                            2008-12-05 14:54:43

OK this code works

I am forcing the compiler to create an absolute

address for the code in L1




int l1_test_code(void) __attribute__ ((l1_text));


int l1_test_code(void)


  return 23;






int do_l1_test(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])


        int val;


        /* int (*mytest)(void)=l1_test_core;*/ /* does not work */

        int (*mytest)(void)=0xffa00034;        /* this does work */


        printf ("l1_test_addr   = %08x\n", l1_test_code);

        printf ("mytest   = %08x\n", mytest);

        val = mytest();

        printf ("mytest val  = %d\n", val);


        return 0;




l1_test_addr   = ffa00034

mytest   = ffa00034

mytest val  = 23




But looe the ability to link directly with the function

in L1 text.

I think this is a compiler / bug or could I do something

to force the compiler not to consider the l1_test_code

as a local  address,




--- Phil Wilshire                                            2008-12-05 14:56:02

OK Thanks Mike



--- Mike Frysinger                                           2008-12-05 16:46:26

yes, you can trampoline either with inline asm or a function pointer in C.  or

build all of u-boot with -mlong-call.  it sucks either way ;).


--- Phil Wilshire                                            2008-12-05 17:06:02

And the answer is ...


Create a small assembler function in a nearby .S file



        [--sp] = rets;

        [--sp] = p2;


        p2 = r0;


        p2 = [sp++];

        rets= [sp++];






Then use this in your "C" file.



int l1_test_code(void) __attribute__ ((l1_text));

int l1_test_code(void)


  return 23;



extern int jump_call(unsigned long caller);


int do_l1_test(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])


        int val;


        printf ("l1_test_addr   = %08x\n", l1_test_code);

        val = jump_call(l1_test_code);

        printf ("l1_test_jump val  = %d\n", val);

        return 0;




This will get you there, a bit more work if you want to add arguments.



  Phil Wilshire












File Name     File Type     File Size     Posted By

No Files Were Found