From 829afafbcbd5503821d59cbdb81bf11860b0864d Mon Sep 17 00:00:00 2001 From: Christian Mauderer Date: Tue, 13 Apr 2021 14:02:39 +0200 Subject: st-sdmmc: Handle short not cache aligned buffers 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; -- cgit v1.2.3