summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/gpio.c3
-rw-r--r--common/system.c6
-rw-r--r--core/nds32/config_core.h14
-rw-r--r--include/common.h8
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 */