Author Topic: Bootloader code & GNU Toolchain  (Read 14748 times)

Offline dkg

  • Newbie
  • *
  • Posts: 48
    • View Profile
Bootloader code & GNU Toolchain
« on: September 08, 2009, 08:41:13 PM »
These may be noobie questions but I am working on a 52259 implementation and trying to get the bootloader functional. I switched to v1.4 when it came out and I am using the GNU toolchain.

The first thing I see is that after the following comment line in /Applications/uTaskerBoot/uTaskerBootLoader.c there doesn't appear to be any code for the _M5223X configuration.
Quote
   // The boot loader has detected the uTasker application code so it will be started now

I would expect to see a line like
Quote
   start_application(UTASKER_APP_START);                                // jump to the application

So I put that line in.  

But then I looked at the code for the function start_application defined in mcf5223X_GNU_boot.s. This short assembler routine does not appear to be getting an argument off the stack but instead gets it from register D0. The code generated by the compiler for the call to start_application did a PEA 0x1000 before the subroutine jump so I think I would expect the routine to get the arg off the stack with something like 'move.l  4(%SP),%A0'.

Am I all wet with these questions? Has the bootloader been tested with the Coldfire processors? Is this something caused by using the GNU toolchain instead of CW? But I still don't see how any code is generated in the uTaskerBoot function to make the call to an existing application when _M5223X is defined.

Thanks for any help.

Dave G.
« Last Edit: September 08, 2009, 10:06:30 PM by dkg »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: Bootloader code
« Reply #1 on: September 08, 2009, 09:25:06 PM »
Hi Dave

I just checked and see that the development version has the following extra lines of code:

#elif defined _HW_AVR32 || (defined _M5223X && defined _GNU)             // {14}
    #ifndef _WINDOWS
    start_application(UTASKER_APP_START);                                // jump to the application
    #endif
#endif


This was added on
   25.07.2009 Use start_application() for M5223X and GCC                 {14}

As the comment states it was added for the GCC M522XX project. I am surprised that it is not in the V1.4 release because the change was probably made during last minute tests.
The fact is however that CW is the overwhelming Coldfire compiler used for the project and I expect that boot loader users do tend to use this (note that CW is also more or less the only way to program the Kirin3 too...).

Your analysis of the jump to the application does see spot on too. The code has been copied from Startup.s, which is used by Codewarrior. Codewarrior has been configured to pass arguments in registers and not on the stack (this is faster and produces small code size) but the GCC will probably pass on the stack and not D0.

So my only conclusion is that the boot loader really probably never has been used with GCC before!
Therefore I am sorry about this lapse in testing.
Perhaps you could add the move of the value from stack and verify that the jump to the application address then completes correctly (also the load of the SP). Maybe that is all that needs to be fixed (hopefully). If not I will have a go on my M52259DEM board too.

Regards

Mark




Offline dkg

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Bootloader code
« Reply #2 on: September 08, 2009, 10:05:30 PM »
I just checked and see that the development version has the following extra lines of code:

#elif defined _HW_AVR32 || (defined _M5223X && defined _GNU)             // {14}
    #ifndef _WINDOWS
    start_application(UTASKER_APP_START);                                // jump to the application
    #endif
#endif


This was added on
   25.07.2009 Use start_application() for M5223X and GCC                 {14}

As the comment states it was added for the GCC M522XX project. I am surprised that it is not in the V1.4 release because the change was probably made during last minute tests.
The fact is however that CW is the overwhelming Coldfire compiler used for the project and I expect that boot loader users do tend to use this (note that CW is also more or less the only way to program the Kirin3 too...).

Yeah, the line in the v1.4 release source doesn't have the second half of the elif ;)

I am curious about your last comment above. Do you mean it is the only way to program the flash? I am successfully using the GCC toolchain and Eclipse for development and debugging with hardware breakpoints. I am using a PE Micro BDM device for programming the flash and the CodeSourcery sprite works fine with that. I was using the TBLCF for a while but it was just too slow in programming the flash.

Your analysis of the jump to the application does see spot on too. The code has been copied from Startup.s, which is used by Codewarrior. Codewarrior has been configured to pass arguments in registers and not on the stack (this is faster and produces small code size) but the GCC will probably pass on the stack and not D0.

