[U-Boot] [PATCH 1/2] Use LINK_OFF to access global data

Joakim Tjernlund Joakim.Tjernlund at transmode.se
Thu Oct 29 17:13:43 CET 2009


Accessing global data before relocation needs
special handling if link address != load address.
Use LINK_OFF to calculate the difference.
---
 common/cmd_nvedit.c           |    2 ++
 common/console.c              |   12 +++++++++---
 common/env_common.c           |    2 +-
 cpu/mpc83xx/cpu.c             |   10 +++++-----
 cpu/mpc83xx/cpu_init.c        |   26 ++++++++++++++------------
 cpu/mpc83xx/speed.c           |   28 +++++++++++-----------------
 drivers/serial/serial.c       |   21 +++++++++++----------
 include/common.h              |    1 -
 include/linux/ctype.h         |    6 +++---
 lib_generic/crc32.c           |    7 ++++++-
 lib_generic/ctype.c           |    2 +-
 lib_generic/display_options.c |    5 +++--
 lib_generic/vsprintf.c        |    9 ++++++---
 lib_ppc/board.c               |    5 +++--
 tools/updater/ctype.c         |    2 +-
 15 files changed, 76 insertions(+), 62 deletions(-)

diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 9f8d531..182c6fe 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -512,6 +512,7 @@ char *getenv (char *name)
 {
 	int i, nxt;
 
+	name = LINK_OFF(name);
 	WATCHDOG_RESET();
 
 	for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
@@ -534,6 +535,7 @@ int getenv_r (char *name, char *buf, unsigned len)
 {
 	int i, nxt;
 
+	name = LINK_OFF(name);
 	for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
 		int val, n;
 
diff --git a/common/console.c b/common/console.c
index dc0d13b..afda83a 100644
--- a/common/console.c
+++ b/common/console.c
@@ -346,7 +346,7 @@ void putc(const char c)
 	}
 }
 
-void puts(const char *s)
+static void printf_puts(const char *s)
 {
 #ifdef CONFIG_SILENT_CONSOLE
 	if (gd->flags & GD_FLG_SILENT)
@@ -367,12 +367,18 @@ void puts(const char *s)
 	}
 }
 
+void puts(const char *s)
+{
+	printf_puts(LINK_OFF(s));
+}
+
 void printf(const char *fmt, ...)
 {
 	va_list args;
 	uint i;
 	char printbuffer[CONFIG_SYS_PBSIZE];
 
+	fmt = LINK_OFF(fmt);
 	va_start(args, fmt);
 
 	/* For this to work, printbuffer must be larger than
@@ -382,7 +388,7 @@ void printf(const char *fmt, ...)
 	va_end(args);
 
 	/* Print the string */
-	puts(printbuffer);
+	printf_puts(printbuffer);
 }
 
 void vprintf(const char *fmt, va_list args)
@@ -396,7 +402,7 @@ void vprintf(const char *fmt, va_list args)
 	i = vsprintf(printbuffer, fmt, args);
 
 	/* Print the string */
-	puts(printbuffer);
+	printf_puts(printbuffer);
 }
 
 /* test if ctrl-c was pressed */
diff --git a/common/env_common.c b/common/env_common.c
index 439a4a9..107e711 100644
--- a/common/env_common.c
+++ b/common/env_common.c
@@ -153,7 +153,7 @@ static uchar env_get_char_init (int index)
 	{
 		c = env_get_char_spec(index);
 	} else {
-		c = default_environment[index];
+		c = LINK_OFF(default_environment)[index];
 	}
 
 	return (c);
diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c
index e38a372..12a2a84 100644
--- a/cpu/mpc83xx/cpu.c
+++ b/cpu/mpc83xx/cpu.c
@@ -51,8 +51,8 @@ int checkcpu(void)
 	char buf[32];
 	int i;
 
-	const struct cpu_type {
-		char name[15];
+	static const struct cpu_type {
+		char *name;
 		u32 partid;
 	} cpu_type_list [] = {
 		CPU_TYPE_ENTRY(8311),
@@ -72,6 +72,7 @@ int checkcpu(void)
 		CPU_TYPE_ENTRY(8378),
 		CPU_TYPE_ENTRY(8379),
 	};
+	const struct cpu_type *cpu_ptr = LINK_OFF(cpu_type_list);
 
 	immr = (immap_t *)CONFIG_SYS_IMMR;
 
@@ -99,11 +100,10 @@ int checkcpu(void)
 	}
 
 	spridr = immr->sysconf.spridr;
-
 	for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++)
