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

Minkyu Kang mk7.kang at samsung.com
Fri Jan 11 08:54:25 CET 2013


Dear Rajeshwari,

On 07/01/13 22:08, Rajeshwari Shinde 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.
> 
> 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 +++++++++++++++++
>  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

Is it SMDK5250 specific?

> +ifdef CONFIG_SPL
> +COBJS  += lowlevel.o

It's a SOBJS.

> +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

please fix this comment.
Maybe this file is not a board specific.

> + *
> + * 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/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();
> +	}
> +
> +	return actions & DO_WAKEUP;
> +}
> 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);
>  
>  /*
>  * 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++;
> +			}
> +		}

indentation error.

> +	*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);
> +}
> +
> +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 (;;)
> +		;
> +}

Thanks,
Minkyu Kang.



More information about the U-Boot mailing list