Jump from assembly to C problem with boot code on MCF52233

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Jump from assembly to C problem with boot code on MCF52233

2,930 Views
pnordby
Contributor I
Hello,

I am in the process of making a boot-code for field flash upgrade of the MCF52233. The MCF52235EVB is "compatible" with our product, and the software without boot-code is similar to this.

My problem occurs when jumping from assembly to C language in the application-code (boot-code runs initially and does this "switch" flawlessly).

The output from gdb and my debugger (BDI2000) at the problem location:
----- 8< ----- 8< -----
(gdb) monitor rd
D0 : 00000000 00000000 00000030 00000006
D4 : 00000018 a661a87d c40f9216 56d33015
A0 : 00000000 44035a4c 200000fc 401d0024
A4 : 1d047492 667d0fa0 00000000 20007ff0
PC : 00027fac     SR : 00002704
(gdb) monitor info
    Target state      : debug mode
    Debug entry cause : single step
    Current PC        : 0x00027fac
(gdb) monitor ti
    Target state      : debug mode
    Debug entry cause : single step
    Current PC        : 0x00000466
(gdb) monitor rd
D0 : 00000000 00000000 00000030 00000006
D4 : 00000018 a661a87d c40f9216 56d33015
A0 : 00000000 44035a4c 200000fc 401d0024
A4 : 1d047492 667d0fa0 00000000 20007fe8
PC : 00000466     SR : 00002704
(gdb)
----- 8< ----- 8< -----

...and the disassembly before and after the jump:
----- 8< ----- 8< -----
   1001c:       7000            moveq #0,%d0
   1001e:       7200            moveq #0,%d1
   10020:       2f08            movel %a0,%sp@-
   10022:       2f00            movel %d0,%sp@-
   10024:       2f01            movel %d1,%sp@-
   10026:       2f0e            movel %fp,%sp@-
   10028:       4ef9 0002 7fac  jmp 27fac <__start1>
----- 8< ----- 8< -----
00027fac <__start1>:
   27fac:       4e56 fffc       linkw %fp,#-4
   27fb0:       2f02            movel %d2,%sp@-
   27fb2:       203c 0003 5550  movel #218448,%d0
   27fb8:       0c80 2000 0000  cmpil #536870912,%d0
   27fbe:       672e            beqs 27fee <__start1+0x42>
----- 8< ----- 8< -----

Here is some parts of relevant pieces in the linker script (... indicates removed stuff):
----- 8< ----- 8< -----
OUTPUT_ARCH(m68k)
ENTRY(__start)
SEARCH_DIR(.)
__DYNAMIC  =  0;

MEMORY
{
  rom (rx) : ORIGIN = 64K, LENGTH = 192K
  ram (rwx) : ORIGIN = 512M, LENGTH = 32K
  bootloader (rx) : ORIGIN = 0K, LENGTH = 48K
  bootconst (rx) : ORIGIN = 48K, LENGTH = 16K
}

PROVIDE (__stack = ORIGIN (ram) + LENGTH (ram));
...

SECTIONS
{
  .text :
  {
    CREATE_OBJECT_SYMBOLS
    *(.app_start .app_start.*)
    *(.text .text.*)
    *(.gnu.linkonce.t.*)
    ...
    . = ALIGN(0x4);
    __INIT_SECTION__ = . ;
    LONG (0x4e560000) /* linkw %fp,#0 */
    *(.init)
    SHORT (0x4e5e) /* unlk %fp */
    SHORT (0x4e75) /* rts */

    . = ALIGN(0x4);
    __FINI_SECTION__ = . ;
    LONG (0x4e560000) /* linkw %fp,#0 */
    *(.fini)
    SHORT (0x4e5e) /* unlk %fp */
    SHORT (0x4e75) /* rts */
    *(.lit)

    . = ALIGN(4);
    _etext = .;
  } >rom

  ...

  .bootloader :
  {
    __interrupt_vector_boot = .;
    cf-boot.o(.bootloader)
    *(.bootloader .bootloader.*)
  } >bootloader

  .bootconst :
  {
    *(.bootconst .bootconst.*)
  } >bootconst
}
----- 8< ----- 8< -----

Did I miss something regarding the linkw instruction in the linker script? Or is some assembly magic required before the jump?


Message Edited by P.Nordby on 2007-06-13 09:38 AM
Labels (1)
0 Kudos
6 Replies

760 Views
SimonMarsden_de
Contributor II
One other idea...

Are you sure that the memory at address 0x27FAC still contains the LINK instruction?

I have known some debuggers to show a disassembly based on what's in the object file, and not what's actually in memory. You could try actually dumping memory to check that the value is still 0x4E56_FFFC


Cheers


Simon
0 Kudos

760 Views
pnordby
Contributor I
Thanks for great feedback, Simon. "monitor ti" is, as you correctly assumed, single step an assembly instruction. Here is more relevant output:

(gdb) monitor rd
D0 : 00000000 00000000 00000030 00000006
D4 : 00000018 a661a87d c40f9216 56d33015
A0 : 401d0002 44035a4c 200000fc 401d0024
A4 : 1d047492 667d0fa0 00000000 20007ff0
PC : 00010022     SR : 00002704
(gdb) x /4w 0x20007ff0
0x20007ff0: 0x00000000  0x00000000  0x00000000  0x401d0002
(gdb) monitor ti
    Target state      : debug mode
    Debug entry cause : single step
    Current PC        : 0x00027fac
(gdb) monitor rd
D0 : 00000000 00000000 00000030 00000006
D4 : 00000018 a661a87d c40f9216 56d33015
A0 : 401d0002 44035a4c 200000fc 401d0024
A4 : 1d047492 667d0fa0 00000000 20007ff0
PC : 00027fac     SR : 00002704
(gdb) monitor ti
    Target state      : debug mode
    Debug entry cause : single step
    Current PC        : 0x00000466
