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

login
register
mail settings
Submitter Stefan Kristiansson
Date Nov. 19, 2011, 5:21 a.m.
Message ID <1321680098-31121-5-git-send-email-stefan.kristiansson@saunalahti.fi>
Download mbox | patch
Permalink /patch/126523/
State Superseded
Headers show

Comments

Stefan Kristiansson - Nov. 19, 2011, 5:21 a.m.
Signed-off-by: Stefan Kristiansson <stefan.kristiansson@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
Mike Frysinger - Nov. 19, 2011, 6:04 a.m.
On Saturday 19 November 2011 00:21:33 Stefan Kristiansson wrote:
> --- /dev/null
> +++ b/arch/openrisc/lib/board.c
>
> +extern int timer_init(void);

common.h already provides this.  delete this line.

> +init_fnc_t *init_sequence[] = {

static init_fnc_t * const init_sequence[] = {

> +	NULL,			/* Terminate this list */

use ARRAY_SIZE(init_sequence) and you don't need the NULL pointer

> +#if defined(CONFIG_NET_MULTI)

this define no longer exists, so delete any references to it

> --- /dev/null
> +++ b/arch/openrisc/lib/timer.c
>
> +#include <asm/system.h>
> +#include <asm/openrisc_exc.h>
> +#include <common.h>

asm/ after non-asm/ includes
-mike
Marek Vasut - Nov. 21, 2011, 10:52 p.m.
> Signed-off-by: Stefan Kristiansson <stefan.kristiansson@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@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@opencores.org
> + *
> + * (C) Copyright 2003, Psyent Corporation <www.psyent.com>
> + * Scott McNutt <smcnutt@psyent.com>
> + *
> + * (C) Copyright 2000-2002
> + * 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
> + */
> +
> +#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@saunalahti.fi> + *
> + * Based on microblaze implementation by:
> + * (C) Copyright 2007 Michal Simek
> + * (C) Copyright 2004 Atmark Techno, Inc.
> + *
> + * Michal  SIMEK <monstr@monstr.eu>
> + * Yasushi SHOJI <yashi@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@saunalahti.fi> + * (C) Copyright 2011, Julius Baxter
> <julius@opencores.org>
> + * (C) Copyright 2003
> + * 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
> + */
> +
> +#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
Stefan Kristiansson - Nov. 22, 2011, 4:19 a.m.
On Mon, Nov 21, 2011 at 11:52:59PM +0100, Marek Vasut wrote:
> >  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.
> 

I never quite worked out where the timer functions belongs,
some have them in interupts.c and some in their own file.
Some have them cpu/ and some in lib/

> > +	asm("l.nop 0x1"); /* Kill any simulation */
> 
> Simulation? Oh, it's an FPGA based CPU or what?
> 

Well, yes, FPGAs are probably the most common case, but also ASIC
implementations exists.
The extra argument to the nop instruction is ignored by hardware,
but have special meanings when ran in simulation.

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

In my opinion it seems to do the same thing as that, what exactly did you
find non-conforming?

Stefan
Marek Vasut - Nov. 22, 2011, 4:48 a.m.
> On Mon, Nov 21, 2011 at 11:52:59PM +0100, Marek Vasut wrote:
> > >  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.
> 
> I never quite worked out where the timer functions belongs,
> some have them in interupts.c and some in their own file.
> Some have them cpu/ and some in lib/
> 
> > > +	asm("l.nop 0x1"); /* Kill any simulation */
> > 
> > Simulation? Oh, it's an FPGA based CPU or what?
> 
> Well, yes, FPGAs are probably the most common case, but also ASIC
> implementations exists.
> The extra argument to the nop instruction is ignored by hardware,
> but have special meanings when ran in simulation.

Hmm ... I'm not quite sure this is right.

> 
> > > +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.
> 
> In my opinion it seems to do the same thing as that, what exactly did you
> find non-conforming?

I was just curious if it's ok. If it is, so be it.
> 
> Stefan
Stefan Kristiansson - Nov. 22, 2011, 6 a.m.
On Tue, Nov 22, 2011 at 05:48:53AM +0100, Marek Vasut wrote:
> > > > +	asm("l.nop 0x1"); /* Kill any simulation */
> > > 
> > > Simulation? Oh, it's an FPGA based CPU or what?
> > 
> > Well, yes, FPGAs are probably the most common case, but also ASIC
> > implementations exists.
> > The extra argument to the nop instruction is ignored by hardware,
> > but have special meanings when ran in simulation.
> 
> Hmm ... I'm not quite sure this is right.
> 

It's not important to have there, I'll just remove it.

Stefan
Marek Vasut - Nov. 22, 2011, 2:10 p.m.
> On Tue, Nov 22, 2011 at 05:48:53AM +0100, Marek Vasut wrote:
> > > > > +	asm("l.nop 0x1"); /* Kill any simulation */
> > > > 
> > > > Simulation? Oh, it's an FPGA based CPU or what?
> > > 
> > > Well, yes, FPGAs are probably the most common case, but also ASIC
> > > implementations exists.
> > > The extra argument to the nop instruction is ignored by hardware,
> > > but have special meanings when ran in simulation.
> > 
> > Hmm ... I'm not quite sure this is right.
> 
> It's not important to have there, I'll just remove it.


No, no, just wait for other people opinion here.

Patch

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@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@opencores.org
+ *
+ * (C) Copyright 2003, Psyent Corporation <www.psyent.com>
+ * Scott McNutt <smcnutt@psyent.com>
+ *
+ * (C) Copyright 2000-2002
+ * 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
+ */
+
+#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);
+
+/*
+ * 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 */
+	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@saunalahti.fi>
+ *
+ * Based on microblaze implementation by:
+ * (C) Copyright 2007 Michal Simek
+ * (C) Copyright 2004 Atmark Techno, Inc.
+ *
+ * Michal  SIMEK <monstr@monstr.eu>
+ * Yasushi SHOJI <yashi@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@saunalahti.fi>
+ * (C) Copyright 2011, Julius Baxter <julius@opencores.org>
+ * (C) Copyright 2003
+ * 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
+ */
+
+#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;
+	}
+}