diff mbox

[U-Boot,v2,3/5] Allow arch-specific setting of global_data in board_init_f_mem()

Message ID 1439261072-1341-4-git-send-email-sjg@chromium.org
State Accepted
Delegated to: Simon Glass
Headers show

Commit Message

Simon Glass Aug. 11, 2015, 2:44 a.m. UTC
At present we have a simple assignment to gd. With some archs this is
implemented as a register or through some other means; a simple assignment
does not suit in all cases.

Change this to a function and add documentation to describe how this all
works.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: York Sun <yorksun@freescale.com>
---

Changes in v2:
- Drop unused 'reserve_size' argument
- Rename arch_setup_gdt() to arch_setup_gd()
- Expand the comment about the 64-byte stack space
- Fix a comma which should be a period
- Add a comment as to why we can't compile the weak arch_setup_gd() on x86

 common/board_f.c | 13 +++++++++++--
 include/common.h | 43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+), 2 deletions(-)

Comments

Bin Meng Aug. 11, 2015, 6:28 a.m. UTC | #1
On Tue, Aug 11, 2015 at 10:44 AM, Simon Glass <sjg@chromium.org> wrote:
> At present we have a simple assignment to gd. With some archs this is
> implemented as a register or through some other means; a simple assignment
> does not suit in all cases.
>
> Change this to a function and add documentation to describe how this all
> works.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: York Sun <yorksun@freescale.com>
> ---
>
> Changes in v2:
> - Drop unused 'reserve_size' argument
> - Rename arch_setup_gdt() to arch_setup_gd()
> - Expand the comment about the 64-byte stack space
> - Fix a comma which should be a period
> - Add a comment as to why we can't compile the weak arch_setup_gd() on x86
>
>  common/board_f.c | 13 +++++++++++--
>  include/common.h | 43 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 54 insertions(+), 2 deletions(-)
>
> diff --git a/common/board_f.c b/common/board_f.c
> index 74f77f1..37b7bf5 100644
> --- a/common/board_f.c
> +++ b/common/board_f.c
> @@ -1027,16 +1027,25 @@ void board_init_f_r(void)
>  }
>  #endif /* CONFIG_X86 */
>
> +/* Unfortunately x86 can't compile this code as gd cannot be assigned */
>  #ifndef CONFIG_X86
> +__weak void arch_setup_gd(struct global_data *gd_ptr)
> +{
> +       gd = gd_ptr;
> +}
> +
>  ulong board_init_f_mem(ulong top)
>  {
> +       struct global_data *gd_ptr;
> +
>         /* Leave space for the stack we are running with now */
>         top -= 0x40;
>
>         top -= sizeof(struct global_data);
>         top = ALIGN(top, 16);
> -       gd = (struct global_data *)top;
> -       memset((void *)gd, '\0', sizeof(*gd));
> +       gd_ptr = (struct global_data *)top;
> +       memset(gd_ptr, '\0', sizeof(*gd));
> +       arch_setup_gd(gd_ptr);
>
>  #ifdef CONFIG_SYS_MALLOC_F_LEN
>         top -= CONFIG_SYS_MALLOC_F_LEN;
> diff --git a/include/common.h b/include/common.h
> index fcc9ae7..48e5006 100644
> --- a/include/common.h
> +++ b/include/common.h
> @@ -217,6 +217,49 @@ extern char console_buffer[];
>  /* arch/$(ARCH)/lib/board.c */
>  void board_init_f(ulong);
>  void board_init_r(gd_t *, ulong) __attribute__ ((noreturn));
> +
> +/**
> + * board_init_f_mem() - Allocate global data and set stack position
> + *
> + * This function is called by each architecture very early in the start-up
> + * code to set up the environment for board_init_f(). It allocates space for
> + * global_data (see include/asm-generic/global_data.h) and places the stack
> + * below this.
> + *
> + * This function requires a stack[1] Normally this is at @top. The function
> + * starts allocating space from 64 bytes below @top. First it creates space
> + * for global_data. Then it calls arch_setup_gd() which sets gd to point to
> + * the global_data space and can reserve additional bytes of space if
> + * required). Finally it allocates early malloc() memory
> + * (CONFIG_SYS_MALLOC_F_LEN). The new top of the stack is just below this,
> + * and it returned by this function.
> + *
> + * [1] Strictly speaking it would be possible to implement this function
> + * in C on many archs such that it does not require a stack. However this
> + * does not seem hugely important as only 64 byte are wasted. The 64 bytes
> + * are used to handle the calling standard which generally requires pushing
> + * addresses or registers onto the stack. We should be able to get away with
> + * less if this becomes important.
> + *
> + * @top:       Top of available memory, also normally the top of the stack
> + * @return:    New stack location
> + */
> +ulong board_init_f_mem(ulong top);
> +
> +/**
> + * arch_setup_gd() - Set up the global_data pointer
> + *
> + * This pointer is special in some architectures and cannot easily be assigned
> + * to. For example on x86 it is implemented by adding a specific record to its
> + * Global Descriptor Table! So we we provide a function to carry out this task.
> + * For most architectures this can simply be:
> + *
> + *    gd = gd_ptr;
> + *
> + * @gd_ptr:    Pointer to global data
> + */
> +void arch_setup_gd(gd_t *gd_ptr);
> +
>  int checkboard(void);
>  int show_board_info(void);
>  int checkflash(void);
> --

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Simon Glass Aug. 12, 2015, 3:55 a.m. UTC | #2
On 11 August 2015 at 00:28, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Tue, Aug 11, 2015 at 10:44 AM, Simon Glass <sjg@chromium.org> wrote:
>> At present we have a simple assignment to gd. With some archs this is
>> implemented as a register or through some other means; a simple assignment
>> does not suit in all cases.
>>
>> Change this to a function and add documentation to describe how this all
>> works.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> Reviewed-by: York Sun <yorksun@freescale.com>
>> ---
>>
>> Changes in v2:
>> - Drop unused 'reserve_size' argument
>> - Rename arch_setup_gdt() to arch_setup_gd()
>> - Expand the comment about the 64-byte stack space
>> - Fix a comma which should be a period
>> - Add a comment as to why we can't compile the weak arch_setup_gd() on x86
>>
>>  common/board_f.c | 13 +++++++++++--
>>  include/common.h | 43 +++++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 54 insertions(+), 2 deletions(-)
>>
>> diff --git a/common/board_f.c b/common/board_f.c
>> index 74f77f1..37b7bf5 100644
>> --- a/common/board_f.c
>> +++ b/common/board_f.c
>> @@ -1027,16 +1027,25 @@ void board_init_f_r(void)
>>  }
>>  #endif /* CONFIG_X86 */
>>
>> +/* Unfortunately x86 can't compile this code as gd cannot be assigned */
>>  #ifndef CONFIG_X86
>> +__weak void arch_setup_gd(struct global_data *gd_ptr)
>> +{
>> +       gd = gd_ptr;
>> +}
>> +
>>  ulong board_init_f_mem(ulong top)
>>  {
>> +       struct global_data *gd_ptr;
>> +
>>         /* Leave space for the stack we are running with now */
>>         top -= 0x40;
>>
>>         top -= sizeof(struct global_data);
>>         top = ALIGN(top, 16);
>> -       gd = (struct global_data *)top;
>> -       memset((void *)gd, '\0', sizeof(*gd));
>> +       gd_ptr = (struct global_data *)top;
>> +       memset(gd_ptr, '\0', sizeof(*gd));
>> +       arch_setup_gd(gd_ptr);
>>
>>  #ifdef CONFIG_SYS_MALLOC_F_LEN
>>         top -= CONFIG_SYS_MALLOC_F_LEN;
>> diff --git a/include/common.h b/include/common.h
>> index fcc9ae7..48e5006 100644
>> --- a/include/common.h
>> +++ b/include/common.h
>> @@ -217,6 +217,49 @@ extern char console_buffer[];
>>  /* arch/$(ARCH)/lib/board.c */
>>  void board_init_f(ulong);
>>  void board_init_r(gd_t *, ulong) __attribute__ ((noreturn));
>> +
>> +/**
>> + * board_init_f_mem() - Allocate global data and set stack position
>> + *
>> + * This function is called by each architecture very early in the start-up
>> + * code to set up the environment for board_init_f(). It allocates space for
>> + * global_data (see include/asm-generic/global_data.h) and places the stack
>> + * below this.
>> + *
>> + * This function requires a stack[1] Normally this is at @top. The function
>> + * starts allocating space from 64 bytes below @top. First it creates space
>> + * for global_data. Then it calls arch_setup_gd() which sets gd to point to
>> + * the global_data space and can reserve additional bytes of space if
>> + * required). Finally it allocates early malloc() memory
>> + * (CONFIG_SYS_MALLOC_F_LEN). The new top of the stack is just below this,
>> + * and it returned by this function.
>> + *
>> + * [1] Strictly speaking it would be possible to implement this function
>> + * in C on many archs such that it does not require a stack. However this
>> + * does not seem hugely important as only 64 byte are wasted. The 64 bytes
>> + * are used to handle the calling standard which generally requires pushing
>> + * addresses or registers onto the stack. We should be able to get away with
>> + * less if this becomes important.
>> + *
>> + * @top:       Top of available memory, also normally the top of the stack
>> + * @return:    New stack location
>> + */
>> +ulong board_init_f_mem(ulong top);
>> +
>> +/**
>> + * arch_setup_gd() - Set up the global_data pointer
>> + *
>> + * This pointer is special in some architectures and cannot easily be assigned
>> + * to. For example on x86 it is implemented by adding a specific record to its
>> + * Global Descriptor Table! So we we provide a function to carry out this task.
>> + * For most architectures this can simply be:
>> + *
>> + *    gd = gd_ptr;
>> + *
>> + * @gd_ptr:    Pointer to global data
>> + */
>> +void arch_setup_gd(gd_t *gd_ptr);
>> +
>>  int checkboard(void);
>>  int show_board_info(void);
>>  int checkflash(void);
>> --
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-x86
diff mbox

Patch

diff --git a/common/board_f.c b/common/board_f.c
index 74f77f1..37b7bf5 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -1027,16 +1027,25 @@  void board_init_f_r(void)
 }
 #endif /* CONFIG_X86 */
 
