diff options
author | Tom Hughes <tomhughes@chromium.org> | 2022-04-01 16:20:56 -0700 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-04-11 19:04:06 +0000 |
commit | ed55b93c6cbf9fb327d9945691dfa86c618eb275 (patch) | |
tree | f62e68ab88b1f63892fcdc89fc0284ad8dee0e3a /core/cortex-m | |
parent | cfc6004eb8d2198b5f3a9c56ff6dafb7f984f739 (diff) | |
download | chrome-ec-ed55b93c6cbf9fb327d9945691dfa86c618eb275.tar.gz |
cortex-m/irq_handler: Replace inline asm with C
When building with clang and LTO is enabled, clang optimizes out
"routine" (the interrupt handler) and fails to link. gcc does not
optimize out the routine.
Rewriting IRQ_HANDLER in C makes it compile with both compilers, though
it uses two more instructions.
Before this change the generated assembly for an interrupt handler on
dartmonkey:
arm-none-eabi-objdump -d ./build/dartmonkey/RW/ec.RW.elf
081027a8 <irq_37_handler>:
81027a8: 4670 mov r0, lr
81027aa: b501 push {r0, lr}
81027ac: f7ff ffea bl 8102784 <uart_interrupt>
81027b0: e8bd 4001 ldmia.w sp!, {r0, lr}
81027b4: f009 bbc4 b.w 810bf40 <task_resched_if_needed>
After this change the generated assembly for an interrupt handler on
dartmonkey:
arm-none-eabi-objdump -d ./build/dartmonkey/RW/ec.RW.elf
081027e0 <irq_37_handler>:
81027e0: b507 push {r0, r1, r2, lr}
81027e2: f8cd e004 str.w lr, [sp, #4]
81027e6: f7ff ffe9 bl 81027bc <uart_interrupt>
81027ea: 9801 ldr r0, [sp, #4]
81027ec: b003 add sp, #12
81027ee: f85d eb04 ldr.w lr, [sp], #4
81027f2: f009 bbc5 b.w 810bf80 <task_resched_if_needed>
BRANCH=none
BUG=b:172020503
TEST=make buildall
TEST=./test/run_device_tests.py --board dartmonkey
=> PASS
Signed-off-by: Tom Hughes <tomhughes@chromium.org>
Change-Id: I7029556afc4a760e81885d8f84b7d787f48c4036
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3566661
Reviewed-by: Paul Fagerburg <pfagerburg@chromium.org>
Diffstat (limited to 'core/cortex-m')
-rw-r--r-- | core/cortex-m/irq_handler.h | 18 |
1 files changed, 8 insertions, 10 deletions
diff --git a/core/cortex-m/irq_handler.h b/core/cortex-m/irq_handler.h index 89be593eee..dceda73958 100644 --- a/core/cortex-m/irq_handler.h +++ b/core/cortex-m/irq_handler.h @@ -9,9 +9,10 @@ #define __CROS_EC_IRQ_HANDLER_H #ifdef CONFIG_TASK_PROFILING -#define bl_task_start_irq_handler "bl task_start_irq_handler\n" +#define TASK_START_IRQ_HANDLER(excep_return) \ + task_start_irq_handler(excep_return) #else -#define bl_task_start_irq_handler "" +#define TASK_START_IRQ_HANDLER(excep_return) #endif /* Helper macros to build the IRQ handler and priority struct names */ @@ -23,20 +24,17 @@ */ #define DECLARE_IRQ(irq, routine, priority) DECLARE_IRQ_(irq, routine, priority) #define DECLARE_IRQ_(irq, routine, priority) \ - void IRQ_HANDLER(irq)(void) __attribute__((naked)); \ + void IRQ_HANDLER(irq)(void); \ typedef struct { \ int fake[irq >= CONFIG_IRQ_COUNT ? -1 : 1]; \ } irq_num_check_##irq; \ static void __keep routine(void); \ void IRQ_HANDLER(irq)(void) \ { \ - asm volatile("mov r0, lr\n" \ - "push {r0, lr}\n" \ - bl_task_start_irq_handler \ - "bl "#routine"\n" \ - "pop {r0, lr}\n" \ - "b task_resched_if_needed\n" \ - ); \ + void *ret = __builtin_return_address(0); \ + TASK_START_IRQ_HANDLER(ret); \ + routine(); \ + task_resched_if_needed(ret); \ } \ const struct irq_priority __keep IRQ_PRIORITY(irq) \ __attribute__((section(".rodata.irqprio"))) \ |