[U-Boot] [PATCH v4 0/27] Create generic board init for ARM, x86, PPC

This series creates a generic board.c implementation which contains the essential functions of the major arch/xxx/lib/board.c files.
What is the motivation for this change?
1. There is a lot of repeated code in the board.c files. Any change to things like setting up the baud rate requires a change in 10 separate places.
2. Since there are 10 separate files, adding a new feature which requires initialisation is painful since it must be independently added in 10 places.
3. As time goes by the architectures naturely diverge since there is limited pressure to compare features or even CONFIG options against simiilar things in other board.c files.
4. New architectures must implement all the features all over again, and sometimes in subtley different ways. This places an unfair burden on getting a new architecture fully functional and running with U-Boot.
5. While it is a bit of a tricky change, I believe it is worthwhile and achievable. There is no requirement that all code be common, only that the code that is common should be located in common/board.c rather than arch/xxx/lib/board.c.
All the functions of board_init_f() and board_init_r() are broken into separate function calls so that they can easily be included or excluded for a particular architecture. It also makes it easier to adopt Graeme's initcall proposal when it is ready.
http://lists.denx.de/pipermail/u-boot/2012-January/114499.html
This series removes the dependency on generic relocation. So relocation happens as one big chunk and is still completely arch-specific. See the relocation series for a proposed solution to this for ARM:
http://lists.denx.de/pipermail/u-boot/2011-December/112928.html
or Graeme's recent x86 series v2:
http://lists.denx.de/pipermail/u-boot/2012-January/114467.html
Instead of moving over a whole architecture, this series takes the approach of simply enabling generic board support for an architecture. It is then up to each board to opt in by defining CONFIG_SYS_GENERIC_BOARD in the board config file. If this is not done, then the code will be generated as before. This allows both sets of code to co-exist until we are comfortable with the generic approach, and enough boards run.
ARM is a relatively large board.c file and one which I can test, therefore I think it is a good target for this series. On the other hand, x86 is relatively small and simple, but different enough that it introduces a few issues to be solved. So I have chosen both ARM and x86 for this series. After a suggestion from Wolfgang I have added PPC also. This is the largest and most feature-full board, so hopefully we have all bases covered in this RFC.
A generic global_data structure is also required. This might upset a few people. Here is my basic reasoning: most fields are the same, all architectures include and need it, most global_data.h files already have #ifdefs to select fields for a particular SOC, so it is hard to see why architecures are different in this area. We can perhaps add a way to put architecture-specific fields into a separate header file, but for now I have judged that to be counter-productive.
Similarly we need a generic bd_info structure, since generic code will be accessing it. I have done this in the same way as global_data and the same comments apply.
There was dicussion on the list about passing gd_t around as a parameter to pre-relocation init functions. I think this makes sense, but it can be done as a separate change, and this series does not require it.
While this series needs to stand on its own (as with the link script cleanup series and the generic relocation series) the goal is the unification of the board init code. So I hope we can address issues with this in mind, rather than focusing too narrowly on particular ARM, x86 or PPC issues.
I have run-tested ARM on Tegra Seaboard only. To try it out, define CONFIG_SYS_GENERIC_BOARD in your board file and rebuild. Most likely on x86 and PPC at least it will hang, but if you are lucky it will print something first :-)
I have run this though MAKEALL with CONFIG_SYS_GENERIC_BOARD on for all ARM, PPC and x86 boards. There are a few failures due to errors in the board config, which I have sent patches for. The main issue is just the difference between __bss_end and __bss_end__.
Note: the first group of commits are required for this series to build, but could be separated out if required. I have included them here for convenience.
Comments welcome.
Changes in v2: - Add CONFIG_SYS_GENERIC_BOARD to allow board to select generic board - Add PowerPC support - Change generic board to an opt-in system on a per-board basic - Rebase to master
Changes in v3: - Add header to new x86 relocate.c and init_helpers.c - Cast away the volatile on gd for memcpy() - Rebase on top of x86/master (which has not yet been pulled to master) - Rebase to master
Changes in v4: - Add asm/sections.h for each architecture - Add three more fields required for ARM - Drop sc520_timer.c patch (warning already fixed by previous patch) - Rebase to master - Updates to sit on top of earlier patches - Use asm/sections.h instead of asm-generic/sections.h
Simon Glass (27): arm: Change board baud_rate to ulong x86: Change board baud_rate to ulong arm: Only display frame buffer info if there is LCD/video support x86: Remove dead code in eNET x86: Add initial memory barrier macros ppc: Add initial memory barrier macros Introduce generic global_data Introduce generic u-boot.h file Introduce generic link section.h symbol files arm: Use sections header to obtain link symbols x86: Change stub example to use asm-generic/sections.h Introduce a basic initcall implementation Define CONFIG_SYS_LEGACY_BOARD everywhere Introduce generic pre-relocation board_f.c Introduce generic post-relocation board_r.c Add spl load feature arm: Enable generic board support Add CONFIG_SYS_SYM_OFFSETS to support offset symbols x86: Use sections header to obtain link symbols Add x86 fields to generic global_data x86: Enable generic board support Add ppc fields to generic global data Adjust board_f for ppc Adjust board_r.c for PowerPC ppc: Enable generic board board tegra: Mark board init files for ARMv4t tegra: Enable generic board for Seaboard.
README | 17 + arch/arm/cpu/armv7/tegra2/config.mk | 2 + arch/arm/include/asm/global_data.h | 7 + arch/arm/include/asm/sections.h | 27 + arch/arm/include/asm/u-boot-arm.h | 4 - arch/arm/include/asm/u-boot.h | 11 +- arch/arm/lib/Makefile | 4 +- arch/arm/lib/board.c | 1 + arch/avr32/config.mk | 3 + arch/avr32/cpu/start.S | 2 +- arch/avr32/cpu/u-boot.lds | 2 +- arch/avr32/include/asm/sections.h | 6 +- arch/avr32/lib/board.c | 2 +- arch/blackfin/config.mk | 3 + arch/blackfin/include/asm/sections.h | 27 + arch/m68k/config.mk | 3 + arch/m68k/include/asm/sections.h | 27 + arch/microblaze/config.mk | 3 + arch/microblaze/include/asm/sections.h | 27 + arch/mips/config.mk | 3 + arch/mips/include/asm/sections.h | 27 + arch/nds32/config.mk | 3 + arch/nds32/include/asm/sections.h | 27 + arch/nios2/config.mk | 3 + arch/nios2/include/asm/sections.h | 27 + arch/openrisc/include/asm/sections.h | 27 + arch/powerpc/include/asm/global_data.h | 7 + arch/powerpc/include/asm/io.h | 8 + arch/powerpc/include/asm/sections.h | 27 + arch/powerpc/include/asm/u-boot.h | 7 + arch/powerpc/lib/Makefile | 4 +- arch/sandbox/config.mk | 3 + arch/sandbox/include/asm/sections.h | 27 + arch/sh/config.mk | 3 + arch/sh/include/asm/sections.h | 27 + arch/sparc/config.mk | 3 + arch/sparc/include/asm/sections.h | 27 + arch/x86/include/asm/global_data.h | 7 + arch/x86/include/asm/io.h | 8 + arch/x86/include/asm/sections.h | 27 + arch/x86/include/asm/u-boot-x86.h | 8 - arch/x86/include/asm/u-boot.h | 13 +- arch/x86/lib/Makefile | 4 +- arch/x86/lib/board.c | 1 + arch/x86/lib/init_helpers.c | 1 + arch/x86/lib/relocate.c | 1 + board/cm4008/flash.c | 1 + board/cm41xx/flash.c | 1 + board/eNET/eNET.c | 5 - common/Makefile | 4 + common/board_f.c | 888 ++++++++++++++++++++++++++++++++ common/board_r.c | 862 +++++++++++++++++++++++++++++++ common/cmd_bdinfo.c | 6 +- config.mk | 8 + examples/standalone/stubs.c | 7 +- include/asm-generic/global_data.h | 241 +++++++++ include/asm-generic/sections.h | 124 +++++ include/asm-generic/u-boot.h | 160 ++++++ include/common.h | 16 + include/configs/seaboard.h | 2 + include/initcall.h | 25 + lib/Makefile | 1 + lib/initcall.c | 41 ++ 63 files changed, 2866 insertions(+), 34 deletions(-) create mode 100644 arch/arm/include/asm/sections.h create mode 100644 arch/blackfin/include/asm/sections.h create mode 100644 arch/m68k/include/asm/sections.h create mode 100644 arch/microblaze/include/asm/sections.h create mode 100644 arch/mips/include/asm/sections.h create mode 100644 arch/nds32/include/asm/sections.h create mode 100644 arch/nios2/include/asm/sections.h create mode 100644 arch/openrisc/include/asm/sections.h create mode 100644 arch/powerpc/include/asm/sections.h create mode 100644 arch/sandbox/include/asm/sections.h create mode 100644 arch/sh/include/asm/sections.h create mode 100644 arch/sparc/include/asm/sections.h create mode 100644 arch/x86/include/asm/sections.h create mode 100644 common/board_f.c create mode 100644 common/board_r.c create mode 100644 include/asm-generic/global_data.h create mode 100644 include/asm-generic/sections.h create mode 100644 include/asm-generic/u-boot.h create mode 100644 include/initcall.h create mode 100644 lib/initcall.c

This is a ulong for some architectures and just unsigned for others. Change ARM to be consistent.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/include/asm/u-boot.h | 2 +- common/cmd_bdinfo.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/include/asm/u-boot.h b/arch/arm/include/asm/u-boot.h index 20e1653..a0691b7 100644 --- a/arch/arm/include/asm/u-boot.h +++ b/arch/arm/include/asm/u-boot.h @@ -37,7 +37,7 @@ #define _U_BOOT_H_ 1
typedef struct bd_info { - int bi_baudrate; /* serial console baudrate */ + unsigned long bi_baudrate; /* serial console baudrate */ unsigned long bi_ip_addr; /* IP Address */ ulong bi_arch_number; /* unique id for this board */ ulong bi_boot_params; /* where this board expects params */ diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index 5359a47..c034ec9 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -361,7 +361,7 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) print_eth(0); printf("ip_addr = %pI4\n", &bd->bi_ip_addr); #endif - printf("baudrate = %d bps\n", bd->bi_baudrate); + printf("baudrate = %ld bps\n", bd->bi_baudrate); #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) print_num("TLB addr", gd->tlb_addr); #endif

This is a ulong for some architectures and just unsigned for others. Change x86 to be consistent.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/include/asm/u-boot.h | 2 +- common/cmd_bdinfo.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/u-boot.h b/arch/x86/include/asm/u-boot.h index 26450eb..dd42209 100644 --- a/arch/x86/include/asm/u-boot.h +++ b/arch/x86/include/asm/u-boot.h @@ -49,7 +49,7 @@ typedef struct bd_info { unsigned short bi_ethspeed; /* Ethernet speed in Mbps */ unsigned long bi_intfreq; /* Internal Freq, in MHz */ unsigned long bi_busfreq; /* Bus Freq, in MHz */ - unsigned int bi_baudrate; /* Console Baudrate */ + unsigned long bi_baudrate; /* Console Baudrate */ unsigned long bi_boot_params; /* where this board expects params */ struct /* RAM configuration */ { diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index c034ec9..54a56f4 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -431,7 +431,7 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("ip_addr = %pI4\n", &bd->bi_ip_addr); print_mhz("ethspeed", bd->bi_ethspeed); #endif - printf("baudrate = %d bps\n", bd->bi_baudrate); + printf("baudrate = %ld bps\n", bd->bi_baudrate);
return 0; }

This value has no meaning otherwise.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/cmd_bdinfo.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index 54a56f4..80c100c 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -369,7 +369,9 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) print_num("reloc off", gd->reloc_off); print_num("irq_sp", gd->irq_sp); /* irq stack pointer */ print_num("sp start ", gd->start_addr_sp); +#if defined(CONFIG_LCD) || defined(CONFIG_VIDEO) print_num("FB base ", gd->fb_base); +#endif /* * TODO: Currently only support for davinci SOC's is added. * Remove this check once all the board implement this.

This avoids a compiler warning about unused variables.
Signed-off-by: Simon Glass sjg@chromium.org ---
board/eNET/eNET.c | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/board/eNET/eNET.c b/board/eNET/eNET.c index 429fe1b..2f26470 100644 --- a/board/eNET/eNET.c +++ b/board/eNET/eNET.c @@ -178,11 +178,6 @@ void show_boot_progress(int val)
int last_stage_init(void) { - int minor; - int major; - - major = minor = 0; - outb(0x00, LED_LATCH_ADDRESS);
register_timer_isr(enet_timer_isr);

Hi Simon,
On Thu, Mar 15, 2012 at 1:16 PM, Simon Glass sjg@chromium.org wrote:
This avoids a compiler warning about unused variables.
Signed-off-by: Simon Glass sjg@chromium.org
board/eNET/eNET.c | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-)
Acked-By: Graeme Russ graeme.russ@gmail.com
I'll apply this to x86/master directly and send a pull request
Regards,
Graeme

On Wed, Mar 14, 2012 at 7:27 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
On Thu, Mar 15, 2012 at 1:16 PM, Simon Glass sjg@chromium.org wrote:
This avoids a compiler warning about unused variables.
Signed-off-by: Simon Glass sjg@chromium.org
board/eNET/eNET.c | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-)
Acked-By: Graeme Russ graeme.russ@gmail.com
I'll apply this to x86/master directly and send a pull request
Thanks Graeme.
Regards,
Graeme

These are available on other architectures, so add them on x86.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/include/asm/io.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 9b757d4..b12bdd8 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -234,4 +234,12 @@ static inline phys_addr_t virt_to_phys(void * vaddr) return (phys_addr_t)(vaddr); }
+/* + * TODO: The kernel offers some more advanced versions of barriers, it might + * have some advantages to use them instead of the simple one here. + */ +#define dmb() __asm__ __volatile__ ("" : : : "memory") +#define __iormb() dmb() +#define __iowmb() dmb() + #endif

These are available on other architectures, so add them on ppc.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/powerpc/include/asm/io.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index 56ac9fe..d246fd8 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -318,4 +318,12 @@ static inline phys_addr_t virt_to_phys(void * vaddr) #endif }
+/* + * TODO: The kernel offers some more advanced versions of barriers, it might + * have some advantages to use them instead of the simple one here. + */ +#define dmb() __asm__ __volatile__ ("" : : : "memory") +#define __iormb() dmb() +#define __iowmb() dmb() + #endif

On 03/14/2012 09:16 PM, Simon Glass wrote:
These are available on other architectures, so add them on ppc.
Signed-off-by: Simon Glass sjg@chromium.org
arch/powerpc/include/asm/io.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index 56ac9fe..d246fd8 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -318,4 +318,12 @@ static inline phys_addr_t virt_to_phys(void * vaddr) #endif }
+/*
- TODO: The kernel offers some more advanced versions of barriers, it might
- have some advantages to use them instead of the simple one here.
- */
+#define dmb() __asm__ __volatile__ ("" : : : "memory") +#define __iormb() dmb() +#define __iowmb() dmb()
What are the semantics of these (they are not the standard Linux barriers), and how is a simple compiler barrier adequate?
-Scott

We want to unify the global_data structure. Most fields are common across architectures, but there are a fair number of SOC-specific additions. It isn't clear how best to deal with these, but for now we just use #ifdef.
Checkpatch warnings here might be unavoidable:
warning: include/asm-generic/global_data.h,43: do not add new typedefs warning: include/asm-generic/global_data.h,117: Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt warning: include/asm-generic/global_data.h,121: storage class should be at the beginning of the declaration
Signed-off-by: Simon Glass sjg@chromium.org ---
include/asm-generic/global_data.h | 115 +++++++++++++++++++++++++++++++++++++ 1 files changed, 115 insertions(+), 0 deletions(-) create mode 100644 include/asm-generic/global_data.h
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h new file mode 100644 index 0000000..6199926 --- /dev/null +++ b/include/asm-generic/global_data.h @@ -0,0 +1,115 @@ +/* + * (C) Copyright 2002-2010 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_GENERIC_GBL_DATA_H +#define __ASM_GENERIC_GBL_DATA_H +/* + * The following data structure is placed in some memory which is + * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or + * some locked parts of the data cache) to allow for a minimum set of + * global variables during system initialization (until we have set + * up the memory controller so that we can use RAM). + * + * Keep it *SMALL* and remember to set GENERATED_GBL_DATA_SIZE > sizeof(gd_t) + * + * sjg@chromium.org: Well it would be nice to have a generic one of these + * since so many fields are similar. But it means that everyone architecture + * will want to add its own nutty fields. Perhaps that is no bad thing since + * it shows up inconsistences and might produce downward pressure on the + * number of fields. + */ + +#ifndef __ASSEMBLY__ +typedef struct global_data { + bd_t *bd; + unsigned long flags; + unsigned long baudrate; +#if defined(CONFIG_LCD) || defined(CONFIG_VIDEO) + unsigned long fb_base; /* Base address of framebuffer mem */ +#endif +#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER) + unsigned long post_log_word; /* Record POST activities */ + unsigned long post_log_res; /* success of POST test */ + unsigned long post_init_f_time; /* When post_init_f started */ +#endif + unsigned long have_console; /* serial_init() was called */ +#ifdef CONFIG_PRE_CONSOLE_BUFFER + unsigned long precon_buf_idx; /* Pre-Console buffer index */ +#endif + unsigned long env_addr; /* Address of Environment struct */ + unsigned long env_valid; /* Checksum of Environment valid? */ + /* Here begins ARM-specific things. Needs discussion */ +#ifdef CONFIG_AT91FAMILY + /* "static data" needed by at91's clock.c */ + unsigned long cpu_clk_rate_hz; + unsigned long main_clk_rate_hz; + unsigned long mck_rate_hz; + unsigned long plla_rate_hz; + unsigned long pllb_rate_hz; + unsigned long at91_pllb_usb_init; +#endif +#ifdef CONFIG_ARM + /* "static data" needed by most of timer.c on ARM platforms */ + unsigned long timer_rate_hz; + unsigned long tbl; + unsigned long tbu; + unsigned long long timer_reset_value; + unsigned long lastinc; +#endif +#ifdef CONFIG_IXP425 + unsigned long timestamp; +#endif + /* TODO: is this the same as relocaddr, or something else? */ + unsigned long dest_addr; /* Post-relocation address of U-Boot */ + unsigned long dest_addr_sp; + unsigned long ram_top; /* Top address of RAM used by U-Boot */ + + unsigned long relocaddr; /* Start address of U-Boot in RAM */ + phys_size_t ram_size; /* RAM size */ + unsigned long mon_len; /* monitor len */ + unsigned long irq_sp; /* irq stack pointer */ + unsigned long start_addr_sp; /* start_addr_stackpointer */ + unsigned long reloc_off; +#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) + unsigned long tlb_addr; +#endif + struct global_data *new_gd; /* relocated global data */ + const void *fdt_blob; /* Our device tree, NULL if none */ + void **jt; /* jump table */ + char env_buf[32]; /* buffer for getenv() before reloc. */ +} gd_t; +#endif + +/* + * Global Data Flags + */ +#define GD_FLG_RELOC 0x00001 /* Code was relocated to RAM */ +#define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */ +#define GD_FLG_SILENT 0x00004 /* Silent mode */ +#define GD_FLG_POSTFAIL 0x00008 /* Critical POST test failed */ +#define GD_FLG_POSTSTOP 0x00010 /* POST seqeunce aborted */ +#define GD_FLG_LOGINIT 0x00020 /* Log Buffer has been initialized */ +#define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */ +#define GD_FLG_ENV_READY 0x00080 /* Env. imported into hash table */ + +#endif /* __ASM_GENERIC_GBL_DATA_H */

Hi Simon,
On Thu, Mar 15, 2012 at 1:16 PM, Simon Glass sjg@chromium.org wrote:
We want to unify the global_data structure. Most fields are common across architectures, but there are a fair number of SOC-specific additions. It isn't clear how best to deal with these, but for now we just use #ifdef.
Checkpatch warnings here might be unavoidable:
warning: include/asm-generic/global_data.h,43: do not add new typedefs warning: include/asm-generic/global_data.h,117: Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt warning: include/asm-generic/global_data.h,121: storage class should be at the beginning of the declaration
IMHO global data does not need to be (and should not be) typedef'd
Regards,
Graeme

Hi Simon,
On Thu, Mar 15, 2012 at 1:16 PM, Simon Glass sjg@chromium.org wrote:
We want to unify the global_data structure. Most fields are common across architectures, but there are a fair number of SOC-specific additions. It isn't clear how best to deal with these, but for now we just use #ifdef.
Checkpatch warnings here might be unavoidable:
warning: include/asm-generic/global_data.h,43: do not add new typedefs warning: include/asm-generic/global_data.h,117: Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt warning: include/asm-generic/global_data.h,121: storage class should be at the beginning of the declaration
Signed-off-by: Simon Glass sjg@chromium.org
+#ifdef CONFIG_AT91FAMILY
- /* "static data" needed by at91's clock.c */
- unsigned long cpu_clk_rate_hz;
- unsigned long main_clk_rate_hz;
- unsigned long mck_rate_hz;
- unsigned long plla_rate_hz;
- unsigned long pllb_rate_hz;
- unsigned long at91_pllb_usb_init;
+#endif +#ifdef CONFIG_ARM
- /* "static data" needed by most of timer.c on ARM platforms */
- unsigned long timer_rate_hz;
- unsigned long tbl;
- unsigned long tbu;
- unsigned long long timer_reset_value;
- unsigned long lastinc;
+#endif
IMHO, global data should contain only globally common members and an arch- specific struct and ditch (most of) the #ifdefs
Regards,
Graeme

