From 96e034f366eacc4bfaed87685d4536dae1e1b91c Mon Sep 17 00:00:00 2001 From: Vincent Palatin Date: Thu, 14 Nov 2013 15:36:49 -0800 Subject: [PATCH] nds32: WORKAROUND for toolchain bug on rodata Sometimes the toolchain tries to put a relocation which is not suitable to access variables in a read-only section. The nds32 gcc uses GP-relative signed 17-bit relocation to access variables stored in .rodata (eg lwi.gp $r0, [ +gp ]) That's wrong since $gp is pointing in the middle of .data and .bss in the SRAM, while .rodata is sitting in flash. Since on IT8380, the flash is at 0x00000 and the SRAM is at 0x80000 (512kB further), the linker will fail trying to create the signed 17-bit relocation (it detect that it needs to truncate it) Force the compiler to put another relocation as a workaround for now. Signed-off-by: Vincent Palatin BRANCH=none BUG=chrome-os-partner:24378 TEST=./util/make_all.sh ; make BOARD=it8380dev check "version" and "gpioget" on spring, link and it8380dev. Change-Id: Ife50adf3a26be28f113292f73a1a70e8d74b5d8c Reviewed-on: https://chromium-review.googlesource.com/176913 Reviewed-by: Vincent Palatin Commit-Queue: Vincent Palatin Tested-by: Vincent Palatin --- common/gpio.c | 3 ++- common/system.c | 6 +++--- core/nds32/config_core.h | 14 ++++++++++++++ include/common.h | 8 ++++++++ 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/common/gpio.c b/common/gpio.c index 93f6c0c2bb..43abdad0d4 100644 --- a/common/gpio.c +++ b/common/gpio.c @@ -64,10 +64,11 @@ static int last_val_changed(int i, int v) void gpio_config_module(enum module_id id, int enable) { const struct gpio_alt_func *af = gpio_alt_funcs; + int count = RO(gpio_alt_funcs_count); int i; /* Set module's pins to alternate functions */ - for (i = 0; i < gpio_alt_funcs_count; i++, af++) { + for (i = 0; i < count; i++, af++) { if (id != af->module_id) continue; /* Pins for some other module */ diff --git a/common/system.c b/common/system.c index 287fd15b42..5a3e9f9e03 100644 --- a/common/system.c +++ b/common/system.c @@ -460,7 +460,7 @@ const char *system_get_version(enum system_image_copy_t copy) /* Handle version of current image */ if (copy == system_get_image_copy() || copy == SYSTEM_IMAGE_UNKNOWN) - return version_data.version; + return &RO(version_data).version[0]; addr = get_base(copy); if (addr == 0xffffffff) @@ -473,8 +473,8 @@ const char *system_get_version(enum system_image_copy_t copy) /* Make sure the version struct cookies match before returning the * version string. */ v = (const struct version_struct *)addr; - if (v->cookie1 == version_data.cookie1 && - v->cookie2 == version_data.cookie2) + if (v->cookie1 == RO(version_data).cookie1 && + v->cookie2 == RO(version_data).cookie2) return v->version; return ""; diff --git a/core/nds32/config_core.h b/core/nds32/config_core.h index 57909a263a..d7a25d27da 100644 --- a/core/nds32/config_core.h +++ b/core/nds32/config_core.h @@ -10,4 +10,18 @@ #define BFD_ARCH nds32 #define BFD_FORMAT "elf32-nds32le" + +/* + * Force the compiler to use a proper relocation when accessing an external + * variable in a read-only section. + * TODO(crosbug.com/p/24378): remove me when the nds32 toolchain bug is fixed. + */ +#undef RO +#define RO(var) \ +({ \ + typeof(var) *__ptr_val; \ + asm volatile("la %0, " #var "\n" : "=r"(__ptr_val)); \ + ((typeof(var))(*__ptr_val)); \ +}) + #endif /* __CONFIG_CORE_H */ diff --git a/include/common.h b/include/common.h index b15b72e629..5f236a1f35 100644 --- a/include/common.h +++ b/include/common.h @@ -110,4 +110,12 @@ enum ec_error_list { #define test_export_static static #endif +/* + * accessor allowing to override some read only data accesses. + * used to workaround a buggy toolchain (cf http://crosbug.com/p/24378) + */ +#ifndef RO +#define RO(var) var +#endif + #endif /* __CROS_EC_COMMON_H */