diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2024-03-27 23:10:19 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2024-03-27 23:10:19 +0000 |
commit | 77f14b575622197a981d8352f9a16afc8b1d7616 (patch) | |
tree | 0a1248fa89b1b1e5845972ccc67d6e191389346a /sys/arch/riscv64/include | |
parent | 78d14e11e6eff6b1907b83cd11e54ec0c55a60e2 (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.h | 10 |
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"); } /*----------------------------------------------------------------------------*/ |