[U-Boot-Users] [PATCH] API: Optimize signature searching scheme in the glue layer.

De-hard code the range in RAM we search for API signature, which might not be uniform accross architectures and board configurations. Instead use current global_data pointer as a hint to narrow down the range the [malloc'ed] signature could reside.
Signed-off-by: Rafal Czubak rcz@semihalf.com Signed-off-by: Rafal Jaworowski raj@semihalf.com --- api_examples/crt0.S | 17 +++++++++++------ api_examples/glue.c | 17 ++++++++++++----- api_examples/glue.h | 6 +++--- 3 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/api_examples/crt0.S b/api_examples/crt0.S index 8d4f706..80b7297 100644 --- a/api_examples/crt0.S +++ b/api_examples/crt0.S @@ -24,14 +24,16 @@ */
#if defined(CONFIG_PPC) - .text
.globl _start _start: + /* Store global data ptr as a hint for U-Boot address range */ + lis %r11, gd_ptr@ha + addi %r11, %r11, gd_ptr@l + stw %r2, 0(%r11) b main
- .globl syscall syscall: lis %r11, syscall_ptr@ha @@ -39,12 +41,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 gd_ptr +gd_ptr: + .long 0 diff --git a/api_examples/glue.c b/api_examples/glue.c index 2bf47ae..7218b86 100644 --- a/api_examples/glue.c +++ b/api_examples/glue.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2007 Semihalf + * (C) Copyright 2007-2008 Semihalf * * Written by: Rafal Jaworowski raj@semihalf.com * @@ -57,16 +57,23 @@ 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 start = 0, end = 0;
if (sig == NULL) return 0;
- sp = (unsigned char *)API_SEARCH_START; + if (gd_ptr == NULL) + return 0; + + /* Global data ptr helps to narrow down the search range */ + start = (uint32_t)gd_ptr & ~(API_SEARCH_LEN - 1); + end = start + API_SEARCH_LEN - API_SIG_MAGLEN;
- while ((sp + (int)API_SIG_MAGLEN) < (unsigned char *)API_SEARCH_END) { + sp = (unsigned char *)start; + while ((sp + API_SIG_MAGLEN) < (unsigned char *)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..76cb580 100644 --- a/api_examples/glue.h +++ b/api_examples/glue.h @@ -30,11 +30,11 @@ #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 (2 * 1024 * 1024) /* 2MB search range */
int syscall(int, int *, ...); -void * syscall_ptr; +extern void *syscall_ptr; +extern gd_t *gd_ptr;
int api_search_sig(struct api_signature **sig);

In message 12178539203180-git-send-email-raj@semihalf.com you wrote:
De-hard code the range in RAM we search for API signature, which might not be uniform accross architectures and board configurations. Instead use current global_data pointer as a hint to narrow down the range the [malloc'ed] signature could reside.
Which is the exact rationale of this? Note that the GD pointer can point basicly anywhere - some part of dual ported RAM, SRAM, OCM, ...
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
In message 12178539203180-git-send-email-raj@semihalf.com you wrote:
De-hard code the range in RAM we search for API signature, which might not be uniform accross architectures and board configurations. Instead use current global_data pointer as a hint to narrow down the range the [malloc'ed] signature could reside.
Which is the exact rationale of this? Note that the GD pointer can point basicly anywhere - some part of dual ported RAM, SRAM, OCM, ...
The idea was to discover the proximity of where to look for the API signature in run-time and only search within some range around it. This way we'd drop static definitions of the search range.
The assumption was that global data should be close enough to U-Boot's malloc area (where the signature is stored) and this works for us on PPC and ARM. Do you see any problems with this approach in general i.e. can it really happen that after relocation we end up with global data stored at distant location than other U-Boot data?
kind regards, Rafal

In message 48970460.2040701@semihalf.com you wrote:
The idea was to discover the proximity of where to look for the API signature in run-time and only search within some range around it. This way we'd drop static definitions of the search range.
I think this is pretty unreliable.
The assumption was that global data should be close enough to U-Boot's malloc area (where the signature is stored) and this works for us on PPC and ARM. Do you see any problems with this approach in general i.e. can it really happen that after relocation we end up with global data stored at distant location than other U-Boot data?
I don't know exactly what other architectures are doing. In any case, you try to build logic on some implementation as it happens to be right now, but since this is nowhere an officially documented interface - it can change any time without warning. To be honest, I am not even sure if the GD data get copied to RAM on PowerPC, and if so, if it's done on all of them.
Best regards,
Wolfgang Denk
participants (2)
-
Rafal Jaworowski
-
Wolfgang Denk