[U-Boot] [PATCH v6 08/13] nds32/lib: add generic funcs in NDS32 lib

Macpaul Lin macpaul at andestech.com
Thu Mar 24 13:28:02 CET 2011


Add Makefile, board.c, interrupts.c and bootm.c functions
to nds32 architecture.

Signed-off-by: Macpaul Lin <macpaul at andestech.com>
---
Changes for v1-v4:
  - code clean up and formatting style.

Changes for v5-v6
  - board.c
   - Do some clean up and add code
   - Remove display banner which hasn't support.
   - Add ftpmu010 related power management unit code.
   - Remove useless LED related code.
   - Move SDRAM init to board sepecific files. (ex. adp-ag101.c)
   - Remove CONFIG_SOFT_I2C which hasn't been support.
   - Remove CONFIG_FSL_ESDHC which hasn't been support.
   - cleanup.

 arch/nds32/lib/Makefile     |   52 +++++++
 arch/nds32/lib/board.c      |  351 
+++++++++++++++++++++++++++++++++++++++++++
 arch/nds32/lib/bootm.c      |  239 +++++++++++++++++++++++++++++
 arch/nds32/lib/interrupts.c |  126 ++++++++++++++++
 4 files changed, 768 insertions(+), 0 deletions(-)
 create mode 100644 arch/nds32/lib/Makefile
 create mode 100644 arch/nds32/lib/board.c
 create mode 100644 arch/nds32/lib/bootm.c
 create mode 100644 arch/nds32/lib/interrupts.c