So my only conclusion is that the boot loader really probably never has been used with GCC before!
Therefore I am sorry about this lapse in testing.
Perhaps you could add the move of the value from stack and verify that the jump to the application address then completes correctly (also the load of the SP). Maybe that is all that needs to be fixed (hopefully). If not I will have a go on my M52259DEM board too.

I did fix the code in start_application and it does now successfully jump to the application code at 0x1000. However, I am now getting a strange behavior when trying to execute a line of code in mcf52235_init which looks like this:
Quote
    while (!(MCF_CLOCK_SYNSR & PLLOCKED)) { SIM_LOCK }                   // wait for PLL to lock

It appears the program goes off into the weeds (the PC is at 0xfffffffe). This isn't a problem when executing the same code in the non-bootmanager version. Still looking at this issue. Any help would be appreciated.

BTW, I also had a minor issue that RAM was only defined 32K in size (in the .ld files) when my processor has 64K. But when I modified it to use the full 64K of the 52259, I discovered the code in start_application would fail because the initial value for SP (also defined in the .ld files) was outside of RAM.

Now I am off to see if the GCC compiler can be configured to pass args through registers :)

Thanks for your quick response. I guess these weren't noobie questions after all  :D

Dave G.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: Bootloader code & GNU Toolchain
« Reply #3 on: September 08, 2009, 10:27:18 PM »
Hi Dave

The reason why I wrote about CW being typically used for programming is because the Freescale CF Flasher doesn't have a configuration of the Kirin3 (see http://forums.freescale.com/freescale/board/message?board.id=CFCOMM&thread.id=7650). I didn't think about the CodeSourcery support, which I haven't used.

while (!(MCF_CLOCK_SYNSR & PLLOCKED)) { SIM_LOCK }                   // wait for PLL to lock

This is surprising. The boot loader doesn't do anything with the PLL so it shouldn't be in any different state than after a normal start without it (?)

It is true that the linker script files are set up for 32k SRAM. The reason is that the smaller devices can have 32k and so the project is set up to be able to run on the smallest devices. If modified to suit the 64k SRAM the initial SP should be 0x10000. As soon as the stack is used the value should be decremented before saving anything and so be in internal SRAM - how was it failing?

Quote
I guess these weren't noobie questions after all
Not at all. The Coldfire project is generally very well tested but it really seems as though you are rather an exception with your environment and this has caught me out a bit. Hopefully you can (quickly) solve the remaining issues!

Regards

Mark

Offline dkg

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Bootloader code & GNU Toolchain
« Reply #4 on: September 08, 2009, 10:46:50 PM »
Hi Mark,

Sorry to be the exception ;)  I just didn't want to spend the money at this time for CodeWarrior tools and the application is expected to be bigger than the 128K limit of the free CW tools -- it already is when I turn off space optimization for debugging purposes.

I know the PLL problem doesn't make sense and I'll look at it more later this week -- who knows maybe it is a stack issue too  ???

I perfectly understand why your default project only uses 32K of RAM. Although, you do now have a MCF5225x specific .ld file (for USB memory) and I thought it probably should be set to 64K.

As for the SP initialization, when it was being initialized to 0x10000 the line of code in start_application that set the SP register would trigger an exception and the debugger reported that there was no writable memory at that location. This may be a debugger issue? Not being an expert in ColdFire architecture (yet), I wasn't sure if the SP is decremented before or after the write of the pushed value. Now that I looked it up, I believe it probably is a problem with the debugger attempting to peek at the contents of the stack or something to that effect. However, to avoid the issue I was willing to sacrifice 4 bytes at the top of the stack so I initialize the SP to 0xfffc for now.

Regards,
Dave G.

Offline dkg

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Bootloader code & GNU Toolchain
« Reply #5 on: September 14, 2009, 04:24:27 PM »
Hey Mark,

I am back to work on this issue and I finally found the problem with the PLL code. But I am not certain of the reasons for the failure based on what I found  ???

The problem boils down to the symbol __FLASH being set by the linker to 0x1000 and used by the application startup code to set FLASHBAR. Of course, flash really starts at 0x0000 but it was apparently unintentionally set to 0x1000 when the rest of the application was relocated to make space for the bootloader code.

But, when FLASHBAR was set improperly, the line that sets the clock SYNCR results in an error exception. I still don't know why the setting of FLASHBAR improperly would affect the clock operation.

