Skip to content

Clean the last cache line of an unaligned range - #709

Open
jseketa wants to merge 1 commit into
rust-embedded:mainfrom
jseketa:clean-dcache-last-line
Open

jseketa wants to merge 1 commit into
rust-embedded:mainfrom
jseketa:clean-dcache-last-line

Conversation

@jseketa

@jseketa jseketa commented Nov 3, 2026

Copy link
Copy Markdown

Fixes #708

The bug:

  1. clean_dcache_by_address rounds addr down to a line.
  2. It counts the lines from size alone.
  3. A range that does not start on a line misses its last line.
  4. clean_invalidate_dcache_by_address does the same.

The fix:

  1. Added dcache_lines.
  2. It rounds the first byte down to its line.
  3. It rounds the last byte down to its line.
  4. It counts the lines from the first to the last.
  5. Both functions use it.

invalidate_dcache_by_address is unchanged.
It requires an aligned addr and size.
For aligned input the old and the new count agree.

Overflow guard:

  1. The last byte is addr + size - 1.
  2. Its address fits for every range, also one that ends at the top of the address space.
  3. Rounding the end, addr + size, up would overflow there.
  4. That is a panic in debug builds and a wrong count in release builds.
  5. A range that runs past the top stops at the top (saturating_add).
  6. It does not wrap around to address 0.

The test, dcache_lines_cover_an_unaligned_range:

  1. A 1460-byte range 20 bytes into a line needs 47 lines.
  2. Every range of 1 to 200 bytes, at 64 start offsets, is fully covered.
  3. None of them gets an extra line.
  4. Ranges in the last line of the address space count without overflow.
  5. A range past the top stops at the top.

The test fails without the fix:

  • With the old count: 46 lines instead of 47.
  • With the end rounded up: attempt to add with overflow.

Tested:

  • cargo test --all --exclude cortex-m-rt --exclude testsuite --features cortex-m/critical-section-single-core: passes
  • cargo clippy --all --features cortex-m/critical-section-single-core -- -D warnings: no warnings
  • cargo fmt --all -- --check: clean
  • cargo build -p cortex-m --target thumbv7em-none-eabihf: no warnings
  • cargo build -p cortex-m --target thumbv6m-none-eabi: no warnings

clean_dcache_by_address rounded addr down to a line.
It counted the lines from size alone.
A range that does not start on a line missed its last line.
clean_invalidate_dcache_by_address did the same.

Count from the line of the first byte to the line of the last byte.
The last byte's address cannot overflow.
A range past the top of the address space stops at the top.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

clean_dcache_by_address misses the last cache line when addr is not line-aligned

1 participant