(gdb) monitor rd
D0 : 00000000 00000000 00000030 00000006
D4 : 00000018 a661a87d c40f9216 56d33015
A0 : 401d0002 44035a4c 200000fc 401d0024
A4 : 1d047492 667d0fa0 00000000 20007fe8
PC : 00000466     SR : 00002704
(gdb) x /8w 0x20007fe0
0x20007fe0: 0x00000152  0x00000000  0x44082704  0x00027fac
0x20007ff0: 0x00000000  0x00000000  0x00000000  0x401d0002
(gdb) x /4w 0x27fa8
0x27fa8 <srand+16>: 0x4e750000  0x4e56fffc  0x2f02203c  0x00035550
(gdb) x /16w 0
0x0 <vector00>: 0x20008000  0x00000400  0x00000466  0x00000466
0x10 <vector04>: 0x00000466  0x00000466  0x00000466  0x00000466
0x20 <vector08>: 0x00000466  0x00000466  0x00000466  0x00000466
0x30 <vector0C>: 0x00000466  0x00000466  0x00000466  0x00000466
(gdb) monitor md 0 8
00000000 : 0x20008000    536903680   ...
00000004 : 0x00000400         1024  ....
00000008 : 0x00000466         1126  ...f
0000000c : 0x00000466         1126  ...f
00000010 : 0x00000466         1126  ...f
00000014 : 0x00000466         1126  ...f
00000018 : 0x00000466         1126  ...f
0000001c : 0x00000466         1126  ...f
(gdb) monitor md 0x27fa8 8
00027fa8 : 0x4e750000   1316290560  Nu..
00027fac : 0x4e56fffc   1314324476  NV..
00027fb0 : 0x2f02203c    788668476  /. <
00027fb4 : 0x00035550       218448  ..UP
00027fb8 : 0x0c802000    209723392  .. .
00027fbc : 0x0000672e        26414  ..g.
00027fc0 : 0x223c2000    574365696  "< .
00027fc4 : 0x04fc203c     83632188  .. <
(gdb) monitor md 0x20007fe0 8
20007fe0 : 0x00000152          338  ...R
20007fe4 : 0x00000000            0  ....
20007fe8 : 0x44082704   1141384964  D.'.
20007fec : 0x00027fac       163756  ....
20007ff0 : 0x00000000            0  ....
20007ff4 : 0x00000000            0  ....
20007ff8 : 0x00000000            0  ....
20007ffc : 0x401d0002   1075642370  @...
(gdb)

Exception decoding functions are not mapped to the vector table at this point (only a "default handler" containing a halt instruction). A minimalistic vector table in flash at adress 0 should be used. The C function I'm trying to run contains code to initialise a vector table in RAM and to set the VBR. I have no reason not to trust the "monitor md" output, as this was as expected when manually erasing flash blocks with the debugger (BDI2000). According to the stack, the exception should decode as follows:
  • format = 0100
  • fs = 0100 = error on instruction fetch
  • vector = 00000010 = access error
I also tried to insert a nop instruction before the jmp, to check if the exception was not related to the link, but the exception still occurred after single stepping the link.

...so I'm a bit lost again.
0 Kudos

760 Views
SimonMarsden_de
Contributor II
I'm puzzled.

Looks like the decrement of A7 was caused by pushing the 8-byte Exception Stack Frame, so ignore what I said about the LINK part-executing.

From what I understand, you've tried putting some NOPs at address 0x27FAC before the LINK, and you can successfully step these but get the exception when the LINK is reached. That would seem to rule out a lot of possible explanations to do with inaccesible memory. If the processor can fetch a NOP, why can't it fetch a LINK?

I can see no reason why the LINK instruction should cause an exception, since you have a valid stack pointer. I'm almost out of ideas, but here are a couple more:

Could this be some effect to do with the Cache - e.g. you're executing garbage out of the cache instead of the real LINK instruction?

Could this be some problem with the debugger? Have you tried running through the LINK instruction to try hitting a breakpoint beyond it?

I'm very interested to hear what you discover - Good Luck !


Cheers


Simon
0 Kudos

760 Views
pnordby
Contributor I
I tried to put nop before the jump.

When I moved the location of the C function, it suddenly worked! This made me examine the CFM, and now I added this assembly magic early in power-up:

    move.l #0x00000000,%d0        /* All flash memory can be used for data and instructions */
    move.l #0x401D0018,%a0        /* CFMDACC */
    move.l %d0,%a0@

...and then it all worked! Thanks for the support.
0 Kudos

760 Views
pnordby
Contributor I
Refer to this thread for a more complete picture of this problem.
0 Kudos

760 Views
SimonMarsden_de
Contributor II
Hi

I'm intrigued! I don't know the answer, but the following observation might help you figure it out.

Looking at the state of A6 and A7, they have the following values before the attempt to step through the instruction at 0x27fac:

A6 = 00000000
A7 = 20007FF0

After the step, they have the values:

A6 = 00000000
A7 = 20007FE8

The instruction you're trying to step through (assuming 'monitor ti' means 'step') is:

linkw %fp,#-4

...or in Freescale's standard mnemonics:

link.w  a6,#-4

The definition of this instruction states that it does the following:

A7 = A7 - 4
(A7) = A6
A6 = A7
A7 = A7 + (-4)

Looking at the before and after values, it appears that A7 is correctly decremented by 8, but A6 does not get the A7 value - it is still 0.

This makes me wonder if the attempt to save the old A6 value caused some sort of bus/access error and the instruction aborted. I don't have any suggestions why this should be, however.


Hope this gives you some new ideas


Simon


0 Kudos