If the ending address in sfcc_cache_wbinv_range(), pa + len, is not
cache-line-aligned, the function spins because len wraps around.
The following patch fixes this.
There still is a subtle detail. If len is zero but pa is non-aligned,
the function is not a no-op. However, shouldn't upper layers handle
things so that zero length does not reach this deep?
OK?
Index: arch/riscv64/dev/sfcc.c
===================================================================
RCS file: src/sys/arch/riscv64/dev/sfcc.c,v
retrieving revision 1.2
diff -u -p -r1.2 sfcc.c
--- arch/riscv64/dev/sfcc.c 22 May 2021 17:07:28 -0000 1.2
+++ arch/riscv64/dev/sfcc.c 15 Jan 2022 11:53:12 -0000
@@ -96,15 +96,15 @@ void
sfcc_cache_wbinv_range(paddr_t pa, paddr_t len)
{
struct sfcc_softc *sc = sfcc_sc;
+ paddr_t end;
- len += pa & (sc->sc_line_size - 1);
+ end = pa + len;
pa &= ~((paddr_t)sc->sc_line_size - 1);
__asm volatile ("fence iorw,iorw" ::: "memory");
- while (len > 0) {
+ while (pa < end) {
bus_space_write_8(sc->sc_iot, sc->sc_ioh, SFCC_FLUSH64, pa);
__asm volatile ("fence iorw,iorw" ::: "memory");
pa += sc->sc_line_size;
- len -= sc->sc_line_size;
}
}