[U-Boot] [PATCH 1/4] API: Use stack pointer as API signature search hint in the glue layer.

De-hardcode range in RAM we search for the API signature. Instead use the stack pointer as a hint to narrow down the range in which the signature could reside (it is malloc'ed on the U-Boot heap, and is hoped to remain in some proximity from stack area). Adjust PowerPC code in API demo to the new scheme.
Signed-off-by: Rafal Czubak rcz@semihalf.com Signed-off-by: Rafal Jaworowski raj@semihalf.com --- api_examples/crt0.S | 14 ++++++++++---- api_examples/glue.c | 11 +++++++++-- api_examples/glue.h | 8 ++++---- 3 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/api_examples/crt0.S b/api_examples/crt0.S index 8d4f706..3129a07 100644 --- a/api_examples/crt0.S +++ b/api_examples/crt0.S @@ -29,6 +29,9 @@
.globl _start _start: + lis %r11, search_hint@ha + addi %r11, %r11, search_hint@l + stw %r1, 0(%r11) b main
@@ -39,12 +42,15 @@ syscall: lwz %r11, 0(%r11) mtctr %r11 bctr - +#else +#error No support for this arch! +#endif
.globl syscall_ptr syscall_ptr: .align 4 .long 0 -#else -#error No support for this arch! -#endif + + .globl search_hint +search_hint: + .long 0 diff --git a/api_examples/glue.c b/api_examples/glue.c index 2bf47ae..200b163 100644 --- a/api_examples/glue.c +++ b/api_examples/glue.c @@ -60,13 +60,20 @@ static int valid_sig(struct api_signature *sig) int api_search_sig(struct api_signature **sig) {
unsigned char *sp; + uint32_t search_start = 0; + uint32_t search_end = 0;
if (sig == NULL) return 0;
- sp = (unsigned char *)API_SEARCH_START; + if (search_hint == 0) + search_hint = 255 * 1024 * 1024;
- while ((sp + (int)API_SIG_MAGLEN) < (unsigned char *)API_SEARCH_END) { + search_start = search_hint & ~0x000fffff; + search_end = search_start + API_SEARCH_LEN - API_SIG_MAGLEN; + + sp = (unsigned char *)search_start; + while ((sp + API_SIG_MAGLEN) < (unsigned char *)search_end) { if (!memcmp(sp, API_SIG_MAGIC, API_SIG_MAGLEN)) { *sig = (struct api_signature *)sp; if (valid_sig(*sig)) diff --git a/api_examples/glue.h b/api_examples/glue.h index a82f783..0adb8b3 100644 --- a/api_examples/glue.h +++ b/api_examples/glue.h @@ -30,12 +30,12 @@ #ifndef _API_GLUE_H_ #define _API_GLUE_H_
-#define API_SEARCH_START (255 * 1024 * 1024) /* start at 1MB below top RAM */ -#define API_SEARCH_END (256 * 1024 * 1024 - 1) /* ...and search to the end */ +#define API_SEARCH_LEN (3 * 1024 * 1024) /* 3MB search range */
-int syscall(int, int *, ...); -void * syscall_ptr; +extern void *syscall_ptr; +extern uint32_t search_hint;
+int syscall(int, int *, ...); int api_search_sig(struct api_signature **sig);
/*

Signed-off-by: Rafal Czubak rcz@semihalf.com Acked-by: Rafal Jaworowski raj@semihalf.com --- api_examples/Makefile | 7 +++---- api_examples/crt0.S | 17 ++++++++++++++++- lib_arm/board.c | 5 +++++ 3 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/api_examples/Makefile b/api_examples/Makefile index 5666f48..4c01437 100644 --- a/api_examples/Makefile +++ b/api_examples/Makefile @@ -23,10 +23,9 @@ ifeq ($(ARCH),ppc) LOAD_ADDR = 0x40000 endif - -#ifeq ($(ARCH),arm) -#LOAD_ADDR = 0xc100000 -#endif +ifeq ($(ARCH),arm) +LOAD_ADDR = 0x1000000 +endif
include $(TOPDIR)/config.mk
diff --git a/api_examples/crt0.S b/api_examples/crt0.S index 3129a07..6daf127 100644 --- a/api_examples/crt0.S +++ b/api_examples/crt0.S @@ -26,7 +26,6 @@ #if defined(CONFIG_PPC)
.text - .globl _start _start: lis %r11, search_hint@ha @@ -42,6 +41,22 @@ syscall: lwz %r11, 0(%r11) mtctr %r11 bctr + +#elif defined(CONFIG_ARM) + + .text + .globl _start +_start: + ldr ip, =search_hint + str sp, [ip] + b main + + + .globl syscall +syscall: + ldr ip, =syscall_ptr + ldr pc, [ip] + #else #error No support for this arch! #endif diff --git a/lib_arm/board.c b/lib_arm/board.c index 2358beb..4cb3f2e 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -404,6 +404,11 @@ void start_armboot (void)
jumptable_init ();
+#if defined(CONFIG_API) + /* Initialize API */ + api_init (); +#endif + console_init_r (); /* fully init console as a device */
#if defined(CONFIG_MISC_INIT_R)

Dear Rafal Jaworowski,
In message 12327136383856-git-send-email-raj@semihalf.com you wrote:
Signed-off-by: Rafal Czubak rcz@semihalf.com Acked-by: Rafal Jaworowski raj@semihalf.com
api_examples/Makefile | 7 +++---- api_examples/crt0.S | 17 ++++++++++++++++- lib_arm/board.c | 5 +++++ 3 files changed, 24 insertions(+), 5 deletions(-)
Applied, thanks.
Best regards,
Wolfgang Denk

Signed-off-by: Rafal Czubak rcz@semihalf.com --- api_examples/demo.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/api_examples/demo.c b/api_examples/demo.c index 69ac318..2510ed8 100644 --- a/api_examples/demo.c +++ b/api_examples/demo.c @@ -135,9 +135,10 @@ int main(int argc, char *argv[])
else if ((rv = ub_dev_read(i, buf, 1, 0)) != 0) errf("could not read from device %d, error %d\n", i, rv); - - printf("Sector 0 dump (512B):\n"); - test_dump_buf(buf, 512); + else { + printf("Sector 0 dump (512B):\n"); + test_dump_buf(buf, 512); + }
ub_dev_close(i); } @@ -178,6 +179,7 @@ int main(int argc, char *argv[]) printf("%s = %s\n", env, ub_env_get(env));
/* reset */ + printf("\n*** Resetting board ***\n"); ub_reset(); printf("\nHmm, reset returned...?!\n");

Dear Rafal Jaworowski,
In message 12327136381068-git-send-email-raj@semihalf.com you wrote:
Signed-off-by: Rafal Czubak rcz@semihalf.com
api_examples/demo.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-)
Applied, thanks.
Best regards,
Wolfgang Denk

- Extend ub_dev_read() and ub_dev_recv() so they return the length actually read, which allows for better control and error handling (this introduces additional error code API_ESYSC returned by the glue mid-layer).
- Clean up definitions naming and usage.
- Other minor cosmetics.
Note these changes do not touch the API proper, so the interface between U-Boot and standalone applications remains unchanged.
Signed-off-by: Rafal Jaworowski raj@semihalf.com --- api_examples/demo.c | 8 ++---- api_examples/glue.c | 58 +++++++++++++++++++++---------------------------- api_examples/glue.h | 16 ++++++++----- include/api_public.h | 1 + 4 files changed, 39 insertions(+), 44 deletions(-)
diff --git a/api_examples/demo.c b/api_examples/demo.c index 2510ed8..df9c4bd 100644 --- a/api_examples/demo.c +++ b/api_examples/demo.c @@ -43,12 +43,11 @@ static char buf[BUF_SZ];
int main(int argc, char *argv[]) { - int rv = 0; - int h, i, j; - int devs_no; + int rv = 0, h, i, j, devs_no; struct api_signature *sig = NULL; ulong start, now; struct device_info *di; + lbasize_t rlen;
if (!api_search_sig(&sig)) return -1; @@ -96,7 +95,6 @@ int main(int argc, char *argv[]) if (devs_no == 0) return -1;
- printf("\n*** Show devices ***\n"); for (i = 0; i < devs_no; i++) { test_dump_di(i); @@ -133,7 +131,7 @@ int main(int argc, char *argv[]) if ((rv = ub_dev_open(i)) != 0) errf("open device %d error %d\n", i, rv);
- else if ((rv = ub_dev_read(i, buf, 1, 0)) != 0) + else if ((rv = ub_dev_read(i, buf, 1, 0, &rlen)) != 0) errf("could not read from device %d, error %d\n", i, rv); else { printf("Sector 0 dump (512B):\n"); diff --git a/api_examples/glue.c b/api_examples/glue.c index 200b163..eff6a7e 100644 --- a/api_examples/glue.c +++ b/api_examples/glue.c @@ -1,7 +1,5 @@ /* - * (C) Copyright 2007 Semihalf - * - * Written by: Rafal Jaworowski raj@semihalf.com + * (C) Copyright 2007-2008 Semihalf, Rafal Jaworowski raj@semihalf.com * * See file CREDITS for list of people who contributed to this * project. @@ -57,8 +55,8 @@ static int valid_sig(struct api_signature *sig) * * returns 1/0 depending on found/not found result */ -int api_search_sig(struct api_signature **sig) { - +int api_search_sig(struct api_signature **sig) +{ unsigned char *sp; uint32_t search_start = 0; uint32_t search_end = 0; @@ -133,8 +131,7 @@ void ub_reset(void) syscall(API_RESET, NULL); }
-#define MR_MAX 5 -static struct mem_region mr[MR_MAX]; +static struct mem_region mr[UB_MAX_MR]; static struct sys_info si;
struct sys_info * ub_get_sys_info(void) @@ -143,7 +140,7 @@ struct sys_info * ub_get_sys_info(void)
memset(&si, 0, sizeof(struct sys_info)); si.mr = mr; - si.mr_no = MR_MAX; + si.mr_no = UB_MAX_MR; memset(&mr, 0, sizeof(mr));
if (!syscall(API_GET_SYS_INFO, &err, (u_int32_t)&si)) @@ -178,17 +175,15 @@ unsigned long ub_get_timer(unsigned long base) * * devices * - * Devices are identified by handles: numbers 0, 1, 2, ..., MAX_DEVS-1 + * Devices are identified by handles: numbers 0, 1, 2, ..., UB_MAX_DEV-1 * ***************************************************************************/
-#define MAX_DEVS 6 - -static struct device_info devices[MAX_DEVS]; +static struct device_info devices[UB_MAX_DEV];
struct device_info * ub_dev_get(int i) { - return ((i < 0 || i >= MAX_DEVS) ? NULL : &devices[i]); + return ((i < 0 || i >= UB_MAX_DEV) ? NULL : &devices[i]); }
/* @@ -202,7 +197,7 @@ int ub_dev_enum(void) struct device_info *di; int n = 0;
- memset(&devices, 0, sizeof(struct device_info) * MAX_DEVS); + memset(&devices, 0, sizeof(struct device_info) * UB_MAX_DEV); di = &devices[0];
if (!syscall(API_DEV_ENUM, NULL, di)) @@ -210,7 +205,7 @@ int ub_dev_enum(void)
while (di->cookie != NULL) {
- if (++n >= MAX_DEVS) + if (++n >= UB_MAX_DEV) break;
/* take another device_info */ @@ -236,7 +231,7 @@ int ub_dev_open(int handle) struct device_info *di; int err = 0;
- if (handle < 0 || handle >= MAX_DEVS) + if (handle < 0 || handle >= UB_MAX_DEV) return API_EINVAL;
di = &devices[handle]; @@ -251,7 +246,7 @@ int ub_dev_close(int handle) { struct device_info *di;
- if (handle < 0 || handle >= MAX_DEVS) + if (handle < 0 || handle >= UB_MAX_DEV) return API_EINVAL;
di = &devices[handle]; @@ -272,7 +267,7 @@ int ub_dev_close(int handle) */ static int dev_valid(int handle) { - if (handle < 0 || handle >= MAX_DEVS) + if (handle < 0 || handle >= UB_MAX_DEV) return 0;
if (devices[handle].state != DEV_STA_OPEN) @@ -292,7 +287,8 @@ static int dev_stor_valid(int handle) return 1; }
-int ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start) +int ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start, + lbasize_t *rlen) { struct device_info *di; lbasize_t act_len; @@ -303,15 +299,12 @@ int ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start)
di = &devices[handle]; if (!syscall(API_DEV_READ, &err, di, buf, &len, &start, &act_len)) - return -1; - - if (err) - return err; + return API_ESYSC;
- if (act_len != len) - return API_EIO; + if (!err && rlen) + *rlen = act_len;
- return 0; + return err; }
static int dev_net_valid(int handle) @@ -325,7 +318,7 @@ static int dev_net_valid(int handle) return 1; }
-int ub_dev_recv(int handle, void *buf, int len) +int ub_dev_recv(int handle, void *buf, int len, int *rlen) { struct device_info *di; int err = 0, act_len; @@ -335,12 +328,12 @@ int ub_dev_recv(int handle, void *buf, int len)
di = &devices[handle]; if (!syscall(API_DEV_READ, &err, di, buf, &len, &act_len)) - return -1; + return API_ESYSC;
- if (err) - return -1; + if (!err && rlen) + *rlen = act_len;
- return act_len; + return (err); }
int ub_dev_send(int handle, void *buf, int len) @@ -353,7 +346,7 @@ int ub_dev_send(int handle, void *buf, int len)
di = &devices[handle]; if (!syscall(API_DEV_WRITE, &err, di, buf, &len)) - return -1; + return API_ESYSC;
return err; } @@ -379,7 +372,6 @@ void ub_env_set(const char *name, char *value) syscall(API_ENV_SET, NULL, (uint32_t)name, (uint32_t)value); }
- static char env_name[256];
const char * ub_env_enum(const char *last) diff --git a/api_examples/glue.h b/api_examples/glue.h index 0adb8b3..6bf47d0 100644 --- a/api_examples/glue.h +++ b/api_examples/glue.h @@ -32,6 +32,9 @@
#define API_SEARCH_LEN (3 * 1024 * 1024) /* 3MB search range */
+#define UB_MAX_MR 5 /* max mem regions number */ +#define UB_MAX_DEV 6 /* max devices number */ + extern void *syscall_ptr; extern uint32_t search_hint;
@@ -39,9 +42,10 @@ int syscall(int, int *, ...); int api_search_sig(struct api_signature **sig);
/* - * ub_ library calls are part of the application, not U-Boot code! They are - * front-end wrappers that are used by the consumer application: they prepare - * arguments for particular syscall and jump to the low level syscall() + * The ub_ library calls are part of the application, not U-Boot code! They + * are front-end wrappers that are used by the consumer application: they + * prepare arguments for particular syscall and jump to the low level + * syscall() */
/* console */ @@ -67,10 +71,10 @@ const char * ub_env_enum(const char *last); int ub_dev_enum(void); int ub_dev_open(int handle); int ub_dev_close(int handle); -int ub_dev_read(int handle, void *buf, - lbasize_t len, lbastart_t start); +int ub_dev_read(int handle, void *buf, lbasize_t len, + lbastart_t start, lbasize_t *rlen); int ub_dev_send(int handle, void *buf, int len); -int ub_dev_recv(int handle, void *buf, int len); +int ub_dev_recv(int handle, void *buf, int len, int *rlen); struct device_info * ub_dev_get(int);
#endif /* _API_GLUE_H_ */ diff --git a/include/api_public.h b/include/api_public.h index d3164f6..5940d81 100644 --- a/include/api_public.h +++ b/include/api_public.h @@ -57,6 +57,7 @@ #define API_ENOMEM 3 /* no memory */ #define API_EBUSY 4 /* busy, occupied etc. */ #define API_EIO 5 /* I/O error */ +#define API_ESYSC 6 /* syscall error */
typedef int (*scp_t)(int, int *, ...);

Dear Rafal Jaworowski,
In message 12327136393883-git-send-email-raj@semihalf.com you wrote:
- Extend ub_dev_read() and ub_dev_recv() so they return the length actually
read, which allows for better control and error handling (this introduces additional error code API_ESYSC returned by the glue mid-layer).
Clean up definitions naming and usage.
Other minor cosmetics.
Note these changes do not touch the API proper, so the interface between U-Boot and standalone applications remains unchanged.
Signed-off-by: Rafal Jaworowski raj@semihalf.com
api_examples/demo.c | 8 ++---- api_examples/glue.c | 58 +++++++++++++++++++++---------------------------- api_examples/glue.h | 16 ++++++++----- include/api_public.h | 1 + 4 files changed, 39 insertions(+), 44 deletions(-)
Applied, thanks.
Best regards,
Wolfgang Denk

Dear Rafal Jaworowski,
In message 12327136383163-git-send-email-raj@semihalf.com you wrote:
De-hardcode range in RAM we search for the API signature. Instead use the stack pointer as a hint to narrow down the range in which the signature could reside (it is malloc'ed on the U-Boot heap, and is hoped to remain in some proximity from stack area). Adjust PowerPC code in API demo to the new scheme.
Signed-off-by: Rafal Czubak rcz@semihalf.com Signed-off-by: Rafal Jaworowski raj@semihalf.com
api_examples/crt0.S | 14 ++++++++++---- api_examples/glue.c | 11 +++++++++-- api_examples/glue.h | 8 ++++---- 3 files changed, 23 insertions(+), 10 deletions(-)
Applied, thanks.
Best regards,
Wolfgang Denk
participants (2)
-
Rafal Jaworowski
-
Wolfgang Denk