Skip to content

Commit 19c8372

Browse files
Pull up following revision(s) (requested by skrll in ticket #38):
sys/arch/riscv/riscv/bus_dma.c: revision 1.11 risc-v: Adjust barriers issued in bus_dmamap_sync for the coherent case. PR/59653 This change adjusts the memory barriers issued by bus_dmamap_sync for the coherent case. In the non-coherent case the CPU cache operations are expected to provide any, and all required barriers. These barriers are emitted after bouncing for PREWRITE and before bouncing for POSTREAD. Net change: op old new --------------------- ---------------------- -------------- PREREAD none fence rw,ow PREWRITE fence iorw,iorw fence rw,ow PREREAD|PREWRITE fence iorw,iorw fence w,ow POSTREAD fence iorw,iorw fence ir,r POSTWRITE none none POSTREAD|POSTWRITE fence iorw,iorw fence ir,r
1 parent 6588087 commit 19c8372

File tree

1 file changed

+49
-10
lines changed

1 file changed

+49
-10
lines changed

sys/arch/riscv/riscv/bus_dma.c

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: bus_dma.c,v 1.10 2025/03/02 01:23:11 riastradh Exp $ */
1+
/* $NetBSD: bus_dma.c,v 1.10.2.1 2025/10/01 16:37:05 martin Exp $ */
22

33
/*-
44
* Copyright (c) 1996, 1997, 1998, 2020 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
3434
#define _RISCV_NEED_BUS_DMA_BOUNCE
3535

3636
#include <sys/cdefs.h>
37-
__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.10 2025/03/02 01:23:11 riastradh Exp $");
37+
__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.10.2.1 2025/10/01 16:37:05 martin Exp $");
3838

3939
#include <sys/param.h>
4040

@@ -1166,38 +1166,77 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset,
11661166
}
11671167
}
11681168

1169-
/* Skip cache frobbing if mapping was COHERENT */
1169+
/*
1170+
* Provide appropriate memory barriers, and skip cache frobbing
1171+
* if mapping is COHERENT.
1172+
*
1173+
* The case of PREREAD is as follows:
1174+
*
1175+
* 1. loads and stores before DMA buffer may be allocated for the
1176+
* purpose
1177+
* 2. bus_dmamap_sync(BUS_DMASYNC_PREREAD)
1178+
* 3. store to register or DMA descriptor to trigger DMA
1179+
*
1180+
* The load/store-before-store ordering is ensured by fence rw, ow.
1181+
*
1182+
* The case of PREWRITE is as follows:
1183+
*
1184+
* 1. stores to DMA buffer. loads can happen later as the buffer is
1185+
* not changed by the device.
1186+
* 2. bus_dmamap_sync(BUS_DMASYNC_PREWRITE)
1187+
* 3. store to register or DMA descriptor to trigger DMA
1188+
*
1189+
* The store-before-store ordering is ensured by fence w,ow.
1190+
*
1191+
* The case of POSTREAD is as follows:
1192+
*
1193+
* 1. load from register or DMA descriptor notifying DMA completion
1194+
* 2. bus_dmamap_sync(BUS_DMASYNC_POSTREAD)
1195+
* 3. loads from DMA buffer to use data, and stores to reuse buffer
1196+
*
1197+
* The stores in (3) will not be speculated and, therefore, don't need
1198+
* specific handling. The load-before-load ordering is provided by
1199+
* fence ir,r.
1200+
*
1201+
* The case of POSTWRITE is as follows:
1202+
*
1203+
* 1. load from register or DMA descriptor notifying DMA completion
1204+
* 2. bus_dmamap_sync(BUS_DMASYNC_POSTWRITE)
1205+
* 3. loads and stores to reuse buffer
1206+
*
1207+
* The stores in (3) will not be speculated, and the load can happen
1208+
* at any time as the DMA buffer is not changed by the device so no
1209+
* barrier is required.
1210+
*/
11701211
if ((map->_dm_flags & _BUS_DMAMAP_COHERENT)) {
11711212
switch (ops) {
11721213
case BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE:
1214+
asm volatile ("fence rw,ow" ::: "memory");
11731215
STAT_INCR(sync_coherent_prereadwrite);
11741216
break;
11751217

11761218
case BUS_DMASYNC_PREREAD:
1219+
asm volatile ("fence rw,ow" ::: "memory");
11771220
STAT_INCR(sync_coherent_preread);
11781221
break;
11791222

11801223
case BUS_DMASYNC_PREWRITE:
1224+
asm volatile ("fence w,ow" ::: "memory");
11811225
STAT_INCR(sync_coherent_prewrite);
11821226
break;
11831227

11841228
case BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE:
1229+
asm volatile ("fence ir,r" ::: "memory");
11851230
STAT_INCR(sync_coherent_postreadwrite);
11861231
break;
11871232

11881233
case BUS_DMASYNC_POSTREAD:
1234+
asm volatile ("fence ir,r" ::: "memory");
11891235
STAT_INCR(sync_coherent_postread);
11901236
break;
11911237

11921238
/* BUS_DMASYNC_POSTWRITE was aleady handled as a fastpath */
11931239
}
1194-
/*
1195-
* Drain the write buffer of DMA operators.
1196-
* 1) when cpu->device (prewrite)
1197-
* 2) when device->cpu (postread)
1198-
*/
1199-
if ((pre_ops & BUS_DMASYNC_PREWRITE) || (post_ops & BUS_DMASYNC_POSTREAD))
1200-
asm volatile ("fence iorw,iorw" ::: "memory");
12011240

12021241
/*
12031242
* Only thing left to do for COHERENT mapping is copy from bounce

0 commit comments

Comments
 (0)