Round 56: the DMA transfer carries the correct bytes end to end; the six bytes come later

A window probe on the DMA loop logs the byte the transfer actually carried at fixed indices. For the run whose rx_addr is the overlay the last lines are idx 0 f0 (correct), idx 1 b5 (correct), idx 2444 00 (correct), idx 2445 00 (correct). Earlier lines belong to other, shorter transfers carrying 0xff or the FAP1 bytes, so the load is a sequence and the one that lands carries the right bytes everywhere, including the window that ends up wrong.

DMA and flash paths are exonerated for the last time. That also opens the possibility that the overlay is correct at transfer time, the CRC passes, the app actually runs, and the six bytes are a post-mortem symptom rather than the cause -- the next measurement reads the overlay back within a fraction of a second of MENU and hashes it.

Own mistake recorded: the window probe was meant to write four lines and wrote 2088, because a condition on the loop index alone also matches every short transfer that starts there. This file warns about capping a diagnostic before knowing the shape of the data; this was the same rule in the other direction.
This commit is contained in:
mckero committed 2026-10-02 13:28:13 +08:00
1 parent 10a2ca16a4
commit e5166dba02
2 files changed
+37

No files matched your search

+25
View File
@@ -1317,6 +1317,31 @@ there is exactly one, and it is correct in every field:
2568 bytes, destination exactly the overlay at 0x20000280, receive address incrementing, both channels agreeing
**Round 56: the transfer carries the correct bytes end to end -- the six bytes are written afterwards.**
A window probe on the DMA loop, logging the byte the transfer actually carried at a few fixed indices, prints
this at the end, for the run whose rx_addr is the overlay:
idx 0: transfer f0, app code f0 (correct)
idx 1: transfer b5, app code b5 (correct)
idx 2444: transfer 00, app code 00 (correct)
idx 2445: transfer 00, app code 00 (correct)
Earlier lines in the same log are other, shorter runs -- many of them carrying 0xff or the FAP1 header bytes --
so the load is not one clean transfer but a sequence, and the one that lands in the overlay carries the right
bytes everywhere, including the window that ends up wrong. The DMA and flash paths are therefore exonerated for
the last time, and whatever writes those six bytes does so after the transfer.
That also opens the possibility this file should have considered earlier: if the overlay is correct at transfer
time, the CRC check may pass, the app may actually run, and the six bytes may be a post-mortem symptom rather
than the cause. The next measurement is to read the overlay back within a fraction of a second of MENU and
hash it: correct then means the load and the verification passed.
My own mistake this round is the mirror image of one this file already documents. The window probe was meant to
write four lines and wrote 2088, because a condition on the loop index alone also matches every short transfer
that happens to start there. The file warns about capping a diagnostic before knowing the shape of the data;
this was the other direction -- flooding it -- and the same rule covers both.
**Round 54: the flash model's own data is correct, and so is the DMA -- so the six bytes are written after the transfer.**
The read path in the model is three lines and returns s->data[(s->addr++) % PY25Q16_SIZE], and the model keeps that
+12
View File
@@ -1973,6 +1973,9 @@ static void py32_dma_run_for_spi(PY32DmaState *s, PY32SpiState *spi)
}
}
const char *wp = g_getenv("UVK5_DMA_WINDOW");
uint32_t wi = 0;
while (count > 0) {
uint8_t out = 0xff;
@@ -1982,6 +1985,15 @@ static void py32_dma_run_for_spi(PY32DmaState *s, PY32SpiState *spi)
const uint8_t in = py32_spi_xfer_byte(spi, out);
/* Diagnostic (UVK5_DMA_WINDOW): the bytes this transfer actually carried, in the
* window where the overlay ends up wrong. Separates "the transfer wrote them"
* from "something wrote them afterwards". */
if (wp && (wi == 0u || wi == 1u || wi == 2444u || wi == 2445u || wi == (count - 1u))) {
FILE *f = fopen(wp, "a");
if (f) { fprintf(f, "idx=%u in=%02x rx=0x%08x\n", wi, in, rx_addr); fclose(f); }
}
wi++;
if (rx >= 0) {
address_space_write(as, rx_addr, MEMTXATTRS_UNSPECIFIED, &in, 1);
}