Hi Graeme,
On Wed, Mar 14, 2012 at 7:35 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
On Thu, Mar 15, 2012 at 1:16 PM, Simon Glass sjg@chromium.org wrote:
We want to unify the global_data structure. Most fields are common across architectures, but there are a fair number of SOC-specific additions. It isn't clear how best to deal with these, but for now we just use #ifdef.
Checkpatch warnings here might be unavoidable:
warning: include/asm-generic/global_data.h,43: do not add new typedefs warning: include/asm-generic/global_data.h,117: Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt warning: include/asm-generic/global_data.h,121: storage class should be at the beginning of the declaration
Signed-off-by: Simon Glass sjg@chromium.org
+#ifdef CONFIG_AT91FAMILY
- /* "static data" needed by at91's clock.c */
- unsigned long cpu_clk_rate_hz;
- unsigned long main_clk_rate_hz;
- unsigned long mck_rate_hz;
- unsigned long plla_rate_hz;
- unsigned long pllb_rate_hz;
- unsigned long at91_pllb_usb_init;
+#endif +#ifdef CONFIG_ARM
- /* "static data" needed by most of timer.c on ARM platforms */
- unsigned long timer_rate_hz;
- unsigned long tbl;
- unsigned long tbu;
- unsigned long long timer_reset_value;
- unsigned long lastinc;
+#endif
IMHO, global data should contain only globally common members and an arch- specific struct and ditch (most of) the #ifdefs
My thinking here was to try to bring everything into a single file. It then should be clearer when things are common between different architectures. Patches to the generic file can be made without also having to patch the non-generic files, etc.
A fair number of the #ifdefs are not needed, or are there because some archs don't implement all the features of U-Boot.
You have an example right there: cpu_clk_rate_hz is similar to cpu_clk and core_clk.
That said it is a bit of a daunting task to amalgamate them.
Also there is the purely practical consideration that if we continue to have an asm/global_data.h then we end up with two global datas. One is for CONFIG_SYS_GENERIC_BOARD and contains just the non-common fields. The other is for non-CONFIG_SYS_GENERIC_BOARD and contains all fields. Ick.
So what do you think?
Regards, Simon
Regards,
Graeme

Hi Simon,
On Thu, Mar 15, 2012 at 1:50 PM, Simon Glass sjg@chromium.org wrote:
Hi Graeme,
On Wed, Mar 14, 2012 at 7:35 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
[snip]
IMHO, global data should contain only globally common members and an arch- specific struct and ditch (most of) the #ifdefs
My thinking here was to try to bring everything into a single file. It then should be clearer when things are common between different architectures. Patches to the generic file can be made without also having to patch the non-generic files, etc.
A fair number of the #ifdefs are not needed, or are there because some archs don't implement all the features of U-Boot.
You have an example right there: cpu_clk_rate_hz is similar to cpu_clk and core_clk.
That said it is a bit of a daunting task to amalgamate them.
Also there is the purely practical consideration that if we continue to have an asm/global_data.h then we end up with two global datas. One is for CONFIG_SYS_GENERIC_BOARD and contains just the non-common fields. The other is for non-CONFIG_SYS_GENERIC_BOARD and contains all fields. Ick.
So what do you think?
Do you really need to unify global data to achieve what the title of the patch series suggests (i.e. to unify the init processing loop)? Maybe you could leave global data as is (or slightly tweak the odd arch) and leave the resolution of just how bad global data is becoming for another day
I only say this because this is turning into "let's do a dirty hack now to partially fix it and leave the rest for later (it'll get done, really, honestly, I promise)" ;)
There will always be arch specific global data members - I see a few options:
- Move them into bd - Move them into an arch_global_data struct inside gd - Move them into an arch_global_data struct totally seperate from gd - Question how many are really required to be in gd (remember, gd is only there to cart around writable global variable before .bss and .data are available after relocation)
Regards,
Graeme

