mcf5282, Line-f exception

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

mcf5282, Line-f exception

2,901 Views
_angelo_
Contributor III

Hi experts,

trying to revive an old mcf5282 dev board i have here, 

by bdm i am:

- initializing rambar to  0x20000221
- loading code into sram,
- executing (step or run) 
- after the execution jumps from _start to _main,  the first lea instruction causes a line-f exception

 

 

20000a7a <__main>:
20000a7a: 4fef ffd8 lea %sp@(-40),%sp
20000a7e: 48d7 7c7c moveml %d2-%d6/%a2-%fp,%sp@
20000a82: 4eb9 2000 08e0 jsr 200008e0 <system_init>

 

 

What i see at the exception is:
- sp is 0x40c02700
- memory read at opcode is correct, 4fefffd8 so shouldn'0t be a line-f

If i put a lea %sp@(-40), %sp  somewhere after _start, i.e. @ 0x@2000043a it get executed without any issue. 
Could it be that the cpu SRAM is damaged on a certain address range as near 0x20000a7a ?

thanks

0 Kudos
Reply
13 Replies

1,751 Views
_angelo_
Contributor III

So, i could be able to have my recover firmware running, to re-flash u-boot. The above start.S is from a small < 64k tool to flash the first loader as u-boot, running through the universal multilink pod.

Solution was moving some code here and there, and the lea instruction was not giving line-f anymore,.

Couldn't still find the real issue, apart suspecting on issues with code sections, or compliers.

I am attaching my linker script in case.

 

 

0 Kudos
Reply

1,764 Views
_angelo_
Contributor III

No., curiously issues came back.

It may happen depending on the toolchain used.

Using:

GCC_EXEC_PREFIX=/opt/toolchains/m68k/gcc-13.2.0-nolibc/m68k-linux/bin/m68k-linux-

produces

20000a22: 4fef ffd8 lea %sp@(-40),%sp     got line-f opcode

Using 

/opt/toolchains/m68k/m68k-sysam-uclinux-uclibc/bin/m68k-sysam-uclinux-uclibc-

produces

2000057e: 2039 4000 0048 movel 40000048 <_stack_start+0x1fff0048>,%d0   (got invalid instruction opcode)

 

Actually compiling with

/opt/toolchains/m68k/gcc-13.2.0-nolibc/m68k-linux/bin/m68k-linux-gcc -pipe -mcpu=5282 -m528x -DCONFIG_MCF5282 -fno-builtin -O2 -ffreestanding -nostdlib -ffunction-sections -fdata-sections -ffixed-d7 -Iinclude  -c -o obj/start.o src/start.S

 

Could anyone provide me a link for a known working toolchain for mcf5282 ?

0 Kudos
Reply

1,736 Views
TomE
Specialist II

I don't think the toolchain has anything to do with it. If they're generating legal instructions that you can decode and compare with the CPU's instructions, then they're fine.

I would suggest not setting the stack pointer at the end of the BSS, but hard-coding it to the top of the SRAM, from 0x2000fffc. Technically I think you can initialise it to 0x20010000, but I always go one 32-bit word lower. Make sure your stack pointer is always four-byte aligned.

If the CPU is giving F-Line exceptions it means the core has fetched an instruction and has read 0xFnnn. That's a floating point opcode. If the CPU doesn't have a floating point processor it takes this exception so they can be emulated.

Likewise, if it reads something "illegal" it will throw an illegal opcode exception, like you're also getting.

The fact that you can read the SRAM and not read these bad values doesn't matter, Somehow the CPU is reading these bad values. The most likely thing is a timing problem (CPU running too fast, bus clocks messed up) and is reading faster than the SRAM can supply the data, or you've got two things on the bus responding at the same time and colliding.

As noted, you might have FLASHBAR and RAMBAR overlapping. FLASHBAR is set up from by the CCM. That depends on RCON and D26/D17/D16. If you don't have an explicit RCON-controlled driver on your board, or pullups or pulldowns on all of the data bus pins read by the CCM at reset, then your CPU might start up somewhat "random". FLASHBAR should default to zero (decoded at zero where the CPU starts executing), but the "Valid" bit should only be set if the CPU starts up in "Single Chip Mode". Read the RCON register from the debugger and see what it start up as (the MODE bit).

You're using a debugger to load code into the onboard SRAM. There's a "debug CPU setup script or file" somewhere there. That automatically runs to initialise various CPU and peripheral registers to get the CPU in a state where it can "just run". This usually contains commands to set up the clock and address decoders. The reason for this is to get you up and running quickly, especially if you want to load your code into EXTERNAL Ram, as the controller and address decoders have to be set up before that can work. Eventually (later in development) you change your code to be Flash-based, and the first thing it has to do is set up all the registers the way that file does (translated to your run-from-FLASH setup).

Check how RCON and the CLKMOD bits are driven on your board. And D16-19, D21, D24-26. They determine the reset configuration. Check the debugger start script in case it writes to FLASHBAR or something else. Try to explain every single register write in this file. Start the CPU on a slower clock (external clock, no PLL) and see if things change.


