Zynq Cortex-A9 Failure at Low Temperature

razed11 wrote on Wednesday, November 11, 2015:

Hi,

In version 7.0.2 portRESTORE_CONTEXT tries to set the SPSR:


	/* Get the SPSR from the stack. */									\
	"LDMFD	LR!, {R0}											\n\t"	\
	"MSR		SPSR, R0

We are seeing a very strange failure at low temperature where the endian bit gets set when this function returns. We added a line after the one above to read back the value and it is different from the value in R0 (but the same as the corrupt value it takes when the function returns with SUBS:

/* And return - correcting the offset in the LR to obtain the */	\
/* correct address. */												\
"SUBS	PC, LR, #4											\n\t"	\``

In 8.x this code was changed and returns in the following way:

/* Return to the task code, loading CPSR on the way. */
RFEIA	sp!

I’m not pointing the finger at the RTOS but I’m curious if you can give us some history on this change and why it was written differently? Can you tell me if there are any restrictions on adding our line “MSR RO, SPSR” to read back the value?

Thanks.

heinbali01 wrote on Wednesday, November 11, 2015:

Hi,

What port and what part (MCU) are you using ?

Sorry, you wrote that already in the title: Zynq Cortex-A9

heinbali01 wrote on Wednesday, November 11, 2015:

Ok, I see it in the title: “Zynq Cortex-A9”.

What you are describing, does that happen during xPortStartScheduler() -> vPortRestoreTaskContext() ?

Coincidentally I recently went through this V8.2.3 port code (for another reason), and I can confirm that every bit falls into the right register at start-up.

Can you tell me which files you used for version V7.0.2 ?

Regards.

razed11 wrote on Friday, November 13, 2015:

Hi Hein,

It happens at portRESTORE_CONTEXT. We’re using 7.0.2 so it’s in portmacro.h.

After doing some reading I can understand why the implementation changed for at least one reason: Not all Cortex-A9s have virtualization extension which means the MSR, MRS instructions used in our 7.0.2 port could be used for all Cortex-A9s (though in practice maybe all are Cortex-A9VE).

I’ve also been told that the SPSR is not guaranteed to be in a well-defined state though I’m waiting to see a citation from ARM. If this is true I still do not believe that this is a FreeRTOS issue as that initialization would have to happen just after reset.

rtel wrote on Friday, November 13, 2015:

There was no official FreeRTOS port for the Cortex-A9 in FreeRTOS
V7.0.2. I suspect the V7.0.2 code you have was created by Xilinx
themselves (Xilinx maintained an unofficial port for some time prior to
ourselves creating an official one), so the change you refer to is not
in fact a change - just a different code base. The first official port
appeared in V8.0.0.