Hi Graeme,
On Wed, Mar 14, 2012 at 8:02 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
On Thu, Mar 15, 2012 at 1:50 PM, Simon Glass sjg@chromium.org wrote:
Hi Graeme,
On Wed, Mar 14, 2012 at 7:35 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
[snip]
IMHO, global data should contain only globally common members and an arch- specific struct and ditch (most of) the #ifdefs
My thinking here was to try to bring everything into a single file. It then should be clearer when things are common between different architectures. Patches to the generic file can be made without also having to patch the non-generic files, etc.
A fair number of the #ifdefs are not needed, or are there because some archs don't implement all the features of U-Boot.
You have an example right there: cpu_clk_rate_hz is similar to cpu_clk and core_clk.
That said it is a bit of a daunting task to amalgamate them.
Also there is the purely practical consideration that if we continue to have an asm/global_data.h then we end up with two global datas. One is for CONFIG_SYS_GENERIC_BOARD and contains just the non-common fields. The other is for non-CONFIG_SYS_GENERIC_BOARD and contains all fields. Ick.
So what do you think?
Do you really need to unify global data to achieve what the title of the patch series suggests (i.e. to unify the init processing loop)? Maybe you could leave global data as is (or slightly tweak the odd arch) and leave the resolution of just how bad global data is becoming for another day
It's not that easy, because in board_f.c and board_r.c and other files there are certain fields required. It doesn't make a huge amount of sense to have generic code which accesses a different global structure depending on what architecture it is built for. Then there are fields are are only used when certain options are defined. Ick.
If I am going to pull this off I need a bit of flexibility. I've looked into this quite a bit and mapped a path through this which I think will work. It requires doing things in stages, or it will never happen.
I only say this because this is turning into "let's do a dirty hack now to partially fix it and leave the rest for later (it'll get done, really, honestly, I promise)" ;)
It was always like that. Although I wouldn't characterise it as a dirty hack. If there was a requirement to do all of this in one big bang then I wouldn't have even started. It is just too hard :-(
There will always be arch specific global data members - I see a few options:
- Move them into bd
I recall talk of getting rid of this (Mike?)
- Move them into an arch_global_data struct inside gd
This was Mike's idea. It is probably the easiest thing to do.
- Move them into an arch_global_data struct totally seperate from gd
I sort-of like this except it would slow down access and maybe increase code size. Then again perhaps that's a good thing if it provides an incentive to reduce the number of arch-specific fields.
- Question how many are really required to be in gd (remember, gd is only there to cart around writable global variable before .bss and .data are available after relocation)
Well yes, I feel there are far more at present than are needed. Having them all there in the open feels like a nice way to draw attention to the mess.
Regards, Simon
Regards,
Graeme

Hi Graeme,
On Wed, Mar 14, 2012 at 8:41 PM, Simon Glass sjg@chromium.org wrote:
Hi Graeme,
On Wed, Mar 14, 2012 at 8:02 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
On Thu, Mar 15, 2012 at 1:50 PM, Simon Glass sjg@chromium.org wrote:
Hi Graeme,
On Wed, Mar 14, 2012 at 7:35 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
[snip]
IMHO, global data should contain only globally common members and an arch- specific struct and ditch (most of) the #ifdefs
My thinking here was to try to bring everything into a single file. It then should be clearer when things are common between different architectures. Patches to the generic file can be made without also having to patch the non-generic files, etc.
A fair number of the #ifdefs are not needed, or are there because some archs don't implement all the features of U-Boot.
You have an example right there: cpu_clk_rate_hz is similar to cpu_clk and core_clk.
That said it is a bit of a daunting task to amalgamate them.
Also there is the purely practical consideration that if we continue to have an asm/global_data.h then we end up with two global datas. One is for CONFIG_SYS_GENERIC_BOARD and contains just the non-common fields. The other is for non-CONFIG_SYS_GENERIC_BOARD and contains all fields. Ick.
So what do you think?
Do you really need to unify global data to achieve what the title of the patch series suggests (i.e. to unify the init processing loop)? Maybe you could leave global data as is (or slightly tweak the odd arch) and leave the resolution of just how bad global data is becoming for another day
It's not that easy, because in board_f.c and board_r.c and other files there are certain fields required. It doesn't make a huge amount of sense to have generic code which accesses a different global structure depending on what architecture it is built for. Then there are fields are are only used when certain options are defined. Ick.
If I am going to pull this off I need a bit of flexibility. I've looked into this quite a bit and mapped a path through this which I think will work. It requires doing things in stages, or it will never happen.
I only say this because this is turning into "let's do a dirty hack now to partially fix it and leave the rest for later (it'll get done, really, honestly, I promise)" ;)
It was always like that. Although I wouldn't characterise it as a dirty hack. If there was a requirement to do all of this in one big bang then I wouldn't have even started. It is just too hard :-(
There will always be arch specific global data members - I see a few options:
- Move them into bd
I recall talk of getting rid of this (Mike?)
- Move them into an arch_global_data struct inside gd
This was Mike's idea. It is probably the easiest thing to do.
- Move them into an arch_global_data struct totally seperate from gd
I sort-of like this except it would slow down access and maybe increase code size. Then again perhaps that's a good thing if it provides an incentive to reduce the number of arch-specific fields.
- Question how many are really required to be in gd (remember, gd is only there to cart around writable global variable before .bss and .data are available after relocation)
Well yes, I feel there are far more at present than are needed. Having them all there in the open feels like a nice way to draw attention to the mess.
Any more comments on this thread? At this stage I am still not sure of the best approach for this header...none of the options is particularly attractive. I can imagine something horrible like:
struct global_data { <common fields> ... #include <asm/arch_global_data.h> };
which would be the smallest code change (essentially no accesses would need to change). But it is too awful.
Of course I have a generic bd structure now, so moving things into there doesn't fix the problem.
So if I rewind back to your first suggestion (just leave global-data and bd as they are now), then I have the problem that I need to add quite a bit of stuff to these structures for every architecture. This is because at present most architectures don't support all the features, and so don't need all the fields. As soon as I have generic C code, I have references in that C code to global data members that only exist for some architectures. Then someone enables CONFIG_SPI, and breaks the board on the architecture that didn't previously have SPI support. I wonder if that matters?
It sort-off seems attractive from the 'less work' point of view, and is a stepping stone along the way, though.
Just to repeat your other ideas:
- Move them into bd
- Move them into an arch_global_data struct inside gd
- Move them into an arch_global_data struct totally seperate from gd
- Question how many are really required to be in gd (remember, gd is
only there to cart around writable global variable before .bss and .data are available after relocation)
(I feel the last one has to come later, though, even if unfortunately it would simplify things now - how on earth are we going to work out what things are really needed in global data?)
Regards, Simon

Hi Simon,
On 03/24/2012 05:40 PM, Simon Glass wrote:
Hi Graeme,
On Wed, Mar 14, 2012 at 8:41 PM, Simon Glass sjg@chromium.org wrote:
Hi Graeme,
On Wed, Mar 14, 2012 at 8:02 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
On Thu, Mar 15, 2012 at 1:50 PM, Simon Glass sjg@chromium.org wrote:
Hi Graeme,
On Wed, Mar 14, 2012 at 7:35 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
[snip]
IMHO, global data should contain only globally common members and an arch- specific struct and ditch (most of) the #ifdefs
My thinking here was to try to bring everything into a single file. It then should be clearer when things are common between different architectures. Patches to the generic file can be made without also having to patch the non-generic files, etc.
A fair number of the #ifdefs are not needed, or are there because some archs don't implement all the features of U-Boot.
You have an example right there: cpu_clk_rate_hz is similar to cpu_clk and core_clk.
That said it is a bit of a daunting task to amalgamate them.
Also there is the purely practical consideration that if we continue to have an asm/global_data.h then we end up with two global datas. One is for CONFIG_SYS_GENERIC_BOARD and contains just the non-common fields. The other is for non-CONFIG_SYS_GENERIC_BOARD and contains all fields. Ick.
So what do you think?
Do you really need to unify global data to achieve what the title of the patch series suggests (i.e. to unify the init processing loop)? Maybe you could leave global data as is (or slightly tweak the odd arch) and leave the resolution of just how bad global data is becoming for another day
It's not that easy, because in board_f.c and board_r.c and other files there are certain fields required. It doesn't make a huge amount of sense to have generic code which accesses a different global structure depending on what architecture it is built for. Then there are fields are are only used when certain options are defined. Ick.
If I am going to pull this off I need a bit of flexibility. I've looked into this quite a bit and mapped a path through this which I think will work. It requires doing things in stages, or it will never happen.
I only say this because this is turning into "let's do a dirty hack now to partially fix it and leave the rest for later (it'll get done, really, honestly, I promise)" ;)
It was always like that. Although I wouldn't characterise it as a dirty hack. If there was a requirement to do all of this in one big bang then I wouldn't have even started. It is just too hard :-(
There will always be arch specific global data members - I see a few options:
- Move them into bd
I recall talk of getting rid of this (Mike?)
- Move them into an arch_global_data struct inside gd
This was Mike's idea. It is probably the easiest thing to do.
- Move them into an arch_global_data struct totally seperate from gd
I sort-of like this except it would slow down access and maybe increase code size. Then again perhaps that's a good thing if it provides an incentive to reduce the number of arch-specific fields.
- Question how many are really required to be in gd (remember, gd is
only there to cart around writable global variable before .bss and .data are available after relocation)
Well yes, I feel there are far more at present than are needed. Having them all there in the open feels like a nice way to draw attention to the mess.
Any more comments on this thread? At this stage I am still not sure of the best approach for this header...none of the options is particularly attractive. I can imagine something horrible like:
struct global_data {
<common fields> ... #include <asm/arch_global_data.h> };
Ick! - NAK NAK NAK NAK ;)
which would be the smallest code change (essentially no accesses would need to change). But it is too awful.
Of course I have a generic bd structure now, so moving things into there doesn't fix the problem.
So if I rewind back to your first suggestion (just leave global-data and bd as they are now), then I have the problem that I need to add quite a bit of stuff to these structures for every architecture. This is because at present most architectures don't support all the features, and so don't need all the fields. As soon as I have generic C code, I have references in that C code to global data members that only exist for some architectures. Then someone enables CONFIG_SPI, and breaks the board on the architecture that didn't previously have SPI support. I wonder if that matters?
It sort-off seems attractive from the 'less work' point of view, and is a stepping stone along the way, though.
Just to repeat your other ideas:
- Move them into bd
- Move them into an arch_global_data struct inside gd
- Move them into an arch_global_data struct totally seperate from gd
- Question how many are really required to be in gd (remember, gd is
only there to cart around writable global variable before .bss and .data are available after relocation)
IIRC the Linux driver model includes a pointer to non-generic driver specific data which only the driver knows what to do with (the framework ignores it) If struct global_data has struct arch_global_data *agd in gd - Means a lot of changing of accessors and maybe a little code increase and slight access penalty (and maybe changes to asm startup code to handle the creation of gd plus agd and setting the pointer)
But that would be way cleaner for stuct global_data
Having agd in gd is probably a lot easier as the auto-generated gd size will be good to use
Hmmm..
arch/asm/global_data.h:
#define HAS_ARCH_GD
struct arch_global_data { ... };
include/global_data.h:
#include <arch/asm/global_data.h>
struct global_data { ... #ifdef HAS_ARCH_GD struct arch_global_data agd; #endif };
I like this better
P.S. Can we ditch the typedef while we are at it?
Q: Are there any board specific global data members anywhere?
(I feel the last one has to come later, though, even if unfortunately it would simplify things now - how on earth are we going to work out what things are really needed in global data?)
Look at the functions which are called prior to relocation - Anything referenced in these functions needs to be in gd
Regards,
Graeme

Hi Graeme,
On Sat, Mar 24, 2012 at 4:14 AM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
On 03/24/2012 05:40 PM, Simon Glass wrote:
Hi Graeme,
On Wed, Mar 14, 2012 at 8:41 PM, Simon Glass sjg@chromium.org wrote:
Hi Graeme,
On Wed, Mar 14, 2012 at 8:02 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
On Thu, Mar 15, 2012 at 1:50 PM, Simon Glass sjg@chromium.org wrote:
Hi Graeme,
On Wed, Mar 14, 2012 at 7:35 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
[snip]
IMHO, global data should contain only globally common members and an arch- specific struct and ditch (most of) the #ifdefs
My thinking here was to try to bring everything into a single file. It then should be clearer when things are common between different architectures. Patches to the generic file can be made without also having to patch the non-generic files, etc.
A fair number of the #ifdefs are not needed, or are there because some archs don't implement all the features of U-Boot.
You have an example right there: cpu_clk_rate_hz is similar to cpu_clk and core_clk.
That said it is a bit of a daunting task to amalgamate them.
Also there is the purely practical consideration that if we continue to have an asm/global_data.h then we end up with two global datas. One is for CONFIG_SYS_GENERIC_BOARD and contains just the non-common fields. The other is for non-CONFIG_SYS_GENERIC_BOARD and contains all fields. Ick.
So what do you think?
Do you really need to unify global data to achieve what the title of the patch series suggests (i.e. to unify the init processing loop)? Maybe you could leave global data as is (or slightly tweak the odd arch) and leave the resolution of just how bad global data is becoming for another day
It's not that easy, because in board_f.c and board_r.c and other files there are certain fields required. It doesn't make a huge amount of sense to have generic code which accesses a different global structure depending on what architecture it is built for. Then there are fields are are only used when certain options are defined. Ick.
If I am going to pull this off I need a bit of flexibility. I've looked into this quite a bit and mapped a path through this which I think will work. It requires doing things in stages, or it will never happen.
I only say this because this is turning into "let's do a dirty hack now to partially fix it and leave the rest for later (it'll get done, really, honestly, I promise)" ;)
It was always like that. Although I wouldn't characterise it as a dirty hack. If there was a requirement to do all of this in one big bang then I wouldn't have even started. It is just too hard :-(
There will always be arch specific global data members - I see a few options:
- Move them into bd
I recall talk of getting rid of this (Mike?)
- Move them into an arch_global_data struct inside gd
This was Mike's idea. It is probably the easiest thing to do.
- Move them into an arch_global_data struct totally seperate from gd
I sort-of like this except it would slow down access and maybe increase code size. Then again perhaps that's a good thing if it provides an incentive to reduce the number of arch-specific fields.
- Question how many are really required to be in gd (remember, gd is only there to cart around writable global variable before .bss and .data are available after relocation)
Well yes, I feel there are far more at present than are needed. Having them all there in the open feels like a nice way to draw attention to the mess.
Any more comments on this thread? At this stage I am still not sure of the best approach for this header...none of the options is particularly attractive. I can imagine something horrible like:
struct global_data { <common fields> ... #include <asm/arch_global_data.h> };
Ick! - NAK NAK NAK NAK ;)
You surprise me :-)
which would be the smallest code change (essentially no accesses would need to change). But it is too awful.
Of course I have a generic bd structure now, so moving things into there doesn't fix the problem.
So if I rewind back to your first suggestion (just leave global-data and bd as they are now), then I have the problem that I need to add quite a bit of stuff to these structures for every architecture. This is because at present most architectures don't support all the features, and so don't need all the fields. As soon as I have generic C code, I have references in that C code to global data members that only exist for some architectures. Then someone enables CONFIG_SPI, and breaks the board on the architecture that didn't previously have SPI support. I wonder if that matters?
It sort-off seems attractive from the 'less work' point of view, and is a stepping stone along the way, though.
Just to repeat your other ideas:
- Move them into bd - Move them into an arch_global_data struct inside gd - Move them into an arch_global_data struct totally seperate from gd - Question how many are really required to be in gd (remember, gd is only there to cart around writable global variable before .bss and .data are available after relocation)
IIRC the Linux driver model includes a pointer to non-generic driver specific data which only the driver knows what to do with (the framework ignores it) If struct global_data has struct arch_global_data *agd in gd - Means a lot of changing of accessors and maybe a little code increase and slight access penalty (and maybe changes to asm startup code to handle the creation of gd plus agd and setting the pointer)
But that would be way cleaner for stuct global_data
Having agd in gd is probably a lot easier as the auto-generated gd size will be good to use
Hmmm..
arch/asm/global_data.h:
#define HAS_ARCH_GD
struct arch_global_data { ... };
include/global_data.h:
#include <arch/asm/global_data.h>
struct global_data { ... #ifdef HAS_ARCH_GD struct arch_global_data agd; #endif };
I like this better
P.S. Can we ditch the typedef while we are at it?
Separate issue, but I can't see why not.
But I now remember the main problem I had with this. CONFIG_SYS_GENERIC_BOARD is an option, not mandatory, so we must not change the C code (much, ideally not at all) to make this work. If we move things around as you suggest then we should probably do it first as part of the normal code, so that generic board can just use it.
So the first change might be to move arch-specific data into an agd structure, and get everything building again. Then finally pull out the common part of each file into a new asm-generic file. It's the opposite way to what I have done so far, but the result will be the same in the end. I suppose my only reservation is that it creates patches initially for little benefit. I will have to think about how to motivate it.
Q: Are there any board specific global data members anywhere?
Probably, if we went into a deep enough. Certainly there are members which are only used for one sub-archs, and some of those sub-archs have a very small number of boards, perhaps 1 in some cases.
(I feel the last one has to come later, though, even if unfortunately it would simplify things now - how on earth are we going to work out what things are really needed in global data?)
Look at the functions which are called prior to relocation - Anything referenced in these functions needs to be in gd
Yes, but I'm just saying that is a long list, and involves a lot of code searching.
Regards,
Graeme
Regards, Simon

Hi Simon,
On 03/25/2012 10:10 AM, Simon Glass wrote:
Hi Graeme,
On Sat, Mar 24, 2012 at 4:14 AM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
[snip]
arch/asm/global_data.h:
#define HAS_ARCH_GD
struct arch_global_data { ... };
include/global_data.h:
#include <arch/asm/global_data.h>
struct global_data { ... #ifdef HAS_ARCH_GD struct arch_global_data agd; #endif };
I like this better
P.S. Can we ditch the typedef while we are at it?
Separate issue, but I can't see why not.
OK - See below
But I now remember the main problem I had with this. CONFIG_SYS_GENERIC_BOARD is an option, not mandatory, so we must not change the C code (much, ideally not at all) to make this work. If we move things around as you suggest then we should probably do it first as part of the normal code, so that generic board can just use it.
Sounds like a solid plan
So the first change might be to move arch-specific data into an agd structure, and get everything building again. Then finally pull out the common part of each file into a new asm-generic file. It's the opposite way to what I have done so far, but the result will be the same in the end. I suppose my only reservation is that it creates patches initially for little benefit. I will have to think about how to motivate it.
Clean-up work that, on the surface, appears to not do much does much more than you think. It may highlight a few nasty quibbles that you hadn't expected that you will need to plan around.
Big changes made against good, clean, consistent code are always easier than against bad, dirty, inconsistent code :)
And I think this is the ideal opportunity to drop the typedef
Q: Are there any board specific global data members anywhere?
Probably, if we went into a deep enough. Certainly there are members which are only used for one sub-archs, and some of those sub-archs have a very small number of boards, perhaps 1 in some cases.
OK, it might be worth investigating HAS_BOARD_GD. Maybe bring that through struct arch_global_data but it's not as clear an issue (there is a symlink to include/arch/asm but none for include/board/. For the time being, we may just have to leave the ifdefs in the include/arch/asm/global_data.h
(I feel the last one has to come later, though, even if unfortunately it would simplify things now - how on earth are we going to work out what things are really needed in global data?)
Look at the functions which are called prior to relocation - Anything referenced in these functions needs to be in gd
Yes, but I'm just saying that is a long list, and involves a lot of code searching.
I didn't say it would be easy ;)
The board_init_f array is a starting point.
I was planning on moving pre-relocation functions into a .init section so they were not copied during code relocation (much like Linux marks init functions so the memory can be free'd post init). Once this is done, identifying 'real' global data members will be trivial
Regards,
Graeme

This file holds the board info structure. We need this to be generic for the unified board series, so create a structure which contains the basic fields required by the main architectures.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v4: - Add three more fields required for ARM
include/asm-generic/u-boot.h | 160 ++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 160 insertions(+), 0 deletions(-) create mode 100644 include/asm-generic/u-boot.h
diff --git a/include/asm-generic/u-boot.h b/include/asm-generic/u-boot.h new file mode 100644 index 0000000..8a684fb --- /dev/null +++ b/include/asm-generic/u-boot.h @@ -0,0 +1,160 @@ +/* + * (C) Copyright 2000 - 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ******************************************************************** + * NOTE: This header file defines an interface to U-Boot. Including + * this (unmodified) header file in another file is considered normal + * use of U-Boot, and does *not* fall under the heading of "derived + * work". + ******************************************************************** + */ + +#ifndef __ASM_GENERIC_U_BOOT_H__ +#define __ASM_GENERIC_U_BOOT_H__ + +/* + * Board information passed to Linux kernel from U-Boot + * + * include/asm-ppc/u-boot.h + */ + +#ifndef __ASSEMBLY__ + +typedef struct bd_info { + unsigned long bi_memstart; /* start of DRAM memory */ + phys_size_t bi_memsize; /* size of DRAM memory in bytes */ + unsigned long bi_flashstart; /* start of FLASH memory */ + unsigned long bi_flashsize; /* size of FLASH memory */ + unsigned long bi_flashoffset; /* reserved area for startup monitor */ + unsigned long bi_sramstart; /* start of SRAM memory */ + unsigned long bi_sramsize; /* size of SRAM memory */ +#ifdef CONFIG_ARM + unsigned long bi_arm_freq; /* arm frequency */ + unsigned long bi_dsp_freq; /* dsp core frequency */ + unsigned long bi_ddr_freq; /* ddr frequency */ +#endif +#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \ + || defined(CONFIG_E500) || defined(CONFIG_MPC86xx) + unsigned long bi_immr_base; /* base of IMMR register */ +#endif +#if defined(CONFIG_MPC5xxx) + unsigned long bi_mbar_base; /* base of internal registers */ +#endif +#if defined(CONFIG_MPC83xx) + unsigned long bi_immrbar; +#endif +#if defined(CONFIG_MPC8220) + unsigned long bi_mbar_base; /* base of internal registers */ + unsigned long bi_inpfreq; /* Input Freq, In MHz */ + unsigned long bi_pcifreq; /* PCI Freq, in MHz */ + unsigned long bi_pevfreq; /* PEV Freq, in MHz */ + unsigned long bi_flbfreq; /* Flexbus Freq, in MHz */ + unsigned long bi_vcofreq; /* VCO Freq, in MHz */ +#endif + unsigned long bi_bootflags; /* boot / reboot flag (Unused) */ + unsigned long bi_ip_addr; /* IP Address */ + unsigned char bi_enetaddr[6]; /* OLD: see README.enetaddr */ + unsigned short bi_ethspeed; /* Ethernet speed in Mbps */ + unsigned long bi_intfreq; /* Internal Freq, in MHz */ + unsigned long bi_busfreq; /* Bus Freq, in MHz */ +#if defined(CONFIG_CPM2) + unsigned long bi_cpmfreq; /* CPM_CLK Freq, in MHz */ + unsigned long bi_brgfreq; /* BRG_CLK Freq, in MHz */ + unsigned long bi_sccfreq; /* SCC_CLK Freq, in MHz */ + unsigned long bi_vco; /* VCO Out from PLL, in MHz */ +#endif +#if defined(CONFIG_MPC512X) + unsigned long bi_ipsfreq; /* IPS Bus Freq, in MHz */ +#endif /* CONFIG_MPC512X */ +#if defined(CONFIG_MPC5xxx) + unsigned long bi_ipbfreq; /* IPB Bus Freq, in MHz */ + unsigned long bi_pcifreq; /* PCI Bus Freq, in MHz */ +#endif + unsigned long bi_baudrate; /* Console Baudrate */ +#if defined(CONFIG_405) || \ + defined(CONFIG_405GP) || \ + defined(CONFIG_405CR) || \ + defined(CONFIG_405EP) || \ + defined(CONFIG_405EZ) || \ + defined(CONFIG_405EX) || \ + defined(CONFIG_440) + unsigned char bi_s_version[4]; /* Version of this structure */ + unsigned char bi_r_version[32]; /* Version of the ROM (AMCC) */ + unsigned int bi_procfreq; /* CPU (Internal) Freq, in Hz */ + unsigned int bi_plb_busfreq; /* PLB Bus speed, in Hz */ + unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */ + unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */ +#endif +#if defined(CONFIG_HYMOD) + hymod_conf_t bi_hymod_conf; /* hymod configuration information */ +#endif + +#ifdef CONFIG_HAS_ETH1 + unsigned char bi_enet1addr[6]; /* OLD: see README.enetaddr */ +#endif +#ifdef CONFIG_HAS_ETH2 + unsigned char bi_enet2addr[6]; /* OLD: see README.enetaddr */ +#endif +#ifdef CONFIG_HAS_ETH3 + unsigned char bi_enet3addr[6]; /* OLD: see README.enetaddr */ +#endif +#ifdef CONFIG_HAS_ETH4 + unsigned char bi_enet4addr[6]; /* OLD: see README.enetaddr */ +#endif +#ifdef CONFIG_HAS_ETH5 + unsigned char bi_enet5addr[6]; /* OLD: see README.enetaddr */ +#endif + +#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || \ + defined(CONFIG_405EZ) || defined(CONFIG_440GX) || \ + defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ + defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) + unsigned int bi_opbfreq; /* OPB clock in Hz */ + int bi_iic_fast[2]; /* Use fast i2c mode */ +#endif +#if defined(CONFIG_NX823) + unsigned char bi_sernum[8]; +#endif +#if defined(CONFIG_4xx) +#if defined(CONFIG_440GX) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) + int bi_phynum[4]; /* Determines phy mapping */ + int bi_phymode[4]; /* Determines phy mode */ +#elif defined(CONFIG_405EP) || defined(CONFIG_405EX) || defined(CONFIG_440) + int bi_phynum[2]; /* Determines phy mapping */ + int bi_phymode[2]; /* Determines phy mode */ +#else + int bi_phynum[1]; /* Determines phy mapping */ + int bi_phymode[1]; /* Determines phy mode */ +#endif +#endif /* defined(CONFIG_4xx) */ + ulong bi_arch_number; /* unique id for this board */ + ulong bi_boot_params; /* where this board expects params */ +#ifdef CONFIG_NR_DRAM_BANKS + struct { /* RAM configuration */ + ulong start; + ulong size; + } bi_dram[CONFIG_NR_DRAM_BANKS]; +#endif /* CONFIG_NR_DRAM_BANKS */ +} bd_t; + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_GENERIC_U_BOOT_H__ */

We create a separate header file for link symbols defined by the link scripts. It is helpful to have these all in one place and try to make them common across architectures. Since Linux already has a similar file, we bring this in even though many of the symbols there are not relevant to us.
Each architecture has its own asm/sections.h where symbols specifc to that architecture can be added. For now everything except AVR32 just includes the generic header.
One change is needed in arch/avr32/lib/board.c to make this conversion work.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v4: - Add asm/sections.h for each architecture
arch/arm/include/asm/sections.h | 27 +++++++ arch/avr32/include/asm/sections.h | 6 +- arch/avr32/lib/board.c | 2 +- arch/blackfin/include/asm/sections.h | 27 +++++++ arch/m68k/include/asm/sections.h | 27 +++++++ arch/microblaze/include/asm/sections.h | 27 +++++++ arch/mips/include/asm/sections.h | 27 +++++++ arch/nds32/include/asm/sections.h | 27 +++++++ arch/nios2/include/asm/sections.h | 27 +++++++ arch/openrisc/include/asm/sections.h | 27 +++++++ arch/powerpc/include/asm/sections.h | 27 +++++++ arch/sandbox/include/asm/sections.h | 27 +++++++ arch/sh/include/asm/sections.h | 27 +++++++ arch/sparc/include/asm/sections.h | 27 +++++++ arch/x86/include/asm/sections.h | 27 +++++++ include/asm-generic/sections.h | 124 ++++++++++++++++++++++++++++++++ 16 files changed, 479 insertions(+), 4 deletions(-) create mode 100644 arch/arm/include/asm/sections.h create mode 100644 arch/blackfin/include/asm/sections.h create mode 100644 arch/m68k/include/asm/sections.h create mode 100644 arch/microblaze/include/asm/sections.h create mode 100644 arch/mips/include/asm/sections.h create mode 100644 arch/nds32/include/asm/sections.h create mode 100644 arch/nios2/include/asm/sections.h create mode 100644 arch/openrisc/include/asm/sections.h create mode 100644 arch/powerpc/include/asm/sections.h create mode 100644 arch/sandbox/include/asm/sections.h create mode 100644 arch/sh/include/asm/sections.h create mode 100644 arch/sparc/include/asm/sections.h create mode 100644 arch/x86/include/asm/sections.h create mode 100644 include/asm-generic/sections.h
diff --git a/arch/arm/include/asm/sections.h b/arch/arm/include/asm/sections.h new file mode 100644 index 0000000..c042cb6 --- /dev/null +++ b/arch/arm/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARM_SECTIONS_H +#define __ASM_ARM_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/avr32/include/asm/sections.h b/arch/avr32/include/asm/sections.h index 3f15788..056d7a0 100644 --- a/arch/avr32/include/asm/sections.h +++ b/arch/avr32/include/asm/sections.h @@ -22,11 +22,11 @@ #ifndef __ASM_AVR32_SECTIONS_H #define __ASM_AVR32_SECTIONS_H
+#include <asm-generic/sections.h> + /* References to section boundaries */
-extern char _text[], _etext[]; -extern char _data[], __data_lma[], _edata[], __edata_lma[]; +extern char __data_lma[], __edata_lma[]; extern char __got_start[], __got_lma[], __got_end[]; -extern char __bss_end__[];
#endif /* __ASM_AVR32_SECTIONS_H */ diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index 63fe297..de1b127 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -176,7 +176,7 @@ void board_init_f(ulong board_type) * - stack */ addr = CONFIG_SYS_SDRAM_BASE + sdram_size; - monitor_len = __bss_end__ - _text; + monitor_len = (char *)__bss_end__ - _text;
/* * Reserve memory for u-boot code, data and bss. diff --git a/arch/blackfin/include/asm/sections.h b/arch/blackfin/include/asm/sections.h new file mode 100644 index 0000000..85af42c --- /dev/null +++ b/arch/blackfin/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_BLACKFIN_SECTIONS_H +#define __ASM_BLACKFIN_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/m68k/include/asm/sections.h b/arch/m68k/include/asm/sections.h new file mode 100644 index 0000000..9228987 --- /dev/null +++ b/arch/m68k/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_M68K_SECTIONS_H +#define __ASM_M68K_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/microblaze/include/asm/sections.h b/arch/microblaze/include/asm/sections.h new file mode 100644 index 0000000..156c149 --- /dev/null +++ b/arch/microblaze/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_MICROBLAZE_SECTIONS_H +#define __ASM_MICROBLAZE_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/mips/include/asm/sections.h b/arch/mips/include/asm/sections.h new file mode 100644 index 0000000..54cd8b3 --- /dev/null +++ b/arch/mips/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_MIPS_SECTIONS_H +#define __ASM_MIPS_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/nds32/include/asm/sections.h b/arch/nds32/include/asm/sections.h new file mode 100644 index 0000000..a65735e --- /dev/null +++ b/arch/nds32/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_NDS32_SECTIONS_H +#define __ASM_NDS32_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/nios2/include/asm/sections.h b/arch/nios2/include/asm/sections.h new file mode 100644 index 0000000..d813563 --- /dev/null +++ b/arch/nios2/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_NIOS2_SECTIONS_H +#define __ASM_NIOS2_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/openrisc/include/asm/sections.h b/arch/openrisc/include/asm/sections.h new file mode 100644 index 0000000..6eb5a66 --- /dev/null +++ b/arch/openrisc/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_OPENRISC_SECTIONS_H +#define __ASM_OPENRISC_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h new file mode 100644 index 0000000..0a94102 --- /dev/null +++ b/arch/powerpc/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_POWERPC_SECTIONS_H +#define __ASM_POWERPC_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/sandbox/include/asm/sections.h b/arch/sandbox/include/asm/sections.h new file mode 100644 index 0000000..db1fabb --- /dev/null +++ b/arch/sandbox/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_SANDBOX_SECTIONS_H +#define __ASM_SANDBOX_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/sh/include/asm/sections.h b/arch/sh/include/asm/sections.h new file mode 100644 index 0000000..8824560 --- /dev/null +++ b/arch/sh/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_SH_SECTIONS_H +#define __ASM_SH_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/sparc/include/asm/sections.h b/arch/sparc/include/asm/sections.h new file mode 100644 index 0000000..90f7fa7 --- /dev/null +++ b/arch/sparc/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_SPARC_SECTIONS_H +#define __ASM_SPARC_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h new file mode 100644 index 0000000..602df86 --- /dev/null +++ b/arch/x86/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_X86_SECTIONS_H +#define __ASM_X86_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h new file mode 100644 index 0000000..62c68f0 --- /dev/null +++ b/include/asm-generic/sections.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* Taken from Linux kernel */ + +#ifndef _ASM_GENERIC_SECTIONS_H_ +#define _ASM_GENERIC_SECTIONS_H_ + +/* References to section boundaries */ + +extern char _text[], _stext[], _etext[]; +extern char _data[], _sdata[], _edata[]; +extern char __bss_start[], __bss_stop[]; +extern char __init_begin[], __init_end[]; +extern char _sinittext[], _einittext[]; +extern char _end[]; +extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[]; +extern char __kprobes_text_start[], __kprobes_text_end[]; +extern char __entry_text_start[], __entry_text_end[]; +extern char __initdata_begin[], __initdata_end[]; +extern char __start_rodata[], __end_rodata[]; + +/* Start and end of .ctors section - used for constructor calls. */ +extern char __ctors_start[], __ctors_end[]; + +/* function descriptor handling (if any). Override + * in asm/sections.h */ +#ifndef dereference_function_descriptor +#define dereference_function_descriptor(p) (p) +#endif + +/* random extra sections (if any). Override + * in asm/sections.h */ +#ifndef arch_is_kernel_text +static inline int arch_is_kernel_text(unsigned long addr) +{ + return 0; +} +#endif + +#ifndef arch_is_kernel_data +static inline int arch_is_kernel_data(unsigned long addr) +{ + return 0; +} +#endif + +#include <elf.h> + +/* U-Boot-specific things begin here */ + +/* Start of U-Boot text region */ +extern char __text_start[]; + +/* This marks the end of the text region which must be relocated */ +extern char __image_copy_end[]; + +/* + * This is the U-Boot entry point - prior to relocation it should be same + * as __text_start + */ +extern void _start(void); + +/* + * ARM needs to use offsets for symbols, since the values of some symbols + * are not resolved prior to relocation (and are just 0). Maybe this can be + * resolved, or maybe other architectures are similar, iwc this should be + * promoted to an architecture option. + */ +#ifdef CONFIG_ARM +#define CONFIG_SYS_SYM_OFFSETS +#endif + +#ifdef CONFIG_SYS_SYM_OFFSETS +/* Start/end of the relocation entries, as an offset from _start */ +extern ulong _rel_dyn_start_ofs; +extern ulong _rel_dyn_end_ofs; + +/* Start/end of the relocation symbol table, as an offset from _start */ +extern ulong _dynsym_start_ofs; + +/* End of the region to be relocated, as an offset form _start */ +extern ulong _image_copy_end_ofs; + +extern ulong _bss_start_ofs; /* BSS start relative to _start */ +extern ulong _bss_end_ofs; /* BSS end relative to _start */ +extern ulong _end_ofs; /* end of image relative to _start */ + +extern ulong _TEXT_BASE; /* code start */ + +#else /* don't use offsets: */ + +/* Exports from the Linker Script */ +extern ulong __data_end; +extern ulong __rel_dyn_start; +extern ulong __rel_dyn_end; +extern ulong __bss_end; + +extern ulong _TEXT_BASE; /* code start */ + +#endif + +/* Some link scripts put a double underscore on the end, so for now... */ +#define __bss_end__ __bss_end + +#endif /* _ASM_GENERIC_SECTIONS_H_ */

Include this header to get access to link symbols, which are otherwise removed.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v4: - Use asm/sections.h instead of asm-generic/sections.h
arch/arm/include/asm/u-boot-arm.h | 4 ---- arch/arm/lib/board.c | 1 + arch/avr32/cpu/start.S | 2 +- arch/avr32/cpu/u-boot.lds | 2 +- board/cm4008/flash.c | 1 + board/cm41xx/flash.c | 1 + 6 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/arch/arm/include/asm/u-boot-arm.h b/arch/arm/include/asm/u-boot-arm.h index 4ca75f9..7cfae9b 100644 --- a/arch/arm/include/asm/u-boot-arm.h +++ b/arch/arm/include/asm/u-boot-arm.h @@ -30,12 +30,8 @@ #define _U_BOOT_ARM_H_ 1
/* for the following variables, see start.S */ -extern ulong _bss_start_ofs; /* BSS start relative to _start */ -extern ulong _bss_end_ofs; /* BSS end relative to _start */ -extern ulong _end_ofs; /* end of image relative to _start */ extern ulong IRQ_STACK_START; /* top of IRQ stack */ extern ulong FIQ_STACK_START; /* top of FIQ stack */ -extern ulong _TEXT_BASE; /* code start */ extern ulong _datarel_start_ofs; extern ulong _datarelrolocal_start_ofs; extern ulong _datarellocal_start_ofs; diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index 500e216..fdd5d15 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -63,6 +63,7 @@ #ifdef CONFIG_DRIVER_LAN91C96 #include "../drivers/net/lan91c96.h" #endif +#include <asm/sections.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/arch/avr32/cpu/start.S b/arch/avr32/cpu/start.S index 71cbc52..c8decea 100644 --- a/arch/avr32/cpu/start.S +++ b/arch/avr32/cpu/start.S @@ -244,7 +244,7 @@ relocate_code: /* zero out .bss */ mov r0, 0 mov r1, 0 - lda.w r9, __bss_end__ + lda.w r9, __bss_end sub r9, r8 1: st.d r10++, r0 sub r9, 8 diff --git a/arch/avr32/cpu/u-boot.lds b/arch/avr32/cpu/u-boot.lds index 0e532f2..4de2fff 100644 --- a/arch/avr32/cpu/u-boot.lds +++ b/arch/avr32/cpu/u-boot.lds @@ -68,5 +68,5 @@ SECTIONS *(.bss.*) } . = ALIGN(8); - __bss_end__ = .; + __bss_end = .; } diff --git a/board/cm4008/flash.c b/board/cm4008/flash.c index 5522bf0..0faf197 100644 --- a/board/cm4008/flash.c +++ b/board/cm4008/flash.c @@ -29,6 +29,7 @@
#include <common.h> #include <linux/byteorder/swab.h> +#include <asm/sections.h>
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */ diff --git a/board/cm41xx/flash.c b/board/cm41xx/flash.c index 5522bf0..0faf197 100644 --- a/board/cm41xx/flash.c +++ b/board/cm41xx/flash.c @@ -29,6 +29,7 @@
#include <common.h> #include <linux/byteorder/swab.h> +#include <asm/sections.h>
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */

We can use the declarations of __bss_start and _end from this header instead of declaring them locally.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v4: - Use asm/sections.h instead of asm-generic/sections.h
examples/standalone/stubs.c | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c index 15e9afc..8fb1765 100644 --- a/examples/standalone/stubs.c +++ b/examples/standalone/stubs.c @@ -217,16 +217,15 @@ void __attribute__((unused)) dummy(void) #include <_exports.h> }
-extern unsigned long __bss_start, _end; +#include <asm/sections.h>
void app_startup(char * const *argv) { - unsigned char * cp = (unsigned char *) &__bss_start; + char *cp = __bss_start;
/* Zero out BSS */ - while (cp < (unsigned char *)&_end) { + while (cp < _end) *cp++ = 0; - }
#if defined(CONFIG_X86) /* x86 does not have a dedicated register for passing global_data */

Hi Simon,
On Thu, Mar 15, 2012 at 1:16 PM, Simon Glass sjg@chromium.org wrote:
We can use the declarations of __bss_start and _end from this header instead of declaring them locally.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v4:
- Use asm/sections.h instead of asm-generic/sections.h
examples/standalone/stubs.c | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c index 15e9afc..8fb1765 100644 --- a/examples/standalone/stubs.c +++ b/examples/standalone/stubs.c @@ -217,16 +217,15 @@ void __attribute__((unused)) dummy(void) #include <_exports.h> }
-extern unsigned long __bss_start, _end; +#include <asm/sections.h>
void app_startup(char * const *argv) {
- unsigned char * cp = (unsigned char *) &__bss_start;
- char *cp = __bss_start;
/* Zero out BSS */
- while (cp < (unsigned char *)&_end) {
- while (cp < _end)
*cp++ = 0;
- }
#if defined(CONFIG_X86) /* x86 does not have a dedicated register for passing global_data */ -- 1.7.7.3
Does not look like x86 to me - looks like common code
Regards,
Graeme

Hi Graeme,
On Wed, Mar 14, 2012 at 7:29 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
On Thu, Mar 15, 2012 at 1:16 PM, Simon Glass sjg@chromium.org wrote:
We can use the declarations of __bss_start and _end from this header instead of declaring them locally.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v4:
- Use asm/sections.h instead of asm-generic/sections.h
examples/standalone/stubs.c | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c index 15e9afc..8fb1765 100644 --- a/examples/standalone/stubs.c +++ b/examples/standalone/stubs.c @@ -217,16 +217,15 @@ void __attribute__((unused)) dummy(void) #include <_exports.h> }
-extern unsigned long __bss_start, _end; +#include <asm/sections.h>
void app_startup(char * const *argv) {
- unsigned char * cp = (unsigned char *) &__bss_start;
- char *cp = __bss_start;
/* Zero out BSS */
- while (cp < (unsigned char *)&_end) {
- while (cp < _end)
*cp++ = 0;
- }
#if defined(CONFIG_X86) /* x86 does not have a dedicated register for passing global_data */ -- 1.7.7.3
Does not look like x86 to me - looks like common code
Yes that tag is wrong. Should I re-issue the patch?
Regards, Simon
Regards,
Graeme

Hi Simon,
On Thu, Mar 15, 2012 at 1:44 PM, Simon Glass sjg@chromium.org wrote:
Hi Graeme,
On Wed, Mar 14, 2012 at 7:29 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
Does not look like x86 to me - looks like common code
Yes that tag is wrong. Should I re-issue the patch?
Yes, but wait until you rev the whole series
Regards,
Graeme

This library supports calling a list of functions one after the other.
It is intended that we move to a more powerful initcall implementation as proposed by Graeme Russ graeme.russ@gmail.com. For now, this allows us to do the basics.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/initcall.h | 25 +++++++++++++++++++++++++ lib/Makefile | 1 + lib/initcall.c | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 0 deletions(-) create mode 100644 include/initcall.h create mode 100644 lib/initcall.c
diff --git a/include/initcall.h b/include/initcall.h new file mode 100644 index 0000000..9e54fa5 --- /dev/null +++ b/include/initcall.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +typedef int (*init_fnc_t)(void); + +int initcall_run_list(init_fnc_t init_sequence[]); diff --git a/lib/Makefile b/lib/Makefile index e6e6ec6..f4d3325 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -41,6 +41,7 @@ COBJS-y += display_options.o COBJS-y += errno.o COBJS-$(CONFIG_OF_CONTROL) += fdtdec.o COBJS-$(CONFIG_GZIP) += gunzip.o +COBJS-y += initcall.o COBJS-y += hashtable.o COBJS-$(CONFIG_LMB) += lmb.o COBJS-y += ldiv.o diff --git a/lib/initcall.c b/lib/initcall.c new file mode 100644 index 0000000..b11048e --- /dev/null +++ b/lib/initcall.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2002-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <initcall.h> + +int initcall_run_list(init_fnc_t init_sequence[]) +{ + init_fnc_t *init_fnc_ptr; + + for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { + if ((*init_fnc_ptr)()) + return -1; + } + return 0; +}

We are introducing a new unified board setup and we want this to be the default. So we need to opt all architectures out first.
Signed-off-by: Simon Glass sjg@chromium.org ---
README | 11 +++++++++++ arch/arm/config.mk | 3 +++ arch/avr32/config.mk | 3 +++ arch/blackfin/config.mk | 3 +++ arch/m68k/config.mk | 3 +++ arch/microblaze/config.mk | 3 +++ arch/mips/config.mk | 3 +++ arch/nds32/config.mk | 3 +++ arch/nios2/config.mk | 3 +++ arch/powerpc/config.mk | 3 +++ arch/sandbox/config.mk | 3 +++ arch/sh/config.mk | 3 +++ arch/sparc/config.mk | 3 +++ arch/x86/config.mk | 3 +++ config.mk | 8 ++++++++ 15 files changed, 58 insertions(+), 0 deletions(-)
diff --git a/README b/README index 8964672..f471627 100644 --- a/README +++ b/README @@ -2770,6 +2770,17 @@ Configuration Settings: cases. This setting can be used to tune behaviour; see lib/hashtable.c for details.
+- CONFIG_SYS_GENERIC_BOARD + This selects the architecture-generic board system instead of the + architecture-specific board files. It is intended to move boards + to this new framework over time. Defining this will disable the + arch/foo/lib/board.c file and use common/board_f.c and + common/board_r.c instead. To use this option your architecture + must support it (i.e. must NOT define CONFIG_SYS_LEGACY_BOARD in + its config.mk file). If you find problems enabling this option on + your board please report the problem and send patches! + + The following definitions that deal with the placement and management of environment data (variable area); in general, we support the following configurations: diff --git a/arch/arm/config.mk b/arch/arm/config.mk index 45f9dca..31e9ef9 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -33,6 +33,9 @@ endif
PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__
+# Move to unified board system later +CONFIG_SYS_LEGACY_BOARD := y + # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: PF_CPPFLAGS_ARM := $(call cc-option,-marm,)
diff --git a/arch/avr32/config.mk b/arch/avr32/config.mk index d8e7ebb..6eb00f6 100644 --- a/arch/avr32/config.mk +++ b/arch/avr32/config.mk @@ -31,3 +31,6 @@ PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections LDFLAGS_u-boot = --gc-sections --relax
LDSCRIPT = $(SRCTREE)/$(CPUDIR)/u-boot.lds + +# Move to unified board system later +CONFIG_SYS_LEGACY_BOARD := y diff --git a/arch/blackfin/config.mk b/arch/blackfin/config.mk index 3595aa2..972afb1 100644 --- a/arch/blackfin/config.mk +++ b/arch/blackfin/config.mk @@ -37,6 +37,9 @@ CONFIG_BFIN_BOOT_MODE := $(strip $(subst ",,$(CONFIG_BFIN_BOOT_MODE))) PLATFORM_RELFLAGS += -ffixed-P3 -fomit-frame-pointer -mno-fdpic PLATFORM_CPPFLAGS += -DCONFIG_BLACKFIN
+# Move to unified board system later +CONFIG_SYS_LEGACY_BOARD := y + LDFLAGS_FINAL += --gc-sections LDFLAGS += -m elf32bfin PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections diff --git a/arch/m68k/config.mk b/arch/m68k/config.mk index 11ba334..11ad9a5 100644 --- a/arch/m68k/config.mk +++ b/arch/m68k/config.mk @@ -29,3 +29,6 @@ PLATFORM_CPPFLAGS += -DCONFIG_M68K -D__M68K__ PLATFORM_LDFLAGS += -n PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections LDFLAGS_FINAL += --gc-sections + +# Move to unified board system later +CONFIG_SYS_LEGACY_BOARD := y diff --git a/arch/microblaze/config.mk b/arch/microblaze/config.mk index abea70b..119a596 100644 --- a/arch/microblaze/config.mk +++ b/arch/microblaze/config.mk @@ -29,3 +29,6 @@ CROSS_COMPILE ?= mb- CONFIG_STANDALONE_LOAD_ADDR ?= 0x80F00000
PLATFORM_CPPFLAGS += -ffixed-r31 -D__microblaze__ + +# Move to unified board system later +CONFIG_SYS_LEGACY_BOARD := y diff --git a/arch/mips/config.mk b/arch/mips/config.mk index 6ab8acd..8f5305e 100644 --- a/arch/mips/config.mk +++ b/arch/mips/config.mk @@ -27,6 +27,9 @@ CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 -T mips.lds
PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__
+# Move to unified board system later +CONFIG_SYS_LEGACY_BOARD := y + # # From Linux arch/mips/Makefile # diff --git a/arch/nds32/config.mk b/arch/nds32/config.mk index c589829..f989053 100644 --- a/arch/nds32/config.mk +++ b/arch/nds32/config.mk @@ -33,3 +33,6 @@ PLATFORM_RELFLAGS += -gdwarf-2 PLATFORM_CPPFLAGS += -DCONFIG_NDS32 -D__nds32__ -G0 -ffixed-10 -fpie
LDFLAGS_u-boot = --gc-sections --relax + +# Move to unified board system later +CONFIG_SYS_LEGACY_BOARD := y diff --git a/arch/nios2/config.mk b/arch/nios2/config.mk index 7b03ed8..0172f70 100644 --- a/arch/nios2/config.mk +++ b/arch/nios2/config.mk @@ -31,3 +31,6 @@ PLATFORM_CPPFLAGS += -G0
LDFLAGS_FINAL += --gc-sections PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections + +# Move to unified board system later +CONFIG_SYS_LEGACY_BOARD := y diff --git a/arch/powerpc/config.mk b/arch/powerpc/config.mk index a307154..e6203dd 100644 --- a/arch/powerpc/config.mk +++ b/arch/powerpc/config.mk @@ -29,6 +29,9 @@ PLATFORM_RELFLAGS += -fpic -mrelocatable -ffunction-sections -fdata-sections PLATFORM_CPPFLAGS += -DCONFIG_PPC -D__powerpc__ PLATFORM_LDFLAGS += -n
+# Move to unified board system later +CONFIG_SYS_LEGACY_BOARD := y + # # When cross-compiling on NetBSD, we have to define __PPC__ or else we # will pick up a va_list declaration that is incompatible with the diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk index 2ec1bb7..38c97d9 100644 --- a/arch/sandbox/config.mk +++ b/arch/sandbox/config.mk @@ -19,3 +19,6 @@
PLATFORM_CPPFLAGS += -DCONFIG_SANDBOX -D__SANDBOX__ PLATFORM_LIBS += -lrt + +# Move to unified board system later +CONFIG_SYS_LEGACY_BOARD := y diff --git a/arch/sh/config.mk b/arch/sh/config.mk index 07ff8b9..0c21ef5 100644 --- a/arch/sh/config.mk +++ b/arch/sh/config.mk @@ -31,3 +31,6 @@ endif PLATFORM_CPPFLAGS += -DCONFIG_SH -D__SH__ PLATFORM_LDFLAGS += -e $(CONFIG_SYS_TEXT_BASE) --defsym reloc_dst=$(CONFIG_SYS_TEXT_BASE) LDFLAGS_FINAL = --gc-sections + +# Move to unified board system later +CONFIG_SYS_LEGACY_BOARD := y diff --git a/arch/sparc/config.mk b/arch/sparc/config.mk index cae7478..b98a173 100644 --- a/arch/sparc/config.mk +++ b/arch/sparc/config.mk @@ -26,3 +26,6 @@ CROSS_COMPILE ?= sparc-elf- CONFIG_STANDALONE_LOAD_ADDR ?= 0x00000000 -L $(gcclibdir) -T sparc.lds
PLATFORM_CPPFLAGS += -DCONFIG_SPARC -D__sparc__ + +# Move to unified board system later +CONFIG_SYS_LEGACY_BOARD := y diff --git a/arch/x86/config.mk b/arch/x86/config.mk index 23cacff..7be3036 100644 --- a/arch/x86/config.mk +++ b/arch/x86/config.mk @@ -48,3 +48,6 @@ NORMAL_LIBGCC = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) PREFIXED_LIBGCC = $(OBJTREE)/arch/$(ARCH)/lib/$(shell basename $(NORMAL_LIBGCC))
export USE_PRIVATE_LIBGCC=$(shell dirname $(PREFIXED_LIBGCC)) + +# Move to unified board system later +CONFIG_SYS_LEGACY_BOARD := y diff --git a/config.mk b/config.mk index ddaa477..a936f1f 100644 --- a/config.mk +++ b/config.mk @@ -206,6 +206,14 @@ ifeq ($(CONFIG_SPL_BUILD),y) CPPFLAGS += -DCONFIG_SPL_BUILD endif
+# Does this architecture support generic board init? +ifneq ($(CONFIG_SYS_LEGACY_BOARD),) +ifneq ($(CONFIG_SYS_GENERIC_BOARD),) +$(error Your architecture does not support generic board. Please undefined \ +CONFIG_SYS_GENERIC_BOARD in your board config file) +endif +endif + ifneq ($(RESET_VECTOR_ADDRESS),) CPPFLAGS += -DRESET_VECTOR_ADDRESS=$(RESET_VECTOR_ADDRESS) endif

This file handles common pre-relocation init for boards which use the generic framework.
It starts up the console, DRAM, performs relocation and then jumps to post-relocation init.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: - Cast away the volatile on gd for memcpy()
Changes in v4: - Use asm/sections.h instead of asm-generic/sections.h
common/Makefile | 3 + common/board_f.c | 490 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 493 insertions(+), 0 deletions(-) create mode 100644 common/board_f.c
diff --git a/common/Makefile b/common/Makefile index 2a31c62..125c2a9 100644 --- a/common/Makefile +++ b/common/Makefile @@ -36,6 +36,9 @@ COBJS-y += s_record.o COBJS-$(CONFIG_SERIAL_MULTI) += serial.o COBJS-y += xyzModem.o
+# boards +COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_f.o + # core command COBJS-y += cmd_boot.o COBJS-$(CONFIG_CMD_BOOTM) += cmd_bootm.o diff --git a/common/board_f.c b/common/board_f.c new file mode 100644 index 0000000..9477721 --- /dev/null +++ b/common/board_f.c @@ -0,0 +1,490 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2002-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <linux/compiler.h> +#include <version.h> +#include <environment.h> +#include <initcall.h> +#include <logbuff.h> +#include <post.h> +#include <asm/io.h> +#include <asm/sections.h> + +/* + * Pointer to initial global data area + * + * Here we initialize it if needed. + */ +#ifdef XTRN_DECLARE_GLOBAL_DATA_PTR +#undef XTRN_DECLARE_GLOBAL_DATA_PTR +#define XTRN_DECLARE_GLOBAL_DATA_PTR /* empty = allocate here */ +DECLARE_GLOBAL_DATA_PTR = (gd_t *) (CONFIG_SYS_INIT_GD_ADDR); +#else +DECLARE_GLOBAL_DATA_PTR; +#endif + +/* TODO: Move to header file */ +int print_cpuinfo(void); + +/* + * sjg: IMO this code should be + * refactored to a single function, something like: + * + * void led_set_state(enum led_colour_t colour, int on); + */ +/************************************************************************ + * Coloured LED functionality + ************************************************************************ + * May be supplied by boards if desired + */ +inline void __coloured_LED_init(void) {} +void coloured_LED_init(void) + __attribute__((weak, alias("__coloured_LED_init"))); +inline void __red_led_on(void) {} +void red_led_on(void) __attribute__((weak, alias("__red_led_on"))); +inline void __red_led_off(void) {} +void red_led_off(void) __attribute__((weak, alias("__red_led_off"))); +inline void __green_led_on(void) {} +void green_led_on(void) __attribute__((weak, alias("__green_led_on"))); +inline void __green_led_off(void) {} +void green_led_off(void) __attribute__((weak, alias("__green_led_off"))); +inline void __yellow_led_on(void) {} +void yellow_led_on(void) __attribute__((weak, alias("__yellow_led_on"))); +inline void __yellow_led_off(void) {} +void yellow_led_off(void) __attribute__((weak, alias("__yellow_led_off"))); +inline void __blue_led_on(void) {} +void blue_led_on(void) __attribute__((weak, alias("__blue_led_on"))); +inline void __blue_led_off(void) {} +void blue_led_off(void) __attribute__((weak, alias("__blue_led_off"))); + +/* + * Why is gd allocated a register? Prior to reloc it might be better to + * just pass it around to each function in this file? + * + * After reloc one could argue that it is hardly used and doesn't need + * to be in a register. Or if it is it should perhaps hold pointers to all + * global data for all modules, so that post-reloc we can avoid the massive + * literal pool we get on ARM. Or perhaps just encourage each module to use + * a structure... + */ + +/* + * Could the CONFIG_SPL_BUILD infection become a flag in gd? + */ + +static int init_baud_rate(void) +{ + gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE); + return 0; +} + +static int display_text_info(void) +{ + ulong bss_start, bss_end; + + bss_start = _bss_start_ofs + _TEXT_BASE; + bss_end = _bss_end_ofs + _TEXT_BASE; + debug("U-Boot code: %08X -> %08lX BSS: -> %08lX\n", + CONFIG_SYS_TEXT_BASE, bss_start, bss_end); + +#ifdef CONFIG_MODEM_SUPPORT + debug("Modem Support enabled\n"); +#endif +#ifdef CONFIG_USE_IRQ + debug("IRQ Stack: %08lx\n", IRQ_STACK_START); + debug("FIQ Stack: %08lx\n", FIQ_STACK_START); +#endif + + return 0; +} + +static int announce_dram_init(void) +{ + puts("DRAM: "); + return 0; +} + +static int display_dram_config(void) +{ + ulong size; + +#ifdef CONFIG_NR_DRAM_BANKS + int i; + + debug("\nRAM Configuration:\n"); + for (i = size = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + size += gd->bd->bi_dram[i].size; + debug("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start); +#ifdef DEBUG + print_size(gd->bd->bi_dram[i].size, "\n"); +#endif + } + debug("\nDRAM: "); +#else + size = gd->ram_size; +#endif + + print_size(size, "\n"); + + return 0; +} + +void __dram_init_banksize(void) +{ +#if defined(CONFIG_NR_DRAM_BANKS) && defined(CONFIG_SYS_SDRAM_BASE) + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = get_effective_memsize(); +#endif +} + +void dram_init_banksize(void) + __attribute__((weak, alias("__dram_init_banksize"))); + +static int setup_global_data_ptr(void) +{ + /* Pointer is writable since we allocated a register for it */ + gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07); + + /* compiler optimization barrier needed for GCC >= 3.4 */ + dmb(); + + return 0; +} + +static int zero_global_data(void) +{ + memset((void *)gd, '\0', sizeof(gd_t)); + + return 0; +} + +static int setup_mon_len(void) +{ + gd->mon_len = _bss_end_ofs; + return 0; +} + +static int setup_fdt(void) +{ +#ifdef CONFIG_OF_EMBED + /* Get a pointer to the FDT */ + gd->fdt_blob = _binary_dt_dtb_start; +#elif defined CONFIG_OF_SEPARATE + /* FDT is at end of image */ + gd->fdt_blob = (void *)(_end_ofs + CONFIG_SYS_TEXT_BASE); +#endif + /* Allow the early environment to override the fdt address */ + gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, + (uintptr_t)gd->fdt_blob); + return 0; +} + +static int setup_reloc(void) +{ + debug("Monitor len: %08lX\n", gd->mon_len); + /* + * Ram is setup, size stored in gd !! + */ + debug("Ram size: %08lX\n", (ulong)gd->ram_size); +#if defined(CONFIG_SYS_MEM_TOP_HIDE) + /* + * Subtract specified amount of memory to hide so that it won't + * get "touched" at all by U-Boot. By fixing up gd->ram_size + * the Linux kernel should now get passed the now "corrected" + * memory size and won't touch it either. This should work + * for arch/ppc and arch/powerpc. Only Linux board ports in + * arch/powerpc with bootwrapper support, that recalculate the + * memory size from the SDRAM controller setup will have to + * get fixed. + */ + gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE; +#endif + gd->dest_addr = gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; + gd->dest_addr_sp = gd->dest_addr; + return 0; +} + +#if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR) +static int reserve_logbuffer(void) +{ + /* reserve kernel log buffer */ + gd->dest_addr -= LOGBUFF_RESERVE; + debug("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, + gd->dest_addr); + return 0; +} +#endif + +#ifdef CONFIG_PRAM +/* reserve protected RAM */ +static int reserve_pram(void) +{ + ulong reg; + + reg = getenv_ulong("pram", 10, CONFIG_PRAM); + gd->dest_addr -= (reg << 10); /* size is in kB */ + debug("Reserving %ldk for protected RAM at %08lx\n", reg, + gd->dest_addr); + return 0; +} +#endif /* CONFIG_PRAM */ + +/* Round memory pointer down to next 4 kB limit */ +static int reserve_round_4k(void) +{ + gd->dest_addr &= ~(4096 - 1); + return 0; +} + +#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) +static int reserve_mmu(void) +{ + /* reserve TLB table */ + gd->dest_addr -= (4096 * 4); + + /* round down to next 64 kB limit */ + gd->dest_addr &= ~(0x10000 - 1); + + gd->tlb_addr = gd->dest_addr; + debug("TLB table at: %08lx\n", gd->tlb_addr); + return 0; +} +#endif + +#ifdef CONFIG_LCD +static int reserve_lcd(void) +{ +#ifdef CONFIG_FB_ADDR + gd->fb_base = CONFIG_FB_ADDR; +#else + /* reserve memory for LCD display (always full pages) */ + gd->dest_addr = lcd_setmem(gd->dest_addr); + gd->fb_base = gd->dest_addr; +#endif /* CONFIG_FB_ADDR */ + return 0; +} +#endif /* CONFIG_LCD */ + +static int reserve_uboot(void) +{ + /* + * reserve memory for U-Boot code, data & bss + * round down to next 4 kB limit + */ + gd->dest_addr -= gd->mon_len; + gd->dest_addr &= ~(4096 - 1); + + debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, + gd->dest_addr); + return 0; +} + +/* reserve memory for malloc() area */ +static int reserve_malloc(void) +{ + gd->dest_addr_sp = gd->dest_addr - TOTAL_MALLOC_LEN; + debug("Reserving %dk for malloc() at: %08lx\n", + TOTAL_MALLOC_LEN >> 10, gd->dest_addr_sp); + return 0; +} + +/* (permanently) allocate a Board Info struct */ +static int reserve_board(void) +{ + gd->dest_addr_sp -= sizeof(bd_t); + gd->bd = (bd_t *)gd->dest_addr_sp; + memset(gd->bd, '\0', sizeof(bd_t)); + debug("Reserving %zu Bytes for Board Info at: %08lx\n", + sizeof(bd_t), gd->dest_addr_sp); + return 0; +} + +static int setup_machine(void) +{ +#ifdef CONFIG_MACH_TYPE + gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */ +#endif + return 0; +} + +static int reserve_global_data(void) +{ + gd->dest_addr_sp -= sizeof(gd_t); + gd->new_gd = (gd_t *)gd->dest_addr_sp; + debug("Reserving %zu Bytes for Global Data at: %08lx\n", + sizeof(gd_t), gd->dest_addr_sp); + return 0; +} + +static int reserve_stacks(void) +{ + /* setup stack pointer for exceptions */ + gd->irq_sp = gd->dest_addr_sp; +#ifdef CONFIG_USE_IRQ + gd->dest_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ); + debug("Reserving %zu Bytes for IRQ stack at: %08lx\n", + CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->dest_addr_sp); + + /* 8-byte alignment for ARM ABI compliance */ + gd->dest_addr_sp &= ~0x07; +#endif + /* leave 3 words for abort-stack, plus 1 for alignment */ + gd->dest_addr_sp -= 16; + + return 0; +} + +static int display_new_sp(void) +{ + debug("New Stack Pointer is: %08lx\n", gd->dest_addr_sp); + + return 0; +} + +#ifdef CONFIG_POST +static int init_post(void) +{ + post_bootmode_init(); + post_run(NULL, POST_ROM | post_bootmode_get(0)); + + return 0; +} +#endif + +static int setup_baud_rate(void) +{ + /* Ick, can we get rid of this line? */ + gd->bd->bi_baudrate = gd->baudrate; + + return 0; +} + +static int setup_dram_config(void) +{ + /* Ram is board specific, so move it to board code ... */ + dram_init_banksize(); + + return 0; +} + +static int jump_to_copy(void) +{ + memcpy(gd->new_gd, (char *)gd, sizeof(gd_t)); + gd->relocaddr = gd->dest_addr; + gd->reloc_off = gd->dest_addr - CONFIG_SYS_TEXT_BASE; + debug("Relocation Offset is: %08lx\n", gd->reloc_off); + debug("Relocating to %08lx, new gd at %p, sp at %08lx\n", + gd->dest_addr, gd->new_gd, gd->dest_addr_sp); + + relocate_code(gd->dest_addr_sp, gd->new_gd, gd->dest_addr); + + return 0; +} + +static init_fnc_t init_sequence_f[] = { + setup_global_data_ptr, + setup_fdt, + setup_mon_len, +#if defined(CONFIG_ARCH_CPU_INIT) + arch_cpu_init, /* basic arch cpu dependent setup */ +#endif +#ifdef CONFIG_OF_CONTROL + fdtdec_check_fdt, +#endif +#if defined(CONFIG_BOARD_EARLY_INIT_F) + board_early_init_f, +#endif + timer_init, /* initialize timer */ +#ifdef CONFIG_FSL_ESDHC + get_clocks, +#endif + env_init, /* initialize environment */ + init_baud_rate, /* initialze baudrate settings */ + serial_init, /* serial communications setup */ + console_init_f, /* stage 1 init of console */ + display_options, /* say that we are here */ + display_text_info, /* show debugging info if required */ +#if defined(CONFIG_DISPLAY_CPUINFO) + print_cpuinfo, /* display cpu info (and speed) */ +#endif +#if defined(CONFIG_DISPLAY_BOARDINFO) + checkboard, /* display board info */ +#endif + announce_dram_init, + dram_init, /* configure available RAM banks */ + setup_dram_config, + display_dram_config, +#ifdef CONFIG_POST + init_post, +#endif + setup_reloc, +#if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR) + reserve_logbuffer, +#endif +#ifdef CONFIG_PRAM + reserve_pram, +#endif + reserve_round_4k, +#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) + reserve_mmu, +#endif +#ifdef CONFIG_LCD + reserve_lcd, +#endif + reserve_uboot, + reserve_malloc, + reserve_board, + setup_machine, + reserve_global_data, + reserve_stacks, + setup_baud_rate, + display_new_sp, + jump_to_copy, + NULL, +}; + +void board_init_f(ulong bootflags) +{ + /* TODO: perhaps declare gd as a local variable */ + + /* TODO: save bootflag into gd->flags */ + if (initcall_run_list(init_sequence_f)) + hang(); + + /* NOTREACHED - jump_to_copy() does not return */ + while (1) + ; +} + +void hang(void) +{ + puts("### ERROR ### Please RESET the board ###\n"); + for (;;) + ; +}

On 03/14/2012 09:16 PM, Simon Glass wrote:
+/*
- sjg: IMO this code should be
- refactored to a single function, something like:
- void led_set_state(enum led_colour_t colour, int on);
- */
+/************************************************************************
- Coloured LED functionality
- May be supplied by boards if desired
- */
+inline void __coloured_LED_init(void) {} +void coloured_LED_init(void)
- __attribute__((weak, alias("__coloured_LED_init")));
+inline void __red_led_on(void) {} +void red_led_on(void) __attribute__((weak, alias("__red_led_on"))); +inline void __red_led_off(void) {} +void red_led_off(void) __attribute__((weak, alias("__red_led_off"))); +inline void __green_led_on(void) {} +void green_led_on(void) __attribute__((weak, alias("__green_led_on"))); +inline void __green_led_off(void) {} +void green_led_off(void) __attribute__((weak, alias("__green_led_off"))); +inline void __yellow_led_on(void) {} +void yellow_led_on(void) __attribute__((weak, alias("__yellow_led_on"))); +inline void __yellow_led_off(void) {} +void yellow_led_off(void) __attribute__((weak, alias("__yellow_led_off"))); +inline void __blue_led_on(void) {} +void blue_led_on(void) __attribute__((weak, alias("__blue_led_on"))); +inline void __blue_led_off(void) {} +void blue_led_off(void) __attribute__((weak, alias("__blue_led_off")));
Is this really the right file for this?
+/*
- Why is gd allocated a register? Prior to reloc it might be better to
- just pass it around to each function in this file?
You're assuming that this is the only file that needs gd.
+static int reserve_stacks(void) +{
- /* setup stack pointer for exceptions */
- gd->irq_sp = gd->dest_addr_sp;
+#ifdef CONFIG_USE_IRQ
- gd->dest_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ);
- debug("Reserving %zu Bytes for IRQ stack at: %08lx\n",
CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->dest_addr_sp);
- /* 8-byte alignment for ARM ABI compliance */
- gd->dest_addr_sp &= ~0x07;
+#endif
- /* leave 3 words for abort-stack, plus 1 for alignment */
- gd->dest_addr_sp -= 16;
- return 0;
+}
What does "leave 3 words for abort-stack, plus 1 for alignment" mean in a generic context? Certainly we shouldn't have references to things like FIQ or ARM ABI.
Do all architectures U-Boot supports have a stack that grows downward?
PowerPC requires 16-byte stack alignment, not 8-byte.
-Scott

Hi Scott,
On Thu, Mar 15, 2012 at 12:09 PM, Scott Wood scottwood@freescale.com wrote:
On 03/14/2012 09:16 PM, Simon Glass wrote:
+/*
- sjg: IMO this code should be
- refactored to a single function, something like:
- void led_set_state(enum led_colour_t colour, int on);
- */
+/************************************************************************
- Coloured LED functionality
- May be supplied by boards if desired
- */
+inline void __coloured_LED_init(void) {} +void coloured_LED_init(void)
- __attribute__((weak, alias("__coloured_LED_init")));
+inline void __red_led_on(void) {} +void red_led_on(void) __attribute__((weak, alias("__red_led_on"))); +inline void __red_led_off(void) {} +void red_led_off(void) __attribute__((weak, alias("__red_led_off"))); +inline void __green_led_on(void) {} +void green_led_on(void) __attribute__((weak, alias("__green_led_on"))); +inline void __green_led_off(void) {} +void green_led_off(void) __attribute__((weak, alias("__green_led_off"))); +inline void __yellow_led_on(void) {} +void yellow_led_on(void) __attribute__((weak, alias("__yellow_led_on"))); +inline void __yellow_led_off(void) {} +void yellow_led_off(void) __attribute__((weak, alias("__yellow_led_off"))); +inline void __blue_led_on(void) {} +void blue_led_on(void) __attribute__((weak, alias("__blue_led_on"))); +inline void __blue_led_off(void) {} +void blue_led_off(void) __attribute__((weak, alias("__blue_led_off")));
Is this really the right file for this?
Not in my opinion, but it comes from arch/arm/lib/board.c, which is why it is here. I have already mentioned my thoughts on this API on the list, and maybe this is something that could be tidied up.
+/*
- Why is gd allocated a register? Prior to reloc it might be better to
- just pass it around to each function in this file?
You're assuming that this is the only file that needs gd.
Not quite - I am wondering whether we should just pass it as an argument whichever file it is in. I think this was in fact discussed on the list and it is better to keep it the way it is. I may look at this later.
+static int reserve_stacks(void) +{
- /* setup stack pointer for exceptions */
- gd->irq_sp = gd->dest_addr_sp;
+#ifdef CONFIG_USE_IRQ
- gd->dest_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ);
- debug("Reserving %zu Bytes for IRQ stack at: %08lx\n",
- CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->dest_addr_sp);
- /* 8-byte alignment for ARM ABI compliance */
- gd->dest_addr_sp &= ~0x07;
+#endif
- /* leave 3 words for abort-stack, plus 1 for alignment */
- gd->dest_addr_sp -= 16;
- return 0;
+}
What does "leave 3 words for abort-stack, plus 1 for alignment" mean in a generic context? Certainly we shouldn't have references to things like FIQ or ARM ABI.
This is limited to code which has CONFIG_USE_IRQ in it. Maybe this function will have to be per-architecture?
Do all architectures U-Boot supports have a stack that grows downward?
So far I have included ARM, x86 and PowerPC. If we add other archs to generic board init, we will need to look at this.
PowerPC requires 16-byte stack alignment, not 8-byte.
OK I will update this.
-Scott
Thanks for reviewing this.
Regards, Simon

On 03/15/2012 04:23 PM, Simon Glass wrote:
+static int reserve_stacks(void) +{
/* setup stack pointer for exceptions */
gd->irq_sp = gd->dest_addr_sp;
+#ifdef CONFIG_USE_IRQ
gd->dest_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ);
debug("Reserving %zu Bytes for IRQ stack at: %08lx\n",
CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->dest_addr_sp);
/* 8-byte alignment for ARM ABI compliance */
gd->dest_addr_sp &= ~0x07;
+#endif
/* leave 3 words for abort-stack, plus 1 for alignment */
gd->dest_addr_sp -= 16;
return 0;
+}
What does "leave 3 words for abort-stack, plus 1 for alignment" mean in a generic context? Certainly we shouldn't have references to things like FIQ or ARM ABI.
This is limited to code which has CONFIG_USE_IRQ in it. Maybe this function will have to be per-architecture?
If CONFIG_USE_IRQ is ARM-specific, perhaps it needs a better name.
Do all architectures U-Boot supports have a stack that grows downward?
So far I have included ARM, x86 and PowerPC. If we add other archs to generic board init, we will need to look at this.
So it's not so much "generic" as supports more than one architecture.
-Scott

Dear Simon Glass,
In message CAPnjgZ1ngBc4SdJbiemQu2znprZ6iwjVRotGMcdVKhdgDSr7tQ@mail.gmail.com you wrote:
+void coloured_LED_init(void)
__attribute__((weak, alias("__coloured_LED_init")));
+inline void __red_led_on(void) {} +void red_led_on(void) __attribute__((weak, alias("__red_led_on"))); +inline void __red_led_off(void) {} +void red_led_off(void) __attribute__((weak, alias("__red_led_off"))); +inline void __green_led_on(void) {} +void green_led_on(void) __attribute__((weak, alias("__green_led_on"))); +inline void __green_led_off(void) {} +void green_led_off(void) __attribute__((weak, alias("__green_led_off"))=
);
+inline void __yellow_led_on(void) {} +void yellow_led_on(void) __attribute__((weak, alias("__yellow_led_on"))=
);
+inline void __yellow_led_off(void) {} +void yellow_led_off(void) __attribute__((weak, alias("__yellow_led_off"=
)));
+inline void __blue_led_on(void) {} +void blue_led_on(void) __attribute__((weak, alias("__blue_led_on"))); +inline void __blue_led_off(void) {} +void blue_led_off(void) __attribute__((weak, alias("__blue_led_off")));
Is this really the right file for this?
Not in my opinion, but it comes from arch/arm/lib/board.c, which is why it is here. I have already mentioned my thoughts on this API on the list, and maybe this is something that could be tidied up.
s/could/should/
This interface is realy ugly crap, and doesn't scale at all.
+/*
- Why is gd allocated a register? Prior to reloc it might be better to
- just pass it around to each function in this file?
You're assuming that this is the only file that needs gd.
Not quite - I am wondering whether we should just pass it as an argument whichever file it is in. I think this was in fact discussed on the list and it is better to keep it the way it is. I may look at this later.
Passing it as arguments will make the code size grow and the code harder to read.
What does "leave 3 words for abort-stack, plus 1 for alignment" mean in a generic context? Certainly we shouldn't have references to things like FIQ or ARM ABI.
This is limited to code which has CONFIG_USE_IRQ in it. Maybe this function will have to be per-architecture?
Yes. Eventually only ARM has this.
Best regards,
Wolfgang Denk

This file handles common post-relocation init for boards which use the generic framework.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v4: - Use asm/sections.h instead of asm-generic/sections.h
common/Makefile | 1 + common/board_r.c | 401 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 402 insertions(+), 0 deletions(-) create mode 100644 common/board_r.c
diff --git a/common/Makefile b/common/Makefile index 125c2a9..a10e5a9 100644 --- a/common/Makefile +++ b/common/Makefile @@ -38,6 +38,7 @@ COBJS-y += xyzModem.o
# boards COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_f.o +COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_r.o
# core command COBJS-y += cmd_boot.o diff --git a/common/board_r.c b/common/board_r.c new file mode 100644 index 0000000..8b9adc2 --- /dev/null +++ b/common/board_r.c @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2002-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#ifdef CONFIG_HAS_DATAFLASH +#include <dataflash.h> +#endif +#include <environment.h> +#include <initcall.h> +#include <logbuff.h> +#include <malloc.h> +#include <mmc.h> +#include <nand.h> +#include <onenand_uboot.h> +#include <serial.h> +#include <stdio_dev.h> +#include <asm/sections.h> + +DECLARE_GLOBAL_DATA_PTR; + +ulong monitor_flash_len; + + +static int initr_reloc(void) +{ + gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ + return 0; +} + +/* + * Some of these functions are needed purely because the functions they + * call return void. If we change them to return 0, these stubs can go away. + */ +static int initr_caches(void) +{ + /* Enable caches */ + enable_caches(); + return 0; +} + +static int initr_reloc_global_data(void) +{ +#ifdef CONFIG_SYS_SYM_OFFSETS + monitor_flash_len = _end_ofs; +#else + monitor_flash_len = (ulong)&__init_end - gd->dest_addr; +#endif +} + +#ifdef CONFIG_SERIAL_MULTI +static int initr_serial(void) +{ + serial_initialize(); + return 0; +} +#endif + +#ifdef CONFIG_LOGBUFFER +unsigned long logbuffer_base(void) +{ + return gd->ram_top - LOGBUFF_LEN; +} + +static int initr_logbuffer(void) +{ + logbuff_init_ptrs(); + return 0; +} +#endif + +#ifdef CONFIG_POST +static int initr_post_backlog(void) +{ + post_output_backlog(); + return 0; +} +#endif + +static int initr_malloc(void) +{ + ulong malloc_start; + + /* The malloc area is immediately below the monitor copy in DRAM */ + malloc_start = gd->dest_addr - TOTAL_MALLOC_LEN; + mem_malloc_init(malloc_start, TOTAL_MALLOC_LEN); + return 0; +} + +static int initr_announce(void) +{ + debug("Now running in RAM - U-Boot at: %08lx\n", gd->dest_addr); + return 0; +} + +#if !defined(CONFIG_SYS_NO_FLASH) +static int initr_flash(void) +{ + ulong flash_size; + + puts("Flash: "); + + flash_size = flash_init(); + if (flash_size <= 0) { + puts("*** failed ***\n"); + return -1; + } + print_size(flash_size, ""); +#ifdef CONFIG_SYS_FLASH_CHECKSUM + { + char *s; + + s = getenv("flashchecksum"); + + /* + * Compute and print flash CRC if flashchecksum is set to 'y' + * + * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX + */ + if (s && (*s == 'y')) { + printf(" CRC: %08X", crc32(0, + (const unsigned char *) CONFIG_SYS_FLASH_BASE, + flash_size)); + } + } +#endif /* CONFIG_SYS_FLASH_CHECKSUM */ + putc('\n'); + return 0; +} +#endif + +#ifdef CONFIG_CMD_NAND +/* go init the NAND */ +int initr_nand(void) +{ + puts("NAND: "); + nand_init(); + return 0; +} +#endif + +#if defined(CONFIG_CMD_ONENAND) +/* go init the NAND */ +int initr_onenand(void) +{ + puts("NAND: "); + onenand_init(); + return 0; +} +#endif + +#ifdef CONFIG_GENERIC_MMC +int initr_mmc(void) +{ + puts("MMC: "); + mmc_initialize(gd->bd); + return 0; +} +#endif + +#ifdef CONFIG_HAS_DATAFLASH +/* Ick - why are these not in a header file? */ +extern int AT91F_DataflashInit(void); +extern void dataflash_print_info(void); + +int initr_dataflash(void) +{ + AT91F_DataflashInit(); + dataflash_print_info(); + return 0; +} +#endif + +static int initr_env(void) +{ + /* initialize environment */ + env_relocate(); + + /* IP Address */ + gd->bd->bi_ip_addr = getenv_IPaddr("ipaddr"); + + /* Initialize from environment */ + load_addr = getenv_ulong("loadaddr", 16, load_addr); +#if defined(CONFIG_CMD_NET) + { + char *s = getenv("bootfile"); + + if (s != NULL) + copy_filename(BootFile, s, sizeof(BootFile)); + } +#endif + return 0; +} + +static int initr_jumptable(void) +{ + jumptable_init(); + return 0; +} + +#if defined(CONFIG_API) +static int initr_api(void) +{ + /* Initialize API */ + api_init(); + return 0; +} +#endif + +/* enable exceptions */ +static int initr_enable_interrupts(void) +{ + enable_interrupts(); + return 0; +} + +#ifdef CONFIG_CMD_NET +static int initr_ethaddr(void) +{ +#if defined(CONFIG_DRIVER_SMC91111) || defined(CONFIG_DRIVER_LAN91C96) + /* Perform network card initialisation if necessary */ + /* XXX: this needs to be moved to board init */ + /* YYY: with initcalls the drivers can do this directly */ + /* ZZZ: and anyway why not do it when we call eth_init()? */ + if (getenv("ethaddr")) { + uchar enetaddr[6]; + eth_getenv_enetaddr("ethaddr", enetaddr); + smc_set_mac_addr(enetaddr); + } +#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */ + + return 0; +} +#endif /* CONFIG_CMD_NET */ + +#ifdef CONFIG_BITBANGMII +static int initr_bbmii(void) +{ + bb_miiphy_init(); + return 0; +} +#endif + +#ifdef CONFIG_CMD_NET +static int initr_net(void) +{ + puts("Net: "); + eth_initialize(gd->bd); +#if defined(CONFIG_RESET_PHY_R) + debug("Reset Ethernet PHY\n"); + reset_phy(); +#endif + return 0; +} +#endif + +#ifdef CONFIG_POST +static int initr_post(void) +{ + post_run(NULL, POST_RAM | post_bootmode_get(0)); + return 0; +} +#endif + +#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER) +/* + * Export available size of memory for Linux, taking into account the + * protected RAM at top of memory + */ +int initr_mem(void) +{ + ulong pram = 0; + char memsz[32]; + +# ifdef CONFIG_PRAM + pram = getenv_ulong("pram", 10, CONFIG_PRAM); +# endif +# if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR) + /* Also take the logbuffer into account (pram is in kB) */ + pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024; +# endif + sprintf(memsz, "%ldk", (gd->ram_size / 1024) - pram); + setenv("mem", memsz); +} +#endif + +static int run_main_loop(void) +{ + /* main_loop() can return to retry autoboot, if so just run it again */ + for (;;) + main_loop(); + return 0; +} + +/* + * Over time we hope to remove these functions with code fragments and + * stub funtcions, and instead call the relevant function directly. + * + * We also hope to remove most of the driver-related init and do it if/when + * the driver is later used. + */ +init_fnc_t init_sequence_r[] = { + initr_reloc, +#ifdef CONFIG_ARM + initr_caches, + board_init, /* Setup chipselects */ +#endif + initr_reloc_global_data, +#ifdef CONFIG_SERIAL_MULTI + initr_serial, +#endif + initr_announce, +#ifdef CONFIG_LOGBUFFER + initr_logbuffer, +#endif +#ifdef CONFIG_POST + initr_post_backlog, +#endif + initr_malloc, +#ifndef CONFIG_SYS_NO_FLASH + initr_flash, +#endif +#ifdef CONFIG_CMD_NAND + initr_nand, +#endif +#ifdef CONFIG_CMD_ONENAND + initr_onenand, +#endif +#ifdef CONFIG_GENERIC_MMC + initr_mmc, +#endif +#ifdef CONFIG_HAS_DATAFLASH + initr_dataflash, +#endif + initr_env, + stdio_init, + initr_jumptable, +#ifdef CONFIG_API + initr_api, +#endif + console_init_r, /* fully init console as a device */ +#ifdef CONFIG_ARCH_MISC_INIT + arch_misc_init, /* miscellaneous arch-dependent init */ +#endif +#ifdef CONFIG_MISC_INIT_R + misc_init_r, /* miscellaneous platform-dependent init */ +#endif + interrupt_init, + initr_enable_interrupts, +#ifdef CONFIG_CMD_NET + initr_ethaddr, +#endif +#ifdef CONFIG_BOARD_LATE_INIT + board_late_init, +#endif +#ifdef CONFIG_BITBANGMII + initr_bbmii, +#endif +#ifdef CONFIG_CMD_NET + initr_net, +#endif +#ifdef CONFIG_POST + initr_post, +#endif + run_main_loop, +}; + +void board_init_r(gd_t *new_gd, ulong dest_addr) +{ + gd = new_gd; + if (initcall_run_list(init_sequence_r)) + hang(); + + /* NOTREACHED - run_main_loop() does not return */ + while (1) + ; +}

This adds secondary program loader support to the generic board.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/board_f.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/common/board_f.c b/common/board_f.c index 9477721..a08f0a1 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -305,6 +305,7 @@ static int reserve_uboot(void) return 0; }
+#ifndef CONFIG_SPL_BUILD /* reserve memory for malloc() area */ static int reserve_malloc(void) { @@ -324,6 +325,7 @@ static int reserve_board(void) sizeof(bd_t), gd->dest_addr_sp); return 0; } +#endif
static int setup_machine(void) { @@ -342,6 +344,7 @@ static int reserve_global_data(void) return 0; }
+#ifndef CONFIG_SPL_BUILD static int reserve_stacks(void) { /* setup stack pointer for exceptions */ @@ -359,6 +362,17 @@ static int reserve_stacks(void)
return 0; } +#endif + +#ifdef CONFIG_SPL_BUILD +static int reserve_stacks_spl(void) +{ + /* Why not -= ? */ + gd->dest_addr_sp += 128; /* leave 32 words for abort-stack */ + gd->irq_sp = gd->dest_addr_sp; + return 0; +} +#endif
static int display_new_sp(void) { @@ -458,11 +472,17 @@ static init_fnc_t init_sequence_f[] = { reserve_lcd, #endif reserve_uboot, +#ifndef CONFIG_SPL_BUILD reserve_malloc, reserve_board, +#endif setup_machine, reserve_global_data, +#ifdef CONFIG_SPL_BUILD + reserve_stacks_spl, +#else reserve_stacks, +#endif setup_baud_rate, display_new_sp, jump_to_copy,

On 03/14/2012 09:16 PM, Simon Glass wrote:
+#ifdef CONFIG_SPL_BUILD +static int reserve_stacks_spl(void) +{
- /* Why not -= ? */
- gd->dest_addr_sp += 128; /* leave 32 words for abort-stack */
- gd->irq_sp = gd->dest_addr_sp;
- return 0;
+} +#endif
Please explain what's going on here, and why it's suitable for all (or at least most) SPLs.
And answer your own question about "Why not -=". :-)
-Scott

This enables generic board support so that ARM boards can define CONFIG_SYS_GENERIC_BOARD.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/config.mk | 3 --- arch/arm/include/asm/global_data.h | 7 +++++++ arch/arm/include/asm/u-boot.h | 9 +++++++++ arch/arm/lib/Makefile | 4 +++- 4 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/arch/arm/config.mk b/arch/arm/config.mk index 31e9ef9..45f9dca 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -33,9 +33,6 @@ endif
PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__
-# Move to unified board system later -CONFIG_SYS_LEGACY_BOARD := y - # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: PF_CPPFLAGS_ARM := $(call cc-option,-marm,)
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index c3ff789..aced4fe 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -23,6 +23,11 @@
#ifndef __ASM_GBL_DATA_H #define __ASM_GBL_DATA_H + +#ifdef CONFIG_SYS_GENERIC_BOARD +/* Use the generic board which requires a unified global_data */ +#include <asm-generic/global_data.h> +#else /* * The following data structure is placed in some memory which is * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or @@ -98,6 +103,8 @@ typedef struct global_data { #define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */ #define GD_FLG_ENV_READY 0x00080 /* Environment imported into hash table */
+#endif /* nCONFIG_SYS_GENERIC_BOARD */ + #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
#endif /* __ASM_GBL_DATA_H */ diff --git a/arch/arm/include/asm/u-boot.h b/arch/arm/include/asm/u-boot.h index a0691b7..fe336b3 100644 --- a/arch/arm/include/asm/u-boot.h +++ b/arch/arm/include/asm/u-boot.h @@ -36,6 +36,12 @@ #ifndef _U_BOOT_H_ #define _U_BOOT_H_ 1
+#ifdef CONFIG_SYS_GENERIC_BOARD +/* Use the generic board which requires a unified bd_info */ +#include <asm-generic/u-boot.h> +#else + +#ifndef __ASSEMBLY__ typedef struct bd_info { unsigned long bi_baudrate; /* serial console baudrate */ unsigned long bi_ip_addr; /* IP Address */ @@ -50,6 +56,9 @@ typedef struct bd_info { ulong size; } bi_dram[CONFIG_NR_DRAM_BANKS]; } bd_t; +#endif + +#endif /* nCONFIG_SYS_GENERIC_BOARD */
/* For image.h:image_check_target_arch() */ #define IH_ARCH_DEFAULT IH_ARCH_ARM diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 300c8fa..11cfc00 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -37,7 +37,9 @@ GLSOBJS += _umodsi3.o
GLCOBJS += div0.o
-COBJS-y += board.o +ifeq ($(CONFIG_SYS_GENERIC_BOARD),) +COBJS-y += board.o +endif COBJS-y += bootm.o COBJS-y += cache.o COBJS-y += cache-cp15.o

Link symbols as created by the link script can either be absolute or relative to the text start. This option switches between the two options so that we can support both.
As we convert architectures over to generic board, we can see if this option is actually needed, or whether it is possible to unify this feature also.
Signed-off-by: Simon Glass sjg@chromium.org ---
README | 6 ++++++ common/board_f.c | 11 +++++++++++ 2 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/README b/README index f471627..251afaf 100644 --- a/README +++ b/README @@ -2780,6 +2780,12 @@ Configuration Settings: its config.mk file). If you find problems enabling this option on your board please report the problem and send patches!
+- CONFIG_SYS_SYM_OFFSETS + This is set by architectures that use offsets for link symbols + instead of absolute values. So bss_start is obtained using an + offset _bss_start_ofs from CONFIG_SYS_TEXT_BASE, rather than + directly. You should not need to touch this setting. +
The following definitions that deal with the placement and management of environment data (variable area); in general, we support the diff --git a/common/board_f.c b/common/board_f.c index a08f0a1..2f14118 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -108,8 +108,13 @@ static int display_text_info(void) { ulong bss_start, bss_end;
+#ifdef CONFIG_SYS_SYM_OFFSETS bss_start = _bss_start_ofs + _TEXT_BASE; bss_end = _bss_end_ofs + _TEXT_BASE; +#else + bss_start = (ulong)&__bss_start; + bss_end = (ulong)&__bss_end; +#endif debug("U-Boot code: %08X -> %08lX BSS: -> %08lX\n", CONFIG_SYS_TEXT_BASE, bss_start, bss_end);
@@ -186,7 +191,11 @@ static int zero_global_data(void)
static int setup_mon_len(void) { +#ifdef CONFIG_SYS_SYM_OFFSETS gd->mon_len = _bss_end_ofs; +#else + gd->mon_len = (ulong)&__bss_end - (ulong)&__text_start; +#endif return 0; }
@@ -423,6 +432,7 @@ static int jump_to_copy(void)
static init_fnc_t init_sequence_f[] = { setup_global_data_ptr, + zero_global_data, setup_fdt, setup_mon_len, #if defined(CONFIG_ARCH_CPU_INIT) @@ -457,6 +467,7 @@ static init_fnc_t init_sequence_f[] = { #ifdef CONFIG_POST init_post, #endif + setup_dram_config, setup_reloc, #if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR) reserve_logbuffer,

These are defined in asm-generic/sections.h, so remove them from architecture-specific files.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v3: - Add header to new x86 relocate.c and init_helpers.c
Changes in v4: - Use asm/sections.h instead of asm-generic/sections.h
arch/x86/include/asm/u-boot-x86.h | 8 -------- arch/x86/lib/board.c | 1 + arch/x86/lib/init_helpers.c | 1 + arch/x86/lib/relocate.c | 1 + 4 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 878a1ee..069cbbc 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -24,14 +24,6 @@ #ifndef _U_BOOT_I386_H_ #define _U_BOOT_I386_H_ 1
-/* Exports from the Linker Script */ -extern ulong __text_start; -extern ulong __data_end; -extern ulong __rel_dyn_start; -extern ulong __rel_dyn_end; -extern ulong __bss_start; -extern ulong __bss_end; - /* cpu/.../cpu.c */ int x86_cpu_init_r(void); int cpu_init_r(void); diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c index 5f0b62c..5931153 100644 --- a/arch/x86/lib/board.c +++ b/arch/x86/lib/board.c @@ -36,6 +36,7 @@ #include <stdio_dev.h> #include <asm/u-boot-x86.h> #include <asm/relocate.h> +#include <asm/sections.h>
#include <asm/init_helpers.h> #include <asm/init_wrappers.h> diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index 9f4dee0..633b72b 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -31,6 +31,7 @@ #include <status_led.h> #include <asm/processor.h> #include <asm/u-boot-x86.h> +#include <asm/sections.h>
#include <asm/init_helpers.h>
diff --git a/arch/x86/lib/relocate.c b/arch/x86/lib/relocate.c index 200baab..cd26636 100644 --- a/arch/x86/lib/relocate.c +++ b/arch/x86/lib/relocate.c @@ -35,6 +35,7 @@ #include <malloc.h> #include <asm/u-boot-x86.h> #include <asm/relocate.h> +#include <asm/sections.h> #include <elf.h>
int copy_uboot_to_ram(void)

These fields are needed for x86.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/asm-generic/global_data.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 6199926..fb976f9 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -44,6 +44,8 @@ typedef struct global_data { bd_t *bd; unsigned long flags; unsigned long baudrate; + unsigned long cpu_clk; /* CPU clock in Hz! */ + unsigned long bus_clk; #if defined(CONFIG_LCD) || defined(CONFIG_VIDEO) unsigned long fb_base; /* Base address of framebuffer mem */ #endif

Hi Simon,
On Thu, Mar 15, 2012 at 1:16 PM, Simon Glass sjg@chromium.org wrote:
These fields are needed for x86.
Signed-off-by: Simon Glass sjg@chromium.org
include/asm-generic/global_data.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 6199926..fb976f9 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -44,6 +44,8 @@ typedef struct global_data { bd_t *bd; unsigned long flags; unsigned long baudrate;
- unsigned long cpu_clk; /* CPU clock in Hz! */
- unsigned long bus_clk;
Refer to my other comment, but this impacts all arches for no good reason
Regards,
Graeme

Hi Graeme,
On Wed, Mar 14, 2012 at 7:36 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Simon,
On Thu, Mar 15, 2012 at 1:16 PM, Simon Glass sjg@chromium.org wrote:
These fields are needed for x86.
Signed-off-by: Simon Glass sjg@chromium.org
include/asm-generic/global_data.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 6199926..fb976f9 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -44,6 +44,8 @@ typedef struct global_data { bd_t *bd; unsigned long flags; unsigned long baudrate;
- unsigned long cpu_clk; /* CPU clock in Hz! */
- unsigned long bus_clk;
Refer to my other comment, but this impacts all arches for no good reason
See my other reply. Let me just add that these values would be pretty useful to most archs.
Regards, Simon
Regards,
Graeme

This enables generic board support so that x86 boards can define CONFIG_SYS_GENERIC_BOARD.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/config.mk | 3 --- arch/x86/include/asm/global_data.h | 7 +++++++ arch/x86/include/asm/u-boot.h | 11 +++++++++++ arch/x86/lib/Makefile | 4 +++- common/board_r.c | 5 +++++ 5 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/arch/x86/config.mk b/arch/x86/config.mk index 7be3036..23cacff 100644 --- a/arch/x86/config.mk +++ b/arch/x86/config.mk @@ -48,6 +48,3 @@ NORMAL_LIBGCC = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) PREFIXED_LIBGCC = $(OBJTREE)/arch/$(ARCH)/lib/$(shell basename $(NORMAL_LIBGCC))
export USE_PRIVATE_LIBGCC=$(shell dirname $(PREFIXED_LIBGCC)) - -# Move to unified board system later -CONFIG_SYS_LEGACY_BOARD := y diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index 908a02c..fe50856 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -23,6 +23,11 @@
#ifndef __ASM_GBL_DATA_H #define __ASM_GBL_DATA_H + +#ifdef CONFIG_SYS_GENERIC_BOARD +/* Use the generic board which requires a unified global_data */ +#include <asm-generic/global_data.h> +#else /* * The following data structure is placed in some memory wich is * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or @@ -86,6 +91,8 @@ static inline gd_t *get_fs_gd_ptr(void) #define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */ #define GD_FLG_ENV_READY 0x00080 /* Environment imported into hash table */
+#endif /* nCONFIG_SYS_GENERIC_BOARD */ + #define DECLARE_GLOBAL_DATA_PTR
#endif /* __ASM_GBL_DATA_H */ diff --git a/arch/x86/include/asm/u-boot.h b/arch/x86/include/asm/u-boot.h index dd42209..ef8b7d5 100644 --- a/arch/x86/include/asm/u-boot.h +++ b/arch/x86/include/asm/u-boot.h @@ -36,6 +36,13 @@ #ifndef _U_BOOT_H_ #define _U_BOOT_H_ 1
+#ifdef CONFIG_SYS_GENERIC_BOARD +/* Use the generic board which requires a unified bd_info */ +#include <asm-generic/u-boot.h> +#else + +#ifndef __ASSEMBLY__ + typedef struct bd_info { unsigned long bi_memstart; /* start of DRAM memory */ phys_size_t bi_memsize; /* size of DRAM memory in bytes */ @@ -58,6 +65,10 @@ typedef struct bd_info { }bi_dram[CONFIG_NR_DRAM_BANKS]; } bd_t;
+#endif /* __ASSEMBLY__ */ + +#endif /* nCONFIG_SYS_GENERIC_BOARD */ + /* For image.h:image_check_target_arch() */ #define IH_ARCH_DEFAULT IH_ARCH_I386
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 51836da..a2083f4 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -30,7 +30,9 @@ SOBJS-$(CONFIG_SYS_PCI_BIOS) += bios_pci.o SOBJS-$(CONFIG_SYS_X86_REALMODE) += realmode_switch.o
COBJS-$(CONFIG_SYS_PC_BIOS) += bios_setup.o -COBJS-y += board.o +ifeq ($(CONFIG_SYS_GENERIC_BOARD),) +COBJS-y += board.o +endif COBJS-y += bootm.o COBJS-y += cmd_boot.o COBJS-y += gcc.o diff --git a/common/board_r.c b/common/board_r.c index 8b9adc2..f587c03 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -56,12 +56,15 @@ static int initr_reloc(void) * Some of these functions are needed purely because the functions they * call return void. If we change them to return 0, these stubs can go away. */ +#ifdef CONFIG_ARM static int initr_caches(void) { + /* TODO: sort out x86 code here */ /* Enable caches */ enable_caches(); return 0; } +#endif
static int initr_reloc_global_data(void) { @@ -232,11 +235,13 @@ static int initr_api(void) #endif
/* enable exceptions */ +#ifdef CONFIG_ARM static int initr_enable_interrupts(void) { enable_interrupts(); return 0; } +#endif
#ifdef CONFIG_CMD_NET static int initr_ethaddr(void)

This adds fields required by PowerPC to the global data.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/asm-generic/global_data.h | 124 +++++++++++++++++++++++++++++++++++++ 1 files changed, 124 insertions(+), 0 deletions(-)
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index fb976f9..fb2891e 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -46,6 +46,114 @@ typedef struct global_data { unsigned long baudrate; unsigned long cpu_clk; /* CPU clock in Hz! */ unsigned long bus_clk; +#if defined(CONFIG_8xx) + unsigned long brg_clk; +#endif +#if defined(CONFIG_CPM2) + /* There are many clocks on the MPC8260 - see page 9-5 */ + unsigned long vco_out; + unsigned long cpm_clk; + unsigned long scc_clk; + unsigned long brg_clk; +#ifdef CONFIG_PCI + unsigned long pci_clk; +#endif +#endif + unsigned long mem_clk; +#if defined(CONFIG_MPC83xx) + /* There are other clocks in the MPC83XX */ + u32 csb_clk; +#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ + defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x) + u32 tsec1_clk; + u32 tsec2_clk; + u32 usbdr_clk; +#endif +#if defined(CONFIG_MPC834x) + u32 usbmph_clk; +#endif /* CONFIG_MPC834x */ +#if defined(CONFIG_MPC8315) + u32 tdm_clk; +#endif + u32 core_clk; + u32 enc_clk; + u32 lbiu_clk; + u32 lclk_clk; + u32 pci_clk; +#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \ + defined(CONFIG_MPC837x) + u32 pciexp1_clk; + u32 pciexp2_clk; +#endif +#if defined(CONFIG_MPC837x) || defined(CONFIG_MPC8315) + u32 sata_clk; +#endif +#if defined(CONFIG_MPC8360) + u32 mem_sec_clk; +#endif /* CONFIG_MPC8360 */ +#endif +#if defined(CONFIG_FSL_ESDHC) + u32 sdhc_clk; +#endif +#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) + u32 lbc_clk; + void *cpu; +#endif /* CONFIG_MPC85xx || CONFIG_MPC86xx */ +#if defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) \ + || defined(CONFIG_MPC86xx) + u32 i2c1_clk; + u32 i2c2_clk; +#endif +#if defined(CONFIG_QE) + u32 qe_clk; + u32 brg_clk; + uint mp_alloc_base; + uint mp_alloc_top; +#endif /* CONFIG_QE */ +#if defined(CONFIG_FSL_LAW) + u32 used_laws; +#endif +#if defined(CONFIG_E500) + u32 used_tlb_cams[(CONFIG_SYS_NUM_TLBCAMS+31)/32]; +#endif +#if defined(CONFIG_MPC5xxx) + unsigned long ipb_clk; + unsigned long pci_clk; +#endif +#if defined(CONFIG_MPC512X) + u32 ips_clk; + u32 csb_clk; + u32 pci_clk; +#endif /* CONFIG_MPC512X */ +#if defined(CONFIG_MPC8220) + unsigned long bExtUart; + unsigned long inp_clk; + unsigned long pci_clk; + unsigned long vco_clk; + unsigned long pev_clk; + unsigned long flb_clk; +#endif + unsigned long reset_status; /* reset status register at boot */ +#if defined(CONFIG_MPC83xx) + unsigned long arbiter_event_attributes; + unsigned long arbiter_event_address; +#endif +#if defined(CONFIG_SYS_ALLOC_DPRAM) || defined(CONFIG_CPM2) + unsigned int dp_alloc_base; + unsigned int dp_alloc_top; +#endif +#if defined(CONFIG_4xx) + u32 uart_clk; +#endif /* CONFIG_4xx */ +#if defined(CONFIG_SYS_GT_6426x) + unsigned int mirror_hack[16]; +#endif +#if defined(CONFIG_A3000) || \ + defined(CONFIG_HIDDEN_DRAGON) || \ + defined(CONFIG_MUSENKI) || \ + defined(CONFIG_SANDPOINT) + void *console_addr; +#endif #if defined(CONFIG_LCD) || defined(CONFIG_VIDEO) unsigned long fb_base; /* Base address of framebuffer mem */ #endif @@ -54,6 +162,22 @@ typedef struct global_data { unsigned long post_log_res; /* success of POST test */ unsigned long post_init_f_time; /* When post_init_f started */ #endif +#ifdef CONFIG_BOARD_TYPES + unsigned long board_type; +#endif +#ifdef CONFIG_MODEM_SUPPORT + unsigned long do_mdm_init; + unsigned long be_quiet; +#endif +#if defined(CONFIG_LWMON) || defined(CONFIG_LWMON5) + unsigned long kbd_status; +#endif +#ifdef CONFIG_SYS_FPGA_COUNT + unsigned fpga_state[CONFIG_SYS_FPGA_COUNT]; +#endif +#if defined(CONFIG_WD_MAX_RATE) + unsigned long long wdt_last; /* trace watch-dog triggering rate */ +#endif unsigned long have_console; /* serial_init() was called */ #ifdef CONFIG_PRE_CONSOLE_BUFFER unsigned long precon_buf_idx; /* Pre-Console buffer index */

This adds ppc features to the generic pre-relocation board init.
This is a separate commit so that these features are clearly shown.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v4: - Updates to sit on top of earlier patches
common/board_f.c | 373 +++++++++++++++++++++++++++++++++++++++++++++++++++++- include/common.h | 16 +++ 2 files changed, 386 insertions(+), 3 deletions(-)
diff --git a/common/board_f.c b/common/board_f.c index 2f14118..bcbc809 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -30,10 +30,31 @@ #include <linux/compiler.h> #include <version.h> #include <environment.h> +#if defined(CONFIG_CMD_IDE) +#include <ide.h> +#endif +#include <i2c.h> #include <initcall.h> #include <logbuff.h> + +/* TODO: Can we move these into arch/ headers? */ +#ifdef CONFIG_8xx +#include <mpc8xx.h> +#endif +#ifdef CONFIG_5xx +#include <mpc5xx.h> +#endif +#ifdef CONFIG_MPC5xxx +#include <mpc5xxx.h> +#endif + #include <post.h> +#include <spi.h> +#include <watchdog.h> #include <asm/io.h> +#ifdef CONFIG_MP +#include <asm/mp.h> +#endif #include <asm/sections.h>
/* @@ -98,6 +119,34 @@ void blue_led_off(void) __attribute__((weak, alias("__blue_led_off"))); * Could the CONFIG_SPL_BUILD infection become a flag in gd? */
+#if defined(CONFIG_WATCHDOG) +static int init_func_watchdog_init(void) +{ + puts(" Watchdog enabled\n"); + WATCHDOG_RESET(); + return 0; +} + +#define INIT_FUNC_WATCHDOG_INIT init_func_watchdog_init, + +int init_func_watchdog_reset(void) +{ + WATCHDOG_RESET(); + return 0; +} + +#else +#define INIT_FUNC_WATCHDOG_INIT +#endif /* CONFIG_WATCHDOG */ + +void __board_add_ram_info(int use_default) +{ + /* please define platform specific board_add_ram_info() */ +} + +void board_add_ram_info(int) + __attribute__ ((weak, alias("__board_add_ram_info"))); + static int init_baud_rate(void) { gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE); @@ -135,6 +184,25 @@ static int announce_dram_init(void) return 0; }
+#ifdef CONFIG_PPC +static int init_func_ram(void) +{ +#ifdef CONFIG_BOARD_TYPES + int board_type = gd->board_type; +#else + int board_type = 0; /* use dummy arg */ +#endif + + gd->ram_size = initdram(board_type); + + if (gd->ram_size > 0) + return 0; + + puts("*** failed ***\n"); + return 1; +} +#endif + static int display_dram_config(void) { ulong size; @@ -155,11 +223,24 @@ static int display_dram_config(void) size = gd->ram_size; #endif
- print_size(size, "\n"); + print_size(size, ""); + board_add_ram_info(0); + putc('\n');
return 0; }
+ulong get_effective_memsize(void) +{ +#ifndef CONFIG_VERY_BIG_RAM + return gd->ram_size; +#else + /* limit stack to what we can reasonable map */ + return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ? + CONFIG_MAX_MEM_MAPPED : gd->ram_size); +#endif +} + void __dram_init_banksize(void) { #if defined(CONFIG_NR_DRAM_BANKS) && defined(CONFIG_SYS_SDRAM_BASE) @@ -171,10 +252,37 @@ void __dram_init_banksize(void) void dram_init_banksize(void) __attribute__((weak, alias("__dram_init_banksize")));
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) +static int init_func_i2c(void) +{ + puts("I2C: "); + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + puts("ready\n"); + return 0; +} +#endif + +#if defined(CONFIG_HARD_SPI) +static int init_func_spi(void) +{ + puts("SPI: "); + spi_init(); + puts("ready\n"); + return 0; +} +#endif + static int setup_global_data_ptr(void) { - /* Pointer is writable since we allocated a register for it */ + /* + * Pointer is writable since we allocated a register for it. + * Can we choose one of these two methods instead of offering both? + */ +#ifdef CONFIG_SYS_INIT_SP_ADDR gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07); +#else + gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); +#endif
/* compiler optimization barrier needed for GCC >= 3.4 */ dmb(); @@ -182,6 +290,7 @@ static int setup_global_data_ptr(void) return 0; }
+__maybe_unused static int zero_global_data(void) { memset((void *)gd, '\0', sizeof(gd_t)); @@ -194,7 +303,8 @@ static int setup_mon_len(void) #ifdef CONFIG_SYS_SYM_OFFSETS gd->mon_len = _bss_end_ofs; #else - gd->mon_len = (ulong)&__bss_end - (ulong)&__text_start; + /* TODO: use (ulong)&__bss_end - (ulong)&__text_start; ? */ + gd->mon_len = (ulong)&__bss_end__ - CONFIG_SYS_MONITOR_BASE; #endif return 0; } @@ -234,7 +344,22 @@ static int setup_reloc(void) */ gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE; #endif +#ifdef CONFIG_NR_DRAM_BANKS gd->dest_addr = gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; +#else + gd->dest_addr = CONFIG_SYS_SDRAM_BASE + get_effective_memsize(); +#endif + gd->ram_top = gd->dest_addr; +#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) + /* + * We need to make sure the location we intend to put secondary core + * boot code is reserved and not used by any part of u-boot + */ + if (gd->dest_addr > determine_mp_bootpg()) { + gd->dest_addr = determine_mp_bootpg(); + debug("Reserving MP boot page to %08lx\n", gd->dest_addr); + } +#endif gd->dest_addr_sp = gd->dest_addr; return 0; } @@ -300,6 +425,19 @@ static int reserve_lcd(void) } #endif /* CONFIG_LCD */
+/* TODO: We should be able to just use CONFIG_VIDEO here */ +#if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) \ + && !defined(CONFIG_ARM) +static int reserve_video(void) +{ + /* reserve memory for video display (always full pages) */ + gd->dest_addr = video_setmem(gd->dest_addr); + gd->fb_base = gd->dest_addr; + + return 0; +} +#endif + static int reserve_uboot(void) { /* @@ -308,6 +446,10 @@ static int reserve_uboot(void) */ gd->dest_addr -= gd->mon_len; gd->dest_addr &= ~(4096 - 1); +#ifdef CONFIG_E500 + /* round down to next 64 kB limit so that IVPR stays aligned */ + gd->dest_addr &= ~(65536 - 1); +#endif
debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, gd->dest_addr); @@ -356,7 +498,13 @@ static int reserve_global_data(void) #ifndef CONFIG_SPL_BUILD static int reserve_stacks(void) { +#ifdef CONFIG_PPC + ulong *s; +#endif + /* setup stack pointer for exceptions */ + gd->dest_addr_sp -= 16; + gd->dest_addr_sp &= ~0xf; gd->irq_sp = gd->dest_addr_sp; #ifdef CONFIG_USE_IRQ gd->dest_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ); @@ -369,6 +517,14 @@ static int reserve_stacks(void) /* leave 3 words for abort-stack, plus 1 for alignment */ gd->dest_addr_sp -= 16;
+#ifdef CONFIG_PPC + /* Clear initial stack frame */ + s = (ulong *) gd->dest_addr_sp; + *s-- = 0; + *s-- = 0; + gd->dest_addr_sp = (ulong) s; +#endif + return 0; } #endif @@ -390,6 +546,106 @@ static int display_new_sp(void) return 0; }
+#ifdef CONFIG_PPC +static int setup_board_part1(void) +{ + bd_t *bd = gd->bd; + + /* + * Save local variables to board info struct + */ + + bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; /* start of memory */ + bd->bi_memsize = gd->ram_size; /* size in bytes */ + +#ifdef CONFIG_SYS_SRAM_BASE + bd->bi_sramstart = CONFIG_SYS_SRAM_BASE; /* start of SRAM */ + bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; /* size of SRAM */ +#endif + +#if defined(CONFIG_8xx) || defined(CONFIG_8260) || defined(CONFIG_5xx) || \ + defined(CONFIG_E500) || defined(CONFIG_MPC86xx) + bd->bi_immr_base = CONFIG_SYS_IMMR; /* base of IMMR register */ +#endif +#if defined(CONFIG_MPC5xxx) + bd->bi_mbar_base = CONFIG_SYS_MBAR; /* base of internal registers */ +#endif +#if defined(CONFIG_MPC83xx) + bd->bi_immrbar = CONFIG_SYS_IMMR; +#endif +#if defined(CONFIG_MPC8220) + bd->bi_mbar_base = CONFIG_SYS_MBAR; /* base of internal registers */ + bd->bi_inpfreq = gd->inp_clk; + bd->bi_pcifreq = gd->pci_clk; + bd->bi_vcofreq = gd->vco_clk; + bd->bi_pevfreq = gd->pev_clk; + bd->bi_flbfreq = gd->flb_clk; + + /* store bootparam to sram (backward compatible), here? */ + { + u32 *sram = (u32 *) CONFIG_SYS_SRAM_BASE; + + *sram++ = gd->ram_size; + *sram++ = gd->bus_clk; + *sram++ = gd->inp_clk; + *sram++ = gd->cpu_clk; + *sram++ = gd->vco_clk; + *sram++ = gd->flb_clk; + *sram++ = 0xb8c3ba11; /* boot signature */ + } +#endif + + return 0; +} + +static int setup_board_part2(void) +{ + bd_t *bd = gd->bd; + + bd->bi_intfreq = gd->cpu_clk; /* Internal Freq, in Hz */ + bd->bi_busfreq = gd->bus_clk; /* Bus Freq, in Hz */ +#if defined(CONFIG_CPM2) + bd->bi_cpmfreq = gd->cpm_clk; + bd->bi_brgfreq = gd->brg_clk; + bd->bi_sccfreq = gd->scc_clk; + bd->bi_vco = gd->vco_out; +#endif /* CONFIG_CPM2 */ +#if defined(CONFIG_MPC512X) + bd->bi_ipsfreq = gd->ips_clk; +#endif /* CONFIG_MPC512X */ +#if defined(CONFIG_MPC5xxx) + bd->bi_ipbfreq = gd->ipb_clk; + bd->bi_pcifreq = gd->pci_clk; +#endif /* CONFIG_MPC5xxx */ + + return 0; +} +#endif + +#ifdef CONFIG_SYS_EXTBDINFO +static int setup_board_extra(void) +{ + bd_t *bd = gd->bd; + + strncpy((char *) bd->bi_s_version, "1.2", sizeof(bd->bi_s_version)); + strncpy((char *) bd->bi_r_version, U_BOOT_VERSION, + sizeof(bd->bi_r_version)); + + bd->bi_procfreq = gd->cpu_clk; /* Processor Speed, In Hz */ + bd->bi_plb_busfreq = gd->bus_clk; +#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || \ + defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ + defined(CONFIG_440EPX) || defined(CONFIG_440GRX) + bd->bi_pci_busfreq = get_PCI_freq(); + bd->bi_opbfreq = get_OPB_freq(); +#elif defined(CONFIG_XILINX_405) + bd->bi_pci_busfreq = get_PCI_freq(); +#endif + + return 0; +} +#endif + #ifdef CONFIG_POST static int init_post(void) { @@ -432,9 +688,17 @@ static int jump_to_copy(void)
static init_fnc_t init_sequence_f[] = { setup_global_data_ptr, +#if !defined(CONFIG_CPM2) && !defined(CONFIG_MPC512X) && \ + !defined(CONFIG_MPC83xx) && !defined(CONFIG_MPC85xx) && \ + !defined(CONFIG_MPC86xx) zero_global_data, +#endif setup_fdt, setup_mon_len, +#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) + /* TODO: can this go into arch_cpu_init()? */ + probecpu, +#endif #if defined(CONFIG_ARCH_CPU_INIT) arch_cpu_init, /* basic arch cpu dependent setup */ #endif @@ -444,30 +708,119 @@ static init_fnc_t init_sequence_f[] = { #if defined(CONFIG_BOARD_EARLY_INIT_F) board_early_init_f, #endif + /* TODO: can any of this go into arch_cpu_init()? */ +#if defined(CONFIG_PPC) && !defined(CONFIG_8xx_CPUCLK_DEFAULT) + get_clocks, /* get CPU and bus clocks (etc.) */ +#if defined(CONFIG_TQM8xxL) && !defined(CONFIG_TQM866M) \ + && !defined(CONFIG_TQM885D) + adjust_sdram_tbs_8xx, +#endif + /* TODO: can we rename this to timer_init()? */ + init_timebase, +#endif +#if defined(CONFIG_BOARD_EARLY_INIT_F) + board_early_init_f, +#endif +#ifdef CONFIG_ARM timer_init, /* initialize timer */ +#endif #ifdef CONFIG_FSL_ESDHC get_clocks, #endif +#ifdef CONFIG_SYS_ALLOC_DPRAM +#if !defined(CONFIG_CPM2) + dpram_init, +#endif +#endif +#if defined(CONFIG_BOARD_POSTCLK_INIT) + board_postclk_init, +#endif env_init, /* initialize environment */ +#if defined(CONFIG_8xx_CPUCLK_DEFAULT) + /* get CPU and bus clocks according to the environment variable */ + get_clocks_866, + /* adjust sdram refresh rate according to the new clock */ + sdram_adjust_866, + init_timebase, +#endif init_baud_rate, /* initialze baudrate settings */ serial_init, /* serial communications setup */ console_init_f, /* stage 1 init of console */ display_options, /* say that we are here */ display_text_info, /* show debugging info if required */ +#if defined(CONFIG_8260) + prt_8260_rsr, + prt_8260_clks, +#endif /* CONFIG_8260 */ +#if defined(CONFIG_MPC83xx) + prt_83xx_rsr, +#endif +#ifdef CONFIG_PPC + checkcpu, +#endif #if defined(CONFIG_DISPLAY_CPUINFO) print_cpuinfo, /* display cpu info (and speed) */ #endif +#if defined(CONFIG_MPC5xxx) + prt_mpc5xxx_clks, +#endif /* CONFIG_MPC5xxx */ +#if defined(CONFIG_MPC8220) + prt_mpc8220_clks, +#endif #if defined(CONFIG_DISPLAY_BOARDINFO) checkboard, /* display board info */ #endif + INIT_FUNC_WATCHDOG_INIT +#if defined(CONFIG_MISC_INIT_F) + misc_init_f, +#endif + INIT_FUNC_WATCHDOG_RESET +#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) + init_func_i2c, +#endif +#if defined(CONFIG_HARD_SPI) + init_func_spi, +#endif announce_dram_init, + /* TODO: unify all these dram functions? */ +#ifdef CONFIG_ARM dram_init, /* configure available RAM banks */ setup_dram_config, +#endif +#ifdef CONFIG_X86 + dram_init_f, /* configure available RAM banks */ +#endif +#ifdef CONFIG_PPC + init_func_ram, +#endif display_dram_config, #ifdef CONFIG_POST + post_init_f, +#endif + INIT_FUNC_WATCHDOG_RESET +#if defined(CONFIG_SYS_DRAM_TEST) + testdram, +#endif /* CONFIG_SYS_DRAM_TEST */ + INIT_FUNC_WATCHDOG_RESET + +#ifdef CONFIG_POST init_post, #endif + INIT_FUNC_WATCHDOG_RESET setup_dram_config, + + /* + * Now that we have DRAM mapped and working, we can + * relocate the code and continue running from DRAM. + * + * Reserve memory at end of RAM for (top down in that order): + * - area that won't get touched by U-Boot and Linux (optional) + * - kernel log buffer + * - protected RAM + * - LCD framebuffer + * - monitor code + * - board info struct + */ setup_reloc, #if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR) reserve_logbuffer, @@ -482,6 +835,11 @@ static init_fnc_t init_sequence_f[] = { #ifdef CONFIG_LCD reserve_lcd, #endif + /* TODO: Why the dependency on CONFIG_8xx? */ +#if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) \ + && !defined(CONFIG_ARM) + reserve_video, +#endif reserve_uboot, #ifndef CONFIG_SPL_BUILD reserve_malloc, @@ -494,8 +852,17 @@ static init_fnc_t init_sequence_f[] = { #else reserve_stacks, #endif +#ifdef CONFIG_PPC + setup_board_part1, + INIT_FUNC_WATCHDOG_RESET + setup_board_part2, +#endif setup_baud_rate, display_new_sp, +#ifdef CONFIG_SYS_EXTBDINFO + setup_board_extra, +#endif + INIT_FUNC_WATCHDOG_RESET jump_to_copy, NULL, }; diff --git a/include/common.h b/include/common.h index 0bda049..3140375 100644 --- a/include/common.h +++ b/include/common.h @@ -284,6 +284,22 @@ int mac_read_from_eeprom(void); extern u8 _binary_dt_dtb_start[]; /* embedded device tree blob */ int set_cpu_clk_info(void);
+#ifdef CONFIG_SYS_GENERIC_BOARD +/* + * Reset the watchdog timer, always returns 0 + * + * This function is here since it is shared between board_f() and board_r(). + */ +int init_func_watchdog_reset(void); +#endif + +#if defined(CONFIG_WATCHDOG) +#define INIT_FUNC_WATCHDOG_RESET init_func_watchdog_reset, +#else +#define INIT_FUNC_WATCHDOG_RESET /* undef */ +#endif /* CONFIG_WATCHDOG */ + + /* * Called when console output is requested before the console is available. * The board should do its best to get the character out to the user any way

On 03/14/2012 09:16 PM, Simon Glass wrote:
This adds ppc features to the generic pre-relocation board init.
This is making this file look not very generic. Can we factor out the parts that are actually generic and leave the rest in arch code, rather than create a mess of ifdefs?
-Scott

+Graeme
Hi Scott,
On Thu, Mar 15, 2012 at 12:12 PM, Scott Wood scottwood@freescale.com wrote:
On 03/14/2012 09:16 PM, Simon Glass wrote:
This adds ppc features to the generic pre-relocation board init.
This is making this file look not very generic. Can we factor out the parts that are actually generic and leave the rest in arch code, rather than create a mess of ifdefs?
Yes that is the plan - Graeme is working on an initcall setup which will make this really easy. For now we have #ifdefs. Bear in mind that most of these were already there in arch/powerpc/lib/board.c.
One other point - one of the reasons that this patch adds so much code is that PPC supports more features than other architectures. In fact I hope that we can make most of those features generic, so that we can remove the PPC #ifdefs and support them for all architectures.
Regards, Simon
-Scott

This adds ppc features to the generic post-relocation board init.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v4: - Updates to sit on top of earlier patches
common/board_r.c | 462 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 459 insertions(+), 3 deletions(-)
diff --git a/common/board_r.c b/common/board_r.c index f587c03..19d162b 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -27,24 +27,84 @@ */
#include <common.h> +/* TODO: can we just include all these headers whether needed or not? */ +#if defined(CONFIG_CMD_BEDBUG) +#include <bedbug/type.h> +#endif #ifdef CONFIG_HAS_DATAFLASH #include <dataflash.h> #endif #include <environment.h> +#if defined(CONFIG_CMD_IDE) +#include <ide.h> +#endif #include <initcall.h> +#ifdef CONFIG_PS2KBD +#include <keyboard.h> +#endif +#if defined(CONFIG_CMD_KGDB) +#include <kgdb.h> +#endif #include <logbuff.h> #include <malloc.h> +#ifdef CONFIG_BITBANGMII +#include <miiphy.h> +#endif #include <mmc.h> #include <nand.h> #include <onenand_uboot.h> +#include <scsi.h> #include <serial.h> +#include <spi.h> #include <stdio_dev.h> +#include <watchdog.h> +#ifdef CONFIG_ADDR_MAP +#include <asm/mmu.h> +#endif #include <asm/sections.h>
DECLARE_GLOBAL_DATA_PTR;
ulong monitor_flash_len;
+/* TODO: Move this prototype to a header? */ +#ifdef CONFIG_SYS_UPDATE_FLASH_SIZE +extern int update_flash_size(int flash_size); +#endif + +int __board_flash_wp_on(void) +{ + /* + * Most flashes can't be detected when write protection is enabled, + * so provide a way to let U-Boot gracefully ignore write protected + * devices. + */ + return 0; +} + +int board_flash_wp_on(void) + __attribute__ ((weak, alias("__board_flash_wp_on"))); + +void __cpu_secondary_init_r(void) +{ +} + +void cpu_secondary_init_r(void) + __attribute__ ((weak, alias("__cpu_secondary_init_r"))); + +static int initr_secondary_cpu(void) +{ + /* + * after non-volatile devices & environment is setup and cpu code have + * another round to deal with any initialization that might require + * full access to the environment or loading of some image (firmware) + * from a non-volatile device + */ + /* TODO: maybe define this for all archs? */ + cpu_secondary_init_r(); + + return 0; +}
static int initr_reloc(void) { @@ -73,6 +133,25 @@ static int initr_reloc_global_data(void) #else monitor_flash_len = (ulong)&__init_end - gd->dest_addr; #endif +#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) + /* + * The gd->cpu pointer is set to an address in flash before relocation. + * We need to update it to point to the same CPU entry in RAM. + * TODO: why not just add gd->reloc_ofs? + */ + gd->cpu += gd->dest_addr - CONFIG_SYS_MONITOR_BASE; +#endif +#ifdef CONFIG_SYS_EXTRA_ENV_RELOC + /* + * Some systems need to relocate the env_addr pointer early because the + * location it points to will get invalidated before env_relocate is + * called. One example is on systems that might use a L2 or L3 cache + * in SRAM mode and initialize that cache from SRAM mode back to being + * a cache in cpu_init_r. + */ + gd->env_addr += gd->dest_addr - CONFIG_SYS_MONITOR_BASE; +#endif + return 0; }
#ifdef CONFIG_SERIAL_MULTI @@ -83,6 +162,27 @@ static int initr_serial(void) } #endif
+#ifdef CONFIG_PPC +static int initr_trap(void) +{ + /* + * Setup trap handlers + */ + trap_init(gd->dest_addr); + + return 0; +} +#endif + +#ifdef CONFIG_ADDR_MAP +static int initr_addr_map(void) +{ + init_addr_map(); + + return 0; +} +#endif + #ifdef CONFIG_LOGBUFFER unsigned long logbuffer_base(void) { @@ -104,6 +204,50 @@ static int initr_post_backlog(void) } #endif
+#ifdef CONFIG_SYS_DELAYED_ICACHE +static int initr_icache_enable(void) +{ + return 0; +} +#endif + +#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500) +static int initr_unlock_ram_in_cache(void) +{ + unlock_ram_in_cache(); /* it's time to unlock D-cache in e500 */ + return 0; +} +#endif + +#ifdef CONFIG_PCI +static int initr_pci(void) +{ + pci_init(); + + return 0; +} +#endif + +#ifdef CONFIG_WINBOND_83C553 +static int initr_w83c553f(void) +{ + /* + * Initialise the ISA bridge + */ + initialise_w83c553f(); + return 0; +} +#endif + +static int initr_barrier(void) +{ +#ifdef CONFIG_PPC + /* TODO: Can we not use dmb() macros for this? */ + asm("sync ; isync"); +#endif + return 0; +} + static int initr_malloc(void) { ulong malloc_start; @@ -123,13 +267,26 @@ static int initr_announce(void) #if !defined(CONFIG_SYS_NO_FLASH) static int initr_flash(void) { - ulong flash_size; + ulong flash_size = 0; + bd_t *bd = gd->bd; + int ok;
puts("Flash: ");
- flash_size = flash_init(); - if (flash_size <= 0) { + if (board_flash_wp_on()) { + printf("Uninitialized - Write Protect On\n"); + /* Since WP is on, we can't find real size. Set to 0 */ + ok = 1; + } else { + flash_size = flash_init(); + ok = flash_size > 0; + } + if (!ok) { puts("*** failed ***\n"); +#ifdef CONFIG_PPC + /* Why does PPC do this? */ + hang(); +#endif return -1; } print_size(flash_size, ""); @@ -152,6 +309,40 @@ static int initr_flash(void) } #endif /* CONFIG_SYS_FLASH_CHECKSUM */ putc('\n'); + + /* update start of FLASH memory */ +#ifdef CONFIG_SYS_FLASH_BASE + bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; +#endif + /* size of FLASH memory (final value) */ + bd->bi_flashsize = flash_size; + +#if defined(CONFIG_SYS_UPDATE_FLASH_SIZE) + /* Make a update of the Memctrl. */ + update_flash_size(flash_size); +#endif + + +#if defined(CONFIG_OXC) || defined(CONFIG_RMU) + /* flash mapped at end of memory map */ + bd->bi_flashoffset = CONFIG_SYS_TEXT_BASE + flash_size; +#elif CONFIG_SYS_MONITOR_BASE == CONFIG_SYS_FLASH_BASE + bd->bi_flashoffset = monitor_flash_len; /* reserved area for monitor */ +#endif + return 0; +} +#endif + +#ifdef CONFIG_PPC +static int initr_spi(void) +{ + /* PPC does this here */ +#ifdef CONFIG_SPI +#if !defined(CONFIG_ENV_IS_IN_EEPROM) + spi_init_f(); +#endif + spi_init_r(); +#endif return 0; } #endif @@ -216,9 +407,56 @@ static int initr_env(void) copy_filename(BootFile, s, sizeof(BootFile)); } #endif +#if defined(CONFIG_SYS_EXTBDINFO) +#if defined(CONFIG_405GP) || defined(CONFIG_405EP) +#if defined(CONFIG_I2CFAST) + /* + * set bi_iic_fast for linux taking environment variable + * "i2cfast" into account + */ + { + char *s = getenv("i2cfast"); + + if (s && ((*s == 'y') || (*s == 'Y'))) { + gd->bd->bi_iic_fast[0] = 1; + gd->bd->bi_iic_fast[1] = 1; + } + } +#endif /* CONFIG_I2CFAST */ +#endif /* CONFIG_405GP, CONFIG_405EP */ +#endif /* CONFIG_SYS_EXTBDINFO */ + return 0; +} + +#ifdef CONFIG_HERMES +static int initr_hermes(void) +{ + if ((gd->board_type >> 16) == 2) + gd->bd->bi_ethspeed = gd->board_type & 0xFFFF; + else + gd->bd->bi_ethspeed = 0xFFFF; return 0; }
+static int initr_hermes_start(void) +{ + if (gd->bd->bi_ethspeed != 0xFFFF) + hermes_start_lxt980((int) gd->bd->bi_ethspeed); + return 0; +} +#endif + +#ifdef CONFIG_SC3 +/* TODO: with new initcalls, move this into the driver */ +extern void sc3_read_eeprom(void); + +static int initr_sc3_read_eeprom(void) +{ + sc3_read_eeprom(); + return 0; +} +#endif + static int initr_jumptable(void) { jumptable_init(); @@ -246,6 +484,8 @@ static int initr_enable_interrupts(void) #ifdef CONFIG_CMD_NET static int initr_ethaddr(void) { + bd_t *bd = gd->bd; + #if defined(CONFIG_DRIVER_SMC91111) || defined(CONFIG_DRIVER_LAN91C96) /* Perform network card initialisation if necessary */ /* XXX: this needs to be moved to board init */ @@ -257,11 +497,63 @@ static int initr_ethaddr(void) smc_set_mac_addr(enetaddr); } #endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */ + /* kept around for legacy kernels only ... ignore the next section */ + eth_getenv_enetaddr("ethaddr", bd->bi_enetaddr); +#ifdef CONFIG_HAS_ETH1 + eth_getenv_enetaddr("eth1addr", bd->bi_enet1addr); +#endif +#ifdef CONFIG_HAS_ETH2 + eth_getenv_enetaddr("eth2addr", bd->bi_enet2addr); +#endif +#ifdef CONFIG_HAS_ETH3 + eth_getenv_enetaddr("eth3addr", bd->bi_enet3addr); +#endif +#ifdef CONFIG_HAS_ETH4 + eth_getenv_enetaddr("eth4addr", bd->bi_enet4addr); +#endif +#ifdef CONFIG_HAS_ETH5 + eth_getenv_enetaddr("eth5addr", bd->bi_enet5addr); +#endif + return 0; +} +#endif /* CONFIG_CMD_NET */ + +#ifdef CONFIG_CMD_KGDB +static int initr_kgdb(void) +{ + puts("KGDB: "); + kgdb_init(); + return 0; +} +#endif + +#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) +static int initr_status_led(void) +{ + status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING); + + return 0; +} +#endif + +#if defined(CONFIG_CMD_SCSI) +static int initr_scsi(void) +{ + puts("SCSI: "); + scsi_init();
return 0; } #endif /* CONFIG_CMD_NET */
+#if defined(CONFIG_CMD_DOC) +static int initr_doc(void) +{ + puts("DOC: "); + doc_init(); +} +#endif + #ifdef CONFIG_BITBANGMII static int initr_bbmii(void) { @@ -291,6 +583,33 @@ static int initr_post(void) } #endif
+#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE) +static int initr_pcmcia(void) +{ + puts("PCMCIA:"); + pcmcia_init(); + return 0; +} +#endif + +#if defined(CONFIG_CMD_IDE) +static int initr_ide(void) +{ +#ifdef CONFIG_IDE_8xx_PCCARD + puts("PCMCIA:"); +#else + puts("IDE: "); +#endif +#if defined(CONFIG_START_IDE) + if (board_start_ide()) + ide_init(); +#else + ide_init(); +#endif + return 0; +} +#endif + #if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER) /* * Export available size of memory for Linux, taking into account the @@ -310,6 +629,37 @@ int initr_mem(void) # endif sprintf(memsz, "%ldk", (gd->ram_size / 1024) - pram); setenv("mem", memsz); + + return 0; +} +#endif + +#ifdef CONFIG_CMD_BEDBUG +static int initr_bedbug(void) +{ + bedbug_init(); + + return 0; +} +#endif + +#ifdef CONFIG_PS2KBD +static int initr_kbd(void) +{ + puts("PS/2: "); + kbd_init(); + return 0; +} +#endif + +#ifdef CONFIG_MODEM_SUPPORT +static int initr_modem(void) +{ + /* TODO: with new initcalls, move this into the driver */ + extern int do_mdm_init; + + do_mdm_init = gd->do_mdm_init; + return 0; } #endif
@@ -327,9 +677,12 @@ static int run_main_loop(void) * * We also hope to remove most of the driver-related init and do it if/when * the driver is later used. + * + * TODO: perhaps reset the watchdog in the initcall function after each call? */ init_fnc_t init_sequence_r[] = { initr_reloc, + /* TODO: could x86/PPC have this also perhaps? */ #ifdef CONFIG_ARM initr_caches, board_init, /* Setup chipselects */ @@ -339,16 +692,51 @@ init_fnc_t init_sequence_r[] = { initr_serial, #endif initr_announce, + INIT_FUNC_WATCHDOG_RESET +#ifdef CONFIG_PPC + initr_trap, +#endif +#ifdef CONFIG_ADDR_MAP + initr_addr_map, +#endif +#if defined(CONFIG_BOARD_EARLY_INIT_R) + board_early_init_r, +#endif + INIT_FUNC_WATCHDOG_RESET #ifdef CONFIG_LOGBUFFER initr_logbuffer, #endif #ifdef CONFIG_POST initr_post_backlog, #endif + INIT_FUNC_WATCHDOG_RESET +#ifdef CONFIG_SYS_DELAYED_ICACHE + initr_icache_enable, +#endif +#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500) + initr_unlock_ram_in_cache, +#endif +#if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT) + /* + * Do early PCI configuration _before_ the flash gets initialised, + * because PCU ressources are crucial for flash access on some boards. + */ + initr_pci, +#endif +#ifdef CONFIG_WINBOND_83C553 + initr_w83c553f, +#endif + initr_barrier, initr_malloc, #ifndef CONFIG_SYS_NO_FLASH initr_flash, #endif + INIT_FUNC_WATCHDOG_RESET +#ifdef CONFIG_PPC + /* initialize higher level parts of CPU like time base and timers */ + cpu_init_r, + initr_spi, +#endif #ifdef CONFIG_CMD_NAND initr_nand, #endif @@ -362,6 +750,24 @@ init_fnc_t init_sequence_r[] = { initr_dataflash, #endif initr_env, + INIT_FUNC_WATCHDOG_RESET + initr_secondary_cpu, +#ifdef CONFIG_SC3 + initr_sc3_read_eeprom, +#endif +#ifdef CONFIG_HERMES + initr_hermes, +#endif +#if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET) + mac_read_from_eeprom, +#endif + INIT_FUNC_WATCHDOG_RESET +#if defined(CONFIG_PCI) && !defined(CONFIG_SYS_EARLY_PCI_INIT) + /* + * Do pci configuration + */ + initr_pci, +#endif stdio_init, initr_jumptable, #ifdef CONFIG_API @@ -374,23 +780,73 @@ init_fnc_t init_sequence_r[] = { #ifdef CONFIG_MISC_INIT_R misc_init_r, /* miscellaneous platform-dependent init */ #endif +#ifdef CONFIG_HERMES + initr_hermes_start, +#endif + INIT_FUNC_WATCHDOG_RESET +#ifdef CONFIG_CMD_KGDB + initr_kgdb, +#endif interrupt_init, +#ifdef CONFIG_ARM initr_enable_interrupts, +#endif +#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) + initr_status_led, +#endif + /* PPC has a udelay(20) here dating from 2002. Why? */ #ifdef CONFIG_CMD_NET initr_ethaddr, #endif #ifdef CONFIG_BOARD_LATE_INIT board_late_init, #endif +#ifdef CONFIG_CMD_SCSI + INIT_FUNC_WATCHDOG_RESET + initr_scsi, +#endif +#ifdef CONFIG_CMD_DOC + INIT_FUNC_WATCHDOG_RESET + initr_doc, +#endif #ifdef CONFIG_BITBANGMII initr_bbmii, #endif #ifdef CONFIG_CMD_NET + INIT_FUNC_WATCHDOG_RESET initr_net, #endif #ifdef CONFIG_POST initr_post, #endif +#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE) + initr_pcmcia, +#endif +#if defined(CONFIG_CMD_IDE) + initr_ide, +#endif +#ifdef CONFIG_LAST_STAGE_INIT + INIT_FUNC_WATCHDOG_RESET + /* + * Some parts can be only initialized if all others (like + * Interrupts) are up and running (i.e. the PC-style ISA + * keyboard). + */ + last_stage_init, +#endif +#ifdef CONFIG_CMD_BEDBUG + INIT_FUNC_WATCHDOG_RESET + initr_bedbug, +#endif +#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER) + initr_mem, +#endif +#ifdef CONFIG_PS2KBD + initr_kbd, +#endif +#ifdef CONFIG_MODEM_SUPPORT + initr_modem, +#endif run_main_loop, };

This enables generic board support so that ppc boards can define CONFIG_SYS_GENERIC_BOARD.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/powerpc/config.mk | 3 --- arch/powerpc/include/asm/global_data.h | 7 +++++++ arch/powerpc/include/asm/u-boot.h | 7 +++++++ arch/powerpc/lib/Makefile | 4 +++- 4 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/config.mk b/arch/powerpc/config.mk index e6203dd..a307154 100644 --- a/arch/powerpc/config.mk +++ b/arch/powerpc/config.mk @@ -29,9 +29,6 @@ PLATFORM_RELFLAGS += -fpic -mrelocatable -ffunction-sections -fdata-sections PLATFORM_CPPFLAGS += -DCONFIG_PPC -D__powerpc__ PLATFORM_LDFLAGS += -n
-# Move to unified board system later -CONFIG_SYS_LEGACY_BOARD := y - # # When cross-compiling on NetBSD, we have to define __PPC__ or else we # will pick up a va_list declaration that is incompatible with the diff --git a/arch/powerpc/include/asm/global_data.h b/arch/powerpc/include/asm/global_data.h index 01f1d4a..3200443 100644 --- a/arch/powerpc/include/asm/global_data.h +++ b/arch/powerpc/include/asm/global_data.h @@ -27,6 +27,11 @@ #include "config.h" #include "asm/types.h"
+#ifdef CONFIG_SYS_GENERIC_BOARD +/* Use the generic board which requires a unified global_data */ +#include <asm-generic/global_data.h> +#else + /* * The following data structure is placed in some memory wich is * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or @@ -198,6 +203,8 @@ typedef struct global_data { #define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */ #define GD_FLG_ENV_READY 0x00080 /* Environment imported into hash table */
+#endif /* nCONFIG_SYS_GENERIC_BOARD */ + #if 1 #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r2") #else /* We could use plain global data, but the resulting code is bigger */ diff --git a/arch/powerpc/include/asm/u-boot.h b/arch/powerpc/include/asm/u-boot.h index b2fa2b5..7cc9af7 100644 --- a/arch/powerpc/include/asm/u-boot.h +++ b/arch/powerpc/include/asm/u-boot.h @@ -34,6 +34,11 @@ * include/asm-ppc/u-boot.h */
+#ifdef CONFIG_SYS_GENERIC_BOARD +/* Use the generic board which requires a unified bd_info */ +#include <asm-generic/u-boot.h> +#else + #ifndef __ASSEMBLY__
typedef struct bd_info { @@ -144,6 +149,8 @@ typedef struct bd_info {
#endif /* __ASSEMBLY__ */
+#endif /* nCONFIG_SYS_GENERIC_BOARD */ + /* For image.h:image_check_target_arch() */ #define IH_ARCH_DEFAULT IH_ARCH_PPC
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index cdd62a2..eef76b5 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -44,7 +44,9 @@ SOBJS-y += ticks.o SOBJS-y += reloc.o
COBJS-$(CONFIG_BAT_RW) += bat_rw.o -COBJS-y += board.o +ifeq ($(CONFIG_SYS_GENERIC_BOARD),) +COBJS-y += board.o +endif COBJS-y += bootm.o COBJS-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount.o COBJS-y += cache.o

Since Tegra executes early code on an ARMv4T (but the rest on ARMv7) we must mark the new board init files for compilation with ARMv4t architecture.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/cpu/armv7/tegra2/config.mk | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/tegra2/config.mk b/arch/arm/cpu/armv7/tegra2/config.mk index 2303dba..4b43dde 100644 --- a/arch/arm/cpu/armv7/tegra2/config.mk +++ b/arch/arm/cpu/armv7/tegra2/config.mk @@ -28,6 +28,8 @@ # file with compatible flags ifdef CONFIG_TEGRA2 CFLAGS_arch/arm/lib/board.o += -march=armv4t +CFLAGS_common/board_f.o += -march=armv4t +CFLAGS_lib/initcall.o += -march=armv4t endif
USE_PRIVATE_LIBGCC = yes

Enable CONFIG_SYS_GENERIC_BOARD for Tegra 2 Seaboard.
Signed-off-by: Simon Glass sjg@chromium.org --- Changes in v2: - Add CONFIG_SYS_GENERIC_BOARD to allow board to select generic board - Add PowerPC support - Change generic board to an opt-in system on a per-board basic - Rebase to master
Changes in v3: - Rebase on top of x86/master (which has not yet been pulled to master) - Rebase to master
Changes in v4: - Drop sc520_timer.c patch (warning already fixed by previous patch) - Rebase to master
include/configs/seaboard.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h index 261f952..11d9e8d 100644 --- a/include/configs/seaboard.h +++ b/include/configs/seaboard.h @@ -27,6 +27,8 @@ #include <asm/sizes.h> #include "tegra2-common.h"
+#define CONFIG_SYS_GENERIC_BOARD + /* High-level configuration options */ #define TEGRA2_SYSMEM "mem=384M@0M nvmem=128M@384M mem=512M@512M" #define V_PROMPT "Tegra2 (SeaBoard) # "

On Wed, Mar 14, 2012 at 07:15:57PM -0700, Simon Glass wrote:
This series creates a generic board.c implementation which contains the essential functions of the major arch/xxx/lib/board.c files.
Let me start by saying that I agree with the premise, please read any inflection/tone as that of someone trying to debug a problem only :)
I'm trying to test this on omap4_panda right now and I'm running into a problem where we hang setting up gd->bd->bi_dram[0]. I don't see why this isn't being set (some quick peeking around and SPL is behaving normally and doing its configure of DRAM and so forth). But I also can't debug this problem as easily as I would like because: (a) despite DEBUG being defined, none of the debug() prints are printing (my printf's are) (b) I assume this is because there's so much reconciliation needed still, but the file is an unwieldy mess. In fact, as I'm writing this and debugging at the same time, it seems reserve_board isn't being called, but it's compiled in, in the non-SPL case. I'm not seeing what's up...

Hi Tom,
On Fri, Mar 16, 2012 at 12:23 PM, Tom Rini trini@ti.com wrote:
On Wed, Mar 14, 2012 at 07:15:57PM -0700, Simon Glass wrote:
This series creates a generic board.c implementation which contains the essential functions of the major arch/xxx/lib/board.c files.
Let me start by saying that I agree with the premise, please read any inflection/tone as that of someone trying to debug a problem only :)
Understood :-)
I'm trying to test this on omap4_panda right now and I'm running into a problem where we hang setting up gd->bd->bi_dram[0]. I don't see why this isn't being set (some quick peeking around and SPL is behaving normally and doing its configure of DRAM and so forth). But I also can't debug this problem as easily as I would like because: (a) despite DEBUG being defined, none of the debug() prints are printing (my printf's are)
There is only one macro that affects that - make sure #define DEBUG is above #include common.h or maybe just change them to printf() to work this out...
(b) I assume this is because there's so much reconciliation needed still, but the file is an unwieldy mess. In fact, as I'm writing this and debugging at the same time, it seems reserve_board isn't being called, but it's compiled in, in the non-SPL case. I'm not seeing what's up...
I split out the SPL stuff because it wasn't exactly clear to me what was different between SPL and normal start-up. Only recently did I get a board that supports SPL, and I was planning on looking at this soon. I can't give any specific guidance other than persistence and good debug tools :-)
But please do let me know how you get on, and thanks for looking at it. This effort is worthy but not easy.
Regards, Simon
-- Tom

On Fri, Mar 16, 2012 at 12:34:20PM -0700, Simon Glass wrote:
Hi Tom,
On Fri, Mar 16, 2012 at 12:23 PM, Tom Rini trini@ti.com wrote:
On Wed, Mar 14, 2012 at 07:15:57PM -0700, Simon Glass wrote:
This series creates a generic board.c implementation which contains the essential functions of the major arch/xxx/lib/board.c files.
Let me start by saying that I agree with the premise, please read any inflection/tone as that of someone trying to debug a problem only :)
Understood :-)
I'm trying to test this on omap4_panda right now and I'm running into a problem where we hang setting up gd->bd->bi_dram[0]. ?I don't see why this isn't being set (some quick peeking around and SPL is behaving normally and doing its configure of DRAM and so forth). ?But I also can't debug this problem as easily as I would like because: (a) despite DEBUG being defined, none of the debug() prints are printing (my printf's are)
There is only one macro that affects that - make sure #define DEBUG is above #include common.h or maybe just change them to printf() to work this out...
I've gone and changed them to printf's, and a lot of stuff I would expect to see, I don't. On tegra, can you do a before/after debug build and see what board_init_f shows?
(b) I assume this is because there's so much reconciliation needed still, but the file is an unwieldy mess. ?In fact, as I'm writing this and debugging at the same time, it seems reserve_board isn't being called, but it's compiled in, in the non-SPL case. ?I'm not seeing what's up...
I split out the SPL stuff because it wasn't exactly clear to me what was different between SPL and normal start-up. Only recently did I get a board that supports SPL, and I was planning on looking at this soon. I can't give any specific guidance other than persistence and good debug tools :-)
Actually, what I'm seeing is more "is this generic or ARM or x86 or PPC code?" There's a lot of that merging that needs doing still and I guess that's part of the mess.
But please do let me know how you get on, and thanks for looking at it. This effort is worthy but not easy.
I'll post patches for omap4_panda and then hopefully omap3_beagle, or die trying :)

On Fri, Mar 16, 2012 at 01:07:23PM -0700, Tom Rini wrote:
On Fri, Mar 16, 2012 at 12:34:20PM -0700, Simon Glass wrote:
Hi Tom,
On Fri, Mar 16, 2012 at 12:23 PM, Tom Rini trini@ti.com wrote:
On Wed, Mar 14, 2012 at 07:15:57PM -0700, Simon Glass wrote:
This series creates a generic board.c implementation which contains the essential functions of the major arch/xxx/lib/board.c files.
Let me start by saying that I agree with the premise, please read any inflection/tone as that of someone trying to debug a problem only :)
Understood :-)
I'm trying to test this on omap4_panda right now and I'm running into a problem where we hang setting up gd->bd->bi_dram[0]. ?I don't see why this isn't being set (some quick peeking around and SPL is behaving normally and doing its configure of DRAM and so forth). ?But I also can't debug this problem as easily as I would like because: (a) despite DEBUG being defined, none of the debug() prints are printing (my printf's are)
There is only one macro that affects that - make sure #define DEBUG is above #include common.h or maybe just change them to printf() to work this out...
I've gone and changed them to printf's, and a lot of stuff I would expect to see, I don't. On tegra, can you do a before/after debug build and see what board_init_f shows?
I've found the problem, but I don't have an easy fix. The problem is we aren't doing things in the same order we used to. We need gd->bd setup before we call setup_dram_config (which is just __dram_init_banksize). This doesn't blow up on Tegra2 as memory starts at 0. That's not true on TI's Cortex-A* parts and we hang :)
So my request for a V5 is to boot with DEBUG enabled and compare CONFIG_SYS_GENERIC_BOARD=y and =n and fix the ordering issues. I suspect this will be complex, or at least a pain due to the unwieldyness I was talking about before of the merged list of calls being so very long and with PPC-specific stuff stuck in (and some ARM and so forth).