Tom

 

0 Kudos
Reply

1,764 Views
_angelo_
Contributor III

Thanks, ok, good to know. I was probably confusing with 5280.

0 Kudos
Reply

1,786 Views
_angelo_
Contributor III

Solved this too, CS was there but not visible with the scope due to wrong horiz scale

Proceeding to get this board running: =). Thanks again.

0 Kudos
Reply

1,785 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Nice to hear the issue had been resoved.

MCF5282 has internal 512KB Flash memory, which is called CFM (ColdFire Flash Module). Detialed info at MCF5282 user manual chapter 6.

I attached below M5282EVK board memory map for your reference:

Hui_Ma_0-1739780794950.png

 

0 Kudos
Reply

1,787 Views
_angelo_
Contributor III

Hi Tom and all,

thanks all for the help

I finally had the time (and the need) to go back on this. 
I could move forward, one issue seems was caused by setting FLASHBAR,
this register is intended for the internal flash base address, but 5282 does not
have any internal flash. Setting it, especially executing with the BDM debugger,
(not sure if it does any difference), was causing next line-f issues.

Anyway, now i am stuck in another issue, i don't see any CS0 toggling accessing
the external flash

void init_parallel_flash(void)
{
	struct cs_regs *cs0 = (struct cs_regs *)CSAR0;

	/* setup CS0 for the flash */
	out_be16(&cs0->csar, CONFIG_SYS_FLASH_BASE >> 16);
	out_be16(&cs0->cscr, CS_CSCR_WS(6) | CS_CSCR_AA | CS_CSCR_PS16);
	out_be32(&cs0->csmr, (CONFIG_SYS_FLASH_MASK + 1));

	baseaddress = (volatile u16 *)CONFIG_SYS_FLASH_BASE;

	flash_reset();
}

 

if i set a loop inside flash_reset(), between 0xAA and 0x55 writes, i see the data bus
toggling but CS0 is always high.

Working on this.

thanks,
regards

angelo

 

 

0 Kudos
Reply

2,842 Views
_angelo_
Contributor III

Thanks Tom,

 

this is what i see at exception time

 

 

pc: 2000046e
§ regs
d0 00000000 d1 200018ac d2 40422233 d3 2050c049
d4 40100100 d5 18409118 d6 94180154 d7 21105083
a0 20000a8a a1 20001794 a2 2000fffc a3 02186440
a4 35a7b4b0 a5 2bcec1ba a6 2000fff4 a7 2000ffe8
pc 2000046e sr 40c02700 fp 2000fff4 sp 2000ffe8
rambar 20000001
vbr    200000c0
§ read mem.l 0x2000ffe8
402c2700
§ read mem.l 0x2000ffec
20000a8a
§ 

 

What i can see is:
FORMAT: 0100   
F-S: 0000
VEC 1011 (11)

SP + 4 shows 0x20000a8a

At that address i see the LEA opcode: 

 

§ read mem.l 0x20000a8a
4fefffd8

 

 

So all seems to be correct, the only nonsense is the line-f exception 

 

 

0 Kudos
Reply

2,822 Views
TomE
Specialist II

It would be better to provide more information. You haven't showed what your #defines are. It would be easier to check the startup code if it was a disassembly, showing the opcodes and data, and not just the source. That would show me your definitions.

A stack dump (all the hex data around the stack pointer) would help.

I notice a few anomalies that are worth investigating:

 

 

vbr    200000c0

 

 

The bottom bits are meant to be zero. They're specified as "not implemented, assumed to be zero, documented as read-as-zero", but the documentation has been wrong before.

 

 

	move.l  #_sbss, %a1
	move.l  #_ebss, %d1
6:
	clr.l   (%a1)+
	cmp.l   %a1,%d1
	bgt.s   6b

 

 

After executing the above, %a1 and %d1 should have the same value, but it looks like %a1 didn't increment, or didn't increment more than once.

 

 

d0 00000000 d1 200018ac d2 40422233 d3 2050c049
d4 40100100 d5 18409118 d6 94180154 d7 21105083
a0 20000a8a a1 20001794 a2 2000fffc a3 02186440

 

 

They don't have the same values. I can't check any further as I don't know what _sbss and _ebss were meant to start out as. Maybe you have the comparison arguments reversed?

"cmp" on the 68k was always problematic. The SunOS compiler writers didn't like "compare src, dst" and preferred the PDP-11 "compare dst, src" as it made the  conditional branches read better. So they reversed the order in the COMPILER, and some compilers might still do that to this day. Whatever - there's something wrong there. Can you single-step part of that loop to see why it isn't working?

I'd suggest ZEROING all the registers you're not using so that when you crash or stop you can spot anything unusual in their (unexpected) contents. You can also load constants into registers as your code runs so you can prove it executed particular instructions.

Also:

 

 

pc 2000046e

 

 

How did it end up THERE? What is there? What are your vectors set to (they should all be set to something that will stop cleanly)? The Vectors go up to 0x200003FC, so that's above that area.

