diff options
-rw-r--r-- | common/gpio.c | 3 | ||||
-rw-r--r-- | common/system.c | 6 | ||||
-rw-r--r-- | core/nds32/config_core.h | 14 | ||||
-rw-r--r-- | 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 */ |