Hi Tom,
On Fri, Mar 16, 2012 at 2:53 PM, Tom Rini trini@ti.com wrote:
On Fri, Mar 16, 2012 at 01:07:23PM -0700, Tom Rini wrote:
On Fri, Mar 16, 2012 at 12:34:20PM -0700, Simon Glass wrote:
Hi Tom,
On Fri, Mar 16, 2012 at 12:23 PM, Tom Rini trini@ti.com wrote:
On Wed, Mar 14, 2012 at 07:15:57PM -0700, Simon Glass wrote:
This series creates a generic board.c implementation which contains the essential functions of the major arch/xxx/lib/board.c files.
Let me start by saying that I agree with the premise, please read any inflection/tone as that of someone trying to debug a problem only :)
Understood :-)
I'm trying to test this on omap4_panda right now and I'm running into a problem where we hang setting up gd->bd->bi_dram[0]. ?I don't see why this isn't being set (some quick peeking around and SPL is behaving normally and doing its configure of DRAM and so forth). ?But I also can't debug this problem as easily as I would like because: (a) despite DEBUG being defined, none of the debug() prints are printing (my printf's are)
There is only one macro that affects that - make sure #define DEBUG is above #include common.h or maybe just change them to printf() to work this out...
I've gone and changed them to printf's, and a lot of stuff I would expect to see, I don't. On tegra, can you do a before/after debug build and see what board_init_f shows?
I've found the problem, but I don't have an easy fix. The problem is we aren't doing things in the same order we used to. We need gd->bd setup before we call setup_dram_config (which is just __dram_init_banksize). This doesn't blow up on Tegra2 as memory starts at 0. That's not true on TI's Cortex-A* parts and we hang :)
Great! Thanks for the info and your efforts on this - much appreciated!
So my request for a V5 is to boot with DEBUG enabled and compare CONFIG_SYS_GENERIC_BOARD=y and =n and fix the ordering issues. I suspect this will be complex, or at least a pain due to the unwieldyness I was talking about before of the merged list of calls being so very long and with PPC-specific stuff stuck in (and some ARM and so forth).
Well I created this by painstakingly comparing the ordering in the different archs and trying to come up with something reasonable. Clearly I got it wrong, but I don't think it's a big job to figure out the error. Hopefully it is not just an incompatibility between the archs.
I will take a look.
Also for DEBUG, can you please tell me which file you added the DEBUG to?
Regards, Simon
-- Tom

