Jump not executed (after taskswitch)

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi
I have implemented a taskswitcher for Ap7000. Since i have the MMU under my control, i try to start applications from 0x1100000 (Program), 0x11100000 (Stack) and 0x11300000 (Heap).

"Simple" programs run perfectly. But "normal" show >interesting< behavior... :-/
Here is test code:

11000000:	e0 61 30 39 	mov	r1,12345
11000004:	e0 60 56 ce 	mov	r0,22222
11000008:	e0 61 30 39 	mov	r1,12345
1100000c:	e0 60 56 ce 	mov	r0,22222
11000010:	e0 61 30 39 	mov	r1,12345
11000014:	e0 60 56 ce 	mov	r0,22222
11000018:	e0 61 30 39 	mov	r1,12345
1100001c:	d7 03       	nop
1100001e:	e0 8f 00 0b 	bral	11000034 <_start>
11000022:	d7 03       	nop
11000024:	d7 03       	nop
11000026:	e0 70 27 23 	mov	r0,75555
1100002a:	e0 71 02 ae 	mov	r1,66222
1100002e:	d7 03       	nop
11000030:	d7 03       	nop

Disassembly of section .reset:
11000034 <_start>:
11000034:	48 1f       	lddpc	pc,11000038 <_start+0x4>
11000036:	00 00       	add	r0,r0
11000038:	11 00       	ld.w	r0,r8++	<<<<<<<<<<<<<<<
1100003a:	00 58       	eor	r8,r0

Disassembly of section .init:
1100003c <_init>:
1100003c:	eb cd 40 40 	pushm	r6,lr
11000040:	48 26       	lddpc	r6,11000048 <_init+0xc>
11000042:	1e 26       	rsub	r6,pc
...

I have inserted code before the C++ startup lib. I write some values to r0 and r1, to test if the code executes. Yes - it does.I change the values after the jump to check if it jumps - Yes it does.
BUT: lddpc pc,11000038 is pure evil.
This instruction does not jump. the "add r0, r0" instruction is executed and the following instruction causes a tlb-miss because due to r8 is initialized with 0.
Its is a verry interesting behavior.. that add r0, r0 is executed is shown through the content of r0. When the tlb-miss exception executed r0 is 44444 (= 22222+222222)

The code is executed from:

void CTaskSwitcher::StartMultiTasking()
{
	//Get first Task
	TaskID = 0;
	STaskDesc* Desc = &Tasks[0];
	//Set "rets" destination
	__builtin_mtsr(AVR32_RAR_SUP, Desc->Registers.pc/*0x11000000 at this time*/);
    __builtin_mtsr(AVR32_RSR_SUP, Desc->Registers.sr/*0 at this time*/);
    //Set some SysRegs (unused JavaStuff) to identify  the running task during runtime
    __builtin_mtsr(TASK_STRUCT_PTR_SYSREG, (int)Desc);
	__builtin_mtsr(TASK_SUPCALL_PTR_SYSREG, (int)Desc->Sup_Call.data);
	//Initialize the mmu for this Task
	mmu.SetupMMUForTask(Desc);
//---------Setup TaskSwitch time
	PrepareNextTaskSwitchTime(20); //20 Ticks
	AVR32_TC0.channel[0].ccr = AVR32_TC_SWTRG_MASK | AVR32_TC_CLKEN_MASK; //Start the timer
    interrupt.EnableInterrupts();
    
    //I am Helpless: Disabling ALL  stuff that can cause this error:
    //Invalidate the BranchTable
    __builtin_mtsr(AVR32_CPUCR, __builtin_mfsr(AVR32_CPUCR) | AVR32_CPUCR_BI_MASK);
    //Disable Branch folding
    __builtin_mtsr(AVR32_CPUCR, __builtin_mfsr(AVR32_CPUCR)& ~AVR32_CPUCR_FE_MASK);
    //Disable Branchprediction
    __builtin_mtsr(AVR32_CPUCR, __builtin_mfsr(AVR32_CPUCR)& ~AVR32_CPUCR_BE_MASK);
    //Disable the use of returnstack
    __builtin_mtsr(AVR32_CPUCR, __builtin_mfsr(AVR32_CPUCR)& ~AVR32_CPUCR_RE_MASK);
//Enable the MMU-Paging
    __builtin_mtsr(AVR32_MMUCR, AVR32_MMUCR_S_MASK | AVR32_MMUCR_E_MASK);
    //Again helpless. Invalidate all caches.
    __builtin_cache(0, AVR32_ICACHE_FLUSH_ALL);
    __builtin_cache(0, AVR32_DCACHE_FLUSH_CLEAN_INV_ALL);

Followed by some ldmts instructions and then rets.
(Forum does not let me post this inline asm instructions :-( )

Does someone has some ideas that could cause this instruction not to jump?

Please help :-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

WOW. I have moved the physical Memorylocation so that virtual adresses match physical adresses. So i can disable paging and debugged the application via instruction stepping!
the Disassembler showes an amzing result:

0x1100000c mov           r0,22222
0x11000010 mov           r1,12345
0x11000014 mov           r0,22222
0x11000018 mov           r1,12345
0x1100001c nop           
0x1100001e bral          0x11000034
0x11000022 nop           
0x11000024 nop           
0x11000026 mov           r0,75555
0x1100002a mov           r1,66222
0x1100002e nop           
0x11000030 nop           
0x11000032 lddpc         pc,0x11000034
0x11000034 add           r0,r0
0x11000036 ld.w          r0,r8++
0x11000038 eor           r8,r0

You can clearly see that the "bral"-Instruction does not jump to the right location.

IS THAT A LINKER ERROR?

A closer look to the disassembling of the ELF:

1100002e:   d7 03          nop
11000030:   d7 03          nop

Disassembly of section .reset:
11000034 <_start>:
11000034:   48 1f          lddpc   pc,11000038 <_start+0x4> 

between the not at 0x..30 and the lddpc at 0x..34 are 4 bytes. 2 bytes are used for the nop. 2 bytes are free then the .reset section begins - it seem that the linker does not check this. 2 bytes free is nonsense. :-/

To solve this i can insert an other 16bit-instruction. Then its works.

But still, with enabled paging the JTAG crashes when executing the program. Without JTAG the Tasks are running well.
What is going on? :-O