BTW, I was wondering if we really should be running through the startup code on the application since that is already done by the bootloader startup. Just a thought ;)

Dave G.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: Bootloader code & GNU Toolchain
« Reply #6 on: September 14, 2009, 05:46:41 PM »
Hi Dave

This is a bit unfortunate since this is a problem which was discussed here:

http://www.utasker.com/forum/index.php?topic=654.msg2830#msg2830

The thread explains everything in some detail so no point me adding anything here apart from the fact that I didn't think of it in relation to the PLL in any way, otherwise I may have realised what was going on without you needing to do more investigation. Sorry.

Regards

Mark

Offline dkg

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Bootloader code & GNU Toolchain
« Reply #7 on: September 14, 2009, 06:16:21 PM »
Hi Mark,

I remember seeing that thread when it first started but never followed it to the conclusion that there was an issue in the startup code for FLASHBAR :(  I wasn't worried about USB operation at the time ;)

Is there a way to access the "development code" that you have made changes to (like CVS or SVN?) or is that something internal to your operation and we don't get to see it until a service pack is released?  I am just wondering if there are other fixes I can check out before I investigate them ;)

Dave G.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: Bootloader code & GNU Toolchain
« Reply #8 on: September 14, 2009, 07:24:30 PM »
Hi Dave

Usually there is a patch thread which can be monitored before SPs are available.
So, I added one with the issues that have been reported since the release: http://www.utasker.com/forum/index.php?topic=644.msg2954#msg2954
Due to various new developments in progress and the risk of incompatibilities if made available too regularly there is no other access to these. Since this is the only known issue I didn't think that it merited a new SP just yet, but it may have been better to create the patch list immediately.

Regards

Mark


Offline dkg

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Bootloader code & GNU Toolchain
« Reply #9 on: September 14, 2009, 07:35:58 PM »
Hi Mark,

Thanks.

But you might want to add two other patches that are a result of the problems I found.

First there is the missing conditional in uTaskerBootLoader.c that will provide the call to start_application in the GNU Bootloader code:
Code: [Select]
#elif defined _HW_AVR32
to
Code: [Select]
#elif defined _HW_AVR32 || (defined _M5223X && defined _GNU)             // {14}

Second, the start_application assembler code for GNU needs to get the argument off the stack instead of via a register:
Change
Code: [Select]
   move.l  %D0,%A0                             /* load SP and the PC and let application continue... */
to
Code: [Select]
   move.l  4(%SP),%A0                         /* load SP and the PC and let application continue... */
in mcf5223X_GNU_boot.s.

Dave G.
« Last Edit: September 14, 2009, 08:50:58 PM by dkg »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: Bootloader code & GNU Toolchain
« Reply #10 on: September 14, 2009, 08:41:46 PM »
Hi Dave

Yes, you are right - I forgot these and will also make them in my development version.

Thanks

Regards

Mark

Offline dkg

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Bootloader code & GNU Toolchain
« Reply #11 on: September 15, 2009, 03:14:06 PM »
Hi Mark,

As a follow-up to these changes there is another one that is important. I had forgotten that when I first built the startup code I noticed the padding at the end of Startup_gnu.s and mcf5223X_GNU_boot.s was wrong. And once I corrected the other issues in the startup code, it needed to change again.

So here is the change I made to make sure our code does not overlap the CFM configuration field (why in the world did they decide to put hardware config registers in the middle of flash memory space anyway?) And, I changed the syntax of the padding statements to make it easier to see what we are doing (at least to me ;))

Change:
Code: [Select]
* 0x98..fill out with zeros - add general purpose assember in this space if required */
    .rept 256-45
    .long 0x00000000 /* fill unused area */
    .endr
/* 0x400..0x417 is used to configure FLASH controller on initialisation */

.rept 265-257
.long 0x00000000 /* flash initialisation range - must be zero */
.endr
to
Code: [Select]
/* 0xa6..fill out with zeros - add general purpose assember in this space if required */
.rept 0x400-0xa6
.byte 0x00 /* fill unused area */
.endr

/* 0x400..0x417 is used to configure FLASH controller on initialisation */
.rept 0x18
.byte 0x00 /* flash initialisation range - must be zero */
.endr