aboutsummaryrefslogtreecommitdiffstats
path: root/src/gfile/gfile_petitfs_diskio_chibios.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gfile/gfile_petitfs_diskio_chibios.c')
-rw-r--r--src/gfile/gfile_petitfs_diskio_chibios.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/src/gfile/gfile_petitfs_diskio_chibios.c b/src/gfile/gfile_petitfs_diskio_chibios.c
index d7ef02aa..61917ee5 100644
--- a/src/gfile/gfile_petitfs_diskio_chibios.c
+++ b/src/gfile/gfile_petitfs_diskio_chibios.c
@@ -10,21 +10,35 @@
#if GFX_USE_GFILE && GFILE_NEED_PETITFS && GFX_USE_OS_CHIBIOS && !GFILE_PETITFS_EXTERNAL_LIB
#include "gfile_petitfs_wrapper.h"
-
#include <string.h>
#if HAL_USE_MMC_SPI && HAL_USE_SDC
-#error "cannot specify both MMC_SPI and SDC drivers"
+ #error "cannot specify both MMC_SPI and SDC drivers"
#endif
#if HAL_USE_MMC_SPI
-extern MMCDriver MMCD1;
+ extern MMCDriver MMCD1;
#elif HAL_USE_SDC
-extern SDCDriver SDCD1;
+ extern SDCDriver SDCD1;
#else
-#error "MMC_SPI or SDC driver must be specified"
+ #error "MMC_SPI or SDC driver must be specified"
#endif
+// WOW - Bugs galore!!! (in ChibiOS)
+// Bugs:
+// 1. ChibiOS DMA operations do not do the appropriate cache flushing or invalidating
+// on cpu's that require it eg STM32F7 series.
+// Instead they provide explicit dmaBufferInvalidate and dmaBufferFlush calls
+// and rely on the user to explicitly flush the cache.
+// Solution: We explicitly flush the cache after any possible DMA operation.
+// 2. Unfortunately these explicit routines also have a bug. They assume that the
+// specified data structure is aligned on a cache line boundary - not a good assumption.
+// Solution: We increase the size provided to ChibiOS so that it does it properly.
+// This assumes of course that we know the size of the cpu cache line.
+#define CPU_CACHE_LINE_SIZE 32
+#define CACHE_FLUSH(buf, sz) dmaBufferFlush((buf), (sz)+(CPU_CACHE_LINE_SIZE-1))
+#define CACHE_INVALIDATE(buf, sz) dmaBufferInvalidate((buf), (sz)+(CPU_CACHE_LINE_SIZE-1))
+
/*-----------------------------------------------------------------------*/
/* Initialize a Drive */
@@ -72,7 +86,7 @@ DRESULT disk_readp (
return RES_ERROR;
#endif
sectpos = sector;
- dmaBufferInvalidate(sectBuf, sizeof(sectBuf));
+ CACHE_INVALIDATE(sectBuf, sizeof(sectBuf));
}
memcpy(buff, sectBuf + offset, count);
return RES_OK;