diff options
author | Christian Mauderer <christian.mauderer@embedded-brains.de> | 2021-04-13 14:02:39 +0200 |
---|---|---|
committer | Christian Mauderer <christian.mauderer@embedded-brains.de> | 2021-04-19 09:03:40 +0200 |
commit | 829afafbcbd5503821d59cbdb81bf11860b0864d (patch) | |
tree | 4444de1a815cea0a3388e71063a437df0ab46b82 | |
parent | 8aa3ddfbd7d64694bc6968aeac90e11056ce8a7d (diff) |
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.
-rw-r--r-- | rtemsbsd/sys/dev/mmc/st-sdmmc.c | 14 |
1 files 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; |