Hi,
My project uses an MCF52230. I'm getting an Access Error Exception (vector = 2), I can't understand why this exception is being generated. Here is the ColdWarrior disassembly of the relevant code:
CALLING FUNCTION:
...
; 347: memset(buf, 0, size);
0x0000002A 0x2F470008 move.l d7,8(a7)
0x0000002E 0x42AF0004 clr.l 4(a7)
0x00000032 0x2E8C move.l a4,(a7)
0x00000034 0x4EB900000000 jsr _memset
CALLED FUNCTION:
; 409: void *memset (void *s, int c, unsigned n)
0x00000000 _memset:
0x00000000 0x4E560000 link a6,#0
0x00000004 0x2F0C move.l a4,-(a7)
0x00000006 0x286E0008 movea.l 8(a6),a4
0x0000000A 0x242E000C move.l 12(a6),d2
0x0000000E 0x222E0010 move.l 16(a6),d1 <<<==== Access Exception Reported Here
; 412: unsigned char *sp = (unsigned char *)s;
0x00000012 0x204C movea.l a4,a0
So what's happening is that the calling function (line 347) pushes three arguments on the stack and then does a JSR to memset(). memset immediately loads all three parameters from the stack into registers. The Access Error Exception is occuring on the "move.l 16(a6),d1", which is loading the third parameter ("n") into register D1. The fault status indicates an Operand Read access error, but I don't understand why. I set a breakpoint at the beginning of the exception handler and confirmed that the value in A6 at the time of the exception is valid; when I look at the stack all the memory locations are exactly what I would expect them to be; the registers A4 and D2 have been loaded with the appropriate arguments from the stack, while D1 has not (makes sense, since the exception is being reported on this instruction).
Memset is called dozens of times before this particular instance fails, many times from the same caller as in this instance. Worse, almost any change to the program will cause the exception to not happen. For example, I inserted a statement incrementing an otherwise unused global variable at the beginning of memset(); this compiled to an "addq.l #1,_globalvar" being generated at offset 0x6 (just before the movea.l). But with this change, I no longer get the access exception. I can put the assigment in another function entirely and that also has the same effect! So somehow just changing the code layout in FLASH affects the error.
I read the ColdFire RM and the 52235RM carefully, but neither provide specifics on what conditions result in an Access Error Exception being generated, and nothing that directly relates to what is happening in this code. So I suspect the actual bug has nothing to do with memset(); but somehow it is manifesting in this error showing up here. This is the most "tangible", reproducible lead I have on the problem. Any suggestions as to what could cause the processor to generate this exception, or what else I should be looking for?
Thanks,
Scott
Read the section "3.3.4.1 Access Error Exception" in the Reference Manual.
The relevant part is probably the bit where it says "The V2 ColdFire processor uses an imprecise reporting mechanism for access errors on operand writes. Because the actual write cycle may be decoupled from the processor’s issuing of the operation, the signaling of an access error appears to be decoupled from the instruction that generated the write.
Accordingly, the PC contained in the exception stack frame merely represents the location in the program when the access error was signaled."
So you might be getting a WRITE exception caused by "move.l a4,-(a7)" but reported later.
Search the Reference Manual for all instances of "Access Error".
What is the "Fault Status" encoding in the Exception Stack Frame? That will give more information on the problem. What is the stacked Status Register?
Check the Stack Pointer is aligned properly.
The CPU might not be getting the same instructions from the FLASH that you are reading. Try changing the CPU Clock speed and/or any settings that control the FLASH access speed. Try turning Speculation on and off. At least on this chip you don't have to worry about the Cache getting out of sync with main memory.
Make sure nothing has corrupted the FLASHBAR or RAMBAR registers, specifically the Address Space Mask bits.
While I've been writing this, someone has suggested checking for the Speculation Fault Errata. Very good suggestion.
Tom
Hi
There is a guide to debugging exceptions here, which may uncover something not seen when stepping into the exception:
http://www.utasker.com/forum/index.php?topic=123.msg468#msg468
Regards
Mark
Hi
Are you using an 'older' chip which hasn't solved the Flash Speculation Errata?
If this is the case apply the workaround according to the errata since this could cause seemingly random exceptions (although I never actually experienced one before applying the errata some 5 years ago).
Regards
Mark