Hello, recently I bought SparkFun RED-V Things Plus which has SiFive FE310-G002 to port NuttX OS.
And during porting NuttX to the board, I found a strange behavior with a lui (load upper immediate) instruction. To reproduce this (perhaps a hardware bug) symptom is very easy.
int hello_main(int argc, FAR char *argv[])
{
uint32_t a = 0x10000;
printf("Hello lui! (a=0x%x) \n", a);
return 0;
}
If I run the above program without gdb, it works without problem.
However, If I add a breakpoint to the hello_main function and continue to run by ‘stepi’ (single step instruction) the program shows incorrect value.
Breakpoint 1, hello_main (argc=1, argv=0x80002eb8) at hello_main.c:55
55 printf("Hello lui! (a=0x%x) \n", a);
(gdb) stepi
0x2001b750 55 printf("Hello lui! (a=0x%x) \n", a);
(gdb) stepi
0x2001b752 55 printf("Hello lui! (a=0x%x) \n", a);
(gdb) disas
Dump of assembler code for function hello_main:
0x2001b74c <+0>: lui a0,0x2001e
0x2001b750 <+4>: addi sp,sp,-16
=> 0x2001b752 <+6>: lui a1,0x10
0x2001b754 <+8>: addi a0,a0,1776 # 0x2001e6f0
0x2001b758 <+12>: sw ra,12(sp)
0x2001b75a <+14>: jal ra,0x2001c2aa <printf>
0x2001b75e <+18>: lw ra,12(sp)
0x2001b760 <+20>: li a0,0
0x2001b762 <+22>: addi sp,sp,16
0x2001b764 <+24>: ret
End of assembler dump.
(gdb) p /x $a1
$1 = 0x80002eb8
(gdb) stepi
0x2001b754 55 printf("Hello lui! (a=0x%x) \n", a);
(gdb) p /x $a1
$2 = 0xffff0000 <== incorrect value is always loaded
As far as I tested, this symptom
(1) does not happen without gdb
(2) does not depend register name.
(3) depends on the immediate value (the range is 0x10-1f ?)
(4) does not happen with gdb + qemu (fe310_e)
Because I don’t have any other FE310-G002 chips, so I’m not sure this issue depends on individual chip.
Thanks,
Masayuki Ishikawa