Maoz Ohad

Instruction pipeline issue

Discussion created by Maoz Ohad on Aug 1, 2011
Latest reply on Aug 3, 2011 by Maoz Ohad

A pipeline issue  in K10?

I think I am seeing a strange pipeline issues.

I have a code running fine , I’ve added an initialize instruction before a function call , and I’ve got an interrupt because “ the chip tried to fetch a command from a non executable location”

The problem existed no matter which variable I am initializing.

I’ve traced the source of the unhandled interrupt to be not the instruction itself, but its location in memory.

See below “good” and “bad” code

I think it is a pipeline issue, as I was able to get rid of the problem by adding a NOP instruction before the problematic instruction or by moving the code a few bytes in memory

I’ve looked at Freescale and ARM datasheet , and the only thing I could find is that the pipeline is 6 word (32bit) long so it can contain up to 3 32 bit instructions or up to 6 16 bit instructions. I couldn’t find a way to tell the hardware to use a pipeline with only 1 or 2 words instead of 3,

Has anyone seen that problem before and have a better solution? , I don’t like the idea of adding NOPs , because this is just like putting a band aid , I may face that problem again in the future.

 

See code below

BAD CODE

          Init_Boot:

000015f8:   stmdb sp!,{r4-r10,lr}

000015fc:   sub sp,sp,#40

1642      bool BOOT_OK=TRUE;

000015fe:   movs r1,#1

00001600:   add r0,sp,#0

00001602:   strb r1,[r0,#2]

1644      char Boot_state_machine=0;

00001604:   movs r4,#0

1655      low_address=0x3FFFF; // max address in block 1 of flash memory

00001606:   movw r6,#0xffff

0000160a:   movt r6,#0x3

1656      high_address=0;

0000160e:   movs r7,#0

1657      exit_reason=EXIT_BOOT_FAILED;

00001610:   mov r9,#0x1

// Changing the order of lines 1642-1655 (assembly address 0x15FE – 0x1606) didn’t help , as long as there was an assembly instruction in  memory location –0x1606 , the memfault interrupt was triggered.

// Removing the initialization of a variable before the function called , that caused memory location to shift – and probably have different scenario in the pipeline – no errors existed, see below “Good” code

 

GOOD

          Init_Boot:

000015ec:   stmdb sp!,{r4-r10,lr}

000015f0:   sub sp,sp,#40

1642      bool BOOT_OK=TRUE;

000015f2:   movs r1,#1

000015f4:   add r0,sp,#0

000015f6:   strb r1,[r0,#2]

1644      char Boot_state_machine=0;

000015f8:   movs r4,#0

1655      low_address=0x3FFFF; // max address in block 1 of flash memory

000015fa:   movw r6,#0xffff

000015fe:   movt r6,#0x3

1656      high_address=0;

00001602:   movs r7,#0

1657      exit_reason=EXIT_BOOT_FAILED;

00001604:   mov r9,#0x1

1677      StrPut(TX_BUFFER,"TEST",4);

00001608:   ldr r3,[pc,#0x34e]

0000160c:   ldr r0,[pc,#0x34e]

00001610:   ldr r1,[pc,#0x34e]

// No new instruction in memory location 0x1606.

Now taking the “bad” code and adding a NOP , made the code to work

BAD with NOP -->GOOD

          Init_Boot:

000015f8:   stmdb sp!,{r4-r10,lr}

000015fc:   sub sp,sp,#40

1642      bool BOOT_OK=TRUE;

000015fe:   movs r1,#1

00001600:   add r0,sp,#0

00001602:   strb r1,[r0,#2]

1644      char Boot_state_machine=0; //

00001604:   movs r4,#0

1654      asm(NOP);

00001606:   nop

1655      low_address=0x3FFFF; // max address in block 1 of flash memory

00001608:   movw r6,#0xffff

0000160c:   movt r6,#0x3

1656      high_address=0;

00001610:   movs r7,#0

1657      exit_reason=EXIT_BOOT_FAILED;

00001612:   mov r9,#0x1

// This time by placing a 16 bit instruction in memory location 0x1606 , instead of a 32 bit instruction as before , solved the problem

 

 

Outcomes