[U-Boot] [PATCH 4/9] openrisc: Add library functions

Marek Vasut marek.vasut at gmail.com
Mon Nov 21 23:52:59 CET 2011


> Signed-off-by: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
> ---
>  arch/openrisc/lib/Makefile |   47 ++++++++++++
>  arch/openrisc/lib/board.c  |  175
> ++++++++++++++++++++++++++++++++++++++++++++ arch/openrisc/lib/bootm.c  | 
>  84 +++++++++++++++++++++
>  arch/openrisc/lib/timer.c  |  104 ++++++++++++++++++++++++++
>  4 files changed, 410 insertions(+), 0 deletions(-)
>  create mode 100644 arch/openrisc/lib/Makefile
>  create mode 100644 arch/openrisc/lib/board.c
>  create mode 100644 arch/openrisc/lib/bootm.c
>  create mode 100644 arch/openrisc/lib/timer.c

Timer support isn't a library function but a CPU function, so move it to 3/9.

> 
> diff --git a/arch/openrisc/lib/Makefile b/arch/openrisc/lib/Makefile
> new file mode 100644
> index 0000000..db3c657
> --- /dev/null
> +++ b/arch/openrisc/lib/Makefile
> @@ -0,0 +1,47 @@
> +#
> +# (C) Copyright 2003-2006
> +# Wolfgang Denk, DENX Software Engineering, wd at 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
> +#
> +
> +include $(TOPDIR)/config.mk
> +
> +LIB	= $(obj)lib$(ARCH).o
> +
> +SOBJS-y	+=
> +
> +COBJS-y	+= board.o
> +COBJS-y	+= bootm.o
> +COBJS-y	+= timer.o
> +
> +SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
> +OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
> +
> +$(LIB):	$(obj).depend $(OBJS)
> +	$(call cmd_link_o_target, $(OBJS))
> +
> +#########################################################################
> +
> +# defines $(obj).depend target
> +include $(SRCTREE)/rules.mk
> +
> +sinclude $(obj).depend
> +
> +#########################################################################
> diff --git a/arch/openrisc/lib/board.c b/arch/openrisc/lib/board.c
> new file mode 100644
> index 0000000..b033031
> --- /dev/null
> +++ b/arch/openrisc/lib/board.c
> @@ -0,0 +1,175 @@
> +/*
> + * (C) Copyright 2011
> + * Julius Baxter, julius at opencores.org
> + *
> + * (C) Copyright 2003, Psyent Corporation <www.psyent.com>
> + * Scott McNutt <smcnutt at psyent.com>
> + *
> + * (C) Copyright 2000-2002
> + * Wolfgang Denk, DENX Software Engineering, wd at 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
> + */
> +
> +#include <common.h>
> +#include <stdio_dev.h>
> +#include <watchdog.h>
> +#include <malloc.h>
> +#include <mmc.h>
> +#include <net.h>
> +#ifdef CONFIG_STATUS_LED
> +#include <status_led.h>
> +#endif
> +#ifdef CONFIG_CMD_NAND
> +#include <nand.h>	/* cannot even include nand.h if it isnt configured */
> +#endif
> +
> +#include <timestamp.h>
> +#include <version.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/*
> + * All attempts to come up with a "common" initialization sequence
> + * that works for all boards and architectures failed: some of the
> + * requirements are just _too_ different. To get rid of the resulting
> + * mess of board dependend #ifdef'ed code we now make the whole
> + * initialization sequence configurable to the user.
> + *
> + * The requirements for any new initalization function is simple: it
> + * receives a pointer to the "global data" structure as it's only
> + * argument, and returns an integer return code, where 0 means
> + * "continue" and != 0 means "fatal error, hang the system".
> + */
> +
> +extern int cache_init(void);
> +extern int timer_init(void);
> +
> +typedef int (init_fnc_t)(void);

What is this ?!

