Skip to content
Snippets Groups Projects
Commit 78757d52 authored by Stanislav Galabov's avatar Stanislav Galabov Committed by Daniel Schwierzeck
Browse files

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: default avatarStanislav Galabov <sgalabov@gmail.com>
parent 713a9e15
No related branches found
No related tags found
No related merge requests found
......@@ -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)
......@@ -662,14 +662,14 @@ void api_init(void)
}
setenv_hex("api_address", (unsigned long)sig);
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,
......
......@@ -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
......
......@@ -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
......
......@@ -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;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment