Amoswap on PLIC memory

Hi everyone,

I am working on a FE310 on the HiFive1 and I have a piece of code that is supposed to clear the “target 0 enables” register (0xc002000).

The compiler (GCC with Ada front-end) generates an amoswap instruction for that, but it looks like the instruction doesn’t have any effect.

You will find my debug session below.

I single step over the: amoswap.w zero,a4,(a5) instruction where $a5=0xc002000 and $a4=0x0.

The value of the PLIC register at 0xc002000 doesn’t seem to change…

0xc002000: 0xd7feddfe

Is there something special with the amoswap instruction on PLIC registers?

Dump of assembler code from 0x204037ca to 0x204037f2:
[…]
=> 0x204037de <system__bb__riscv_plic__initialize+22>: amoswap.w zero,a4,(a5)
0x204037e2 <system__bb__riscv_plic__initialize+26>: lui a4,0xc000
[…]
End of assembler dump.
0x204037de 57 (others => (As_Array => True, Arr => (others => False)));
(gdb) p $a5
$8 = 0xc002000
(gdb) x/x $a5
0xc002000: 0xd7feddfe
(gdb) p $a4
$9 = 0x0
(gdb) si
Dump of assembler code from 0x204037ce to 0x204037f6:
[…]
0x204037de <system__bb__riscv_plic__initialize+22>: amoswap.w zero,a4,(a5)
=> 0x204037e2 <system__bb__riscv_plic__initialize+26>: lui a4,0xc000
[…]
End of assembler dump.
(gdb) x/x $a5
0xc002000: 0xd7feddfe

I don’t know specifically about PLIC registers. I do know I’ve seen AMO instructions recommended for manipulating device registers in general, especially because with the way Tilelink works the AMO might actually be executed in a cache controller or even by the device itself, rather than dragging the data all the way to the CPU and back. However, that doesn’t apply to the FE310.

I seem to recall something about single-stepping not being a good idea with AMO instructions. It may be better to set a break point on the next instruction and use Continue.

Thank you @bruce, I will check if single stepping is the problem here.

Subsidiary question: Are 8bit and 16bit accesses valid on the MMIO?

I could not find this information in the documentation.