Skip to content

Commit 26d49ef

Browse files
committed
mimxrt/sdcard: Add cache coherency operations for DMA transfers.
Add explicit data cache management to ensure DMA transfers work correctly on systems with data cache enabled (e.g., MIMXRT1170). For writes: Clean cache to RAM before transfer so DMA reads correct data. For reads: Clean and invalidate cache before transfer, then invalidate again after transfer completes to discard any speculative cache line fills that may have occurred during the DMA. Also fix writeblocks to use MP_BUFFER_READ (reading from buffer to write to card) and update read/writeblocks to raise OSError on failure. Signed-off-by: Andrew Leech <[email protected]>
1 parent 2f1b12e commit 26d49ef

File tree

2 files changed

+19
-13
lines changed

2 files changed

+19
-13
lines changed

ports/mimxrt/machine_sdcard.c

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,13 @@ static MP_DEFINE_CONST_FUN_OBJ_1(machine_sdcard_deinit_obj, machine_sdcard_deini
101101

102102
// readblocks(block_num, buf)
103103
static mp_obj_t machine_sdcard_readblocks(mp_obj_t self_in, mp_obj_t block_num, mp_obj_t buf) {
104-
mp_buffer_info_t bufinfo;
105104
mimxrt_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in);
105+
mp_buffer_info_t bufinfo;
106106
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
107-
108-
if (sdcard_read(self, bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SDCARD_DEFAULT_BLOCK_SIZE)) {
109-
return MP_OBJ_NEW_SMALL_INT(0);
110-
} else {
111-
return MP_OBJ_NEW_SMALL_INT(-MP_EIO);
107+
if (!sdcard_read(self, bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SDCARD_DEFAULT_BLOCK_SIZE)) {
108+
mp_raise_OSError(MP_EIO);
112109
}
110+
return mp_const_none;
113111
}
114112
static MP_DEFINE_CONST_FUN_OBJ_3(machine_sdcard_readblocks_obj, machine_sdcard_readblocks);
115113

@@ -140,15 +138,13 @@ static MP_DEFINE_CONST_FUN_OBJ_1(machine_sdcard_info_obj, machine_sdcard_info);
140138

141139
// writeblocks(block_num, buf)
142140
static mp_obj_t machine_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t block_num, mp_obj_t buf) {
143-
mp_buffer_info_t bufinfo;
144141
mimxrt_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in);
145-
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
146-
147-
if (sdcard_write(self, bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SDCARD_DEFAULT_BLOCK_SIZE)) {
148-
return MP_OBJ_NEW_SMALL_INT(0);
149-
} else {
150-
return MP_OBJ_NEW_SMALL_INT(-MP_EIO);
142+
mp_buffer_info_t bufinfo;
143+
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
144+
if (!sdcard_write(self, bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SDCARD_DEFAULT_BLOCK_SIZE)) {
145+
mp_raise_OSError(MP_EIO);
151146
}
147+
return mp_const_none;
152148
}
153149
static MP_DEFINE_CONST_FUN_OBJ_3(machine_sdcard_writeblocks_obj, machine_sdcard_writeblocks);
154150

ports/mimxrt/sdcard.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,10 @@ bool sdcard_read(mimxrt_sdcard_obj_t *card, uint8_t *buffer, uint32_t block_num,
869869
return false;
870870
}
871871

872+
// Ensure cache is flushed and invalidated so when DMA updates RAM
873+
// from the peripheral, the CPU reads the new data.
874+
MP_HAL_CLEANINVALIDATE_DCACHE(buffer, block_count * card->block_len);
875+
872876
usdhc_data_t data = {
873877
.enableAutoCommand12 = true,
874878
.enableAutoCommand23 = false,
@@ -897,6 +901,9 @@ bool sdcard_read(mimxrt_sdcard_obj_t *card, uint8_t *buffer, uint32_t block_num,
897901

898902
if (status == kStatus_Success) {
899903
card->status = command.response[0];
904+
// Invalidate cache again after DMA completes to discard any speculative
905+
// cache line fills that may have occurred during the transfer.
906+
MP_HAL_CLEANINVALIDATE_DCACHE(buffer, block_count * card->block_len);
900907
return true;
901908
} else {
902909
return false;
@@ -908,6 +915,9 @@ bool sdcard_write(mimxrt_sdcard_obj_t *card, uint8_t *buffer, uint32_t block_num
908915
return false;
909916
}
910917

918+
// Ensure cache is flushed to RAM so DMA can read the correct data.
919+
MP_HAL_CLEAN_DCACHE(buffer, block_count * card->block_len);
920+
911921
usdhc_data_t data = {
912922
.enableAutoCommand12 = true,
913923
.enableAutoCommand23 = false,

0 commit comments

Comments
 (0)