On Fri, Mar 16, 2012 at 03:19:20PM -0700, Simon Glass wrote:
Hi Tom,
On Fri, Mar 16, 2012 at 2:53 PM, Tom Rini trini@ti.com wrote:
[snip]
So my request for a V5 is to boot with DEBUG enabled and compare CONFIG_SYS_GENERIC_BOARD=y and =n and fix the ordering issues. ?I suspect this will be complex, or at least a pain due to the unwieldyness I was talking about before of the merged list of calls being so very long and with PPC-specific stuff stuck in (and some ARM and so forth).
Well I created this by painstakingly comparing the ordering in the different archs and trying to come up with something reasonable. Clearly I got it wrong, but I don't think it's a big job to figure out the error. Hopefully it is not just an incompatibility between the archs.
Yeah. I suspect it'll be easier on you since that code feels like a place that once you've got a lot of mental notes made you can fiddle in quickly.
I will take a look.
k. Hoping v5 is as easy to turn on for omap* as it is for Tegra :)
Also for DEBUG, can you please tell me which file you added the DEBUG to?
include/configs/omap4_common.h since that's where I usually dump that (and it works fine in the old setup).
participants (5)
-
Graeme Russ
-
Scott Wood
-
Simon Glass
-
Tom Rini
-
Wolfgang Denk