summaryrefslogtreecommitdiff
path: root/core/cortex-m0
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
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')
-rw-r--r--core/cortex-m0/build.mk1
-rw-r--r--core/cortex-m0/ec.lds.S2
-rw-r--r--core/cortex-m0/init.S65
-rw-r--r--core/cortex-m0/panic-internal.h11
-rw-r--r--core/cortex-m0/panic.c2
-rw-r--r--core/cortex-m0/vecttable.c136
6 files changed, 150 insertions, 67 deletions
diff --git a/core/cortex-m0/build.mk b/core/cortex-m0/build.mk
index 2023bd9607..4f2f749977 100644
--- a/core/cortex-m0/build.mk
+++ b/core/cortex-m0/build.mk
@@ -19,6 +19,7 @@ LDFLAGS_EXTRA+=-flto
endif
core-y=cpu.o init.o thumb_case.o div.o lmul.o ldivmod.o mula.o uldivmod.o
+core-y+=vecttable.o
core-$(CONFIG_COMMON_PANIC_OUTPUT)+=panic.o
core-$(CONFIG_COMMON_RUNTIME)+=switch.o task.o
diff --git a/core/cortex-m0/ec.lds.S b/core/cortex-m0/ec.lds.S
index 2b4a88d85a..c72ec5a5cc 100644
--- a/core/cortex-m0/ec.lds.S
+++ b/core/cortex-m0/ec.lds.S
@@ -40,7 +40,7 @@ SECTIONS
} > SHARED_LIB
#endif
.text : {
- STRINGIFY(OUTDIR/core/CORE/init.o) (.text.vecttable)
+ *(.text.vecttable)
. = ALIGN(4);
__image_data_offset = .;
KEEP(*(.rodata.ver))
diff --git a/core/cortex-m0/init.S b/core/cortex-m0/init.S
index 9b8a774415..0aa587f128 100644
--- a/core/cortex-m0/init.S
+++ b/core/cortex-m0/init.S
@@ -7,71 +7,6 @@
#include "config.h"
-.section .text.vecttable
-
-.macro vector name
-.long \name\()_handler
-.weak \name\()_handler
-.set \name\()_handler, default_handler
-.endm
-
-.macro vector_irq number
-.if \number < CONFIG_IRQ_COUNT
-vector irq_\()\number
-.endif
-.endm
-
-/* Exceptions vector */
-vectors:
-.long stack_end @ initial stack pointer
-.long reset @ reset handler
-vector nmi @ NMI handler
-vector hard_fault @ HardFault handler
-vector mpu_fault @ MPU fault handler
-vector bus_fault @ Bus fault handler
-vector usage_fault @ Usage fault handler
-.long 0 @ reserved
-.long 0 @ reserved
-.long 0 @ reserved
-.long 0 @ reserved
-vector svc @ SWI
-vector debug @ Debug handler
-.long 0 @ reserved
-vector pendsv @ PendSV handler
-vector sys_tick @ SysTick handler
-vector_irq 0 @ IRQ 0 handler
-vector_irq 1 @ IRQ 1 handler
-vector_irq 2 @ IRQ 2 handler
-vector_irq 3 @ IRQ 3 handler
-vector_irq 4 @ IRQ 4 handler
-vector_irq 5 @ IRQ 5 handler
-vector_irq 6 @ IRQ 6 handler
-vector_irq 7 @ IRQ 7 handler
-vector_irq 8 @ IRQ 8 handler
-vector_irq 9 @ IRQ 9 handler
-vector_irq 10 @ IRQ 10 handler
-vector_irq 11 @ IRQ 11 handler
-vector_irq 12 @ IRQ 12 handler
-vector_irq 13 @ IRQ 13 handler
-vector_irq 14 @ IRQ 14 handler
-vector_irq 15 @ IRQ 15 handler
-vector_irq 16 @ IRQ 16 handler
-vector_irq 17 @ IRQ 17 handler
-vector_irq 18 @ IRQ 18 handler
-vector_irq 19 @ IRQ 19 handler
-vector_irq 20 @ IRQ 20 handler
-vector_irq 21 @ IRQ 21 handler
-vector_irq 22 @ IRQ 22 handler
-vector_irq 23 @ IRQ 23 handler
-vector_irq 24 @ IRQ 24 handler
-vector_irq 25 @ IRQ 25 handler
-vector_irq 26 @ IRQ 26 handler
-vector_irq 27 @ IRQ 27 handler
-vector_irq 28 @ IRQ 28 handler
-vector_irq 29 @ IRQ 29 handler
-vector_irq 30 @ IRQ 30 handler
-vector_irq 31 @ IRQ 31 handler
-
#ifdef CHIP_FAMILY_STM32F0
/* Allocate space for SRAM vector table at SRAM based address */
.section .bss.vector_table
diff --git a/core/cortex-m0/panic-internal.h b/core/cortex-m0/panic-internal.h
new file mode 100644
index 0000000000..cd30849f53
--- /dev/null
+++ b/core/cortex-m0/panic-internal.h
@@ -0,0 +1,11 @@
+/* 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.
+ */
+
+#ifndef __CROS_EC_PANIC_INTERNAL_H
+#define __CROS_EC_PANIC_INTERNAL_H
+
+void exception_panic(void) __attribute__((noreturn, naked));
+
+#endif /* __CROS_EC_PANIC_INTERNAL_H */
diff --git a/core/cortex-m0/panic.c b/core/cortex-m0/panic.c
index 02adb63164..b8777784e2 100644
--- a/core/cortex-m0/panic.c
+++ b/core/cortex-m0/panic.c
@@ -8,6 +8,7 @@
#include "cpu.h"
#include "host_command.h"
#include "panic.h"
+#include "panic-internal.h"
#include "printf.h"
#include "system.h"
#include "task.h"
@@ -138,7 +139,6 @@ void __keep report_panic(void)
*
* Declare this as a naked call so we can extract raw LR and IPSR values.
*/
-__keep void exception_panic(void) __attribute__((naked));
void exception_panic(void)
{
/* Save registers and branch directly to panic handler */
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