[PATCH rtems-libbsd 2/2] st-sdmmc: Handle short not cache aligned buffers

Christian Mauderer christian.mauderer at embedded-brains.de
Wed Apr 14 07:20:45 UTC 2021


Possible data sources for SD driver:

- mmc_sd_switch():
    - length: 64 byte;
    - buffer on stack
- mmc_test_bus_width():
    - length: 4 or 8 byte
    - buffer in program memory or on stack
- mmc_app_send_scr():
    - length: 8 byte
    - buffer from device ivar structure
- mmc_app_sd_status():
    - length: 64 byte
    - buffer from device ivar structure
- mmc_send_ext_csd():
    - length: MMC_EXTCSD_SIZE = 512
    - buffer from device ivar structure
- rtems_bsd_mmcsd_disk_read_write():
    - length: depends on read
    - buffer from rtems_blkdev buffer -> already aligned
- mmcsd_ioctl_cmd():
    - length: depends on call
    - buffer malloced, not aligned -> patched in RTEMS

So the problematic buffers are only the ones up to 512 bytes. Copy these data
into a buffer to avoid that problem.
---
 rtemsbsd/sys/dev/mmc/st-sdmmc.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/rtemsbsd/sys/dev/mmc/st-sdmmc.c b/rtemsbsd/sys/dev/mmc/st-sdmmc.c
index e50b400a..4b202952 100644
--- a/rtemsbsd/sys/dev/mmc/st-sdmmc.c
+++ b/rtemsbsd/sys/dev/mmc/st-sdmmc.c
@@ -117,7 +117,8 @@ __FBSDID("$FreeBSD$");
 #define RES_IRQ_SDMMC 2
 #define RES_NR 3
 
-#define DMA_BUF_SIZE CPU_CACHE_LINE_BYTES
+/* Maximum non-aligned buffer is 512 byte from mmc_send_ext_csd() */
+#define DMA_BUF_SIZE 512
 
 #if 0
 #define debug_print(sc, lvl, ...) \
@@ -575,14 +576,19 @@ st_sdmmc_cmd_do(struct st_sdmmc_softc *sc, struct mmc_command *cmd)
 
 		BSD_ASSERT(xferlen % (1 << blksize) == 0);
 
-		if (xferlen < CPU_CACHE_LINE_BYTES) {
+		data = cmd->data->data;
+		/*
+		 * Check whether data have to be copied. Reason is either
+		 * misaligned start address or misaligned length.
+		 */
+		if (((uintptr_t)data % CPU_CACHE_LINE_BYTES != 0) ||
+		    (xferlen % CPU_CACHE_LINE_BYTES) != 0) {
+			BSD_ASSERT(xferlen < DMA_BUF_SIZE);
 			if ((cmd->data->flags & MMC_DATA_READ) == 0) {
 				memcpy(sc->dmabuf, cmd->data->data, xferlen);
 			}
 			data = sc->dmabuf;
 			short_xfer = true;
-		} else {
-			data = cmd->data->data;
 		}
 
 		dctrl |= blksize << SDMMC_DCTRL_DBLOCKSIZE_Pos;
-- 
2.26.2



More information about the devel mailing list