From 39c64c0cc46969abf8928848ad9a543b4d83c248 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 6 Sep 2017 00:55:55 +0200 Subject: [PATCH] Use far-ranged jumps for DH_TRAMPOLINE Fixes japaric/cortex-m-rtfm#42 Note that this will make all generated crates that target an armv6 device fail to compile unless they add a build script enabling the added `cfg`. --- src/generate.rs | 56 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/src/generate.rs b/src/generate.rs index 84f5efc7..7ff894d6 100644 --- a/src/generate.rs +++ b/src/generate.rs @@ -87,7 +87,7 @@ pub fn device( }); } - ::generate::interrupt(target, &d.peripherals, items); + ::generate::interrupt(d, target, &d.peripherals, items); const CORE_PERIPHERALS: &[&str] = &[ "CPUID", @@ -173,6 +173,7 @@ pub fn device( /// Generates code for `src/interrupt.rs` pub fn interrupt( + device: &Device, target: &Target, peripherals: &[Peripheral], items: &mut Vec, @@ -241,21 +242,48 @@ pub fn interrupt( let n = util::unsuffixed(u64(pos)); match *target { Target::CortexM => { - mod_items.push(quote! { - #[cfg(all(target_arch = "arm", feature = "rt"))] - global_asm!(" - .thumb_func - DH_TRAMPOLINE: - b DEFAULT_HANDLER - "); + let is_armv6 = match device.cpu { + Some(ref cpu) if cpu.name.starts_with("CM0") => true, + _ => false, + }; - /// Hack to compile on x86 - #[cfg(all(target_arch = "x86_64", feature = "rt"))] - global_asm!(" - DH_TRAMPOLINE: - jmp DEFAULT_HANDLER - "); + if is_armv6 { + // Cortex-M0(+) are ARMv6 and don't have `b.w` (branch with 16 MB range). This + // can cause linker errors when the handler is too far away. Instead of a small + // inline assembly shim, we generate a function for those targets and let the + // compiler do the work (sacrificing a few bytes of code). + mod_items.push(quote! { + #[cfg(feature = "rt")] + extern "C" { + fn DEFAULT_HANDLER(); + } + + #[cfg(feature = "rt")] + #[allow(non_snake_case)] + #[no_mangle] + pub unsafe extern "C" fn DH_TRAMPOLINE() { + DEFAULT_HANDLER(); + } + }); + } else { + mod_items.push(quote! { + #[cfg(all(target_arch = "arm", feature = "rt"))] + global_asm!(" + .thumb_func + DH_TRAMPOLINE: + b DEFAULT_HANDLER + "); + + /// Hack to compile on x86 + #[cfg(all(target_arch = "x86_64", feature = "rt"))] + global_asm!(" + DH_TRAMPOLINE: + jmp DEFAULT_HANDLER + "); + }) + } + mod_items.push(quote! { #[cfg(feature = "rt")] global_asm!(#aliases);