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

Specifically tested on MIPS under QEMU (works with all combination of bit-ness and endian-ness)
Signed-off-by: Stanislav Galabov sgalabov@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;
participants (1)
-
Stanislav Galabov