fix(fpu): write random value to fpsr/fpcr instead of read
The inline assembly code to write random values to FPSR and FPCR,
actually does a read. This zero out the random value that is used as a
template to fill FPU [Q0-Q31] registers.
When this helper routine is used by Non-secure, SP or Realm context
the FPU state written to the registers is always zero. The test cases
that verifies whether the FPU state is preserved across the world switch
might PASS always as it works with an empty FPU state.
This fix also changes fpu_state_print() to print the content of Q0-Q31
registers instead of the address.
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: I7bc2deba034b9bb4b6c1b15fe91f4562fd64d8f0
diff --git a/lib/extensions/fpu/fpu.c b/lib/extensions/fpu/fpu.c
index da887b3..b08e64c 100644
--- a/lib/extensions/fpu/fpu.c
+++ b/lib/extensions/fpu/fpu.c
@@ -68,8 +68,8 @@
* Write random value to FPCR FPSR.
* Note write will be ignored for reserved bits.
*/
- __asm__ volatile ("mrs %0, fpsr\n" : "=r" (temp));
- __asm__ volatile ("mrs %0, fpcr\n" : "=r" (temp));
+ __asm__ volatile ("msr fpsr, %0\n" : : "r" (temp));
+ __asm__ volatile ("msr fpcr, %0\n" : : "r" (temp));
/*
* Read back current FPCR FPSR and write to template,
@@ -80,9 +80,10 @@
fpu_template_in->fpcr = fpcr;
for (unsigned int num = 0U; num < FPU_Q_COUNT; num++) {
- memset((uint8_t *)fpu_template_in->q[num], temp * num,
+ memset((uint8_t *)fpu_template_in->q[num], temp * (num + 1),
sizeof(fpu_template_in->q[0]));
}
+
__asm__ volatile(
fill_simd_helper(0, 1)
fill_simd_helper(2, 3)
@@ -108,8 +109,9 @@
{
INFO("dumping FPU registers :\n");
for (unsigned int num = 0U; num < FPU_Q_COUNT; num++) {
- INFO("Q[%u]=0x%llx%llx\n", num, (uint64_t)vec->q[num * FPU_Q_SIZE],
- (uint64_t)(vec->q[num * FPU_Q_SIZE + 1]));
+ uint64_t __unused *qreg = (uint64_t *)&vec->q[num];
+
+ INFO("Q[%02u]=0x%016llx_%016llx\n", num, *qreg, *(qreg + 1));
}
INFO("FPCR=0x%lx FPSR=0x%lx\n", vec->fpcr, vec->fpsr);
}