From 0b135cfc2e524dc249b75057b55dd4cc09842e27 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Sun, 13 May 2007 20:58:00 +0900 Subject: sh: First support code of SuperH. Signed-off-by: Nobuhiro Iwamatsu --- lib_sh/Makefile | 42 ++++++++++++++ lib_sh/board.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib_sh/sh_linux.c | 74 +++++++++++++++++++++++++ lib_sh/time.c | 76 +++++++++++++++++++++++++ 4 files changed, 355 insertions(+) create mode 100644 lib_sh/Makefile create mode 100644 lib_sh/board.c create mode 100644 lib_sh/sh_linux.c create mode 100644 lib_sh/time.c (limited to 'lib_sh') diff --git a/lib_sh/Makefile b/lib_sh/Makefile new file mode 100644 index 000000000..c84276af8 --- /dev/null +++ b/lib_sh/Makefile @@ -0,0 +1,42 @@ +# +# Copyright (c) 2007 +# Nobuhiro Iwamatsu +# +# 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).a + +SOBJS = + +COBJS = board.o sh_linux.o # time.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/lib_sh/board.c b/lib_sh/board.c new file mode 100644 index 000000000..c3f846257 --- /dev/null +++ b/lib_sh/board.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2007 + * Nobuhiro Iwamatsu + * + * 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 +#include +#include +#include +#include +#include +#include + +extern void malloc_bin_reloc (void); +extern int cpu_init(void); +extern int board_init(void); +extern int dram_init(void); +extern int watchdog_init(void); +extern int timer_init(void); + +const char version_string[] = U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")"; + +unsigned long monitor_flash_len = CFG_MONITOR_LEN; + +static unsigned long mem_malloc_start; +static unsigned long mem_malloc_end; +static unsigned long mem_malloc_brk; + +static void mem_malloc_init (void) +{ + + mem_malloc_start = (TEXT_BASE - CFG_GBL_DATA_SIZE - CFG_MALLOC_LEN); + mem_malloc_end = (mem_malloc_start + CFG_MALLOC_LEN - 16); + mem_malloc_brk = mem_malloc_start; + memset ((void *) mem_malloc_start, 0, + (mem_malloc_end - mem_malloc_start)); +} + +void *sbrk (ptrdiff_t increment) +{ + unsigned long old = mem_malloc_brk; + unsigned long new = old + increment; + + if ((new < mem_malloc_start) || + (new > mem_malloc_end)) { + return NULL; + } + + mem_malloc_brk = new; + return (void *) old; +} + +typedef int (init_fnc_t) (void); + +init_fnc_t *init_sequence[] = +{ + cpu_init, /* basic cpu dependent setup */ + board_init, /* basic board dependent setup */ + interrupt_init, /* set up exceptions */ + env_init, /* event init */ + serial_init, /* SCIF init */ + watchdog_init, + console_init_f, + display_options, + checkcpu, + checkboard, + dram_init, /* SDRAM init */ + NULL /* Terminate this list */ +}; + +void sh_generic_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + bd_t *bd; + init_fnc_t **init_fnc_ptr; + char *s, *e; + int i; + + memset (gd, 0, CFG_GBL_DATA_SIZE); + + gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ + + 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 = CFG_SDRAM_BASE; + bd->bi_memsize = CFG_SDRAM_SIZE; + bd->bi_flashstart = CFG_FLASH_BASE; +#if defined(CFG_SRAM_BASE) && defined(CFG_SRAM_SIZE) + bd->bi_sramstart= CFG_SRAM_BASE; + bd->bi_sramsize = CFG_SRAM_SIZE; +#endif + bd->bi_baudrate = CONFIG_BAUDRATE; + + for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { + if ((*init_fnc_ptr) () != 0) { + hang(); + } + } + + timer_init(); + + /* flash_init need timer_init().(TMU) */ + bd->bi_flashsize = flash_init(); + printf("FLASH: %dMB\n", bd->bi_flashsize / (1024*1024)); + + mem_malloc_init(); + malloc_bin_reloc(); + env_relocate(); + +#if (CONFIG_COMMANDS & CFG_CMD_NET) + bd->bi_ip_addr = getenv_IPaddr ("ipaddr"); + s = getenv ("ethaddr"); + for (i = 0; i < 6; ++i) { + bd->bi_enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0; + if (s) s = (*e) ? e + 1 : e; + } +#endif + devices_init(); + jumptable_init(); + console_init_r(); + interrupt_init(); +#ifdef BOARD_LATE_INIT + board_late_init (); +#endif +#if (CONFIG_COMMANDS & CFG_CMD_NET) +#if defined(CONFIG_NET_MULTI) + puts ("Net: "); +#endif + eth_initialize(gd->bd); +#endif + while (1) { + main_loop(); + } +} + + +/***********************************************************************/ + +void hang (void) +{ + puts ("Board ERROR \n"); + for (;;); +} diff --git a/lib_sh/sh_linux.c b/lib_sh/sh_linux.c new file mode 100644 index 000000000..7237ab338 --- /dev/null +++ b/lib_sh/sh_linux.c @@ -0,0 +1,74 @@ +/* + * (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 +#include +#include + +extern image_header_t header; /* common/cmd_bootm.c */ + +/* The SH kernel reads arguments from the empty zero page at location + * 0 at the start of SDRAM. The following are copied from + * arch/sh/kernel/setup.c and may require tweaking if the kernel sources + * change. + */ +#define PARAM ((unsigned char *)CFG_SDRAM_BASE + 0x1000) + +#define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000)) +#define RAMDISK_FLAGS (*(unsigned long *) (PARAM+0x004)) +#define ORIG_ROOT_DEV (*(unsigned long *) (PARAM+0x008)) +#define LOADER_TYPE (*(unsigned long *) (PARAM+0x00c)) +#define INITRD_START (*(unsigned long *) (PARAM+0x010)) +#define INITRD_SIZE (*(unsigned long *) (PARAM+0x014)) +/* ... */ +#define COMMAND_LINE ((char *) (PARAM+0x100)) + +#define RAMDISK_IMAGE_START_MASK 0x07FF + +#ifdef CFG_DEBUG +static void hexdump (unsigned char *buf, int len) +{ + int i; + + for (i = 0; i < len; i++) { + if ((i % 16) == 0) + printf ("%s%08x: ", i ? "\n" : "", (unsigned int) &buf[i]); + printf ("%02x ", buf[i]); + } + printf ("\n"); +} +#endif + +void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + ulong addr, ulong *len_ptr, int verify) +{ + image_header_t *hdr = &header; + char *bootargs = getenv("bootargs"); + void (*kernel) (void) = (void (*)(void)) ntohl (hdr->ih_ep); + + /* Setup parameters */ + memset(PARAM, 0, 0x1000); /* Clear zero page */ + strcpy(COMMAND_LINE, bootargs); + kernel(); +} + diff --git a/lib_sh/time.c b/lib_sh/time.c new file mode 100644 index 000000000..362013682 --- /dev/null +++ b/lib_sh/time.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2007 + * Nobuhiro Iwamatsu + * + * 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 +#include + +static void tmu_timer_start (unsigned int timer) +{ + if (timer > 2) + return; + + *((volatile unsigned char *) TSTR0) |= (1 << timer); +} + +int timer_init (void) +{ + *(volatile u16 *)TCR0 = 0; + + tmu_timer_start (0); + return 0; +} + +unsigned long long get_ticks (void) +{ + return (0 - *((volatile unsigned int *) TCNT0)); +} + +unsigned long get_timer (unsigned long base) +{ + return ((0 - *((volatile unsigned int *) TCNT0)) - base); +} + +void set_timer (unsigned long t) +{ + *((volatile unsigned int *) TCNT0) = (0 - t); +} + +void reset_timer (void) +{ + set_timer (0); +} + +void udelay (unsigned long usec) +{ + unsigned int start = get_timer (0); + unsigned int end = start + (usec * ((CFG_HZ + 500000) / 1000000)); + + while (get_timer (0) < end) + continue; +} + +unsigned long get_tbclk (void) +{ + return CFG_HZ; +} + -- cgit v1.2.3