openrisc: Add library functions

Signed-off-by: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
This commit is contained in:
Stefan Kristiansson 2011-11-26 19:04:52 +00:00 committed by Wolfgang Denk
parent 272f84bbdf
commit e0f1fd4c82
4 changed files with 403 additions and 0 deletions

View File

@ -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
#########################################################################

168
arch/openrisc/lib/board.c Normal file
View File

@ -0,0 +1,168 @@
/*
* (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);
/*
* Initialization sequence
*/
static int (* const init_sequence[])(void) = {
cache_init,
timer_init, /* initialize timer */
env_init,
serial_init,
console_init_f,
display_options,
checkcpu,
checkboard,
};
/***********************************************************************/
void board_init(void)
{
bd_t *bd;
int i;
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 (i = 0; i < ARRAY_SIZE(init_sequence); i++) {
WATCHDOG_RESET();
if (init_sequence[i]())
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)
puts("NET: ");
eth_initialize(bd);
#endif
/* main_loop */
for (;;) {
WATCHDOG_RESET();
main_loop();
}
}
/***********************************************************************/
void hang(void)
{
disable_interrupts();
puts("### ERROR ### Please reset board ###\n");
for (;;)
;
}

84
arch/openrisc/lib/bootm.c Normal file
View File

@ -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;
}

104
arch/openrisc/lib/timer.c Normal file
View File

@ -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 <common.h>
#include <asm/system.h>
#include <asm/openrisc_exc.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;
}
}