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 <vpalatin@chromium.org>

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 <vpalatin@chromium.org>
Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
Vincent Palatin
2013-11-14 15:36:49 -08:00
committed by chrome-internal-fetch
parent 93cc00fde1
commit 96e034f366
4 changed files with 27 additions and 4 deletions

View File

@@ -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 */

View File

@@ -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 "";

View File

@@ -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 */

View File

@@ -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 */