From f46b67134b57d00cbb188f2e2e2b45b3ae962c29 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 13 Aug 2026 11:55:11 +0200 Subject: [PATCH] Fix "Out of range pc-relative fixup value" with dcache asm. Fixes #682 --- cortex-m/CHANGELOG.md | 5 +++++ cortex-m/src/peripheral/scb.rs | 12 ++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/cortex-m/CHANGELOG.md b/cortex-m/CHANGELOG.md index d88407fa..c65958e4 100644 --- a/cortex-m/CHANGELOG.md +++ b/cortex-m/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed +- `SCB::enable_icache` and `SCB::enable_dcache` now build the CCR address with + `movw`/`movt` instead of `ldr =`, fixing "out of range pc-relative fixup value" + errors when the asm block is inlined into a large function. + ## [v0.7.8] - 2026-07-21 ### Deprecated diff --git a/cortex-m/src/peripheral/scb.rs b/cortex-m/src/peripheral/scb.rs index 278638b3..678657dc 100644 --- a/cortex-m/src/peripheral/scb.rs +++ b/cortex-m/src/peripheral/scb.rs @@ -368,7 +368,11 @@ impl SCB { // its own, and is only `unsafe` here because it's asm. unsafe { asm!( - "ldr {0}, =0xE000ED14", // CCR + // Build the CCR address (0xE000ED14) with movw/movt instead of `ldr =`, as the + // latter emits a PC-relative load from a literal pool which can end up out of + // range when this asm block is inlined into a large function. + "movw {0}, #0xED14", // CCR address, lower half + "movt {0}, #0xE000", // CCR address, upper half "mrs {2}, PRIMASK", // save critical nesting info "cpsid i", // mask interrupts "ldr {1}, [{0}]", // read CCR @@ -454,7 +458,11 @@ impl SCB { unsafe { asm!( // Should this be replaced with a register modify? - "ldr {0}, =0xE000ED14", // CCR + // Build the CCR address (0xE000ED14) with movw/movt instead of `ldr =`, as the + // latter emits a PC-relative load from a literal pool which can end up out of + // range when this asm block is inlined into a large function. + "movw {0}, #0xED14", // CCR address, lower half + "movt {0}, #0xE000", // CCR address, upper half "mrs {2}, PRIMASK", // save critical nesting info "cpsid i", // mask interrupts "ldr {1}, [{0}]", // read CCR