stm32/dma,spi: Fix invalid SPI reads due to D-Cache coherency.#13717
stm32/dma,spi: Fix invalid SPI reads due to D-Cache coherency.#13717dpgeorge merged 3 commits intomicropython:masterfrom
Conversation
1428022 to
fe79346
Compare
We should definitely include those tests in the repo, and I suggest making these tests separate file(s) to the existing tests, adding a comment at the top of the file of the require hardware connections, and then possibly trying to auto-detect those hardware connections (eg toggle IO and see if it changes) and SKIP'ing if they are not there. Alternatives:
Note there are already some tests in |
|
Very good catch. The PR works here, just reading with a constant pattern supplied. I have an inverter here in my test set-up between MOSI and MISO, so it works with any value pair, including 0x00 and 0xff. |
fe79346 to
9070244
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #13717 +/- ##
=======================================
Coverage 98.39% 98.39%
=======================================
Files 161 161
Lines 21078 21078
=======================================
Hits 20739 20739
Misses 339 339 ☔ View full report in Codecov by Sentry. |
|
Have added regression test in |
The inline functions that these are wrappers around already account for cache line size. Signed-off-by: Angus Gratton <angus@redyak.com.au>
The existing MPU_CONFIG_DISABLE macro enables the MPU region but disables all access to it. The rename is necessary to support an MPU_CONFIG_DISABLE macro that actually disables the MPU region entirely. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
This new DMA API corrects possible cache coherency issues on chips with D-Cache, when working with buffers at arbitrary memory locations (i.e. supplied by Python code). The API is used by SPI to fix an issue with corrupt data when reading from SPI using DMA in certain cases. A regression test is included (it depends on external hardware connection). Explanation: 1) It's necessary to invalidate D-Cache after a DMA RX operation completes in case the CPU reads (or speculatively reads) from the DMA RX region during the operation. This seems to have been the root cause of issue micropython#13471 (only when src==dest for this case). 2) More generally, it is also necessary to temporarily mark the first and last cache lines of a DMA RX operation as "uncached", in case the DMA buffer shares this cache line with unrelated data. The CPU could otherwise write the other data at any time during the DMA operation (for example from an interrupt handler), creating a dirty cache line that's inconsistent with the DMA result. Fixes issue micropython#13471. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
9070244 to
7fd8a6d
Compare
See micropython issue micropython#13471 and the related PR micropython#13717 for an explanation of a similar issue in the SPI DMA driver. Signed-off-by: Peter Züger <zueger.peter@icloud.com>
See micropython issue micropython#13471 and the related PR micropython#13717 for an explanation of a similar issue in the SPI DMA driver. Signed-off-by: Peter Züger <zueger.peter@icloud.com>
See micropython issue micropython#13471 and the related PR micropython#13717 for an explanation of a similar issue in the SPI DMA driver. Signed-off-by: Peter Züger <zueger.peter@icloud.com>
See micropython issue micropython#13471 and the related PR micropython#13717 for an explanation of a similar issue in the SPI DMA driver. Signed-off-by: Peter Züger <zueger.peter@icloud.com>
See micropython issue micropython#13471 and the related PR micropython#13717 for an explanation of a similar issue in the SPI DMA driver. Signed-off-by: Peter Züger <zueger.peter@icloud.com>
See micropython issue micropython#13471 and the related PR micropython#13717 for an explanation of a similar issue in the SPI DMA driver. Signed-off-by: Peter Züger <zueger.peter@icloud.com>
See micropython issue micropython#13471 and the related PR micropython#13717 for an explanation of a similar issue in the SPI DMA driver. Signed-off-by: Peter Züger <zueger.peter@icloud.com>

Adds a new DMA API to protect against cache coherency issues on chips with D-Cache, when working with arbitrary buffers (i.e. supplied by Python code).
The API is added to SPI, fixes #13471. Future work may be needed to call this API from other STM32 drivers that use DMA with arbitrary buffers.
Explanation:
It's necessary to invalidate D-Cache after a DMA RX operation completes, in case the CPU read (or speculatively accessed) memory in the DMA region during the operation. This seems to have been the root cause of STM32: SPI.read(n) fails if n > 1 (regression) #13471 (and only when src==dest, for that case.)
More generally, it is also necessary to temporarily mark the first and last cache lines of a DMA RX operation as "uncached", in case the DMA buffer shares this cache line with unrelated data. The CPU could otherwise write the other data at any time during the DMA operation (for example from an interrupt handler), creating a dirty cache line that's inconsistent with the DMA result.
Test code
Regression test included in the PR, based on the work done by @peterhinch and @robert-hh in the linked issue.