openrisc: Add library functions
Signed-off-by: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
This commit is contained in:
parent
272f84bbdf
commit
e0f1fd4c82
47
arch/openrisc/lib/Makefile
Normal file
47
arch/openrisc/lib/Makefile
Normal 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
168
arch/openrisc/lib/board.c
Normal 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
84
arch/openrisc/lib/bootm.c
Normal 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
104
arch/openrisc/lib/timer.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user