> +
> +/*
> + * Initialization sequence
> + */
> +
> +init_fnc_t *init_sequence[] = {
> +	cache_init,
> +	timer_init,		/* initialize timer */
> +	env_init,
> +	serial_init,
> +	console_init_f,
> +	display_options,
> +	checkcpu,
> +	checkboard,
> +	NULL,			/* Terminate this list */
> +};
> +
> +
> +/***********************************************************************/
> +void board_init(void)
> +{
> +	bd_t *bd;
> +	init_fnc_t **init_fnc_ptr;
> +
> +	gd = (gd_t *)CONFIG_SYS_GBL_DATA_ADDR;
> +
> +	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
> +
> +	gd->bd = (bd_t *)(gd+1);	/* At end of global data */
> +	gd->baudrate = CONFIG_BAUDRATE;
> +	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
> +
> +	bd = gd->bd;
> +	bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
> +	bd->bi_memsize = CONFIG_SYS_SDRAM_SIZE;
> +#ifndef CONFIG_SYS_NO_FLASH
> +	bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
> +#endif
> +#if	defined(CONFIG_SYS_SRAM_BASE) && defined(CONFIG_SYS_SRAM_SIZE)
> +	bd->bi_sramstart = CONFIG_SYS_SRAM_BASE;
> +	bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE;
> +#endif
> +	bd->bi_baudrate = CONFIG_BAUDRATE;
> +
> +	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
> +		WATCHDOG_RESET();
> +		if ((*init_fnc_ptr)() != 0)
> +			hang();
> +	}
> +
> +	WATCHDOG_RESET();
> +
> +	/* The Malloc area is immediately below the monitor copy in RAM */
> +	mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);
> +
> +#ifndef CONFIG_SYS_NO_FLASH
> +	WATCHDOG_RESET();
> +	bd->bi_flashsize = flash_init();
> +#endif
> +
> +#ifdef CONFIG_CMD_NAND
> +	puts("NAND:  ");
> +	nand_init();
> +#endif
> +
> +#ifdef CONFIG_GENERIC_MMC
> +	puts("MMC:   ");
> +	mmc_initialize(bd);
> +#endif
> +
> +	WATCHDOG_RESET();
> +	env_relocate();
> +
> +	WATCHDOG_RESET();
> +	stdio_init();
> +	jumptable_init();
> +	console_init_r();
> +
> +	WATCHDOG_RESET();
> +	interrupt_init();
> +
> +#if defined(CONFIG_BOARD_LATE_INIT)
> +	board_late_init();
> +#endif
> +
> +#if defined(CONFIG_CMD_NET)
> +#if defined(CONFIG_NET_MULTI)
> +	puts("NET:   ");
> +#endif
> +	eth_initialize(bd);
> +#endif
> +
> +	/* main_loop */
> +	for (;;) {
> +		WATCHDOG_RESET();
> +		main_loop();
> +	}
> +}
> +
> +
> +/***********************************************************************/
> +
> +void hang(void)
> +{
> +	disable_interrupts();
> +	puts("### ERROR ### Please reset board ###\n");
> +	asm("l.nop 0x1"); /* Kill any simulation */

Simulation? Oh, it's an FPGA based CPU or what?

> +	for (;;)
> +		;
> +}
> diff --git a/arch/openrisc/lib/bootm.c b/arch/openrisc/lib/bootm.c
> new file mode 100644
> index 0000000..2c5d9ae
> --- /dev/null
> +++ b/arch/openrisc/lib/bootm.c
> @@ -0,0 +1,84 @@
> +/*
> + * (C) Copyright 2011 Stefan Kristiansson
> <stefan.kristiansson at saunalahti.fi> + *
> + * Based on microblaze implementation by:
> + * (C) Copyright 2007 Michal Simek
> + * (C) Copyright 2004 Atmark Techno, Inc.
> + *
> + * Michal  SIMEK <monstr at monstr.eu>
> + * Yasushi SHOJI <yashi at atmark-techno.com>
> + *
> + * 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 <command.h>
> +#include <image.h>
> +#include <u-boot/zlib.h>
> +#include <asm/byteorder.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int do_bootm_linux(int flag, int argc, char * const argv[],
> +			bootm_headers_t *images)
> +{
> +	void	(*kernel) (unsigned int);
> +	ulong	rd_data_start, rd_data_end;
> +
> +	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
> +		return 1;
> +
> +	int	ret;
> +
> +	char	*of_flat_tree = NULL;
> +#if defined(CONFIG_OF_LIBFDT)
> +	/* did generic code already find a device tree? */
> +	if (images->ft_len)
> +		of_flat_tree = images->ft_addr;
> +#endif
> +
> +	kernel = (void (*)(unsigned int))images->ep;
> +
> +	/* find ramdisk */
> +	ret = boot_get_ramdisk(argc, argv, images, IH_ARCH_OPENRISC,
> +			&rd_data_start, &rd_data_end);
> +	if (ret)
> +		return 1;
> +
> +	show_boot_progress(15);
> +
> +	if (!of_flat_tree && argc > 3)
> +		of_flat_tree = (char *)simple_strtoul(argv[3], NULL, 16);
> +#ifdef DEBUG
> +	printf("## Transferring control to Linux (at address 0x%08lx) " \
> +				"ramdisk 0x%08lx, FDT 0x%08lx...\n",
> +		(ulong) kernel, rd_data_start, (ulong) of_flat_tree);
> +#endif
> +	if (dcache_status() || icache_status())
> +		flush_cache((ulong)kernel, max(checkdcache(), checkicache()));
> +
> +	/*
> +	 * Linux Kernel Parameters (passing device tree):
> +	 * r3: pointer to the fdt, followed by the board info data
> +	 */
> +	kernel((unsigned int) of_flat_tree);
> +	/* does not return */
> +
> +	return 1;
> +}
> diff --git a/arch/openrisc/lib/timer.c b/arch/openrisc/lib/timer.c
> new file mode 100644
> index 0000000..52d2be9
> --- /dev/null
> +++ b/arch/openrisc/lib/timer.c
> @@ -0,0 +1,104 @@
> +/*
> + * (C) Copyright 2011, Stefan Kristiansson
> <stefan.kristiansson at saunalahti.fi> + * (C) Copyright 2011, Julius Baxter
> <julius at opencores.org>
> + * (C) Copyright 2003
> + * Wolfgang Denk, DENX Software Engineering, wd at 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
> + */
> +
> +#include <asm/system.h>
> +#include <asm/openrisc_exc.h>
> +#include <common.h>
> +
> +static ulong timestamp;
> +
> +/* how many counter cycles in a jiffy */
> +#define TIMER_COUNTER_CYCLES 
> (CONFIG_SYS_CLK_FREQ/CONFIG_SYS_OPENRISC_TMR_HZ) +/* how many ms elapses
> between each timer interrupt */
> +#define TIMER_TIMESTAMP_INC   (1000/CONFIG_SYS_OPENRISC_TMR_HZ)
> +/* how many cycles per ms */
> +#define TIMER_CYCLES_MS       (CONFIG_SYS_CLK_FREQ/1000)
> +/* how many cycles per us */
> +#define TIMER_CYCLES_US       (CONFIG_SYS_CLK_FREQ/1000000uL)
> +
> +void timer_isr(void)
> +{
> +	timestamp += TIMER_TIMESTAMP_INC;
> +	mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT |
> +		(TIMER_COUNTER_CYCLES & SPR_TTMR_TP));
> +}
> +
> +int timer_init(void)
> +{
> +	/* Install timer exception handler */
> +	exception_install_handler(EXC_TIMER, timer_isr);
> +
> +	/* Set up the timer for the first expiration. */
> +	timestamp = 0;
> +
> +	mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT |
> +		(TIMER_COUNTER_CYCLES & SPR_TTMR_TP));
> +
> +	/* Enable tick timer exception in supervisor register */
> +	mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_TEE);
> +
> +	return 0;
> +}
> +
> +void reset_timer(void)
> +{
> +	timestamp = 0;
> +
> +	mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT |
> +		(TIMER_COUNTER_CYCLES & SPR_TTMR_TP));
> +}
> +
> +/*
> + * The timer value in ms is calculated by taking the
> + * value accumulated by full timer revolutions plus the value
> + * accumulated in this period
> + */
> +ulong get_timer(ulong base)
> +{
> +	return timestamp + mfspr(SPR_TTCR)/TIMER_CYCLES_MS - base;
> +}
> +
> +void set_timer(ulong t)
> +{
> +	reset_timer();
> +	timestamp = t;
> +}
> +
> +void __udelay(ulong usec)
> +{
> +	ulong elapsed = 0;
> +	ulong tick;
> +	ulong last_tick;
> +
> +	last_tick = mfspr(SPR_TTCR);
> +	while ((elapsed / TIMER_CYCLES_US) < usec) {
> +		tick = mfspr(SPR_TTCR);
> +		if (tick >= last_tick)
> +			elapsed += (tick - last_tick);
> +		else
> +			elapsed += TIMER_COUNTER_CYCLES - (last_tick - tick);
> +		last_tick = tick;
> +	}
> +}

I'm not sure if this conforms with current timer api, can you cross-check with 
arch/arm/arm926ejs/mx28/timer.c ? That's the latest addition and should conform.

M


More information about the U-Boot mailing list