summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2015-04-27 14:47:19 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-05-19 02:46:27 +0000
commit2650ff3d70c9933e4c3dcd1401ca66b4426def4a (patch)
tree7a4658b060d3439a525a7562c226358d55424035
parentcb29daa58c0fa5866a7847c454967ef0376c7688 (diff)
downloadchrome-ec-2650ff3d70c9933e4c3dcd1401ca66b4426def4a.tar.gz
Add option to enable GCC LTO
Add CONFIG_LTO to use GCC Link-Time Optimizations to try to reduce the flash footprint of the firmware. Add additional protection to some functions/data to avoid removal by the linker when their usage is not obvious. Signed-off-by: Vincent Palatin <vpalatin@chromium.org> BRANCH=none BUG=none TEST=make buildall (with and without LTO enable on all boards) Change-Id: I586b8c1eda4592b416c85383b65153c1d5ab0059 Reviewed-on: https://chromium-review.googlesource.com/271291 Trybot-Ready: Vincent Palatin <vpalatin@chromium.org> Tested-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Alec Berg <alecaberg@chromium.org> Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--Makefile.toolchain2
-rw-r--r--board/zinger/runtime.c2
-rw-r--r--chip/mec1322/watchdog.c2
-rw-r--r--chip/npcx/watchdog.c2
-rw-r--r--chip/stm32/gpio.c2
-rw-r--r--chip/stm32/hwtimer.c2
-rw-r--r--chip/stm32/hwtimer32.c2
-rw-r--r--common/clz.c4
-rw-r--r--common/main.c2
-rw-r--r--common/version.c4
-rw-r--r--core/cortex-m/build.mk5
-rw-r--r--core/cortex-m/irq_handler.h1
-rw-r--r--core/cortex-m/panic.c4
-rw-r--r--core/cortex-m/task.c6
-rw-r--r--core/cortex-m/watchdog.c2
-rw-r--r--core/cortex-m0/atomic.h2
-rw-r--r--core/cortex-m0/build.mk5
-rw-r--r--core/cortex-m0/panic.c4
-rw-r--r--core/cortex-m0/task.c2
-rw-r--r--include/common.h10
-rw-r--r--include/config.h3
-rw-r--r--include/console.h4
-rw-r--r--include/hooks.h2
-rw-r--r--include/host_command.h2
24 files changed, 51 insertions, 25 deletions
diff --git a/Makefile.toolchain b/Makefile.toolchain
index 8beb7b2c0f..f875751115 100644
--- a/Makefile.toolchain
+++ b/Makefile.toolchain
@@ -55,7 +55,7 @@ LIBFTDI_LDLIBS=$(shell $(PKG_CONFIG) --libs lib${LIBFTDI_NAME})
BUILD_CFLAGS= $(LIBFTDI_CFLAGS) $(CPPFLAGS) -O3 $(CFLAGS_DEBUG) $(CFLAGS_WARN)
HOST_CFLAGS=$(CPPFLAGS) -O3 $(CFLAGS_DEBUG) $(CFLAGS_WARN) -DHOST_TOOLS_BUILD
-LDFLAGS=-nostdlib -Wl,-X -Wl,--gc-sections -Wl,--build-id=none
+LDFLAGS=-nostdlib -Wl,-X -Wl,--gc-sections -Wl,--build-id=none $(LDFLAGS_EXTRA)
BUILD_LDFLAGS=$(LIBFTDI_LDLIBS)
HOST_TEST_LDFLAGS=-T core/host/host_exe.lds -lrt -pthread -rdynamic -lm\
$(if $(TEST_COVERAGE),-fprofile-arcs,)
diff --git a/board/zinger/runtime.c b/board/zinger/runtime.c
index 0dfb51aed4..f2b40cbfd9 100644
--- a/board/zinger/runtime.c
+++ b/board/zinger/runtime.c
@@ -216,7 +216,7 @@ uint32_t task_wait_event(int timeout_us)
return evt;
}
-void cpu_reset(void)
+void __keep cpu_reset(void)
{
/* Disable interrupts */
asm volatile("cpsid i");
diff --git a/chip/mec1322/watchdog.c b/chip/mec1322/watchdog.c
index 3d6c4fc89c..c547b79911 100644
--- a/chip/mec1322/watchdog.c
+++ b/chip/mec1322/watchdog.c
@@ -73,7 +73,7 @@ int watchdog_init(void)
}
#ifdef CONFIG_WATCHDOG_HELP
-void watchdog_check(uint32_t excep_lr, uint32_t excep_sp)
+void __keep watchdog_check(uint32_t excep_lr, uint32_t excep_sp)
{
/* Clear status */
MEC1322_TMR16_STS(0) |= 1;
diff --git a/chip/npcx/watchdog.c b/chip/npcx/watchdog.c
index f72be3cb7b..036a768bb6 100644
--- a/chip/npcx/watchdog.c
+++ b/chip/npcx/watchdog.c
@@ -45,7 +45,7 @@ void watchdog_init_warning_timer(void)
task_enable_irq(ITIM16_INT(ITIM_WDG_NO));
}
-void watchdog_check(uint32_t excep_lr, uint32_t excep_sp)
+void __keep watchdog_check(uint32_t excep_lr, uint32_t excep_sp)
{
int wd_cnt;
/* Clear timeout status for event */
diff --git a/chip/stm32/gpio.c b/chip/stm32/gpio.c
index d58ce29328..683303688f 100644
--- a/chip/stm32/gpio.c
+++ b/chip/stm32/gpio.c
@@ -115,7 +115,7 @@ int gpio_enable_interrupt(enum gpio_signal signal)
/*****************************************************************************/
/* Interrupt handler */
-void gpio_interrupt(void)
+void __keep gpio_interrupt(void)
{
int bit;
/* process only GPIO EXTINTs (EXTINT0..15) not other EXTINTs */
diff --git a/chip/stm32/hwtimer.c b/chip/stm32/hwtimer.c
index a1053e28c8..2658cf5734 100644
--- a/chip/stm32/hwtimer.c
+++ b/chip/stm32/hwtimer.c
@@ -372,7 +372,7 @@ int __hw_clock_source_init(uint32_t start_t)
#ifdef CONFIG_WATCHDOG_HELP
-void watchdog_check(uint32_t excep_lr, uint32_t excep_sp)
+void __keep watchdog_check(uint32_t excep_lr, uint32_t excep_sp)
{
struct timer_ctlr *timer = (struct timer_ctlr *)TIM_WD_BASE;
diff --git a/chip/stm32/hwtimer32.c b/chip/stm32/hwtimer32.c
index e04f540d04..ef6e9321c4 100644
--- a/chip/stm32/hwtimer32.c
+++ b/chip/stm32/hwtimer32.c
@@ -189,7 +189,7 @@ int __hw_clock_source_init(uint32_t start_t)
#define IRQ_WD IRQ_TIM(TIM_WATCHDOG)
-void watchdog_check(uint32_t excep_lr, uint32_t excep_sp)
+void __keep watchdog_check(uint32_t excep_lr, uint32_t excep_sp)
{
/* clear status */
STM32_TIM_SR(TIM_WATCHDOG) = 0;
diff --git a/common/clz.c b/common/clz.c
index 30c987e367..456683b0cd 100644
--- a/common/clz.c
+++ b/common/clz.c
@@ -5,6 +5,8 @@
* Software emulation for CLZ instruction
*/
+#include "common.h"
+
/**
* Count leading zeros
*
@@ -12,7 +14,7 @@
* @return the number of leading 0-bits in x,
* starting at the most significant bit position.
*/
-int __clzsi2(int x)
+int __keep __clzsi2(int x)
{
int r = 0;
diff --git a/common/main.c b/common/main.c
index f30f2970cd..a2f86abdee 100644
--- a/common/main.c
+++ b/common/main.c
@@ -33,7 +33,7 @@
#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
-test_mockable int main(void)
+test_mockable __keep int main(void)
{
/*
* Pre-initialization (pre-verified boot) stage. Initialization at
diff --git a/common/version.c b/common/version.c
index b6cc8e1d8b..331f155571 100644
--- a/common/version.c
+++ b/common/version.c
@@ -11,14 +11,14 @@
#include "ec_version.h"
#include "version.h"
-const struct version_struct version_data
+const struct version_struct __keep version_data
__attribute__((section(".rodata.ver"))) = {
CROS_EC_VERSION_COOKIE1,
CROS_EC_VERSION32,
CROS_EC_VERSION_COOKIE2
};
-const char build_info[] __attribute__((section(".rodata.buildinfo"))) =
+const char build_info[] __keep __attribute__((section(".rodata.buildinfo"))) =
CROS_EC_VERSION " " DATE " " BUILDER;
uint32_t ver_get_numcommits(void)
diff --git a/core/cortex-m/build.mk b/core/cortex-m/build.mk
index 522f6dedeb..5724a9ba39 100644
--- a/core/cortex-m/build.mk
+++ b/core/cortex-m/build.mk
@@ -17,6 +17,11 @@ CFLAGS_CPU+=-mthumb -Os -mno-sched-prolog
CFLAGS_CPU+=-mno-unaligned-access
CFLAGS_CPU+=$(CFLAGS_FPU-y)
+ifneq ($(CONFIG_LTO),)
+CFLAGS_CPU+=-flto
+LDFLAGS_EXTRA+=-flto
+endif
+
core-y=cpu.o init.o ldivmod.o uldivmod.o
core-$(CONFIG_COMMON_PANIC_OUTPUT)+=panic.o
core-$(CONFIG_COMMON_RUNTIME)+=switch.o task.o
diff --git a/core/cortex-m/irq_handler.h b/core/cortex-m/irq_handler.h
index 2b49de15e1..602c3245e4 100644
--- a/core/cortex-m/irq_handler.h
+++ b/core/cortex-m/irq_handler.h
@@ -24,6 +24,7 @@
#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 __keep routine(void); \
void IRQ_HANDLER(irq)(void) \
{ \
asm volatile("mov r0, lr\n" \
diff --git a/core/cortex-m/panic.c b/core/cortex-m/panic.c
index 6b81e8c484..0d484bf1d0 100644
--- a/core/cortex-m/panic.c
+++ b/core/cortex-m/panic.c
@@ -302,7 +302,7 @@ void panic_data_print(const struct panic_data *pdata)
#endif
}
-void report_panic(void)
+void __keep report_panic(void)
{
struct panic_data *pdata = pdata_ptr;
uint32_t sp;
@@ -352,7 +352,7 @@ void report_panic(void)
*
* Declare this as a naked call so we can extract raw LR and IPSR values.
*/
-void exception_panic(void) __attribute__((naked));
+void __keep exception_panic(void) __attribute__((naked));
void exception_panic(void)
{
/* Save registers and branch directly to panic handler */
diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c
index 69b92d5de8..342fcdcf39 100644
--- a/core/cortex-m/task.c
+++ b/core/cortex-m/task.c
@@ -284,7 +284,7 @@ void __schedule(int desched, int resched)
}
#ifdef CONFIG_TASK_PROFILING
-void task_start_irq_handler(void *excep_return)
+void __keep task_start_irq_handler(void *excep_return)
{
/*
* Get time before checking depth, in case this handler is
@@ -312,7 +312,7 @@ void task_start_irq_handler(void *excep_return)
}
#endif
-void task_resched_if_needed(void *excep_return)
+void __keep task_resched_if_needed(void *excep_return)
{
/*
* Continue iff a rescheduling event happened or profiling is active,
@@ -414,7 +414,7 @@ void task_enable_irq(int irq)
CPU_NVIC_EN(irq / 32) = 1 << (irq % 32);
}
-void task_disable_irq(int irq)
+void __keep task_disable_irq(int irq)
{
CPU_NVIC_DIS(irq / 32) = 1 << (irq % 32);
}
diff --git a/core/cortex-m/watchdog.c b/core/cortex-m/watchdog.c
index 8366f48d0a..229009330e 100644
--- a/core/cortex-m/watchdog.c
+++ b/core/cortex-m/watchdog.c
@@ -12,7 +12,7 @@
#include "uart.h"
#include "watchdog.h"
-void watchdog_trace(uint32_t excep_lr, uint32_t excep_sp)
+void __keep watchdog_trace(uint32_t excep_lr, uint32_t excep_sp)
{
uint32_t psp;
uint32_t *stack;
diff --git a/core/cortex-m0/atomic.h b/core/cortex-m0/atomic.h
index 8ba1b66739..62bc2ff370 100644
--- a/core/cortex-m0/atomic.h
+++ b/core/cortex-m0/atomic.h
@@ -23,7 +23,7 @@
#asm_op" %0, %0, %2\n" \
" str %0, [%1]\n" \
" cpsie i\n" \
- : "=&r" (reg0) \
+ : "=&b" (reg0) \
: "b" (a), "r" (v) : "cc"); \
} while (0)
diff --git a/core/cortex-m0/build.mk b/core/cortex-m0/build.mk
index c87df856e0..5f2bc32eb5 100644
--- a/core/cortex-m0/build.mk
+++ b/core/cortex-m0/build.mk
@@ -13,6 +13,11 @@ CROSS_COMPILE?=arm-none-eabi-
CFLAGS_CPU+=-mthumb -Os -mno-sched-prolog
CFLAGS_CPU+=-mno-unaligned-access
+ifneq ($(CONFIG_LTO),)
+CFLAGS_CPU+=-flto
+LDFLAGS_EXTRA+=-flto
+endif
+
core-y=cpu.o init.o thumb_case.o div.o lmul.o ldivmod.o uldivmod.o
core-$(CONFIG_COMMON_PANIC_OUTPUT)+=panic.o
core-$(CONFIG_COMMON_RUNTIME)+=switch.o task.o
diff --git a/core/cortex-m0/panic.c b/core/cortex-m0/panic.c
index 2ba22c6998..cb347054ea 100644
--- a/core/cortex-m0/panic.c
+++ b/core/cortex-m0/panic.c
@@ -104,7 +104,7 @@ void panic_data_print(const struct panic_data *pdata)
print_reg(15, sregs, 6);
}
-void report_panic(void)
+void __keep report_panic(void)
{
struct panic_data *pdata = pdata_ptr;
uint32_t sp;
@@ -139,7 +139,7 @@ void report_panic(void)
*
* Declare this as a naked call so we can extract raw LR and IPSR values.
*/
-void exception_panic(void) __attribute__((naked));
+__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/task.c b/core/cortex-m0/task.c
index ffdbe49595..d26a82b6d2 100644
--- a/core/cortex-m0/task.c
+++ b/core/cortex-m0/task.c
@@ -181,7 +181,7 @@ int task_start_called(void)
/**
* Scheduling system call
*/
-task_ *__svc_handler(int desched, task_id_t resched)
+task_ __attribute__((noinline)) *__svc_handler(int desched, task_id_t resched)
{
task_ *current, *next;
#ifdef CONFIG_TASK_PROFILING
diff --git a/include/common.h b/include/common.h
index 59e66b7f29..af451a3ec9 100644
--- a/include/common.h
+++ b/include/common.h
@@ -58,6 +58,16 @@
#define __packed __attribute__((packed))
#endif
+/*
+ * Force the toolchain to keep a symbol even with Link Time Optimization
+ * activated.
+ *
+ * Useful for C functions called only from assembly or through special sections.
+ */
+#ifndef __keep
+#define __keep __attribute__((used)) __attribute__((externally_visible))
+#endif
+
/* There isn't really a better place for this */
#define C_TO_K(temp_c) ((temp_c) + 273)
#define K_TO_C(temp_c) ((temp_c) - 273)
diff --git a/include/config.h b/include/config.h
index 36c1b3f53a..53232410ac 100644
--- a/include/config.h
+++ b/include/config.h
@@ -970,6 +970,9 @@
/* Support LPC interface */
#undef CONFIG_LPC
+/* Use Link-Time Optimizations to try to reduce the firmware code size */
+#undef CONFIG_LTO
+
/* Presence of a Bosh Sensortec BMM150 magnetometer behind a BMI160. */
#undef CONFIG_MAG_BMI160_BMM150
diff --git a/include/console.h b/include/console.h
index ee6897821d..00036d3632 100644
--- a/include/console.h
+++ b/include/console.h
@@ -134,13 +134,13 @@ void console_has_input(void);
#ifdef CONFIG_CONSOLE_CMDHELP
#define DECLARE_CONSOLE_COMMAND(name, routine, argdesc, shorthelp, longhelp) \
static const char __con_cmd_label_##name[] = #name; \
- const struct console_command __con_cmd_##name \
+ const struct console_command __keep __con_cmd_##name \
__attribute__((section(".rodata.cmds." #name))) \
= {__con_cmd_label_##name, routine, argdesc, shorthelp}
#else
#define DECLARE_CONSOLE_COMMAND(name, routine, argdesc, shorthelp, longhelp) \
static const char __con_cmd_label_##name[] = #name; \
- const struct console_command __con_cmd_##name \
+ const struct console_command __keep __con_cmd_##name \
__attribute__((section(".rodata.cmds." #name))) \
= {__con_cmd_label_##name, routine}
#endif
diff --git a/include/hooks.h b/include/hooks.h
index 15ab778c5b..f5a728d8e1 100644
--- a/include/hooks.h
+++ b/include/hooks.h
@@ -231,7 +231,7 @@ int hook_call_deferred(void (*routine)(void), int us);
* order in which hooks are called.
*/
#define DECLARE_HOOK(hooktype, routine, priority) \
- const struct hook_data CONCAT4(__hook_, hooktype, _, routine) \
+ const struct hook_data __keep CONCAT4(__hook_, hooktype, _, routine) \
__attribute__((section(".rodata." STRINGIFY(hooktype)))) \
= {routine, priority}
diff --git a/include/host_command.h b/include/host_command.h
index f95fe06966..2667cb9a27 100644
--- a/include/host_command.h
+++ b/include/host_command.h
@@ -209,7 +209,7 @@ void host_packet_receive(struct host_packet *pkt);
/* Register a host command handler */
#define DECLARE_HOST_COMMAND(command, routine, version_mask) \
- const struct host_command __host_cmd_##command \
+ const struct host_command __keep __host_cmd_##command \
__attribute__((section(".rodata.hcmds"))) \
= {routine, command, version_mask}