diff --git a/arch/nds32/lib/Makefile b/arch/nds32/lib/Makefile
new file mode 100644
index 0000000..eca4324
--- /dev/null
+++ b/arch/nds32/lib/Makefile
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# Copyright (C) 2011 Andes Technology Corporation
+# Shawn Lin, Andes Technology Corporation <nobuhiro at andestech.com>
+# Macpaul Lin, Andes Technology Corporation <macpaul at andestech.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 $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(ARCH).o
+
+OBJS	:= board.o bootm.o interrupts.o
+
+all:	$(LIB)
+
+$(LIB):	$(OBJS) $(SOBJS)
+	$(AR) crv $@ $^
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/nds32/lib/board.c b/arch/nds32/lib/board.c
new file mode 100644
index 0000000..8776b04
--- /dev/null
+++ b/arch/nds32/lib/board.c
@@ -0,0 +1,351 @@
+/*
+ * (C) Copyright 2002-2006
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * Copyright (C) 2011 Andes Technology Corporation
+ * Shawn Lin, Andes Technology Corporation <nobuhiro at andestech.com>
+ * Macpaul Lin, Andes Technology Corporation <macpaul at andestech.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 <malloc.h>
+#include <stdio_dev.h>
+#include <timestamp.h>
+#include <version.h>
+#include <net.h>
+#include <serial.h>
+#include <nand.h>
+#include <onenand_uboot.h>
+#include <mmc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+extern ulong __bss_end;
+ulong monitor_flash_len;
+
+#ifndef CONFIG_IDENT_STRING
+#define CONFIG_IDENT_STRING ""
+#endif
+
+const char version_string[] =
+	U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME 
")"CONFIG_IDENT_STRING;
+
+/*
+ * Init Utilities
+ */
+
+#if !defined(CONFIG_BAUDRATE)
+#define CONFIG_BAUDRATE 38400
+#endif
+static int init_baudrate (void)
+{
+	char tmp[64];	/* long enough for environment variables */
+	int i = getenv_f("baudrate", tmp, sizeof (tmp));
+
+	gd->bd->bi_baudrate = gd->baudrate = (i > 0)
+			? (int) simple_strtoul (tmp, NULL, 10)
+			: CONFIG_BAUDRATE;
+
+	return(0);
+}
+
+/*
+ * WARNING: this code looks "cleaner" than the PowerPC version, but
+ * has the disadvantage that you either get nothing, or everything.
+ * On PowerPC, you might see "DRAM: " before the system hangs - which
+ * gives a simple yet clear indication which part of the
+ * initialization if failing.
+ */
+static int display_dram_config (void)
+{
+	int i;
+
+#ifdef DEBUG
+	puts("RAM Configuration:\n");
+
+	for(i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
+		printf("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
+		print_size(gd->bd->bi_dram[i].size, "\n");
+	}
+#else
+	ulong size = 0;
+
+	for (i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
+		size += gd->bd->bi_dram[i].size;
+	}
+	puts("DRAM:  ");
+	print_size(size, "\n");
+#endif
+
+	return(0);
+}
+
+#ifndef CONFIG_SYS_NO_FLASH
+static void display_flash_config (ulong size)
+{
+	puts("Flash: ");
+	print_size(size, "\n");
+}
+#endif /* CONFIG_SYS_NO_FLASH */
+
+#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
+#include <pci.h>
+static int nds32_pci_init(void)
+{
+	pci_init();
+	return 0;
+}
+#endif /* CONFIG_CMD_PCI || CONFIG_PCI */
+
+#if defined(CONFIG_PMU) || defined (CONFIG_PCU)
+static int pmu_init(void)
+{
+#if defined(CONFIG_FTPMU010_POWER)
+#ifdef __NDS32_N1213_43U1H__	/* AG101: internal definition in toolchain 
*/
+	ftpmu010_sdram_clk_disable(CONFIG_SYS_FTPMU010_PDLLCR0_HCLKOUTDIS);
+	ftpmu010_mfpsr_select_dev(FTPMU010_MFPSR_AC97CLKSEL);
+	ftpmu010_sdramhtc_set(CONFIG_SYS_FTPMU010_SDRAMHTC);
+#endif	/* __NDS32_N1213_43U1H__ */
+#endif
+	return 0;
+}
+#endif
+
+/*
+ * Breathe some life into the board...
+ *
+ * Initialize a serial port as console, and carry out some hardware
+ * tests.
+ *
+ * The first part of initialization is running from Flash memory;
+ * its main purpose is to initialize the RAM so that we
+ * can relocate the monitor code to RAM.
+ */
+
+/*
+ * 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 dependent #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".
+ */
+typedef int (init_fnc_t)(void);
+
+int print_cpuinfo(void);
+
+init_fnc_t *init_sequence[] = {
+#if defined(CONFIG_ARCH_CPU_INIT)
+	arch_cpu_init,		/* basic arch cpu dependent setup */
+#endif
+#if defined(CONFIG_PMU) || defined (CONFIG_PCU)
+	pmu_init,
+#endif
+	board_init,		/* basic board dependent setup */
+#if defined(CONFIG_USE_IRQ)
+	interrupt_init,		/* set up exceptions */
+#endif
+	timer_init,		/* initialize timer */
+	env_init,		/* initialize environment */
+	init_baudrate,		/* initialze baudrate settings */
+	serial_init,		/* serial communications setup */
+	console_init_f,		/* stage 1 init of console */
+#if defined(CONFIG_DISPLAY_CPUINFO)
+	print_cpuinfo,		/* display cpu info (and speed) */
+#endif
+#if defined(CONFIG_DISPLAY_BOARDINFO)
+	checkboard,		/* display board info */
+#endif
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+	init_func_i2c,
+#endif
+	dram_init,		/* configure available RAM banks */
+#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
+	nds32_pci_init,
+#endif
+	display_dram_config,
+	NULL,
+};
+
+void start_andesboot (void)
+{
+	init_fnc_t **init_fnc_ptr;
+	char *s;
+#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
+	unsigned long addr;
+#endif
+
+	/* Pointer is writable since we allocated a register for it */
+	gd = (gd_t*)(_andesboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));
+	/* compiler optimization barrier needed for GCC >= 3.4 */
+	__asm__ __volatile__("": : :"memory");
+
+	memset((void*)gd, 0, sizeof (gd_t));
+	gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
+	memset(gd->bd, 0, sizeof (bd_t));
+
+	gd->flags |= GD_FLG_RELOC;
+
+	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
+		if ((*init_fnc_ptr)() != 0) {
+			hang();
+		}
+	}
+
+	/* andesboot_start is defined in the board-specific linker script */
+	mem_malloc_init(_andesboot_start - CONFIG_SYS_MALLOC_LEN,
+			CONFIG_SYS_MALLOC_LEN);
+
+#ifndef CONFIG_SYS_NO_FLASH
+	/* configure available FLASH banks */
+	gd->bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
+	gd->bd->bi_flashsize = flash_init();
+	gd->bd->bi_flashoffset = CONFIG_SYS_FLASH_BASE + gd->bd->bi_flashsize;
+
+	if (gd->bd->bi_flashsize)
+			display_flash_config(gd->bd->bi_flashsize);
+#endif /* CONFIG_SYS_NO_FLASH */
+
+#ifdef CONFIG_VFD
+#	ifndef PAGE_SIZE
+#	  define PAGE_SIZE 4096
+#	endif
+	/*
+	 * reserve memory for VFD display (always full pages)
+	 */
+	/* bss_end is defined in the board-specific linker script */
+	addr = (__bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+	vfd_setmem(addr);
+	gd->fb_base = addr;
+#endif /* CONFIG_VFD */
+
+#ifdef CONFIG_LCD
+	/* board init may have inited fb_base */
+	if (!gd->fb_base) {
+#		ifndef PAGE_SIZE
+#		  define PAGE_SIZE 4096
+#		endif
+		/*
+		 * reserve memory for LCD display (always full pages)
+		 */
+		/* bss_end is defined in the board-specific linker script */
+		addr = (__bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+		lcd_setmem(addr);
+		gd->fb_base = addr;
+	}
+#endif /* CONFIG_LCD */
+
+#if defined(CONFIG_CMD_NAND)
+	puts("NAND:  ");
+	nand_init();		/* go init the NAND */
+#endif
+
+#if defined(CONFIG_CMD_ONENAND)
+	onenand_init();
+#endif
+
+	/* initialize environment */
+	env_relocate();
+
+#ifdef CONFIG_VFD
+	/* must do this after the framebuffer is allocated */
+	drv_vfd_init();
+#endif /* CONFIG_VFD */
+
+#ifdef CONFIG_SERIAL_MULTI
+	serial_initialize();
+#endif
+
+	/* IP Address */
+	gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
+
+	stdio_init();	/* get the devices list going. */
+
+	jumptable_init();
+
+#if defined(CONFIG_API)
+	/* Initialize API */
+	api_init();
+#endif
+
+	console_init_r();	/* fully init console as a device */
+
+#if defined(CONFIG_ARCH_MISC_INIT)
+	/* miscellaneous arch dependent initialisations */
+	arch_misc_init();
+#endif
+#if defined(CONFIG_MISC_INIT_R)
+	/* miscellaneous platform dependent initialisations */
+	misc_init_r();
+#endif
+
+	/* enable exceptions */
+	enable_interrupts();
+
+	/* Perform network card initialisation if necessary */
+
+	/* Initialize from environment */
+	if ((s = getenv ("loadaddr")) != NULL) {
+		load_addr = simple_strtoul (s, NULL, 16);
+	}
+#if defined(CONFIG_CMD_NET)
+	if ((s = getenv ("bootfile")) != NULL) {
+		copy_filename (BootFile, s, sizeof (BootFile));
+	}
+#endif
+
+#ifdef BOARD_LATE_INIT
+	board_late_init ();
+#endif
+
+#ifdef CONFIG_GENERIC_MMC
+	puts("MMC:   ");
+	mmc_initialize (gd->bd);
+#endif
+
+#if defined(CONFIG_CMD_NET)
+#if defined(CONFIG_NET_MULTI)
+	puts("Net:   ");
+#endif
+	eth_initialize(gd->bd);
+#if defined(CONFIG_RESET_PHY_R)
+	debug("Reset Ethernet PHY\n");
+	reset_phy();
+#endif
+#endif
+	/* main_loop() can return to retry autoboot, if so just run it again. 
*/
+	for (;;) {
+		main_loop();
+	}
+
+	/* NOTREACHED - no way out of command loop except booting */
+}
+
+void hang(void)
+{
+	puts("### ERROR ### Please RESET the board ###\n");
+	for (;;);
+}
diff --git a/arch/nds32/lib/bootm.c b/arch/nds32/lib/bootm.c
new file mode 100644
index 0000000..38c5e98
--- /dev/null
+++ b/arch/nds32/lib/bootm.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2011 Andes Technology Corporation
+ * Shawn Lin, Andes Technology Corporation <nobuhiro at andestech.com>
+ * Macpaul Lin, Andes Technology Corporation <macpaul at andestech.com>
+ *
+ * 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-1307USA
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <image.h>
+#include <u-boot/zlib.h>
+#include <asm/byteorder.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
+    defined (CONFIG_CMDLINE_TAG) || \
+    defined (CONFIG_INITRD_TAG) || \
+    defined (CONFIG_SERIAL_TAG) || \
+    defined (CONFIG_REVISION_TAG)
+static void setup_start_tag(bd_t *bd);
+
+# ifdef CONFIG_SETUP_MEMORY_TAGS
+static void setup_memory_tags(bd_t *bd);
+# endif
+static void setup_commandline_tag(bd_t *bd, char *commandline);
+
+# ifdef CONFIG_INITRD_TAG
+static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong 
initrd_end);
+# endif
+static void setup_end_tag(bd_t *bd);
+
+static struct tag *params;
+#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || 
CONFIG_INITRD_TAG */
+
+int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t 
*images)
+{
+	bd_t	*bd = gd->bd;
+	char	*s;
+	int	machid = bd->bi_arch_number;
+	void	(*theKernel)(int zero, int arch, uint params);
+
+#ifdef CONFIG_CMDLINE_TAG
+	char *commandline = getenv("bootargs");
+#endif
+
+	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
+		return 1;
+
+	theKernel = (void (*)(int, int, uint))images->ep;
+
+	s = getenv("machid");
+	if (s) {
+		machid = simple_strtoul (s, NULL, 16);
+		printf("Using machid 0x%x from environment\n", machid);
+	}
+
+	show_boot_progress (15);
+
+	debug ("## Transferring control to Linux (at address %08lx) ...\n",
+	       (ulong)theKernel);
+
+#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
+    defined (CONFIG_CMDLINE_TAG) || \
+    defined (CONFIG_INITRD_TAG) || \
+    defined (CONFIG_SERIAL_TAG) || \
+    defined (CONFIG_REVISION_TAG)
+	setup_start_tag(bd);
+#ifdef CONFIG_SERIAL_TAG
+	setup_serial_tag(&params);
+#endif
+#ifdef CONFIG_REVISION_TAG
+	setup_revision_tag(&params);
+#endif
+#ifdef CONFIG_SETUP_MEMORY_TAGS
+	setup_memory_tags(bd);
+#endif
+#ifdef CONFIG_CMDLINE_TAG
+	setup_commandline_tag(bd, commandline);
+#endif
+#ifdef CONFIG_INITRD_TAG
+	if (images->rd_start && images->rd_end)
+		setup_initrd_tag (bd, images->rd_start, images->rd_end);
+#endif
+	setup_end_tag(bd);
+#endif
+
+	/* we assume that the kernel is in place */
+	printf("\nStarting kernel ...\n\n");
+
+#ifdef CONFIG_USB_DEVICE
+	{
+		extern void udc_disconnect(void);
+		udc_disconnect();
+	}
+#endif
+
+	cleanup_before_linux();
+
+	theKernel(0, machid, bd->bi_boot_params);
+	/* does not return */
+
+	return 1;
+}
+
+
+#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
+    defined (CONFIG_CMDLINE_TAG) || \
+    defined (CONFIG_INITRD_TAG) || \
+    defined (CONFIG_SERIAL_TAG) || \
+    defined (CONFIG_REVISION_TAG)
+static void setup_start_tag(bd_t *bd)
+{
+	params = (struct tag *)bd->bi_boot_params;
+
+	params->hdr.tag = ATAG_CORE;
+	params->hdr.size = tag_size(tag_core);
+
+	params->u.core.flags = 0;
+	params->u.core.pagesize = 0;
+	params->u.core.rootdev = 0;
+
+	params = tag_next(params);
+}
+
+
+#ifdef CONFIG_SETUP_MEMORY_TAGS
+static void setup_memory_tags (bd_t *bd)
+{
+	int i;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		params->hdr.tag = ATAG_MEM;
+		params->hdr.size = tag_size(tag_mem32);
+
+		params->u.mem.start = bd->bi_dram[i].start;
+		params->u.mem.size = bd->bi_dram[i].size;
+
+		params = tag_next(params);
+	}
+}
+#endif /* CONFIG_SETUP_MEMORY_TAGS */
+
+
+static void setup_commandline_tag(bd_t *bd, char *commandline)
+{
+	char *p;
+
+	if (!commandline)
+		return;
+
+	/* eat leading white space */
+	for (p = commandline; *p == ' '; p++);
+
+	/* skip non-existent command lines so the kernel will still
+	 * use its default command line.
+	 */
+	if (*p == '\0')
+		return;
+
+	params->hdr.tag = ATAG_CMDLINE;
+	params->hdr.size =
+		(sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2;
+
+	strcpy(params->u.cmdline.cmdline, p);
+
+	params = tag_next(params);
+}
+
+
+#ifdef CONFIG_INITRD_TAG
+static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong 
initrd_end)
+{
+	/* an ATAG_INITRD node tells the kernel where the compressed
+	 * ramdisk can be found. ATAG_RDIMG is a better name, actually.
+	 */
+	params->hdr.tag = ATAG_INITRD2;
+	params->hdr.size = tag_size (tag_initrd);
+
+	params->u.initrd.start = initrd_start;
+	params->u.initrd.size = initrd_end - initrd_start;
+
+	params = tag_next (params);
+}
+#endif /* CONFIG_INITRD_TAG */
+
+#ifdef CONFIG_SERIAL_TAG
+void setup_serial_tag(struct tag **tmp)
+{
+	struct tag *params = *tmp;
+	struct tag_serialnr serialnr;
+	void get_board_serial(struct tag_serialnr *serialnr);
+
+	get_board_serial(&serialnr);
+	params->hdr.tag = ATAG_SERIAL;
+	params->hdr.size = tag_size(tag_serialnr);
+	params->u.serialnr.low = serialnr.low;
+	params->u.serialnr.high= serialnr.high;
+	params = tag_next(params);
+	*tmp = params;
+}
+#endif
+
+#ifdef CONFIG_REVISION_TAG
+void setup_revision_tag(struct tag **in_params)
+{
+	u32 rev = 0;
+	u32 get_board_rev(void);
+
+	rev = get_board_rev();
+	params->hdr.tag = ATAG_REVISION;
+	params->hdr.size = tag_size(tag_revision);
+	params->u.revision.rev = rev;
+	params = tag_next(params);
+}
+#endif  /* CONFIG_REVISION_TAG */
+
+
+static void setup_end_tag (bd_t *bd)
+{
+	params->hdr.tag = ATAG_NONE;
+	params->hdr.size = 0;
+}
+
+#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || 
CONFIG_INITRD_TAG */
diff --git a/arch/nds32/lib/interrupts.c b/arch/nds32/lib/interrupts.c
new file mode 100644
index 0000000..9c39cd9
--- /dev/null
+++ b/arch/nds32/lib/interrupts.c
@@ -0,0 +1,126 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu at sysgo.de>
+ *
+ * Copyright (C) 2011 Andes Technology Corporation
+ * Shawn Lin, Andes Technology Corporation <nobuhiro at andestech.com>
+ * Macpaul Lin, Andes Technology Corporation <macpaul at andestech.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 <asm/ptregs.h>
+#undef INTERRUPT_MODE
+
+extern void reset_cpu(ulong addr);
+
+int GIE_status(void)
+{
+	int ret;
+
+	__asm__ __volatile__ (
+		"mfsr	$p0, $psw	\n\t"
+		"andi	%0, %0, 0x1	\n\t"
+		: "=r" (ret)
+		:
+		: "memory"
+	);
+	return ret;
+}
+
+#ifdef CONFIG_USE_INTERRUPT
+
+/* enable interrupts */
+void enable_interrupts (void)
+{
+	__asm__ __volatile__("setgie.e");
+}
+
+/*
+ * disable interrupts
+ * Return TRUE if GIE is enabled before we disable it.
+ */
+int disable_interrupts (void)
+{
+	int GIE_ori_status;
+
+	GIE_ori_status = GIE_status();
+
+	__asm__ __volatile__("setgie.d");
+
+	return GIE_ori_status;
+}
+#endif
+
+void bad_mode(void)
+{
+	panic("Resetting CPU ...\n");
+	reset_cpu(0);
+}
+
+void show_regs(struct pt_regs *regs)
+{
+	const char *processor_modes[]=
+	{ "USER", "SuperUser" , "HyperVisor" };
+
+	printf("\n");
+	printf("pc : [<%08lx>]	sp: [<%08lx>]\n"
+		"ra : %08lx  gp : %08lx  fp : %08lx\n",
+		regs->PC, regs->SP, regs->RA, regs->GP, regs->FP);
+	printf("D1H: %08lx  D1L: %08lx  D0H: %08lx  D0L: %08lx\n",
+		regs->D1HI, regs->D1LO, regs->D0HI, regs->D0LO);
+	printf("r27: %08lx  r26: %08lx  r25: %08lx  r24: %08lx\n",
+		regs->R27, regs->R26, regs->R25, regs->R24);
+	printf("r23: %08lx  r22: %08lx  r21: %08lx  r20: %08lx\n",
+		regs->R23, regs->R22, regs->R21, regs->R20);
+	printf("r19: %08lx  r18: %08lx  r17: %08lx  r16: %08lx\n",
+		regs->R19, regs->R18, regs->R17, regs->R16);
+	printf("r15: %08lx  r14: %08lx  r13: %08lx  r12: %08lx\n",
+		regs->R15, regs->R14, regs->R13, regs->R12);
+	printf("r11: %08lx  r10: %08lx  r9 : %08lx  r8 : %08lx\n",
+		regs->R11, regs->R10, regs->R9, regs->R8);
+	printf("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
+		regs->R7, regs->R6, regs->R5, regs->R4);
+	printf("r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
+		regs->R3, regs->R2, regs->R1, regs->R0);
+	printf("  Interrupts %s  Mode %s\n",
+		interrupts_enabled(regs) ? "on" : "off",
+		processor_modes[processor_mode(regs)]);
+}
+
+void do_interruption(struct pt_regs *pt_regs, int EVIC_num)
+{
+	const char *interruption_type[]= {
+		"Reset",
+		"TLB Fill",
+		"TLB Not Present",
+		"TLB Misc",
+		"VLPT Miss",
+		"Cache Parity Error",
+		"Debug",
+		"General Exception",
+		"External Interrupt"
+	};
+
+	printf("%s\n", interruption_type[EVIC_num]);
+		show_regs(pt_regs);
+	bad_mode();
+}
-- 
1.7.3.5



CONFIDENTIALITY NOTICE:

This e-mail (and its attachments) may contain confidential and legally 
privileged information or information protected from disclosure. If you 
are not the intended recipient, you are hereby notified that any 
disclosure, copying, distribution, or use of the information contained 
herein is strictly prohibited. In this case, please immediately notify the 
sender by return e-mail, delete the message (and any accompanying 
documents) and destroy all printed hard copies. Thank you for your 
cooperation.

Copyright ANDES TECHNOLOGY CORPORATION - All Rights Reserved.



More information about the U-Boot mailing list