| /* Copyright 2018 The ChromiumOS Authors |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| * |
| * Cortex-M CPU vector table |
| */ |
| |
| #ifndef ___INIT |
| #define ___INIT |
| #include "compiler.h" |
| #include "config.h" |
| #include "panic-internal.h" |
| #include "task.h" |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| #endif /* __INIT */ |
| |
| typedef void (*func)(void); |
| |
| #ifndef PASS |
| #define PASS 1 |
| #endif |
| |
| #if PASS == 1 |
| |
| void __attribute__((naked)) default_handler(void) |
| { |
| /* |
| * An (enforced) long tail call to preserve exn_return in lr without |
| * restricting the relative placement of default_handler and |
| * exception_panic. |
| */ |
| asm volatile("bx %0\n" : : "r"(exception_panic)); |
| } |
| |
| #define table(x) x |
| |
| /* Note: the alias target must be defined in this translation unit */ |
| #define weak_with_default __attribute__((used, weak, alias("default_handler"))) |
| |
| #define vec(name) extern void weak_with_default name##_handler(void); |
| #define irq(num) vec(irq_##num) |
| |
| #define item(name) extern void name(void); |
| #define null |
| |
| extern void stack_end(void); /* not technically correct, it's just a pointer */ |
| extern void reset(void); |
| |
| #endif /* PASS 1 */ |
| |
| #if PASS == 2 |
| #undef table |
| #undef vec |
| #undef irq |
| #undef item |
| #undef null |
| |
| /* number of elements before the first irq vector */ |
| #define IRQ_OFFSET 16 |
| /* element in the table that is null: extra IRQs are routed there, |
| * then finally overwritten |
| */ |
| #define IRQ_UNUSED_OFFSET 8 |
| |
| /* Disable warning that "initializer overrides prior initialization of this |
| * subobject", since we are explicitly doing this to handle the unused IRQs. |
| */ |
| DISABLE_CLANG_WARNING("-Winitializer-overrides") |
| |
| #define table(x) \ |
| const func vectors[] __attribute__(( \ |
| section(".text.vecttable"))) = { x[IRQ_UNUSED_OFFSET] = null } |
| |
| #define vec(name) name##_handler, |
| #define irq(num) \ |
| [num < CONFIG_IRQ_COUNT ? num + IRQ_OFFSET : IRQ_UNUSED_OFFSET] = \ |
| vec(irq_##num) |
| |
| #define item(name) name, |
| #define null (void *)0, |
| #endif /* PASS 2 */ |
| |
| table(item(stack_end) item(reset) vec(nmi) vec(hard_fault) vec(mpu_fault) vec( |
| bus_fault) vec(usage_fault) null null null null vec(svc) vec(debug) |
| null vec(pendsv) vec(sys_tick) irq(0) irq(1) irq(2) irq(3) irq(4) |
| irq(5) irq(6) irq(7) irq(8) irq(9) irq(10) irq(11) irq(12) |
| irq(13) irq(14) irq(15) irq(16) irq(17) irq(18) |
| irq(19) irq(20) irq(21) irq(22) irq(23) |
| irq(24) irq(25) irq(26) irq(27) |
| irq(28) irq(29) irq(30) |
| irq(31)); |
| |
| #if PASS == 2 |
| ENABLE_CLANG_WARNING("-Winitializer-overrides") |
| #endif |
| |
| #if PASS == 1 |
| #undef PASS |
| #define PASS 2 |
| #include "vecttable.c" |
| #endif |