[#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

Priority:

Medium     Assignee:

Mike Frysinger

Category:

N/A     Fixed In Release:

N/A

Found In Release:

2008R1.5     Status:

Closed

Board:

STAMP     Processor:

BF537

Silicon Revision:

    Resolution:

Duplicated

Is the bug repeatable?:

yes     

Summary: Crash when trying to execute from L1 text

Details:

 

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!

 

SEQUENCER STATUS:

SEQSTAT: 00002021  IPEND: 3fc00bc  SYSCFG: 0032

  HWERRCAUSE: 0x0

  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

 

Follow-ups

 

--- 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

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

 

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

OK Thanks Mike

   Phil

 

--- 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

----------------------------------------------------------------

ENTRY(_jump_call)

        [--sp] = rets;

        [--sp] = p2;

 

        p2 = r0;

        call(p2);

        p2 = [sp++];

        rets= [sp++];

 

        rts;

ENDPROC(_jump_call)

-----------------------------------------------------------------------

 

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.

 

Regards

  Phil Wilshire

 

 

 

    Files

    Changes

    Commits

    Dependencies

    Duplicates

    Associations

    Tags

 

File Name     File Type     File Size     Posted By

No Files Were Found

Attachments

    Outcomes