summaryrefslogtreecommitdiff
path: root/sys/arch/riscv64/include
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2024-03-27 23:10:19 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2024-03-27 23:10:19 +0000
commit77f14b575622197a981d8352f9a16afc8b1d7616 (patch)
tree0a1248fa89b1b1e5845972ccc67d6e191389346a /sys/arch/riscv64/include
parent78d14e11e6eff6b1907b83cd11e54ec0c55a60e2 (diff)
The RISC-V architecture specification says that memory read/writes are
not ordered with respect to mmio read/writes. This appears to happen on T-Head C920 cores as I'm seeing interrupts being enabled before the lock is released in mtx_leave() despite program order releasing the lock before enabling interrupts. This is fixed by adding the necessary fences in more or less the same places where Linux uses them. ok patrick@, jca@
Diffstat (limited to 'sys/arch/riscv64/include')
-rw-r--r--sys/arch/riscv64/include/bus.h10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/arch/riscv64/include/bus.h b/sys/arch/riscv64/include/bus.h
index 14a324c04d3..9e6449976ab 100644
--- a/sys/arch/riscv64/include/bus.h
+++ b/sys/arch/riscv64/include/bus.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bus.h,v 1.5 2022/12/29 11:35:01 kettenis Exp $ */
+/* $OpenBSD: bus.h,v 1.6 2024/03/27 23:10:18 kettenis Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB Sweden. All rights reserved.
@@ -265,8 +265,10 @@ bus_space_copy_1(void *v, bus_space_handle_t h1, bus_size_t o1,
char *s = (char *)(h1 + o1);
char *d = (char *)(h2 + o2);
+ __asm volatile ("fence w,o" ::: "memory");
while (c--)
*d++ = *s++;
+ __asm volatile ("fence io,iwr" ::: "memory");
}
@@ -277,8 +279,10 @@ bus_space_copy_2(void *v, bus_space_handle_t h1, bus_size_t o1,
short *s = (short *)(h1 + o1);
short *d = (short *)(h2 + o2);
+ __asm volatile ("fence w,o" ::: "memory");
while (c--)
*d++ = *s++;
+ __asm volatile ("fence io,iwr" ::: "memory");
}
static __inline void
@@ -288,8 +292,10 @@ bus_space_copy_4(void *v, bus_space_handle_t h1, bus_size_t o1,
int *s = (int *)(h1 + o1);
int *d = (int *)(h2 + o2);
+ __asm volatile ("fence w,o" ::: "memory");
while (c--)
*d++ = *s++;
+ __asm volatile ("fence io,iwr" ::: "memory");
}
static __inline void
@@ -299,8 +305,10 @@ bus_space_copy_8(void *v, bus_space_handle_t h1, bus_size_t o1,
int64_t *s = (int64_t *)(h1 + o1);
int64_t *d = (int64_t *)(h2 + o2);
+ __asm volatile ("fence w,o" ::: "memory");
while (c--)
*d++ = *s++;
+ __asm volatile ("fence io,iwr" ::: "memory");
}
/*----------------------------------------------------------------------------*/