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 <s...@chromium.org> wrote: > Hi Rajeshwari, > > On Fri, Jan 11, 2013 at 2:43 AM, Rajeshwari Birje > <rajeshwari.bi...@gmail.com> wrote: >> Hi Simon, >> >> Thank you for comments. >> >> On Thu, Jan 10, 2013 at 11:04 PM, Simon Glass <s...@chromium.org> wrote: >>> Hi Rajeshwari, >>> >>> On Mon, Jan 7, 2013 at 5:08 AM, Rajeshwari Shinde >>> <rajeshwar...@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 <rajeshwar...@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@lists.denx.de >>> http://lists.denx.de/mailman/listinfo/u-boot >> >> >> >> -- >> Regards, >> Rajeshwari Shinde -- Regards, Rajeshwari Shinde _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot