There is at least one gotcha that I am aware of. You will need to re-enable HTIF for 32-bit hosts. See this piece of code:
https://github.com/riscv/riscv-pk/blob/e5846a2bc707eaa58dc8ab6a8d20a090c6ee8570/machine/htif.h#L6-L13
As far as I can tell, QEMU should be able to handle split 32-bit writes to the 64-bit HTIF registers however I haven’t tested it.
Essentially you would remove the #ifdef and use the same definition of TOHOST_CMD. As I said, I have not tested it. I am not sure if the compiler makes any guarantees with respect to the order of writes however one would imagine the low word, which is the least significant word on a little-endian host, meaning the device and command would be stored afterwards. Of course there is no barriers (memory fences) so this is based on an assumption of in-order execution. Really HTIF needs special consideration for 32-bit hosts with appropriate memory barriers. From reading the qemu/hw/riscv/riscv_htif.c, it seems that the driver is written with respect for split writes for double words.
It would be nice to document and harden the HTIF two-register communication protocol, including specifying 32-bit and 64-bit operation…
You might want to start with a simple program to test. I just uploaded riscv-probe which proves that the QEMU HTIF emulation works with 32-bit, so theoretically we could submit a PR to remove the ifdef from riscv-pk. See results here (note the same binaries will run in spike):
-
https://github.com/michaeljclark/riscv-probe
$ qemu-system-riscv64 -nographic -machine spike_v1.10 -kernel bin/riscv64/probe-htif
isa: rv64imafdcsu
csr: fflags (not supported) cause=2
csr: frm (not supported) cause=2
csr: fcsr (not supported) cause=2
csr: cycle 0x0000000000009236
csr: time 0x0000000000009cf4
csr: instret 0x000000000000a41a
csr: cycleh (not supported) cause=2
csr: timeh 0x0000000000000000
csr: instreth (not supported) cause=2
csr: mvendorid 0x0000000000000000
csr: marchid 0x0000000000000000
csr: mimpid 0x0000000000000000
csr: mhartid 0x0000000000000000
csr: mstatus 0x0000000000000000
csr: misa 0x800000000014112d
csr: medeleg 0x0000000000000000
csr: mideleg 0x0000000000000000
csr: mie 0x0000000000000000
csr: mtvec 0x0000000080000004
csr: mcounteren 0x0000000000000000
csr: mscratch 0x0000000000000000
csr: mepc 0x000000008000081e
csr: mcause 0x0000000000000002
csr: mip 0x0000000000000000
csr: sstatus 0x0000000000000000
csr: sie 0x0000000000000000
csr: stvec 0x0000000000000000
csr: scounteren 0x0000000000000000
csr: sscratch 0x0000000000000000
csr: sepc 0x0000000000000000
csr: scause 0x0000000000000000
csr: sip 0x0000000000000000
$ qemu-system-riscv32 -nographic -machine spike_v1.10 -kernel bin/riscv32/probe-htif
isa: rv32imafdcsu
csr: fflags (not supported) cause=2
csr: frm (not supported) cause=2
csr: fcsr (not supported) cause=2
csr: cycle 0x00008458
csr: time 0x00008d36
csr: instret 0x000093b2
csr: cycleh (not supported) cause=2
csr: timeh 0x00000000
csr: instreth (not supported) cause=2
csr: mvendorid 0x00000000
csr: marchid 0x00000000
csr: mimpid 0x00000000
csr: mhartid 0x00000000
csr: mstatus 0x00000000
csr: misa 0x4014112d
csr: medeleg 0x00000000
csr: mideleg 0x00000000
csr: mie 0x00000000
csr: mtvec 0x80000004
csr: mcounteren 0x00000000
csr: mscratch 0x00000000
csr: mepc 0x80000a14
csr: mcause 0x00000002
csr: mip 0x00000000
csr: sstatus 0x00000000
csr: sie 0x00000000
csr: stvec 0x00000000
csr: scounteren 0x00000000
csr: sscratch 0x00000000
csr: sepc 0x00000000
csr: scause 0x00000000
csr: sip 0x00000000