1
0
mirror of synced 2026-03-06 18:51:17 +00:00

Avoid some potential race conditions

This commit is contained in:
Romain Dolbeau
2021-07-25 06:32:48 -04:00
parent 6aa4734550
commit 0c5e750453
2 changed files with 28 additions and 14 deletions

View File

@@ -609,6 +609,8 @@ sbusfpga_sdram_diskstart(device_t self, struct buf *bp)
#undef CSR_SDPHY_BASE
#undef CSR_TRNG_BASE
#define DMA_STATUS_CHECK_BITS (0x01F)
int
dma_init(struct sbusfpga_sdram_softc *sc) {
sc->dma_blk_size = exchange_with_mem_blk_size_read(sc);
@@ -666,7 +668,7 @@ dma_memtest(struct sbusfpga_sdram_softc *sc) {
unsigned long *kva_ulong = (unsigned long*)sc->sc_dma_kva;
unsigned long val;
unsigned int blkn = 0; // 113;
unsigned int testdatasize = 4096;
const unsigned int testdatasize = 4096;
unsigned int blkcnt ;
int count;
@@ -677,7 +679,7 @@ dma_memtest(struct sbusfpga_sdram_softc *sc) {
val = lfsr(32, val);
kva_ulong[i] = val;
}
aprint_normal_dev(sc->dk.sc_dev, "First value: 0x%08lx\n", kva_ulong[0]);
aprint_normal_dev(sc->dk.sc_dev, "First / last value: 0x%08lx 0x%08lx\n", kva_ulong[0], kva_ulong[(testdatasize/sizeof(unsigned long))-1]);
#if 0
if (sc->sc_bufsiz_mmap > 0) {
@@ -739,13 +741,13 @@ dma_memtest(struct sbusfpga_sdram_softc *sc) {
}
count = 0;
while ((((blkcnt = exchange_with_mem_dma_status_read(sc)) & 0x3) != 0) && (count < 10)) {
while ((((blkcnt = exchange_with_mem_dma_status_read(sc)) & DMA_STATUS_CHECK_BITS) != 0) && (count < 10)) {
aprint_normal_dev(sc->dk.sc_dev, "DMA Write-to-Sdram hasn't reached SDRAM yet (status 0x%08x)\n", blkcnt);
count ++;
delay(DEF_BLK_DELAY);
}
if (blkcnt & 0x3) {
if (blkcnt & DMA_STATUS_CHECK_BITS) {
aprint_error_dev(sc->dk.sc_dev, "DMA Write-to-Sdram can't reach SDRAM ? (%u, status 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", blkcnt & 0x0000FFFF,
exchange_with_mem_dma_status_read(sc),
exchange_with_mem_last_blk_read(sc),
@@ -784,7 +786,7 @@ dma_memtest(struct sbusfpga_sdram_softc *sc) {
for (int i = 0 ; i < testdatasize/sizeof(unsigned long) ; i++) {
kva_ulong[i] = 0x0c0ffee0;
}
aprint_normal_dev(sc->dk.sc_dev, "First value: 0x%08lx\n", kva_ulong[0]);
aprint_normal_dev(sc->dk.sc_dev, "First / last value: 0x%08lx 0x%08lx\n", kva_ulong[0], kva_ulong[(testdatasize/sizeof(unsigned long))-1]);
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, 4096, BUS_DMASYNC_PREWRITE);
@@ -824,15 +826,15 @@ dma_memtest(struct sbusfpga_sdram_softc *sc) {
}
count = 0;
while ((((blkcnt = exchange_with_mem_dma_status_read(sc)) & 0x3) != 0) && (count < 10)) {
while ((((blkcnt = exchange_with_mem_dma_status_read(sc)) & DMA_STATUS_CHECK_BITS) != 0) && (count < 10)) {
aprint_normal_dev(sc->dk.sc_dev, "DMA Read-from-Sdram hasn't reached memory yet (status 0x%08x)\n", blkcnt);
count ++;
delay(DEF_BLK_DELAY);
}
aprint_normal_dev(sc->dk.sc_dev, "First value: 0x%08lx\n", kva_ulong[0]);
aprint_normal_dev(sc->dk.sc_dev, "First /last value: 0x%08lx 0x%08lx\n", kva_ulong[0], kva_ulong[(testdatasize/sizeof(unsigned long))-1]);
if (blkcnt & 0x3) {
if (blkcnt & DMA_STATUS_CHECK_BITS) {
aprint_error_dev(sc->dk.sc_dev, "DMA Read-from-Sdram can't reach memory ? (%u, status 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", blkcnt & 0x0000FFFF,
exchange_with_mem_dma_status_read(sc),
exchange_with_mem_last_blk_read(sc),
@@ -900,13 +902,13 @@ static int sbusfpga_sdram_read_block(struct sbusfpga_sdram_softc *sc, const u_in
#endif
count = 0;
while ((((check = exchange_with_mem_dma_status_read(sc)) & 0x3) != 0) && (count < blkcnt)) {
aprint_normal_dev(sc->dk.sc_dev, "DMA Write-to-Sdram hasn't reached SDRAM yet (status 0x%08x)\n", check);
while ((((check = exchange_with_mem_dma_status_read(sc)) & DMA_STATUS_CHECK_BITS) != 0) && (count < blkcnt)) {
//aprint_normal_dev(sc->dk.sc_dev, "DMA Write-to-Sdram hasn't reached SDRAM yet (status 0x%08x)\n", check);
count ++;
delay(DEF_BLK_DELAY);
}
if (check & 0x3) {
if (check & DMA_STATUS_CHECK_BITS) {
aprint_error_dev(sc->dk.sc_dev, "DMA can't reach memory/SDRAM ? (%u, status 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n",
check & 0x0000FFFF,
exchange_with_mem_dma_status_read(sc),
@@ -961,13 +963,13 @@ static int sbusfpga_sdram_write_block(struct sbusfpga_sdram_softc *sc, const u_i
#endif
count = 0;
while ((((check = exchange_with_mem_dma_status_read(sc)) & 0x3) != 0) && (count < blkcnt)) {
aprint_normal_dev(sc->dk.sc_dev, "DMA Write-to-Sdram hasn't reached SDRAM yet (status 0x%08x)\n", check);
while ((((check = exchange_with_mem_dma_status_read(sc)) & DMA_STATUS_CHECK_BITS) != 0) && (count < blkcnt)) {
//aprint_normal_dev(sc->dk.sc_dev, "DMA Read_from-Sdram hasn't reached SDRAM yet (status 0x%08x)\n", check);
count ++;
delay(DEF_BLK_DELAY);
}
if (check & 0x3) {
if (check & DMA_STATUS_CHECK_BITS) {
aprint_error_dev(sc->dk.sc_dev, "DMA can't reach memory/SDRAM ? (%u, status 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n",
check & 0x0000FFFF,
exchange_with_mem_dma_status_read(sc),

View File

@@ -1,5 +1,6 @@
from migen import *
from migen.genlib.fifo import *
from migen.genlib.cdc import PulseSynchronizer
from litex.soc.interconnect.csr import *
from litex.soc.interconnect import wishbone
@@ -70,9 +71,20 @@ class ExchangeWithMem(Module, AutoCSR):
self.submodules.req_r_fsm = req_r_fsm = FSM(reset_state="Reset")
self.submodules.req_w_fsm = req_w_fsm = FSM(reset_state="Reset")
# this could use CSRFields...
self.comb += self.dma_status.status[0:1].eq(~req_r_fsm.ongoing("Idle")) # Read FSM Busy
self.comb += self.dma_status.status[1:2].eq(~req_w_fsm.ongoing("Idle")) # Write FSM Busy
self.comb += self.dma_status.status[2:3].eq(self.fromsbus_fifo.readable) # Some data available to write to memory
self.submodules.fromsbus_req_fifo_readable_sync = PulseSynchronizer("sbus", "sys")
fromsbus_req_fifo_readable_in_sys = Signal()
self.comb += self.fromsbus_req_fifo_readable_sync.i.eq(self.fromsbus_req_fifo.readable)
self.comb += fromsbus_req_fifo_readable_in_sys.eq(self.fromsbus_req_fifo_readable_sync.o)
self.comb += self.dma_status.status[3:4].eq(fromsbus_req_fifo_readable_in_sys) # we still have outstanding requests
self.submodules.tosbus_fifo_readable_sync = PulseSynchronizer("sbus", "sys")
tosbus_fifo_readable_in_sys = Signal()
self.comb += self.tosbus_fifo_readable_sync.i.eq(self.tosbus_fifo.readable)
self.comb += tosbus_fifo_readable_in_sys.eq(self.tosbus_fifo_readable_sync.o)
self.comb += self.dma_status.status[4:5].eq(tosbus_fifo_readable_in_sys) # there's still data to be sent to memory; this will drop before the last SBus Master Cycle is finished, but then the SBus is busy so the host won't be able to read the status before the cycle is finished so we're good
self.comb += self.dma_status.status[8:9].eq(req_r_fsm.ongoing("ReqFromMemory"))
self.comb += self.dma_status.status[9:10].eq(req_r_fsm.ongoing("WaitForData"))