summaryrefslogtreecommitdiff
path: root/core/cortex-m0/vecttable.c
diff options
context:
space:
mode:
authorPatrick Georgi <pgeorgi@google.com>2018-08-16 10:24:30 +0200
committerchrome-bot <chrome-bot@chromium.org>2018-10-16 10:30:36 -0700
commit9a16a6b9cf701d43ba0e7e8f71ac081e15430be3 (patch)
tree2a6ef97c2a80e3c4bc1cf27c369d85ba5cd04ff3 /core/cortex-m0/vecttable.c
parent35720d34cb1b853dce0f04e2909e2c7d92f324bc (diff)
downloadchrome-ec-9a16a6b9cf701d43ba0e7e8f71ac081e15430be3.tar.gz
cortex-m0: Generate vector table in C
Different versions of the linker behave differently when mixing object built with lto enabled (desirable for code size reduction) and disabled (assembler code), especially when they refer to each other symbols: The file evaluation order of the linker becomes important as it eliminates dead code at various points in time, and LTO code referring to non-LTO code or vice versa, is not visible at early runs. Sadly, just changing the order on the command line isn't sufficient: What works for gcc8 breaks gcc6 (and may behave different in even more ways on gcc4 or other versions). Therefore, implement the vector table in C, so it's compiled in LTO mode, just like the code it refers to. This is a port of Change-Id: I9b75f6558f0357e18000ff1161096c8f9c94a8ac BUG=b:65441143 BRANCH=none TEST=with this change the vector table for whiskers looks much more reasonable (ie. not mostly empty) Change-Id: Ifd39289ecb16b81cdf41427ce190984510d3fd3c Signed-off-by: Patrick Georgi <pgeorgi@google.com> Reviewed-on: https://chromium-review.googlesource.com/1120333 Commit-Ready: Patrick Georgi <pgeorgi@chromium.org> Tested-by: Patrick Georgi <pgeorgi@chromium.org> Tested-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org> Reviewed-by: Stefan Reinauer <reinauer@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1177382 Reviewed-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org>
Diffstat (limited to 'core/cortex-m0/vecttable.c')
-rw-r--r--core/cortex-m0/vecttable.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/core/cortex-m0/vecttable.c b/core/cortex-m0/vecttable.c
new file mode 100644
index 0000000000..a4b5c8831d
--- /dev/null
+++ b/core/cortex-m0/vecttable.c
@@ -0,0 +1,136 @@
+/* Copyright (c) 2018 The Chromium OS Authors. All rights reserved.
+ * 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 <stddef.h>
+#include <stdint.h>
+
+#include "config.h"
+#include "panic-internal.h"
+#include "task.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);
+
+#pragma GCC diagnostic push
+#if __GNUC__ >= 8
+#pragma GCC diagnostic ignored "-Wattribute-alias"
+#endif
+#pragma GCC diagnostic pop
+
+#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
+
+#define table(x) func vectors[] __attribute__((section(".text.vecttable,\"a\" @"))) = { 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 == 1
+#undef PASS
+#define PASS 2
+#include "vecttable.c"
+#endif