-		if (cpu_type_list[i].partid == PARTID_NO_E(spridr)) {
+		if (cpu_ptr[i].partid == PARTID_NO_E(spridr)) {
 			puts("MPC");
-			puts(cpu_type_list[i].name);
+			puts(cpu_ptr[i].name);
 			if (IS_E_PROCESSOR(spridr))
 				puts("E");
 			if (REVID_MAJOR(spridr) >= 2)
diff --git a/cpu/mpc83xx/cpu_init.c b/cpu/mpc83xx/cpu_init.c
index 031e8d5..2912dec 100644
--- a/cpu/mpc83xx/cpu_init.c
+++ b/cpu/mpc83xx/cpu_init.c
@@ -42,13 +42,14 @@ static void config_qe_ioports(void)
 	u8	port, pin;
 	int	dir, open_drain, assign;
 	int	i;
-
-	for (i = 0; qe_iop_conf_tab[i].assign != QE_IOP_TAB_END; i++) {
-		port		= qe_iop_conf_tab[i].port;
-		pin		= qe_iop_conf_tab[i].pin;
-		dir		= qe_iop_conf_tab[i].dir;
-		open_drain	= qe_iop_conf_tab[i].open_drain;
-		assign		= qe_iop_conf_tab[i].assign;
+	qe_iop_conf_t *qe_ptr = LINK_OFF(qe_iop_conf_tab);
+
+	for (i = 0; qe_ptr[i].assign != QE_IOP_TAB_END; i++) {
+		port		= qe_ptr[i].port;
+		pin		= qe_ptr[i].pin;
+		dir		= qe_ptr[i].dir;
+		open_drain	= qe_ptr[i].open_drain;
+		assign		= qe_ptr[i].assign;
 		qe_config_iopin(port, pin, dir, open_drain, assign);
 	}
 }
@@ -501,7 +502,7 @@ static int print_83xx_arb_event(int force)
  */
 int prt_83xx_rsr(void)
 {
-	static struct {
+	static const struct reset_type {
 		ulong mask;
 		char *desc;
 	} bits[] = {
@@ -515,7 +516,7 @@ int prt_83xx_rsr(void)
 		RSR_SRS,  "External/Internal Soft"}, {
 		RSR_HRS,  "External/Internal Hard"}
 	};
-	static int n = sizeof bits / sizeof bits[0];
+	const struct reset_type *bp = LINK_OFF(bits);
 	ulong rsr = gd->reset_status;
 	int i;
 	char *sep;
@@ -523,9 +524,10 @@ int prt_83xx_rsr(void)
 	puts("Reset Status:");
 
 	sep = " ";
-	for (i = 0; i < n; i++)
-		if (rsr & bits[i].mask) {
-			printf("%s%s", sep, bits[i].desc);
+	for (i = 0; i < ARRAY_SIZE(bits); i++)
+		if (rsr & bp[i].mask) {
+			puts(sep);
+			puts(bp[i].desc);
 			sep = ", ";
 		}
 	puts("\n");
diff --git a/cpu/mpc83xx/speed.c b/cpu/mpc83xx/speed.c
index bde7e92..001387a 100644
--- a/cpu/mpc83xx/speed.c
+++ b/cpu/mpc83xx/speed.c
@@ -98,7 +98,8 @@ int get_clocks(void)
 	u32 corecnf_tab_index;
 	u8 corepll;
 	u32 lcrr;
-
+	corecnf_t *cnf_tab;
+	int csb_r;
 	u32 csb_clk;
 #if defined(CONFIG_MPC834x) || defined(CONFIG_MPC831x) || defined(CONFIG_MPC837x)
 	u32 tsec1_clk;
@@ -413,28 +414,21 @@ int get_clocks(void)
 		/* corecnf_tab_index is too high, possibly worng value */
 		return -11;
 	}
-	switch (corecnf_tab[corecnf_tab_index].core_csb_ratio) {
-	case _byp:
-	case _x1:
-	case _1x:
+	cnf_tab = LINK_OFF(corecnf_tab);
+	csb_r = cnf_tab[corecnf_tab_index].core_csb_ratio;
+	/* Cannot use a switch stmt here, it uses linked address */
+	if (csb_r == _byp || csb_r == _x1 || csb_r == _1x)
 		core_clk = csb_clk;
-		break;
-	case _1_5x:
+	else if (csb_r == _1_5x)
 		core_clk = (3 * csb_clk) / 2;
-		break;
-	case _2x:
+	else if (csb_r == _2x)
 		core_clk = 2 * csb_clk;
-		break;
-	case _2_5x:
+	else if (csb_r == _2_5x)
 		core_clk = (5 * csb_clk) / 2;
-		break;
-	case _3x:
+	else if (csb_r == _3x)
 		core_clk = 3 * csb_clk;
-		break;
-	default:
-		/* unkown core to csb ratio */
+	else  /* unkown core to csb ratio */
 		return -13;
-	}
 
 #if defined(CONFIG_MPC8360) || defined(CONFIG_MPC832x)
 	qepmf = (im->reset.rcwl & HRCWL_CEPMF) >> HRCWL_CEPMF_SHIFT;
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index dd5f332..4ccfb56 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -85,9 +85,9 @@ static NS16550_t serial_ports[4] = {
 #endif
 };
 
-#define PORT	serial_ports[port-1]
+#define PORT	(LINK_OFF(serial_ports)[port-1])
 #if defined(CONFIG_CONS_INDEX)
-#define CONSOLE	(serial_ports[CONFIG_CONS_INDEX-1])
+#define CONSOLE	(LINK_OFF(serial_ports)[CONFIG_CONS_INDEX-1])
 #endif
 
 #if defined(CONFIG_SERIAL_MULTI)
@@ -159,26 +159,27 @@ static int calc_divisor (NS16550_t port)
 int serial_init (void)
 {
 	int clock_divisor;
+	NS16550_t * sp = LINK_OFF(serial_ports);
 
 #ifdef CONFIG_NS87308
 	initialise_ns87308();
 #endif
 
 #ifdef CONFIG_SYS_NS16550_COM1
-	clock_divisor = calc_divisor(serial_ports[0]);
-	NS16550_init(serial_ports[0], clock_divisor);
+	clock_divisor = calc_divisor(sp[0]);
+	NS16550_init(sp[0], clock_divisor);
 #endif
 #ifdef CONFIG_SYS_NS16550_COM2
-	clock_divisor = calc_divisor(serial_ports[1]);
-	NS16550_init(serial_ports[1], clock_divisor);
+	clock_divisor = calc_divisor(sp[1]);
+	NS16550_init(sp[1], clock_divisor);
 #endif
 #ifdef CONFIG_SYS_NS16550_COM3
-	clock_divisor = calc_divisor(serial_ports[2]);
-	NS16550_init(serial_ports[2], clock_divisor);
+	clock_divisor = calc_divisor(sp[2]);
+	NS16550_init(sp[2], clock_divisor);
 #endif
 #ifdef CONFIG_SYS_NS16550_COM4
-	clock_divisor = calc_divisor(serial_ports[3]);
-	NS16550_init(serial_ports[3], clock_divisor);
+	clock_divisor = calc_divisor(sp[3]);
+	NS16550_init(sp[3], clock_divisor);
 #endif
 
 	return (0);
diff --git a/include/common.h b/include/common.h
index 90c9a13..67add2d 100644
--- a/include/common.h
+++ b/include/common.h
@@ -99,7 +99,6 @@ const void * link_off(const void *);
 #define link_off(x) ((const void *)(x))
 #endif
 #define LINK_OFF(x) ((__typeof__(&(x)[0]))link_off(x))
-#define GOT_OFF(x) LINK_OFF(x)
 #ifdef	CONFIG_4xx
 #include <ppc4xx.h>
 #endif
diff --git a/include/linux/ctype.h b/include/linux/ctype.h
index afa3639..5873c55 100644
--- a/include/linux/ctype.h
+++ b/include/linux/ctype.h
@@ -1,6 +1,6 @@
 #ifndef _LINUX_CTYPE_H
 #define _LINUX_CTYPE_H
-
+#include <common.h>
 /*
  * NOTE! This ctype does not handle EOF like the standard C
  * library is required to.
@@ -15,9 +15,9 @@
 #define _X	0x40	/* hex digit */
 #define _SP	0x80	/* hard space (0x20) */
 
-extern unsigned char _ctype[];
+extern const unsigned char _ctype[];
 
-#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
+#define __ismask(x) (LINK_OFF(_ctype)[(int)(unsigned char)(x)])
 
 #define isalnum(c)	((__ismask(c)&(_U|_L|_D)) != 0)
 #define isalpha(c)	((__ismask(c)&(_U|_L)) != 0)
diff --git a/lib_generic/crc32.c b/lib_generic/crc32.c
index b27048c..2e11548 100644
--- a/lib_generic/crc32.c
+++ b/lib_generic/crc32.c
@@ -148,7 +148,7 @@ const uint32_t * ZEXPORT get_crc_table()
 #endif
 
 /* ========================================================================= */
-#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO1(buf) crc = crc_tab[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
 #define DO2(buf)  DO1(buf); DO1(buf);
 #define DO4(buf)  DO2(buf); DO2(buf);
 #define DO8(buf)  DO4(buf); DO4(buf);
@@ -156,6 +156,11 @@ const uint32_t * ZEXPORT get_crc_table()
 /* ========================================================================= */
 uint32_t ZEXPORT crc32 (uint32_t crc, const Bytef *buf, uInt len)
 {
+#ifdef LINK_OFF
+    const uint32_t *crc_tab = LINK_OFF(crc_table);
+#else
+    const uint32_t *crc_tab = crc_table;
+#endif
 #ifdef DYNAMIC_CRC_TABLE
     if (crc_table_empty)
       make_crc_table();
diff --git a/lib_generic/ctype.c b/lib_generic/ctype.c
index 6ed0468..dffe563 100644
--- a/lib_generic/ctype.c
+++ b/lib_generic/ctype.c
@@ -29,7 +29,7 @@
 
 #include <linux/ctype.h>
 
-unsigned char _ctype[] = {
+const unsigned char _ctype[] = {
 _C,_C,_C,_C,_C,_C,_C,_C,			/* 0-7 */
 _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,		/* 8-15 */
 _C,_C,_C,_C,_C,_C,_C,_C,			/* 16-23 */
diff --git a/lib_generic/display_options.c b/lib_generic/display_options.c
index 2dc2567..6b9fba2 100644
--- a/lib_generic/display_options.c
+++ b/lib_generic/display_options.c
@@ -31,9 +31,9 @@ int display_options (void)
 	extern char version_string[];
 
 #if defined(BUILD_TAG)
-	printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG);
+	printf ("\n\n%s, Build: %s\n\n", LINK_OFF(version_string), LINK_OFF(BUILD_TAG));
 #else
-	printf ("\n\n%s\n\n", version_string);
+	printf ("\n\n%s\n\n", LINK_OFF(version_string));
 #endif
 	return 0;
 }
@@ -49,6 +49,7 @@ void print_size (phys_size_t size, const char *s)
 	phys_size_t d = 1 << 30;		/* 1 GB */
 	char  c = 'G';
 
+	s = LINK_OFF(s);
 	if (size < d) {			/* try MB */
 		c = 'M';
 		d = 1 << 20;
diff --git a/lib_generic/vsprintf.c b/lib_generic/vsprintf.c
index 3d95728..b779f56 100644
--- a/lib_generic/vsprintf.c
+++ b/lib_generic/vsprintf.c
@@ -37,8 +37,8 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
 
 const char hex_asc[] = "0123456789abcdef";
-#define hex_asc_lo(x)   hex_asc[((x) & 0x0f)]
-#define hex_asc_hi(x)   hex_asc[((x) & 0xf0) >> 4]
+#define hex_asc_lo(x)   LINK_OFF(hex_asc)[((x) & 0x0f)]
+#define hex_asc_hi(x)   LINK_OFF(hex_asc)[((x) & 0xf0) >> 4]
 
 static inline char *pack_hex_byte(char *buf, u8 byte)
 {
@@ -303,7 +303,7 @@ static char *number(char *buf, unsigned NUM_TYPE num, int base, int size, int pr
 		int shift = 3;
 		if (base == 16) shift = 4;
 		do {
-			tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
+			tmp[i++] = (LINK_OFF(digits)[((unsigned char)num) & mask] | locase);
 			num >>= shift;
 		} while (num);
 	} else { /* base 10 */
@@ -675,6 +675,7 @@ int sprintf(char * buf, const char *fmt, ...)
 	va_list args;
 	int i;
 
+	fmt = LINK_OFF(fmt);
 	va_start(args, fmt);
 	i=vsprintf(buf,fmt,args);
 	va_end(args);
@@ -684,6 +685,8 @@ int sprintf(char * buf, const char *fmt, ...)
 void panic(const char *fmt, ...)
 {
 	va_list	args;
+
+	fmt = LINK_OFF(fmt);
 	va_start(args, fmt);
 	vprintf(fmt, args);
 	putc('\n');
diff --git a/lib_ppc/board.c b/lib_ppc/board.c
index 765f97a..f9a7d30 100644
--- a/lib_ppc/board.c
+++ b/lib_ppc/board.c
@@ -384,8 +384,9 @@ void board_init_f (ulong bootflag)
 	memset ((void *) gd, 0, sizeof (gd_t));
 #endif
 
-	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
-		if ((*init_fnc_ptr) () != 0) {
+	for (init_fnc_ptr = LINK_OFF(init_sequence); *init_fnc_ptr;
+	     ++init_fnc_ptr) {
+		if (((init_fnc_t *)link_off(*init_fnc_ptr)) () != 0) {
 			hang ();
 		}
 	}
diff --git a/tools/updater/ctype.c b/tools/updater/ctype.c
index 6ed0468..dffe563 100644
--- a/tools/updater/ctype.c
+++ b/tools/updater/ctype.c
@@ -29,7 +29,7 @@
 
 #include <linux/ctype.h>
 
-unsigned char _ctype[] = {
+const unsigned char _ctype[] = {
 _C,_C,_C,_C,_C,_C,_C,_C,			/* 0-7 */
 _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,		/* 8-15 */
 _C,_C,_C,_C,_C,_C,_C,_C,			/* 16-23 */
-- 
1.6.4.4



More information about the U-Boot mailing list