+/* Unfortunately x86 can't compile this code as gd cannot be assigned */
 #ifndef CONFIG_X86
+__weak void arch_setup_gd(struct global_data *gd_ptr)
+{
+	gd = gd_ptr;
+}
+
 ulong board_init_f_mem(ulong top)
 {
+	struct global_data *gd_ptr;
+
 	/* Leave space for the stack we are running with now */
 	top -= 0x40;
 
 	top -= sizeof(struct global_data);
 	top = ALIGN(top, 16);
-	gd = (struct global_data *)top;
-	memset((void *)gd, '\0', sizeof(*gd));
+	gd_ptr = (struct global_data *)top;
+	memset(gd_ptr, '\0', sizeof(*gd));
+	arch_setup_gd(gd_ptr);
 
 #ifdef CONFIG_SYS_MALLOC_F_LEN
 	top -= CONFIG_SYS_MALLOC_F_LEN;
diff --git a/include/common.h b/include/common.h
index fcc9ae7..48e5006 100644
--- a/include/common.h
+++ b/include/common.h
@@ -217,6 +217,49 @@  extern char console_buffer[];
 /* arch/$(ARCH)/lib/board.c */
 void board_init_f(ulong);
 void board_init_r(gd_t *, ulong) __attribute__ ((noreturn));
+
+/**
+ * board_init_f_mem() - Allocate global data and set stack position
+ *
+ * This function is called by each architecture very early in the start-up
+ * code to set up the environment for board_init_f(). It allocates space for
+ * global_data (see include/asm-generic/global_data.h) and places the stack
+ * below this.
+ *
+ * This function requires a stack[1] Normally this is at @top. The function
+ * starts allocating space from 64 bytes below @top. First it creates space
+ * for global_data. Then it calls arch_setup_gd() which sets gd to point to
+ * the global_data space and can reserve additional bytes of space if
+ * required). Finally it allocates early malloc() memory
+ * (CONFIG_SYS_MALLOC_F_LEN). The new top of the stack is just below this,
+ * and it returned by this function.
+ *
+ * [1] Strictly speaking it would be possible to implement this function
+ * in C on many archs such that it does not require a stack. However this
+ * does not seem hugely important as only 64 byte are wasted. The 64 bytes
+ * are used to handle the calling standard which generally requires pushing
+ * addresses or registers onto the stack. We should be able to get away with
+ * less if this becomes important.
+ *
+ * @top:	Top of available memory, also normally the top of the stack
+ * @return:	New stack location
+ */
+ulong board_init_f_mem(ulong top);
+
+/**
+ * arch_setup_gd() - Set up the global_data pointer
+ *
+ * This pointer is special in some architectures and cannot easily be assigned
+ * to. For example on x86 it is implemented by adding a specific record to its
+ * Global Descriptor Table! So we we provide a function to carry out this task.
+ * For most architectures this can simply be:
+ *
+ *    gd = gd_ptr;
+ *
+ * @gd_ptr:	Pointer to global data
+ */
+void arch_setup_gd(gd_t *gd_ptr);
+
 int checkboard(void);
 int show_board_info(void);
 int checkflash(void);