[U-Boot] [PATCH 2/4 V2] SMDK5250: Convert lowlevel_init.S to lowlevel_init.c

Rajeshwari Birje rajeshwari.birje at gmail.com
Mon Jan 14 07:32:15 CET 2013


Hi Minkyu Kang,

>OK, but is this something you intend to fix, perhaps in a future
> series? It seems like you need separate directories sooner rather than
> later.I don't think this is board-specific code, but chip-specific.

Please do let me know your opinion on the above comment.

Regards,
Rajeshwari Shinde.

On Fri, Jan 11, 2013 at 7:54 PM, Simon Glass <sjg at chromium.org> wrote:
> Hi Rajeshwari,
>
> On Fri, Jan 11, 2013 at 2:43 AM, Rajeshwari Birje
> <rajeshwari.birje at gmail.com> wrote:
>> Hi Simon,
>>
>> Thank you for comments.
>>
>> On Thu, Jan 10, 2013 at 11:04 PM, Simon Glass <sjg at chromium.org> wrote:
>>> Hi Rajeshwari,
>>>
>>> On Mon, Jan 7, 2013 at 5:08 AM, Rajeshwari Shinde
>>> <rajeshwari.s at samsung.com> wrote:
>>>> This patch converts lowlevel_init.S to lowlevel_init_c.c for
>>>> SMDK5250.
>>>> Lowlevel.S as of now added only for SMDK5250 and same can be
>>>> extended to other SOC in future.
>>>
>>> Should perhaps also mention new feature (controllable memory reset for resume?)
>> -OK
>>>
>>>>
>>>> Signed-off-by: Rajeshwari Shinde <rajeshwari.s at samsung.com>
>>>> ---
>>>> Changes in V2:
>>>>         - Renamed lowlevel_init.S to lowlevel.S and moved to
>>>>         arch/arm/cpu/armv7/exynos/
>>>>         - Moved power mode defines to power.h
>>>>         - Added early serial support.
>>>>         - Renamed mem_reset to reset.
>>>>  arch/arm/cpu/armv7/exynos/Makefile       |    6 ++
>>>>  arch/arm/cpu/armv7/exynos/lowlevel.S     |   35 ++++++++
>>>>  arch/arm/include/asm/arch-exynos/power.h |    8 ++
>>>>  board/samsung/smdk5250/Makefile          |    2 +-
>>>>  board/samsung/smdk5250/dmc_common.c      |    4 +-
>>>>  board/samsung/smdk5250/dmc_init_ddr3.c   |    6 +-
>>>>  board/samsung/smdk5250/lowlevel_init.S   |   96 --------------------
>>>>  board/samsung/smdk5250/lowlevel_init.c   |   81 +++++++++++++++++
>>>
>>> Any change we could move all of this to arch/arm/cpu/armv7/exynos...?
>> We do not have a separate directory for exynos5 and exynos4 and if we
>> add all these files in arch/arm/cpu/armv7/exynos it would break the
>> compilation for EXYNOS4. Also Later versions of exynos5 have different
>> memory and timing variants.
>
> OK, but is this something you intend to fix, perhaps in a future
> series? It seems like you need separate directories sooner rather than
> later.I don't think this is board-specific code, but chip-specific.
>
>>>
>>> It really doesn't relate to this board alone, but to the chip.
>>>
>>>>  board/samsung/smdk5250/setup.h           |   19 ++++-
>>>>  board/samsung/smdk5250/spl_boot.c        |  140 +++++++++++++++++++++++++++--
>>>>  spl/Makefile                             |    4 +
>>>>  11 files changed, 288 insertions(+), 113 deletions(-)
>>>>  create mode 100644 arch/arm/cpu/armv7/exynos/lowlevel.S
>>>>  delete mode 100644 board/samsung/smdk5250/lowlevel_init.S
>>>>  create mode 100644 board/samsung/smdk5250/lowlevel_init.c
>>>>
>>>> diff --git a/arch/arm/cpu/armv7/exynos/Makefile b/arch/arm/cpu/armv7/exynos/Makefile
>>>> index 9119961..2aa2722 100644
>>>> --- a/arch/arm/cpu/armv7/exynos/Makefile
>>>> +++ b/arch/arm/cpu/armv7/exynos/Makefile
>>>> @@ -22,6 +22,12 @@ include $(TOPDIR)/config.mk
>>>>
>>>>  LIB    = $(obj)lib$(SOC).o
>>>>
>>>> +ifdef CONFIG_SMDK5250
>>>> +ifdef CONFIG_SPL
>>>> +COBJS  += lowlevel.o
>>>
>>> Could do:
>>>
>>> COBJS-$(CONFIG_SPL)  += lowlevel.o
>>>
>>> and remove the inner ifdef
>> - OK
>>>
>>>> +endif
>>>> +endif
>>>> +
>>>>  COBJS  += clock.o power.o soc.o system.o pinmux.o
>>>>
>>>>  SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
>>>> diff --git a/arch/arm/cpu/armv7/exynos/lowlevel.S b/arch/arm/cpu/armv7/exynos/lowlevel.S
>>>> new file mode 100644
>>>> index 0000000..7307959
>>>> --- /dev/null
>>>> +++ b/arch/arm/cpu/armv7/exynos/lowlevel.S
>>>> @@ -0,0 +1,35 @@
>>>> +/*
>>>> + * Lowlevel setup for SMDK5250 board based on S5PC520
>>>> + *
>>>> + * Copyright (C) 2012 Samsung Electronics
>>>> + *
>>>> + * 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 <config.h>
>>>> +#include <asm/arch/cpu.h>
>>>> +
>>>> +       .globl lowlevel_init
>>>> +lowlevel_init:
>>>> +       /*
>>>> +        * Set the stack pointer, although it will be overwritten by the caller
>>>> +        * It seems we will not boot if this function is empty.
>>>> +        */
>>>> +       ldr     sp, =CONFIG_IRAM_STACK
>>>> +       mov     pc, lr
>>>> diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h
>>>> index f6d0278..d6fd29e 100644
>>>> --- a/arch/arm/include/asm/arch-exynos/power.h
>>>> +++ b/arch/arm/include/asm/arch-exynos/power.h
>>>> @@ -874,4 +874,12 @@ void power_ps_hold_setup(void);
>>>>
>>>>  /* Read the resume function and call it */
>>>>  void power_exit_wakeup(void);
>>>> +
>>>> +
>>>> +/* Power Down Modes
>>>> + * User defined values in inform1 register
>>>> + */
>>>> +#define EXYNOS_CHECK_SLEEP     0x00000BAD
>>>> +#define EXYNOS_CHECK_DIDLE     0xBAD00000
>>>> +#define EXYNOS_CHECK_LPA       0xABAD0000
>>>>  #endif
>>>> diff --git a/board/samsung/smdk5250/Makefile b/board/samsung/smdk5250/Makefile
>>>> index 47c6a5a..7eaef09 100644
>>>> --- a/board/samsung/smdk5250/Makefile
>>>> +++ b/board/samsung/smdk5250/Makefile
>>>> @@ -24,7 +24,6 @@ include $(TOPDIR)/config.mk
>>>>
>>>>  LIB    = $(obj)lib$(BOARD).o
>>>>
>>>> -SOBJS  := lowlevel_init.o
>>>>
>>>>  COBJS  := clock_init.o
>>>>  COBJS  += dmc_common.o dmc_init_ddr3.o
>>>> @@ -37,6 +36,7 @@ endif
>>>>
>>>>  ifdef CONFIG_SPL_BUILD
>>>>  COBJS  += spl_boot.o
>>>> +COBJS  += lowlevel_init.o
>>>
>>> Can you use this form instead of ifdef here?
>>>
>>> COBJS-$(CONFIG_SPL)  += lowlevel_init.o
>>>
>>>
>>>>  endif
>>>>
>>>>  SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
>>>> diff --git a/board/samsung/smdk5250/dmc_common.c b/board/samsung/smdk5250/dmc_common.c
>>>> index 109602a..f637bf9 100644
>>>> --- a/board/samsung/smdk5250/dmc_common.c
>>>> +++ b/board/samsung/smdk5250/dmc_common.c
>>>> @@ -175,7 +175,7 @@ void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc)
>>>>         writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1);
>>>>  }
>>>>
>>>> -void mem_ctrl_init()
>>>> +void mem_ctrl_init(int reset)
>>>>  {
>>>>         struct spl_machine_param *param = spl_get_machine_params();
>>>>         struct mem_timings *mem;
>>>> @@ -185,7 +185,7 @@ void mem_ctrl_init()
>>>>
>>>>         /* If there are any other memory variant, add their init call below */
>>>>         if (param->mem_type == DDR_MODE_DDR3) {
>>>> -               ret = ddr3_mem_ctrl_init(mem, param->mem_iv_size);
>>>> +               ret = ddr3_mem_ctrl_init(mem, param->mem_iv_size, reset);
>>>>                 if (ret) {
>>>>                         /* will hang if failed to init memory control */
>>>>                         while (1)
>>>> diff --git a/board/samsung/smdk5250/dmc_init_ddr3.c b/board/samsung/smdk5250/dmc_init_ddr3.c
>>>> index e050790..a5a70df 100644
>>>> --- a/board/samsung/smdk5250/dmc_init_ddr3.c
>>>> +++ b/board/samsung/smdk5250/dmc_init_ddr3.c
>>>> @@ -40,7 +40,8 @@ static void reset_phy_ctrl(void)
>>>>         writel(DDR3PHY_CTRL_PHY_RESET, &clk->lpddr3phy_ctrl);
>>>>  }
>>>>
>>>> -int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size)
>>>> +int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
>>>> +                       int reset)
>>>>  {
>>>>         unsigned int val;
>>>>         struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl;
>>>> @@ -51,7 +52,8 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size)
>>>>         phy1_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY1_BASE;
>>>>         dmc = (struct exynos5_dmc *)EXYNOS5_DMC_CTRL_BASE;
>>>>
>>>> -       reset_phy_ctrl();
>>>> +       if (reset)
>>>> +               reset_phy_ctrl();
>>>>
>>>>         /* Set Impedance Output Driver */
>>>>         val = (mem->impedance << CA_CK_DRVR_DS_OFFSET) |
>>>> diff --git a/board/samsung/smdk5250/lowlevel_init.S b/board/samsung/smdk5250/lowlevel_init.S
>>>> deleted file mode 100644
>>>> index bc6cb6f..0000000
>>>> --- a/board/samsung/smdk5250/lowlevel_init.S
>>>> +++ /dev/null
>>>> @@ -1,96 +0,0 @@
>>>> -/*
>>>> - * Lowlevel setup for SMDK5250 board based on S5PC520
>>>> - *
>>>> - * Copyright (C) 2012 Samsung Electronics
>>>> - *
>>>> - * 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 <config.h>
>>>> -#include <version.h>
>>>> -#include <asm/arch/cpu.h>
>>>> -
>>>> -_TEXT_BASE:
>>>> -       .word   CONFIG_SYS_TEXT_BASE
>>>> -
>>>> -       .globl lowlevel_init
>>>> -lowlevel_init:
>>>> -
>>>> -       /* use iRAM stack in bl2 */
>>>> -       ldr     sp, =CONFIG_IRAM_STACK
>>>> -       stmdb   r13!, {ip,lr}
>>>> -
>>>> -       /* check reset status */
>>>> -       ldr     r0, =(EXYNOS5_POWER_BASE + INFORM1_OFFSET)
>>>> -       ldr     r1, [r0]
>>>> -
>>>> -       /* AFTR wakeup reset */
>>>> -       ldr     r2, =S5P_CHECK_DIDLE
>>>> -       cmp     r1, r2
>>>> -       beq     exit_wakeup
>>>> -
>>>> -       /* LPA wakeup reset */
>>>> -       ldr     r2, =S5P_CHECK_LPA
>>>> -       cmp     r1, r2
>>>> -       beq     exit_wakeup
>>>> -
>>>> -       /* Sleep wakeup reset */
>>>> -       ldr     r2, =S5P_CHECK_SLEEP
>>>> -       cmp     r1, r2
>>>> -       beq     wakeup_reset
>>>> -
>>>> -       /*
>>>> -        * If U-boot is already running in RAM, no need to relocate U-Boot.
>>>> -        * Memory controller must be configured before relocating U-Boot
>>>> -        * in ram.
>>>> -        */
>>>> -       ldr     r0, =0x0ffffff          /* r0 <- Mask Bits*/
>>>> -       bic     r1, pc, r0              /* pc <- current addr of code */
>>>> -                                       /* r1 <- unmasked bits of pc */
>>>> -       ldr     r2, _TEXT_BASE          /* r2 <- original base addr in ram */
>>>> -       bic     r2, r2, r0              /* r2 <- unmasked bits of r2*/
>>>> -       cmp     r1, r2                  /* compare r1, r2 */
>>>> -       beq     1f                      /* r0 == r1 then skip sdram init */
>>>> -
>>>> -       /* init system clock */
>>>> -       bl      system_clock_init
>>>> -
>>>> -       /* Memory initialize */
>>>> -       bl      mem_ctrl_init
>>>> -
>>>> -1:
>>>> -       bl      tzpc_init
>>>> -       ldmia   r13!, {ip,pc}
>>>> -
>>>> -wakeup_reset:
>>>> -       bl      system_clock_init
>>>> -       bl      mem_ctrl_init
>>>> -       bl      tzpc_init
>>>> -
>>>> -exit_wakeup:
>>>> -       /* Load return address and jump to kernel */
>>>> -       ldr     r0, =(EXYNOS5_POWER_BASE + INFORM0_OFFSET)
>>>> -
>>>> -       /* r1 = physical address of exynos5_cpu_resume function*/
>>>> -       ldr     r1, [r0]
>>>> -
>>>> -       /* Jump to kernel */
>>>> -       mov     pc, r1
>>>> -       nop
>>>> -       nop
>>>> diff --git a/board/samsung/smdk5250/lowlevel_init.c b/board/samsung/smdk5250/lowlevel_init.c
>>>> new file mode 100644
>>>> index 0000000..22bdd2b
>>>> --- /dev/null
>>>> +++ b/board/samsung/smdk5250/lowlevel_init.c
>>>> @@ -0,0 +1,81 @@
>>>> +/*
>>>> + * Lowlevel setup for SMDK5250 board based on S5PC520
>>>> + *
>>>> + * Copyright (C) 2012 Samsung Electronics
>>>> + * 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
>>>> + */
>>>> +
>>>> +#include <common.h>
>>>> +#include <config.h>
>>>> +#include <asm/arch/cpu.h>
>>>> +#include <asm/arch/dmc.h>
>>>> +#include <asm/arch/power.h>
>>>> +#include <asm/arch/tzpc.h>
>>>> +#include <asm/arch/periph.h>
>>>> +#include <asm/arch/pinmux.h>
>>>> +#include "setup.h"
>>>> +
>>>> +/* These are the things we can do during low-level init */
>>>> +enum {
>>>> +       DO_WAKEUP       = 1 << 0,
>>>> +       DO_CLOCKS       = 1 << 1,
>>>> +       DO_MEM_RESET    = 1 << 2,
>>>> +       DO_UART         = 1 << 3,
>>>> +};
>>>> +
>>>> +int do_lowlevel_init(void)
>>>> +{
>>>> +       uint32_t reset_status;
>>>> +       int actions = 0;
>>>> +
>>>> +       arch_cpu_init();
>>>> +
>>>> +       reset_status = power_read_reset_status();
>>>> +
>>>> +       switch (reset_status) {
>>>> +       case EXYNOS_CHECK_SLEEP:
>>>> +               actions = DO_CLOCKS | DO_WAKEUP;
>>>> +               break;
>>>> +       case EXYNOS_CHECK_DIDLE:
>>>> +       case EXYNOS_CHECK_LPA:
>>>> +               actions = DO_WAKEUP;
>>>> +               break;
>>>> +       default:
>>>> +               /* This is a normal boot (not a wake from sleep) */
>>>> +               actions = DO_CLOCKS | DO_MEM_RESET | DO_UART;
>>>> +       }
>>>> +
>>>> +       if (actions & DO_CLOCKS)
>>>> +               system_clock_init();
>>>> +
>>>> +       if (actions & DO_UART) {
>>>> +               exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE);
>>>> +               serial_init();
>>>> +               timer_init();
>>>> +       }
>>>> +
>>>> +       if (actions & DO_CLOCKS) {
>>>> +               mem_ctrl_init(actions & DO_MEM_RESET);
>>>> +               tzpc_init();
>>>
>>> I think serial SPL support is coming later.
>> So you want to initialise  serial SPL support after mem_ctrl_init and tzpc_init?
>
> No, I meant earlier, but please ignore my comment, i was confused. At
> present we can't move it earlier because the clocks need to be started
> up, and that happens in a big monolithic operation.
>
> What you have here is fine.
>
>>>
>>>> +       }
>>>> +
>>>> +       return actions & DO_WAKEUP;
>>>> +}
>>>> diff --git a/board/samsung/smdk5250/setup.h b/board/samsung/smdk5250/setup.h
>>>> index a159601..f1d9f79 100644
>>>> --- a/board/samsung/smdk5250/setup.h
>>>> +++ b/board/samsung/smdk5250/setup.h
>>>> @@ -537,9 +537,11 @@ enum {
>>>>   *                     which the DMC uses to decide how to split a memory
>>>>   *                     chunk into smaller chunks to support concurrent
>>>>   *                     accesses; may vary across boards.
>>>> + * @param reset                Reset DDR PHY during initialization.
>>>>   * @return 0 if ok, SETUP_ERR_... if there is a problem
>>>>   */
>>>> -int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size);
>>>> +int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
>>>> +                       int reset);
>>>>
>>>>  /*
>>>>   * Configure ZQ I/O interface
>>>> @@ -587,8 +589,21 @@ void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc);
>>>>   */
>>>>  void update_reset_dll(struct exynos5_dmc *, enum ddr_mode);
>>>>
>>>> +/*
>>>> + * Memory initialization
>>>> + *
>>>> + * @param reset     Reset PHY during initialization.
>>>> + */
>>>> +void mem_ctrl_init(int reset);
>>>> +
>>>>  void sdelay(unsigned long);
>>>> -void mem_ctrl_init(void);
>>>>  void system_clock_init(void);
>>>>  void tzpc_init(void);
>>>> +
>>>> +/**
>>>> + * Init subsystems according to the reset status
>>>> + *
>>>> + * @return 0 for a normal boot, non-zero for a resume
>>>> + */
>>>> +int do_lowlevel_init(void);
>>>>  #endif
>>>> diff --git a/board/samsung/smdk5250/spl_boot.c b/board/samsung/smdk5250/spl_boot.c
>>>> index d8f3c1e..a1c8d3d 100644
>>>> --- a/board/samsung/smdk5250/spl_boot.c
>>>> +++ b/board/samsung/smdk5250/spl_boot.c
>>>> @@ -20,18 +20,16 @@
>>>>   * MA 02111-1307 USA
>>>>   */
>>>>
>>>> -#include<common.h>
>>>> -#include<config.h>
>>>> +#include <common.h>
>>>> +#include <config.h>
>>>> +#include <asm/arch/spl.h>
>>>> +#include <asm/arch/cpu.h>
>>>> +#include <asm/arch/power.h>
>>>> +#include "setup.h"
>>>>
>>>> -enum boot_mode {
>>>> -       BOOT_MODE_MMC = 4,
>>>> -       BOOT_MODE_SERIAL = 20,
>>>> -       /* Boot based on Operating Mode pin settings */
>>>> -       BOOT_MODE_OM = 32,
>>>> -       BOOT_MODE_USB,  /* Boot using USB download */
>>>> -};
>>>> +DECLARE_GLOBAL_DATA_PTR;
>>>>
>>>> -       typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst);
>>>> +typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst);
>>>
>>> What is happening with thsi file? I think there is another patch which
>>> changes things here.
>>>
>>>>
>>>>  /*
>>>>  * Copy U-boot from mmc to RAM:
>>>> @@ -62,15 +60,49 @@ void copy_uboot_to_ram(void)
>>>>         }
>>>>  }
>>>>
>>>> +void memzero(void *s, size_t n)
>>>> +{
>>>> +       char *ptr = s;
>>>> +       size_t i;
>>>> +
>>>> +       for (i = 0; i < n; i++)
>>>> +               *ptr++ = '\0';
>>>> +}
>>>> +
>>>> +/**
>>>> + * Set up the U-Boot global_data pointer
>>>> + *
>>>> + * This sets the address of the global data, and sets up basic values.
>>>> + *
>>>> + * @param gdp   Value to give to gd
>>>> + */
>>>> +static void setup_global_data(gd_t *gdp)
>>>> +{
>>>> +       gd = gdp;
>>>> +       memzero((void *)gd, sizeof(gd_t));
>>>> +       gd->flags |= GD_FLG_RELOC;
>>>> +       gd->baudrate = CONFIG_BAUDRATE;
>>>> +       gd->have_console = 1;
>>>> +}
>>>> +
>>>>  void board_init_f(unsigned long bootflag)
>>>>  {
>>>> +       __attribute__((aligned(8))) gd_t local_gd;
>>>>         __attribute__((noreturn)) void (*uboot)(void);
>>>> +
>>>> +       setup_global_data(&local_gd);
>>>> +
>>>> +       if (do_lowlevel_init())
>>>> +               power_exit_wakeup();
>>>> +
>>>>         copy_uboot_to_ram();
>>>>
>>>>         /* Jump to U-Boot image */
>>>>         uboot = (void *)CONFIG_SYS_TEXT_BASE;
>>>>         (*uboot)();
>>>> +
>>>>         /* Never returns Here */
>>>> +       panic("%s: u-boot jump failed", __func__);
>>>>  }
>>>>
>>>>  /* Place Holders */
>>>> @@ -83,3 +115,91 @@ void board_init_r(gd_t *id, ulong dest_addr)
>>>>  }
>>>>
>>>>  void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {}
>>>> +
>>>> +/*
>>>> + * The following functions are required when linking console library to SPL.
>>>> + *
>>>> + * Enabling UART in SPL u-boot requires console library. But some
>>>> + * functions we needed in the console library depends on a bunch
>>>> + * of library in libgeneric, like lib/ctype.o, lib/div64.o, lib/string.o,
>>>> + * and lib/vsprintf.o. Adding them makes the SPL u-boot too large and not
>>>> + * fit into the expected size.
>>>> + *
>>>> + * So we mock these functions in SPL, i.e. vsprintf(), panic(), etc.,
>>>> + * in order to cut its dependency.
>>>> + */
>>>> +static int _vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
>>>> +{
>>>> +       char *str = buf, *s;
>>>> +       char *end = str + size - 1;
>>>> +       ulong u;
>>>> +
>>>> +       if (size == 0)
>>>> +               return -1;
>>>> +
>>>> +       /*
>>>> +        * We won't implement all full functions of vsprintf().
>>>> +        * We only implement %s and %u, and ignore others and directly use
>>>> +        * the original format string as its result.
>>>> +        */
>>>> +
>>>> +       while (*fmt && (str < end)) {
>>>> +               if (*fmt != '%') {
>>>> +                       *str++ = *fmt++;
>>>> +                       continue;
>>>> +               }
>>>> +               fmt++;
>>>> +               switch (*fmt) {
>>>> +               case '%':
>>>> +                       *str++ = *fmt++;
>>>> +                       break;
>>>> +               case 's':
>>>> +                       fmt++;
>>>> +                       s = va_arg(args, char *);
>>>> +                       while (*s && (str < end))
>>>> +                               *str++ = *s++;
>>>> +                       break;
>>>> +               case 'u':
>>>> +                       fmt++;
>>>> +                       u = va_arg(args, ulong);
>>>> +                       s = simple_itoa(u);
>>>> +                               while (*s && (str < end))
>>>> +                                       *str++ = *s++;
>>>> +                               break;
>>>> +               default:
>>>> +                       /* Print the original string for unsupported formats */
>>>> +                       *str++ = '%';
>>>> +                       if  (str < end)
>>>> +                               *str++ = *fmt++;
>>>> +                       }
>>>> +               }
>>>> +       *str = '\0';
>>>> +       return str - buf;
>>>> +}
>>>> +
>>>> +/* Implement vsprintf in case someone doesn't have CONFIG_SYS_VSNPRINTF */
>>>> +int vsprintf(char *buf, const char *fmt, va_list args)
>>>> +{
>>>> +       return _vscnprintf(buf, CONFIG_SYS_PBSIZE, fmt, args);
>>>> +}
>>>
>>> This is ready for use by SPL serial support, right?
>> Yes it is.
>>>
>>>> +
>>>> +char *simple_itoa(ulong i)
>>>> +{
>>>> +       /* 21 digits plus null terminator, good for 64-bit or smaller ints */
>>>> +       static char local[22] __attribute__((section(".data")));
>>>> +       char *p = &local[21];
>>>> +
>>>> +       *p-- = '\0';
>>>> +       do {
>>>> +               *p-- = '0' + i % 10;
>>>> +               i /= 10;
>>>> +       } while (i > 0);
>>>> +       return p + 1;
>>>> +}
>>>> +
>>>> +void hang(void)
>>>> +{
>>>> +       puts("### ERROR ### Please RESET the board ###\n");
>>>> +       for (;;)
>>>> +               ;
>>>> +}
>>>> diff --git a/spl/Makefile b/spl/Makefile
>>>> index 6dbb105..3aab466 100644
>>>> --- a/spl/Makefile
>>>> +++ b/spl/Makefile
>>>> @@ -86,6 +86,10 @@ ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
>>>>  LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
>>>>  endif
>>>>
>>>> +ifneq ($(CONFIG_EXYNOS4)$(CONFIG_EXYNOS5),)
>>>> +LIBS-y += $(CPUDIR)/s5p-common/libs5p-common.o
>>>> +endif
>>>> +
>>>>  ifeq ($(SOC),tegra20)
>>>>  LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o
>>>>  LIBS-y += arch/$(ARCH)/cpu/tegra-common/libcputegra-common.o
>>>> --
>>>> 1.7.4.4
>>>>
>>>
>>> Regards,
>>> Simon
>>> _______________________________________________
>>> U-Boot mailing list
>>> U-Boot at lists.denx.de
>>> http://lists.denx.de/mailman/listinfo/u-boot
>>
>>
>>
>> --
>> Regards,
>> Rajeshwari Shinde



-- 
Regards,
Rajeshwari Shinde


More information about the U-Boot mailing list