[U-Boot] [PATCH 3/4] Fix FreeBSD loader API so that it works on both 32-bit and 64-bit targets.

Stanislav Galabov sgalabov at gmail.com
Wed Feb 17 14:23:31 CET 2016


Specifically tested on MIPS under QEMU (works with all  combination of bit-ness and endian-ness)

Signed-off-by: Stanislav Galabov <sgalabov at gmail.com>
---
 api/api.c             | 58 +++++++++++++++++++++++++--------------------------
 examples/api/Makefile |  4 ++++
 examples/api/crt0.S   | 13 ++++++------
 examples/api/glue.c   | 18 ++++++++--------
 4 files changed, 49 insertions(+), 44 deletions(-)

diff --git a/api/api.c b/api/api.c
index c5f6edb..ae1160c 100644
--- a/api/api.c
+++ b/api/api.c
@@ -52,7 +52,7 @@ static int API_getc(va_list ap)
 {
 	int *c;
 
-	if ((c = (int *)va_arg(ap, u_int32_t)) == NULL)
+	if ((c = (int *)va_arg(ap, uintptr_t)) == NULL)
 		return API_EINVAL;
 
 	*c = getc();
@@ -68,7 +68,7 @@ static int API_tstc(va_list ap)
 {
 	int *t;
 
-	if ((t = (int *)va_arg(ap, u_int32_t)) == NULL)
+	if ((t = (int *)va_arg(ap, uintptr_t)) == NULL)
 		return API_EINVAL;
 
 	*t = tstc();
@@ -84,7 +84,7 @@ static int API_putc(va_list ap)
 {
 	char *c;
 
-	if ((c = (char *)va_arg(ap, u_int32_t)) == NULL)
+	if ((c = (char *)va_arg(ap, uintptr_t)) == NULL)
 		return API_EINVAL;
 
 	putc(*c);
@@ -100,7 +100,7 @@ static int API_puts(va_list ap)
 {
 	char *s;
 
-	if ((s = (char *)va_arg(ap, u_int32_t)) == NULL)
+	if ((s = (char *)va_arg(ap, uintptr_t)) == NULL)
 		return API_EINVAL;
 
 	puts(s);
@@ -132,7 +132,7 @@ static int API_get_sys_info(va_list ap)
 {
 	struct sys_info *si;
 
-	si = (struct sys_info *)va_arg(ap, u_int32_t);
+	si = (struct sys_info *)va_arg(ap, uintptr_t);
 	if (si == NULL)
 		return API_ENOMEM;
 
@@ -148,7 +148,7 @@ static int API_udelay(va_list ap)
 {
 	unsigned long *d;
 
-	if ((d = (unsigned long *)va_arg(ap, u_int32_t)) == NULL)
+	if ((d = (unsigned long *)va_arg(ap, unsigned long)) == NULL)
 		return API_EINVAL;
 
 	udelay(*d);
@@ -164,11 +164,11 @@ static int API_get_timer(va_list ap)
 {
 	unsigned long *base, *cur;
 
-	cur = (unsigned long *)va_arg(ap, u_int32_t);
+	cur = (unsigned long *)va_arg(ap, unsigned long);
 	if (cur == NULL)
 		return API_EINVAL;
 
-	base = (unsigned long *)va_arg(ap, u_int32_t);
+	base = (unsigned long *)va_arg(ap, unsigned long);
 	if (base == NULL)
 		return API_EINVAL;
 
@@ -199,7 +199,7 @@ static int API_dev_enum(va_list ap)
 	struct device_info *di;
 
 	/* arg is ptr to the device_info struct we are going to fill out */
-	di = (struct device_info *)va_arg(ap, u_int32_t);
+	di = (struct device_info *)va_arg(ap, uintptr_t);
 	if (di == NULL)
 		return API_EINVAL;
 
@@ -233,7 +233,7 @@ static int API_dev_open(va_list ap)
 	int err = 0;
 
 	/* arg is ptr to the device_info struct */
-	di = (struct device_info *)va_arg(ap, u_int32_t);
+	di = (struct device_info *)va_arg(ap, uintptr_t);
 	if (di == NULL)
 		return API_EINVAL;
 
@@ -265,7 +265,7 @@ static int API_dev_close(va_list ap)
 	int err = 0;
 
 	/* arg is ptr to the device_info struct */
-	di = (struct device_info *)va_arg(ap, u_int32_t);
+	di = (struct device_info *)va_arg(ap, uintptr_t);
 	if (di == NULL)
 		return API_EINVAL;
 
@@ -319,7 +319,7 @@ static int API_dev_write(va_list ap)
 	int err = 0;
 
 	/* 1. arg is ptr to the device_info struct */
-	di = (struct device_info *)va_arg(ap, u_int32_t);
+	di = (struct device_info *)va_arg(ap, uintptr_t);
 	if (di == NULL)
 		return API_EINVAL;
 
@@ -329,12 +329,12 @@ static int API_dev_write(va_list ap)
 		return API_ENODEV;
 
 	/* 2. arg is ptr to buffer from where to get data to write */
-	buf = (void *)va_arg(ap, u_int32_t);
+	buf = (void *)va_arg(ap, uintptr_t);
 	if (buf == NULL)
 		return API_EINVAL;
 
 	/* 3. arg is length of buffer */
-	len = (int *)va_arg(ap, u_int32_t);
+	len = (int *)va_arg(ap, uintptr_t);
 	if (len == NULL)
 		return API_EINVAL;
 	if (*len <= 0)
@@ -387,7 +387,7 @@ static int API_dev_read(va_list ap)
 	int *len_net, *act_len_net;
 
 	/* 1. arg is ptr to the device_info struct */
-	di = (struct device_info *)va_arg(ap, u_int32_t);
+	di = (struct device_info *)va_arg(ap, uintptr_t);
 	if (di == NULL)
 		return API_EINVAL;
 
@@ -397,23 +397,23 @@ static int API_dev_read(va_list ap)
 		return API_ENODEV;
 
 	/* 2. arg is ptr to buffer from where to put the read data */
-	buf = (void *)va_arg(ap, u_int32_t);
+	buf = (void *)va_arg(ap, uintptr_t);
 	if (buf == NULL)
 		return API_EINVAL;
 
 	if (di->type & DEV_TYP_STOR) {
 		/* 3. arg - ptr to var with # of blocks to read */
-		len_stor = (lbasize_t *)va_arg(ap, u_int32_t);
+		len_stor = (lbasize_t *)va_arg(ap, uintptr_t);
 		if (!len_stor)
 			return API_EINVAL;
 		if (*len_stor <= 0)
 			return API_EINVAL;
 
 		/* 4. arg - ptr to var with start block */
-		start = (lbastart_t *)va_arg(ap, u_int32_t);
+		start = (lbastart_t *)va_arg(ap, uintptr_t);
 
 		/* 5. arg - ptr to var where to put the len actually read */
-		act_len_stor = (lbasize_t *)va_arg(ap, u_int32_t);
+		act_len_stor = (lbasize_t *)va_arg(ap, uintptr_t);
 		if (!act_len_stor)
 			return API_EINVAL;
 
@@ -422,14 +422,14 @@ static int API_dev_read(va_list ap)
 	} else if (di->type & DEV_TYP_NET) {
 
 		/* 3. arg points to the var with length of packet to read */
-		len_net = (int *)va_arg(ap, u_int32_t);
+		len_net = (int *)va_arg(ap, uintptr_t);
 		if (!len_net)
 			return API_EINVAL;
 		if (*len_net <= 0)
 			return API_EINVAL;
 
 		/* 4. - ptr to var where to put the len actually read */
-		act_len_net = (int *)va_arg(ap, u_int32_t);
+		act_len_net = (int *)va_arg(ap, uintptr_t);
 		if (!act_len_net)
 			return API_EINVAL;
 
@@ -453,9 +453,9 @@ static int API_env_get(va_list ap)
 {
 	char *name, **value;
 
-	if ((name = (char *)va_arg(ap, u_int32_t)) == NULL)
+	if ((name = (char *)va_arg(ap, uintptr_t)) == NULL)
 		return API_EINVAL;
-	if ((value = (char **)va_arg(ap, u_int32_t)) == NULL)
+	if ((value = (char **)va_arg(ap, uintptr_t)) == NULL)
 		return API_EINVAL;
 
 	*value = getenv(name);
@@ -476,9 +476,9 @@ static int API_env_set(va_list ap)
 {
 	char *name, *value;
 
-	if ((name = (char *)va_arg(ap, u_int32_t)) == NULL)
+	if ((name = (char *)va_arg(ap, uintptr_t)) == NULL)
 		return API_EINVAL;
-	if ((value = (char *)va_arg(ap, u_int32_t)) == NULL)
+	if ((value = (char *)va_arg(ap, uintptr_t)) == NULL)
 		return API_EINVAL;
 
 	setenv(name, value);
@@ -498,9 +498,9 @@ static int API_env_enum(va_list ap)
 	int i, n;
 	char *last, **next;
 
-	last = (char *)va_arg(ap, u_int32_t);
+	last = (char *)va_arg(ap, unsigned long);
 
-	if ((next = (char **)va_arg(ap, u_int32_t)) == NULL)
+	if ((next = (char **)va_arg(ap, uintptr_t)) == NULL)
 		return API_EINVAL;
 
 	if (last == NULL)
@@ -661,14 +661,14 @@ void api_init(void)
 		return;
 	}
 
-	debugf("API sig @ 0x%08x\n", sig);
+	debugf("API sig @ 0x%lX\n", (unsigned long)sig);
 	memcpy(sig->magic, API_SIG_MAGIC, 8);
 	sig->version = API_SIG_VERSION;
 	sig->syscall = &syscall;
 	sig->checksum = 0;
 	sig->checksum = crc32(0, (unsigned char *)sig,
 			      sizeof(struct api_signature));
-	debugf("syscall entry: 0x%08x\n", sig->syscall);
+	debugf("syscall entry: 0x%lX\n", (unsigned long)sig->syscall);
 }
 
 void platform_set_mr(struct sys_info *si, unsigned long start, unsigned long size,
diff --git a/examples/api/Makefile b/examples/api/Makefile
index 4e9b8ea..6cffee7 100644
--- a/examples/api/Makefile
+++ b/examples/api/Makefile
@@ -11,8 +11,12 @@ ifeq ($(ARCH),arm)
 LOAD_ADDR = 0x1000000
 endif
 ifeq ($(ARCH),mips)
+ifdef CONFIG_64BIT
+LOAD_ADDR = 0xffffffff80200000
+else
 LOAD_ADDR = 0x80200000
 endif
+endif
 
 # Resulting ELF and binary exectuables will be named demo and demo.bin
 extra-y = demo
diff --git a/examples/api/crt0.S b/examples/api/crt0.S
index ced2c82..5a7049d 100644
--- a/examples/api/crt0.S
+++ b/examples/api/crt0.S
@@ -41,28 +41,29 @@ syscall:
 	ldr	pc, [ip]
 
 #elif defined(CONFIG_MIPS)
+#include <asm/asm.h>
 	.text
 	.globl __start
 	.ent __start
 __start:
-	sw	$sp, search_hint
+	PTR_S	$sp, search_hint
 	b	main
 	.end __start
 
 	.globl syscall
 	.ent syscall
 syscall:
-	sw	$ra, return_addr
-	lw	$t9, syscall_ptr
+	PTR_S	$ra, return_addr
+	PTR_L	$t9, syscall_ptr
 	jalr	$t9
 	nop
-	lw	$ra, return_addr
+	PTR_L	$ra, return_addr
 	jr	$ra
 	nop
 	.end syscall
 
 return_addr:
-	.align 4
+	.align 8
 	.long 0
 #else
 #error No support for this arch!
@@ -70,7 +71,7 @@ return_addr:
 
 	.globl syscall_ptr
 syscall_ptr:
-	.align	4
+	.align	8
 	.long	0
 
 	.globl search_hint
diff --git a/examples/api/glue.c b/examples/api/glue.c
index d619518..8aabf32 100644
--- a/examples/api/glue.c
+++ b/examples/api/glue.c
@@ -77,7 +77,7 @@ int ub_getc(void)
 {
 	int c;
 
-	if (!syscall(API_GETC, NULL, (uint32_t)&c))
+	if (!syscall(API_GETC, NULL, &c))
 		return -1;
 
 	return c;
@@ -87,7 +87,7 @@ int ub_tstc(void)
 {
 	int t;
 
-	if (!syscall(API_TSTC, NULL, (uint32_t)&t))
+	if (!syscall(API_TSTC, NULL, &t))
 		return -1;
 
 	return t;
@@ -95,12 +95,12 @@ int ub_tstc(void)
 
 void ub_putc(char c)
 {
-	syscall(API_PUTC, NULL, (uint32_t)&c);
+	syscall(API_PUTC, NULL, &c);
 }
 
 void ub_puts(const char *s)
 {
-	syscall(API_PUTS, NULL, (uint32_t)s);
+	syscall(API_PUTS, NULL, s);
 }
 
 /****************************************
@@ -126,7 +126,7 @@ struct sys_info * ub_get_sys_info(void)
 	si.mr_no = UB_MAX_MR;
 	memset(&mr, 0, sizeof(mr));
 
-	if (!syscall(API_GET_SYS_INFO, &err, (u_int32_t)&si))
+	if (!syscall(API_GET_SYS_INFO, &err, &si))
 		return NULL;
 
 	return ((err) ? NULL : &si);
@@ -344,7 +344,7 @@ char * ub_env_get(const char *name)
 {
 	char *value;
 
-	if (!syscall(API_ENV_GET, NULL, (uint32_t)name, (uint32_t)&value))
+	if (!syscall(API_ENV_GET, NULL, name, &value))
 		return NULL;
 
 	return value;
@@ -352,7 +352,7 @@ char * ub_env_get(const char *name)
 
 void ub_env_set(const char *name, char *value)
 {
-	syscall(API_ENV_SET, NULL, (uint32_t)name, (uint32_t)value);
+	syscall(API_ENV_SET, NULL, name, value);
 }
 
 static char env_name[256];
@@ -369,7 +369,7 @@ const char * ub_env_enum(const char *last)
 	 * 'name=val' string), since the API_ENUM_ENV call uses envmatch()
 	 * internally, which handles such case
 	 */
-	if (!syscall(API_ENV_ENUM, NULL, (uint32_t)last, (uint32_t)&env))
+	if (!syscall(API_ENV_ENUM, NULL, last, &env))
 		return NULL;
 
 	if (!env)
@@ -396,7 +396,7 @@ int ub_display_get_info(int type, struct display_info *di)
 {
 	int err = 0;
 
-	if (!syscall(API_DISPLAY_GET_INFO, &err, (uint32_t)type, (uint32_t)di))
+	if (!syscall(API_DISPLAY_GET_INFO, &err, type, di))
 		return API_ESYSC;
 
 	return err;
-- 
1.9.1


More information about the U-Boot mailing list