mirror of
https://github.com/smaeul/u-boot.git
synced 2025-10-13 20:36:02 +01:00
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>
This commit is contained in:
parent
713a9e15bb
commit
78757d52c8
58
api/api.c
58
api/api.c
@ -52,7 +52,7 @@ static int API_getc(va_list ap)
|
|||||||
{
|
{
|
||||||
int *c;
|
int *c;
|
||||||
|
|
||||||
if ((c = (int *)va_arg(ap, u_int32_t)) == NULL)
|
if ((c = (int *)va_arg(ap, uintptr_t)) == NULL)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
*c = getc();
|
*c = getc();
|
||||||
@ -68,7 +68,7 @@ static int API_tstc(va_list ap)
|
|||||||
{
|
{
|
||||||
int *t;
|
int *t;
|
||||||
|
|
||||||
if ((t = (int *)va_arg(ap, u_int32_t)) == NULL)
|
if ((t = (int *)va_arg(ap, uintptr_t)) == NULL)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
*t = tstc();
|
*t = tstc();
|
||||||
@ -84,7 +84,7 @@ static int API_putc(va_list ap)
|
|||||||
{
|
{
|
||||||
char *c;
|
char *c;
|
||||||
|
|
||||||
if ((c = (char *)va_arg(ap, u_int32_t)) == NULL)
|
if ((c = (char *)va_arg(ap, uintptr_t)) == NULL)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
putc(*c);
|
putc(*c);
|
||||||
@ -100,7 +100,7 @@ static int API_puts(va_list ap)
|
|||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
if ((s = (char *)va_arg(ap, u_int32_t)) == NULL)
|
if ((s = (char *)va_arg(ap, uintptr_t)) == NULL)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
puts(s);
|
puts(s);
|
||||||
@ -132,7 +132,7 @@ static int API_get_sys_info(va_list ap)
|
|||||||
{
|
{
|
||||||
struct sys_info *si;
|
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)
|
if (si == NULL)
|
||||||
return API_ENOMEM;
|
return API_ENOMEM;
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ static int API_udelay(va_list ap)
|
|||||||
{
|
{
|
||||||
unsigned long *d;
|
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;
|
return API_EINVAL;
|
||||||
|
|
||||||
udelay(*d);
|
udelay(*d);
|
||||||
@ -164,11 +164,11 @@ static int API_get_timer(va_list ap)
|
|||||||
{
|
{
|
||||||
unsigned long *base, *cur;
|
unsigned long *base, *cur;
|
||||||
|
|
||||||
cur = (unsigned long *)va_arg(ap, u_int32_t);
|
cur = (unsigned long *)va_arg(ap, unsigned long);
|
||||||
if (cur == NULL)
|
if (cur == NULL)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
base = (unsigned long *)va_arg(ap, u_int32_t);
|
base = (unsigned long *)va_arg(ap, unsigned long);
|
||||||
if (base == NULL)
|
if (base == NULL)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ static int API_dev_enum(va_list ap)
|
|||||||
struct device_info *di;
|
struct device_info *di;
|
||||||
|
|
||||||
/* arg is ptr to the device_info struct we are going to fill out */
|
/* 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)
|
if (di == NULL)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
@ -233,7 +233,7 @@ static int API_dev_open(va_list ap)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
/* arg is ptr to the device_info struct */
|
/* 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)
|
if (di == NULL)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ static int API_dev_close(va_list ap)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
/* arg is ptr to the device_info struct */
|
/* 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)
|
if (di == NULL)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
@ -319,7 +319,7 @@ static int API_dev_write(va_list ap)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
/* 1. arg is ptr to the device_info struct */
|
/* 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)
|
if (di == NULL)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
@ -329,12 +329,12 @@ static int API_dev_write(va_list ap)
|
|||||||
return API_ENODEV;
|
return API_ENODEV;
|
||||||
|
|
||||||
/* 2. arg is ptr to buffer from where to get data to write */
|
/* 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)
|
if (buf == NULL)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
/* 3. arg is length of buffer */
|
/* 3. arg is length of buffer */
|
||||||
len = (int *)va_arg(ap, u_int32_t);
|
len = (int *)va_arg(ap, uintptr_t);
|
||||||
if (len == NULL)
|
if (len == NULL)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
if (*len <= 0)
|
if (*len <= 0)
|
||||||
@ -387,7 +387,7 @@ static int API_dev_read(va_list ap)
|
|||||||
int *len_net, *act_len_net;
|
int *len_net, *act_len_net;
|
||||||
|
|
||||||
/* 1. arg is ptr to the device_info struct */
|
/* 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)
|
if (di == NULL)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
@ -397,23 +397,23 @@ static int API_dev_read(va_list ap)
|
|||||||
return API_ENODEV;
|
return API_ENODEV;
|
||||||
|
|
||||||
/* 2. arg is ptr to buffer from where to put the read data */
|
/* 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)
|
if (buf == NULL)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
if (di->type & DEV_TYP_STOR) {
|
if (di->type & DEV_TYP_STOR) {
|
||||||
/* 3. arg - ptr to var with # of blocks to read */
|
/* 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)
|
if (!len_stor)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
if (*len_stor <= 0)
|
if (*len_stor <= 0)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
/* 4. arg - ptr to var with start block */
|
/* 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 */
|
/* 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)
|
if (!act_len_stor)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
@ -422,14 +422,14 @@ static int API_dev_read(va_list ap)
|
|||||||
} else if (di->type & DEV_TYP_NET) {
|
} else if (di->type & DEV_TYP_NET) {
|
||||||
|
|
||||||
/* 3. arg points to the var with length of packet to read */
|
/* 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)
|
if (!len_net)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
if (*len_net <= 0)
|
if (*len_net <= 0)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
/* 4. - ptr to var where to put the len actually read */
|
/* 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)
|
if (!act_len_net)
|
||||||
return API_EINVAL;
|
return API_EINVAL;
|
||||||
|
|
||||||
@ -453,9 +453,9 @@ static int API_env_get(va_list ap)
|
|||||||
{
|
{
|
||||||
char *name, **value;
|
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;
|
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;
|
return API_EINVAL;
|
||||||
|
|
||||||
*value = getenv(name);
|
*value = getenv(name);
|
||||||
@ -476,9 +476,9 @@ static int API_env_set(va_list ap)
|
|||||||
{
|
{
|
||||||
char *name, *value;
|
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;
|
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;
|
return API_EINVAL;
|
||||||
|
|
||||||
setenv(name, value);
|
setenv(name, value);
|
||||||
@ -498,9 +498,9 @@ static int API_env_enum(va_list ap)
|
|||||||
int i, n;
|
int i, n;
|
||||||
char *last, **next;
|
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;
|
return API_EINVAL;
|
||||||
|
|
||||||
if (last == NULL)
|
if (last == NULL)
|
||||||
@ -662,14 +662,14 @@ void api_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
setenv_hex("api_address", (unsigned long)sig);
|
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);
|
memcpy(sig->magic, API_SIG_MAGIC, 8);
|
||||||
sig->version = API_SIG_VERSION;
|
sig->version = API_SIG_VERSION;
|
||||||
sig->syscall = &syscall;
|
sig->syscall = &syscall;
|
||||||
sig->checksum = 0;
|
sig->checksum = 0;
|
||||||
sig->checksum = crc32(0, (unsigned char *)sig,
|
sig->checksum = crc32(0, (unsigned char *)sig,
|
||||||
sizeof(struct api_signature));
|
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,
|
void platform_set_mr(struct sys_info *si, unsigned long start, unsigned long size,
|
||||||
|
@ -11,8 +11,12 @@ ifeq ($(ARCH),arm)
|
|||||||
LOAD_ADDR = 0x1000000
|
LOAD_ADDR = 0x1000000
|
||||||
endif
|
endif
|
||||||
ifeq ($(ARCH),mips)
|
ifeq ($(ARCH),mips)
|
||||||
|
ifdef CONFIG_64BIT
|
||||||
|
LOAD_ADDR = 0xffffffff80200000
|
||||||
|
else
|
||||||
LOAD_ADDR = 0x80200000
|
LOAD_ADDR = 0x80200000
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
# Resulting ELF and binary exectuables will be named demo and demo.bin
|
# Resulting ELF and binary exectuables will be named demo and demo.bin
|
||||||
extra-y = demo
|
extra-y = demo
|
||||||
|
@ -41,28 +41,29 @@ syscall:
|
|||||||
ldr pc, [ip]
|
ldr pc, [ip]
|
||||||
|
|
||||||
#elif defined(CONFIG_MIPS)
|
#elif defined(CONFIG_MIPS)
|
||||||
|
#include <asm/asm.h>
|
||||||
.text
|
.text
|
||||||
.globl __start
|
.globl __start
|
||||||
.ent __start
|
.ent __start
|
||||||
__start:
|
__start:
|
||||||
sw $sp, search_hint
|
PTR_S $sp, search_hint
|
||||||
b main
|
b main
|
||||||
.end __start
|
.end __start
|
||||||
|
|
||||||
.globl syscall
|
.globl syscall
|
||||||
.ent syscall
|
.ent syscall
|
||||||
syscall:
|
syscall:
|
||||||
sw $ra, return_addr
|
PTR_S $ra, return_addr
|
||||||
lw $t9, syscall_ptr
|
PTR_L $t9, syscall_ptr
|
||||||
jalr $t9
|
jalr $t9
|
||||||
nop
|
nop
|
||||||
lw $ra, return_addr
|
PTR_L $ra, return_addr
|
||||||
jr $ra
|
jr $ra
|
||||||
nop
|
nop
|
||||||
.end syscall
|
.end syscall
|
||||||
|
|
||||||
return_addr:
|
return_addr:
|
||||||
.align 4
|
.align 8
|
||||||
.long 0
|
.long 0
|
||||||
#else
|
#else
|
||||||
#error No support for this arch!
|
#error No support for this arch!
|
||||||
@ -70,7 +71,7 @@ return_addr:
|
|||||||
|
|
||||||
.globl syscall_ptr
|
.globl syscall_ptr
|
||||||
syscall_ptr:
|
syscall_ptr:
|
||||||
.align 4
|
.align 8
|
||||||
.long 0
|
.long 0
|
||||||
|
|
||||||
.globl search_hint
|
.globl search_hint
|
||||||
|
@ -77,7 +77,7 @@ int ub_getc(void)
|
|||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if (!syscall(API_GETC, NULL, (uint32_t)&c))
|
if (!syscall(API_GETC, NULL, &c))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
@ -87,7 +87,7 @@ int ub_tstc(void)
|
|||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
if (!syscall(API_TSTC, NULL, (uint32_t)&t))
|
if (!syscall(API_TSTC, NULL, &t))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
@ -95,12 +95,12 @@ int ub_tstc(void)
|
|||||||
|
|
||||||
void ub_putc(char c)
|
void ub_putc(char c)
|
||||||
{
|
{
|
||||||
syscall(API_PUTC, NULL, (uint32_t)&c);
|
syscall(API_PUTC, NULL, &c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ub_puts(const char *s)
|
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;
|
si.mr_no = UB_MAX_MR;
|
||||||
memset(&mr, 0, sizeof(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 NULL;
|
||||||
|
|
||||||
return ((err) ? NULL : &si);
|
return ((err) ? NULL : &si);
|
||||||
@ -344,7 +344,7 @@ char * ub_env_get(const char *name)
|
|||||||
{
|
{
|
||||||
char *value;
|
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 NULL;
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
@ -352,7 +352,7 @@ char * ub_env_get(const char *name)
|
|||||||
|
|
||||||
void ub_env_set(const char *name, char *value)
|
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];
|
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()
|
* 'name=val' string), since the API_ENUM_ENV call uses envmatch()
|
||||||
* internally, which handles such case
|
* 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;
|
return NULL;
|
||||||
|
|
||||||
if (!env)
|
if (!env)
|
||||||
@ -396,7 +396,7 @@ int ub_display_get_info(int type, struct display_info *di)
|
|||||||
{
|
{
|
||||||
int err = 0;
|
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 API_ESYSC;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user