Illegal Instruction on MCF52235

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

Illegal Instruction on MCF52235

2,875 Views
FredT
Contributor II
Hi there, I'm having a "Illegal instruction" on the following function.

int decode_unsigned32(const uint8_t * apdu, uint32_t * value) {
    if (value) {
        *value = ((uint32_t)((((uint32_t)apdu[0]) << 24) & 0xff000000));
        *value |= ((uint32_t)((((uint32_t)apdu[1]) << 16) & 0x00ff0000));
        *value |= ((uint32_t)((((uint32_t)apdu[2]) << 8) & 0x0000ff00));
        *value |= ((uint32_t)(((uint32_t)apdu[3]) & 0x000000ff));
    }

    return 4;
}

The problem is that I'm having the "Illegal instruction", I'm changing part of the code that have nothing to do with this function (like removing a printf function in another function), and the problem is gone, but when I'm changing some printing code elsewhere, the problem come back. When I'm looking at the assembler instruction that cause de problem, it's not always the same instruction, but always is this function.

FredT
Labels (1)
0 Kudos
8 Replies

659 Views
admin
Specialist II
Did you check the errata?
See section 'Internal Flash Speculation Address Qualification Incomplete'.
It could be something else, of course. But I have experienced this.
0 Kudos

659 Views
FredT
Contributor II
You're the man, man ! Seems like somthing like this:

apdu pointer address = 0x200031ed
Illegal instruction -- PC = 0X0031E8

Thank you for the info.

FredT
0 Kudos

659 Views
FredT
Contributor II
I'm trying to apply the Workaround 2 for the address speculation mechanism Errata but I can't get my program to work. Here's what my .lcf file was:

# Memory ranges   

MEMORY {
   vectorrom   (RX)  : ORIGIN = 0x00000000, LENGTH = 0x00000400
   cfmprotrom  (RX)  : ORIGIN = 0x00000400, LENGTH = 0x00000020  
   code        (RX)  : ORIGIN = 0x00000500, LENGTH = 0x0003FB00
   vectorram   (RWX) : ORIGIN = 0x20000000, LENGTH = 0x00000400
   userram     (RWX) : ORIGIN = 0x20000400, LENGTH = 0x00007C00
}     

Here are the change:
# Memory ranges   

MEMORY {
   vectorrom   (RX)  : ORIGIN = 0x00000000, LENGTH = 0x00000400
   cfmprotrom  (RX)  : ORIGIN = 0x00000400, LENGTH = 0x00000020  
   code        (RX)  : ORIGIN = 0x00000500, LENGTH = 0x00037B00
   vectorram   (RWX) : ORIGIN = 0x20038000, LENGTH = 0x00000400
   userram     (RWX) : ORIGIN = 0x20038400, LENGTH = 0x00007C00
}     

The program doesn't work and I have a "Bus Error" when in debug. I guess it's because I have no RAM at 0x20038000. Where am I suppose to change the RAM base address. I have also tried to change only the RAMBAR address, but still the same result.

# 32 Kbytes Internal SRAM
#   ___RAMBAR         = 0x20000000;
   ___RAMBAR         = 0x20038000;
   ___RAMBAR_SIZE    = 0x00008000;

# 256 KByte Internal Flash Memory
   ___FLASHBAR       = 0x00000000;
#   ___FLASHBAR_SIZE  = 0x00040000;
   ___FLASHBAR_SIZE  = 0x00038000;

Thank for the help.

Fred
0 Kudos

659 Views
admin
Specialist II
Just had a look at MCU initialization code that comes with Codewarrior. It appears there are 2 places where RAMBAR is initialized: one in support_common.h (MEMORY_INIT macro), the other in MCF5223*.cfg (debugger initialization script). You don't need the second one unless you are using the debugger. But you probably are using it, so you need to fix that script too.
By the way, there is also the SCM_RAMBAR register. If you are not planning to use DMA, ignore it. But if you are, you should know that it can only be set at a 64K boundary (unlike the CPU RAMBAR register.) So that workaround #2 can complicate other matters too.
As for me, I used workaround #1.
0 Kudos

659 Views
FredT
Contributor II
I'm trying to disable the address speculation mechanism, but it's said in the reference manual that the address of the FLASHBAR register is CPU + 0xC04.

What do they mean by CPU ? Where can I find this value ?

Fred
0 Kudos

659 Views
admin
Specialist II
address of the FLASHBAR register is CPU + 0xC04

It means that the register is accessed with the MOVEC instruction. You don't need to know 0xC04, the assembler knows the address. Instead, you would write something like this:
MOVEC D0, FLASHBAR


Look for the function __initialize_hardware(). I think FLASHBAR initialization, including the extra bits, is there.
0 Kudos

659 Views
taigbr
Contributor I
Hi,

maybe I am wrong, but a good way to get illegal instructions is to omit
some parameters when calling a function or using a value instead of
a pointer.
Something like:
error =  decode_unsigned32(&bytevalue);
error =  decode_unsigned32(&byte,value);
Whatever was left on the stack will be taken as pointer to value and
if you are lucky it will eat up your stack and return to somewhere.
Regards, Georg

0 Kudos

659 Views
mjbcswitzerland
Specialist V
Hi

In the assembler start up code you can use the following to disable the Internal Flash Speculation Address Qualification (using method 1):

move.l  #0x161,d0   /* workaround 1 due to the Internal FLASH Speculation error in the first devices */
movec   d0,RAMBAR0


I never used method 2 since it is rather restrictive for devices with small memory footprints. See:
http://forums.freescale.com/freescale/board/message?board.id=CFCOMM&message.id=1420&query.id=13482#M...


Regards

Mark

www.uTasker.com




0 Kudos