Maybe the debugger and pod are doing something funny. Maybe it is using trace interrupts and the trace vector or a debug vector. Maybe it is rewriting the code (some debuggers replace the next instruction with a "halt" before running and then replace it after the halt to simulate a single-step).

If you can, single step this stuff. That can cause problems, so emulate single-stepping by putting breakpoints "ahead of yourself" and letting the code run into them.

Then start messing around. Replace the code at _main with a bunch of NOPs. See if it fails on the first instruction, or whether that instruction has to be the LEA. Move the code around. Realign it. Change the jsr to main to a jmp. Move stuff to the stack and read it back again. Just change things until the symptoms change, then chase those.

Tom

 

0 Kudos
Reply

2,858 Views
_angelo_
Contributor III

Hi Tom and Mark, thanks for the support.

I afraid this cpu is damaged, even if it would be very strange.

This is the brief init code i am running loading stuff by BDM, after rambar init now at 0x20000001

_start:
	nop
	nop
	move.w	#0x2700, %sr

	/*
	 * At reset IPSBAR is set to 0x40000000
	 * IPSBAR + 0 = IPSBAR
	 * IPSBAR + 8 = RAMBAR
	 */
	move.l  #(CONFIG_IPSBAR + 1), %d0
	move.l  %d0, 0x40000000

	/* setting RAMBAR always to iternal sram start */
	/* move.l	#(CONFIG_INIT_RAM_ADDR + 0x221), %d0 */
	move.l	#(CONFIG_INIT_RAM_ADDR + 0x1), %d0
	movec	%d0, %rambar
	/* second rambar */
	move.l	%d0, 0x40000008

	/* vector table from sram */
	move.l	#0x20000000, %d0
	movec	%d0, %vbr

	move.l	#(CONFIG_SYS_FLASH_BASE + 0x21), %d0
	movec	%d0, %FLASHBAR

	/* initialize general use internal ram */
	move.l	#0, %d0
	move.l	#(ICACHE_STATUS), %a1
	move.l	#(DCACHE_STATUS), %a2
	move.l	%d0, (%a1)
	move.l	%d0, (%a2)

	/* set stackpointer to end of internal ram to get some stackspace for
	   the first c-code */
	move.l	#(CONFIG_INIT_RAM_ADDR + CONFIG_INIT_RAM_SIZE - 8), %sp

	 /* prepare stack and frame-pointers */
	move.l  %sp, -(%sp)
	move.l  %sp, %fp

	/* Now clear BSS segment in sram
	 */
	move.l  #_sbss, %a1
	move.l  #_ebss, %d1
6:
	clr.l   (%a1)+
	cmp.l   %a1,%d1
	bgt.s   6b

	move.l	#__main, %a0
	jsr	(%a0)

 

Then code at main

20000a8a <__main>:
20000a8a:       4fef ffd8       lea %sp@(-40),%sp
20000a8e:       48d7 7c7c       moveml %d2-%d6/%a2-%fp,%sp@

it's really strange a line-f exception, this is why i suspect in some hw issue.

Board is that mcf5282evb rev 1.1 from DigitalDNA

0 Kudos
Reply

2,854 Views
TomE
Specialist II

You don't need to write to the Core RAMBAR again. But I guess this code is meant to also run in Flash, in which case it does need to do that.

The value written to the second RAMBAR is slightly wrong. It doesn't have a "Valid" bit. It should matter (bits are "reserved, should be zero). The second RAMBAR is only needed to be set up for DMA access to the SRAM to work.

If your code is getting all the way to the call to _main, then pretty much everything is working.

Do you have vectors set up? Do you have vectors set up to trap the exceptions? Or is the BDM debugger helpfully set up to trap the exceptions for you and tell you what happened? Even if it is doing that, the CPU should have stored an Exception Frame.

If you can get the F-Line Exception to fully trigger, then it writes a detailed exception frame on the stack. This is detailed in section 2.3.3.1. Decode it or post the stack frame.

The Reference Manual details the frame, but not very well and not well enough to decode it. Get the "Coldfire Family Programmer's Reference Manual" (usually "CFPRM.pdf"). Read the "Exception Processing" chapter.

"F Line" means an illegal instruction with all-ones in the top four bits. Somehow the CPU is fetching that. From somewhere. Possibly not from where you think it was. Make sure you scatter breakpoints ahead of where you think the code is going in case it gets away from you.

The CPU isn't broken. It's executing a lot of code OK. You're also running all this code within the CPU, so the rest of the dev board doesn't matter. As long as the CPU has power and a clock it'll run.

Good luck

Tom

 

0 Kudos
Reply

2,870 Views
TomE
Specialist II
Mike is right. You RAMBAR setup is disabling User Data and CPU Space access to the SRAM. But I don't think that's your problem. The LEA instruction is accessing the Stack, but nowhere in your post do you say you initialised the Stack Pointer. You need to set the SP to somewhere in SRAM, usually at the top (0x2000FFFE for 64k SRAM).
0 Kudos
Reply

2,874 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

Could you try to initializating set RAMBAR = 0x20000001?

Then could ou check if there still has this line-f exception.

Mike

0 Kudos
Reply