Browse Source

Merge branch 'master' of git://git.denx.de/u-boot-mips

Tom Rini 8 years ago
parent
commit
a2cb31086f

+ 32 - 0
arch/mips/Kconfig

@@ -20,6 +20,7 @@ config TARGET_QEMU_MIPS
 	select SUPPORTS_CPU_MIPS32_R2
 	select SUPPORTS_CPU_MIPS32_R2
 	select SUPPORTS_CPU_MIPS64_R1
 	select SUPPORTS_CPU_MIPS64_R1
 	select SUPPORTS_CPU_MIPS64_R2
 	select SUPPORTS_CPU_MIPS64_R2
+	select ROM_EXCEPTION_VECTORS
 
 
 config TARGET_MALTA
 config TARGET_MALTA
 	bool "Support malta"
 	bool "Support malta"
@@ -40,6 +41,7 @@ config TARGET_MALTA
 	select SUPPORTS_CPU_MIPS64_R6
 	select SUPPORTS_CPU_MIPS64_R6
 	select SWAP_IO_SPACE
 	select SWAP_IO_SPACE
 	select MIPS_L1_CACHE_SHIFT_6
 	select MIPS_L1_CACHE_SHIFT_6
+	select ROM_EXCEPTION_VECTORS
 
 
 config TARGET_VCT
 config TARGET_VCT
 	bool "Support vct"
 	bool "Support vct"
@@ -47,6 +49,7 @@ config TARGET_VCT
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
 	select SUPPORTS_CPU_MIPS32_R2
 	select SYS_MIPS_CACHE_INIT_RAM_LOAD
 	select SYS_MIPS_CACHE_INIT_RAM_LOAD
+	select ROM_EXCEPTION_VECTORS
 
 
 config TARGET_DBAU1X00
 config TARGET_DBAU1X00
 	bool "Support dbau1x00"
 	bool "Support dbau1x00"
@@ -55,6 +58,7 @@ config TARGET_DBAU1X00
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
 	select SUPPORTS_CPU_MIPS32_R2
 	select SYS_MIPS_CACHE_INIT_RAM_LOAD
 	select SYS_MIPS_CACHE_INIT_RAM_LOAD
+	select ROM_EXCEPTION_VECTORS
 	select MIPS_TUNE_4KC
 	select MIPS_TUNE_4KC
 
 
 config TARGET_PB1X00
 config TARGET_PB1X00
@@ -63,6 +67,7 @@ config TARGET_PB1X00
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
 	select SUPPORTS_CPU_MIPS32_R2
 	select SYS_MIPS_CACHE_INIT_RAM_LOAD
 	select SYS_MIPS_CACHE_INIT_RAM_LOAD
+	select ROM_EXCEPTION_VECTORS
 	select MIPS_TUNE_4KC
 	select MIPS_TUNE_4KC
 
 
 config ARCH_ATH79
 config ARCH_ATH79
@@ -91,6 +96,7 @@ config TARGET_BOSTON
 	select SUPPORTS_CPU_MIPS64_R1
 	select SUPPORTS_CPU_MIPS64_R1
 	select SUPPORTS_CPU_MIPS64_R2
 	select SUPPORTS_CPU_MIPS64_R2
 	select SUPPORTS_CPU_MIPS64_R6
 	select SUPPORTS_CPU_MIPS64_R6
+	select ROM_EXCEPTION_VECTORS
 
 
 config TARGET_XILFPGA
 config TARGET_XILFPGA
 	bool "Support Imagination Xilfpga"
 	bool "Support Imagination Xilfpga"
@@ -103,6 +109,7 @@ config TARGET_XILFPGA
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
 	select SUPPORTS_CPU_MIPS32_R2
 	select MIPS_L1_CACHE_SHIFT_4
 	select MIPS_L1_CACHE_SHIFT_4
+	select ROM_EXCEPTION_VECTORS
 	help
 	help
 	  This supports IMGTEC MIPSfpga platform
 	  This supports IMGTEC MIPSfpga platform
 
 
@@ -192,6 +199,20 @@ config CPU_MIPS64_R6
 
 
 endchoice
 endchoice
 
 
+menu "General setup"
+
+config ROM_EXCEPTION_VECTORS
+	bool "Build U-Boot image with exception vectors"
+	help
+	  Enable this to include exception vectors in the U-Boot image. This is
+	  required if the U-Boot entry point is equal to the address of the
+	  CPU reset exception vector (e.g. U-Boot as ROM loader in Qemu,
+	  U-Boot booted from parallel NOR flash).
+	  Disable this, if the U-Boot image is booted from DRAM (e.g. by SPL).
+	  In that case the image size will be reduced by 0x500 bytes.
+
+endmenu
+
 menu "OS boot interface"
 menu "OS boot interface"
 
 
 config MIPS_BOOT_CMDLINE_LEGACY
 config MIPS_BOOT_CMDLINE_LEGACY
@@ -281,6 +302,17 @@ config SWAP_IO_SPACE
 config SYS_MIPS_CACHE_INIT_RAM_LOAD
 config SYS_MIPS_CACHE_INIT_RAM_LOAD
 	bool
 	bool
 
 
+config MIPS_INIT_STACK_IN_SRAM
+	bool
+	default n
+	help
+	  Select this if the initial stack frame could be setup in SRAM.
+	  Normally the initial stack frame is set up in DRAM which is often
+	  only available after lowlevel_init. With this option the initial
+	  stack frame and the early C environment is set up before
+	  lowlevel_init. Thus lowlevel_init does not need to be implemented
+	  in assembler.
+
 config SYS_DCACHE_SIZE
 config SYS_DCACHE_SIZE
 	int
 	int
 	default 0
 	default 0

+ 112 - 61
arch/mips/cpu/start.S

@@ -34,30 +34,57 @@
 # define STATUS_SET	ST0_KX
 # define STATUS_SET	ST0_KX
 #endif
 #endif
 
 
-	/*
-	 * For the moment disable interrupts, mark the kernel mode and
-	 * set ST0_KX so that the CPU does not spit fire when using
-	 * 64-bit addresses.
-	 */
-	.macro	setup_c0_status set clr
-	.set	push
-	mfc0	t0, CP0_STATUS
-	or	t0, ST0_CU0 | \set | 0x1f | \clr
-	xor	t0, 0x1f | \clr
-	mtc0	t0, CP0_STATUS
-	.set	noreorder
-	sll	zero, 3				# ehb
-	.set	pop
+	.set noreorder
+
+	.macro init_wr sel
+	MTC0	zero, CP0_WATCHLO,\sel
+	mtc0	t1, CP0_WATCHHI,\sel
+	mfc0	t0, CP0_WATCHHI,\sel
+	bgez	t0, wr_done
+	 nop
 	.endm
 	.endm
 
 
-	.set noreorder
+	.macro uhi_mips_exception
+	move	k0, t9		# preserve t9 in k0
+	move	k1, a0		# preserve a0 in k1
+	li	t9, 15		# UHI exception operation
+	li	a0, 0		# Use hard register context
+	sdbbp	1		# Invoke UHI operation
+	.endm
+
+	.macro setup_stack_gd
+	li	t0, -16
+	PTR_LI	t1, CONFIG_SYS_INIT_SP_ADDR
+	and	sp, t1, t0		# force 16 byte alignment
+	PTR_SUBU \
+		sp, sp, GD_SIZE		# reserve space for gd
+	and	sp, sp, t0		# force 16 byte alignment
+	move	k0, sp			# save gd pointer
+#ifdef CONFIG_SYS_MALLOC_F_LEN
+	li	t2, CONFIG_SYS_MALLOC_F_LEN
+	PTR_SUBU \
+		sp, sp, t2		# reserve space for early malloc
+	and	sp, sp, t0		# force 16 byte alignment
+#endif
+	move	fp, sp
+
+	/* Clear gd */
+	move	t0, k0
+1:
+	PTR_S	zero, 0(t0)
+	blt	t0, t1, 1b
+	 PTR_ADDIU t0, PTRSIZE
+
+#ifdef CONFIG_SYS_MALLOC_F_LEN
+	PTR_S	sp, GD_MALLOC_BASE(k0)	# gd->malloc_base offset
+#endif
+	.endm
 
 
 ENTRY(_start)
 ENTRY(_start)
 	/* U-Boot entry point */
 	/* U-Boot entry point */
 	b	reset
 	b	reset
-	 nop
+	 mtc0	zero, CP0_COUNT	# clear cp0 count for most accurate boot timing
 
 
-	.org 0x10
 #if defined(CONFIG_SYS_XWAY_EBU_BOOTCFG)
 #if defined(CONFIG_SYS_XWAY_EBU_BOOTCFG)
 	/*
 	/*
 	 * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to
 	 * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to
@@ -66,47 +93,53 @@ ENTRY(_start)
 	 * initial configuration for that EBU in order to access the flash
 	 * initial configuration for that EBU in order to access the flash
 	 * device with correct parameters. This config option is board-specific.
 	 * device with correct parameters. This config option is board-specific.
 	 */
 	 */
+	.org 0x10
 	.word CONFIG_SYS_XWAY_EBU_BOOTCFG
 	.word CONFIG_SYS_XWAY_EBU_BOOTCFG
 	.word 0x0
 	.word 0x0
-#elif defined(CONFIG_MALTA)
+#endif
+#if defined(CONFIG_MALTA)
 	/*
 	/*
 	 * Linux expects the Board ID here.
 	 * Linux expects the Board ID here.
 	 */
 	 */
+	.org 0x10
 	.word 0x00000420	# 0x420 (Malta Board with CoreLV)
 	.word 0x00000420	# 0x420 (Malta Board with CoreLV)
 	.word 0x00000000
 	.word 0x00000000
 #endif
 #endif
 
 
+#if defined(CONFIG_ROM_EXCEPTION_VECTORS)
+	/*
+	 * Exception vector entry points. When running from ROM, an exception
+	 * cannot be handled. Halt execution and transfer control to debugger,
+	 * if one is attached.
+	 */
 	.org 0x200
 	.org 0x200
 	/* TLB refill, 32 bit task */
 	/* TLB refill, 32 bit task */
-1:	b	1b
-	 nop
+	uhi_mips_exception
 
 
 	.org 0x280
 	.org 0x280
 	/* XTLB refill, 64 bit task */
 	/* XTLB refill, 64 bit task */
-1:	b	1b
-	 nop
+	uhi_mips_exception
 
 
 	.org 0x300
 	.org 0x300
 	/* Cache error exception */
 	/* Cache error exception */
-1:	b	1b
-	 nop
+	uhi_mips_exception
 
 
 	.org 0x380
 	.org 0x380
 	/* General exception */
 	/* General exception */
-1:	b	1b
-	 nop
+	uhi_mips_exception
 
 
 	.org 0x400
 	.org 0x400
 	/* Catch interrupt exceptions */
 	/* Catch interrupt exceptions */
-1:	b	1b
-	 nop
+	uhi_mips_exception
 
 
 	.org 0x480
 	.org 0x480
 	/* EJTAG debug exception */
 	/* EJTAG debug exception */
 1:	b	1b
 1:	b	1b
 	 nop
 	 nop
 
 
-	.align 4
+	.org 0x500
+#endif
+
 reset:
 reset:
 #if __mips_isa_rev >= 6
 #if __mips_isa_rev >= 6
 	mfc0	t0, CP0_CONFIG, 5
 	mfc0	t0, CP0_CONFIG, 5
@@ -128,17 +161,51 @@ reset:
 	b	3b
 	b	3b
 	 nop
 	 nop
 
 
-	/* Clear watch registers */
-4:	MTC0	zero, CP0_WATCHLO
+	/* Init CP0 Status */
+4:	mfc0	t0, CP0_STATUS
+	and	t0, ST0_IMPL
+	or	t0, ST0_BEV | ST0_ERL | STATUS_SET
+	mtc0	t0, CP0_STATUS
+
+	/*
+	 * Check whether CP0 Config1 is implemented. If not continue
+	 * with legacy Watch register initialization.
+	 */
+	mfc0	t0, CP0_CONFIG
+	bgez	t0, wr_legacy
+	 nop
+
+	/*
+	 * Check WR bit in CP0 Config1 to determine if Watch registers
+	 * are implemented.
+	 */
+	mfc0	t0, CP0_CONFIG, 1
+	andi	t0, (1 << 3)
+	beqz	t0, wr_done
+	 nop
+
+	/* Clear Watch Status bits and disable watch exceptions */
+	li	t1, 0x7		# Clear I, R and W conditions
+	init_wr	0
+	init_wr	1
+	init_wr	2
+	init_wr	3
+	init_wr	4
+	init_wr	5
+	init_wr	6
+	init_wr	7
+	b	wr_done
+	 nop
+
+wr_legacy:
+	MTC0	zero, CP0_WATCHLO
 	mtc0	zero, CP0_WATCHHI
 	mtc0	zero, CP0_WATCHHI
 
 
-	/* WP(Watch Pending), SW0/1 should be cleared */
+wr_done:
+	/* Clear WP, IV and SW interrupts */
 	mtc0	zero, CP0_CAUSE
 	mtc0	zero, CP0_CAUSE
 
 
-	setup_c0_status STATUS_SET 0
-
-	/* Init Timer */
-	mtc0	zero, CP0_COUNT
+	/* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
 	mtc0	zero, CP0_COMPARE
 	mtc0	zero, CP0_COMPARE
 
 
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
@@ -167,6 +234,11 @@ reset:
 	 nop
 	 nop
 #endif
 #endif
 
 
+#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
+	/* Set up initial stack and global data */
+	setup_stack_gd
+#endif
+
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
 # ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
 # ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
 	/* Initialize any external memory */
 	/* Initialize any external memory */
@@ -188,35 +260,14 @@ reset:
 # endif
 # endif
 #endif
 #endif
 
 
-	/* Set up temporary stack */
-	li	t0, -16
-	PTR_LI	t1, CONFIG_SYS_INIT_SP_ADDR
-	and	sp, t1, t0		# force 16 byte alignment
-	PTR_SUBU \
-		sp, sp, GD_SIZE		# reserve space for gd
-	and	sp, sp, t0		# force 16 byte alignment
-	move	k0, sp			# save gd pointer
-#ifdef CONFIG_SYS_MALLOC_F_LEN
-	li	t2, CONFIG_SYS_MALLOC_F_LEN
-	PTR_SUBU \
-		sp, sp, t2		# reserve space for early malloc
-	and	sp, sp, t0		# force 16 byte alignment
-#endif
-	move	fp, sp
-
-	/* Clear gd */
-	move	t0, k0
-1:
-	PTR_S	zero, 0(t0)
-	blt	t0, t1, 1b
-	 PTR_ADDIU t0, PTRSIZE
-
-#ifdef CONFIG_SYS_MALLOC_F_LEN
-	PTR_S	sp, GD_MALLOC_BASE(k0)	# gd->malloc_base offset
+#ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
+	/* Set up initial stack and global data */
+	setup_stack_gd
 #endif
 #endif
 
 
 	move	a0, zero		# a0 <-- boot_flags = 0
 	move	a0, zero		# a0 <-- boot_flags = 0
 	PTR_LA	t9, board_init_f
 	PTR_LA	t9, board_init_f
+
 	jr	t9
 	jr	t9
 	 move	ra, zero
 	 move	ra, zero
 
 

+ 5 - 0
arch/mips/include/asm/asm-offsets.h

@@ -0,0 +1,5 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <generated/asm-offsets.h>

+ 2 - 0
arch/mips/include/asm/cache.h

@@ -19,6 +19,7 @@
  */
  */
 #define CONFIG_SYS_CACHELINE_SIZE ARCH_DMA_MINALIGN
 #define CONFIG_SYS_CACHELINE_SIZE ARCH_DMA_MINALIGN
 
 
+#ifndef __ASSEMBLY__
 /**
 /**
  * mips_cache_probe() - Probe the properties of the caches
  * mips_cache_probe() - Probe the properties of the caches
  *
  *
@@ -27,5 +28,6 @@
  * functions such as flush_cache may be called.
  * functions such as flush_cache may be called.
  */
  */
 void mips_cache_probe(void);
 void mips_cache_probe(void);
+#endif
 
 
 #endif /* __MIPS_CACHE_H__ */
 #endif /* __MIPS_CACHE_H__ */

+ 1 - 1
arch/mips/include/asm/io.h

@@ -501,7 +501,7 @@ map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
 	if (flags == MAP_NOCACHE)
 	if (flags == MAP_NOCACHE)
 		return ioremap(paddr, len);
 		return ioremap(paddr, len);
 
 
-	return (void *)paddr;
+	return (void *)CKSEG0ADDR(paddr);
 }
 }
 
 
 /*
 /*

+ 1 - 0
arch/mips/include/asm/mipsregs.h

@@ -299,6 +299,7 @@
 #define	 STATUSF_IP14		(_ULCAST_(1) <<	 6)
 #define	 STATUSF_IP14		(_ULCAST_(1) <<	 6)
 #define	 STATUSB_IP15		7
 #define	 STATUSB_IP15		7
 #define	 STATUSF_IP15		(_ULCAST_(1) <<	 7)
 #define	 STATUSF_IP15		(_ULCAST_(1) <<	 7)
+#define ST0_IMPL		(_ULCAST_(3) <<	 16)
 #define ST0_CH			0x00040000
 #define ST0_CH			0x00040000
 #define ST0_NMI			0x00080000
 #define ST0_NMI			0x00080000
 #define ST0_SR			0x00100000
 #define ST0_SR			0x00100000

+ 8 - 0
arch/mips/include/asm/system.h

@@ -262,4 +262,12 @@ extern void __die_if_kernel(const char *, struct pt_regs *, const char *where,
 #define die_if_kernel(msg, regs)					\
 #define die_if_kernel(msg, regs)					\
 	__die_if_kernel(msg, regs, __FILE__ ":"__FUNCTION__, __LINE__)
 	__die_if_kernel(msg, regs, __FILE__ ":"__FUNCTION__, __LINE__)
 
 
+static inline void execution_hazard_barrier(void)
+{
+	__asm__ __volatile__(
+		".set noreorder\n"
+		"ehb\n"
+		".set reorder");
+}
+
 #endif /* _ASM_SYSTEM_H */
 #endif /* _ASM_SYSTEM_H */

+ 4 - 0
arch/mips/include/asm/u-boot-mips.h

@@ -5,4 +5,8 @@
 #ifndef _U_BOOT_MIPS_H_
 #ifndef _U_BOOT_MIPS_H_
 #define _U_BOOT_MIPS_H_
 #define _U_BOOT_MIPS_H_
 
 
+void exc_handler(void);
+void except_vec3_generic(void);
+void except_vec_ejtag_debug(void);
+
 #endif /* _U_BOOT_MIPS_H_ */
 #endif /* _U_BOOT_MIPS_H_ */

+ 3 - 0
arch/mips/lib/Makefile

@@ -7,6 +7,9 @@
 
 
 obj-y	+= cache.o
 obj-y	+= cache.o
 obj-y	+= cache_init.o
 obj-y	+= cache_init.o
+obj-y	+= genex.o
+obj-y	+= stack.o
+obj-y	+= traps.o
 
 
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
 
 

+ 61 - 0
arch/mips/lib/asm-offsets.c

@@ -0,0 +1,61 @@
+/*
+ * offset.c: Calculate pt_regs and task_struct offsets.
+ *
+ * Copyright (C) 1996 David S. Miller
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ *
+ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/ptrace.h>
+#include <linux/stddef.h>
+#include <linux/kbuild.h>
+
+void output_ptreg_defines(void)
+{
+	COMMENT("MIPS pt_regs offsets.");
+	OFFSET(PT_R0, pt_regs, regs[0]);
+	OFFSET(PT_R1, pt_regs, regs[1]);
+	OFFSET(PT_R2, pt_regs, regs[2]);
+	OFFSET(PT_R3, pt_regs, regs[3]);
+	OFFSET(PT_R4, pt_regs, regs[4]);
+	OFFSET(PT_R5, pt_regs, regs[5]);
+	OFFSET(PT_R6, pt_regs, regs[6]);
+	OFFSET(PT_R7, pt_regs, regs[7]);
+	OFFSET(PT_R8, pt_regs, regs[8]);
+	OFFSET(PT_R9, pt_regs, regs[9]);
+	OFFSET(PT_R10, pt_regs, regs[10]);
+	OFFSET(PT_R11, pt_regs, regs[11]);
+	OFFSET(PT_R12, pt_regs, regs[12]);
+	OFFSET(PT_R13, pt_regs, regs[13]);
+	OFFSET(PT_R14, pt_regs, regs[14]);
+	OFFSET(PT_R15, pt_regs, regs[15]);
+	OFFSET(PT_R16, pt_regs, regs[16]);
+	OFFSET(PT_R17, pt_regs, regs[17]);
+	OFFSET(PT_R18, pt_regs, regs[18]);
+	OFFSET(PT_R19, pt_regs, regs[19]);
+	OFFSET(PT_R20, pt_regs, regs[20]);
+	OFFSET(PT_R21, pt_regs, regs[21]);
+	OFFSET(PT_R22, pt_regs, regs[22]);
+	OFFSET(PT_R23, pt_regs, regs[23]);
+	OFFSET(PT_R24, pt_regs, regs[24]);
+	OFFSET(PT_R25, pt_regs, regs[25]);
+	OFFSET(PT_R26, pt_regs, regs[26]);
+	OFFSET(PT_R27, pt_regs, regs[27]);
+	OFFSET(PT_R28, pt_regs, regs[28]);
+	OFFSET(PT_R29, pt_regs, regs[29]);
+	OFFSET(PT_R30, pt_regs, regs[30]);
+	OFFSET(PT_R31, pt_regs, regs[31]);
+	OFFSET(PT_LO, pt_regs, lo);
+	OFFSET(PT_HI, pt_regs, hi);
+	OFFSET(PT_EPC, pt_regs, cp0_epc);
+	OFFSET(PT_BVADDR, pt_regs, cp0_badvaddr);
+	OFFSET(PT_STATUS, pt_regs, cp0_status);
+	OFFSET(PT_CAUSE, pt_regs, cp0_cause);
+	DEFINE(PT_SIZE, sizeof(struct pt_regs));
+	BLANK();
+}

+ 1 - 1
arch/mips/lib/bootm.c

@@ -42,7 +42,7 @@ void arch_lmb_reserve(struct lmb *lmb)
 
 
 	/* adjust sp by 4K to be safe */
 	/* adjust sp by 4K to be safe */
 	sp -= 4096;
 	sp -= 4096;
-	lmb_reserve(lmb, sp, CONFIG_SYS_SDRAM_BASE + gd->ram_size - sp);
+	lmb_reserve(lmb, sp, gd->ram_top - sp);
 }
 }
 
 
 static void linux_cmdline_init(void)
 static void linux_cmdline_init(void)

+ 224 - 0
arch/mips/lib/genex.S

@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2002, 2007  Maciej W. Rozycki
+ * Copyright (C) 2001, 2012 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/asm-offsets.h>
+
+#define STATMASK 0x1f
+
+	.set	noreorder
+
+	/*
+	 * Macros copied and adapted from Linux MIPS
+	 */
+	.macro	SAVE_AT
+	.set	push
+	.set	noat
+	LONG_S	$1, PT_R1(sp)
+	.set	pop
+	.endm
+
+	.macro	SAVE_TEMP
+#if __mips_isa_rev < 6
+	mfhi	v1
+#endif
+#ifdef CONFIG_32BIT
+	LONG_S	$8, PT_R8(sp)
+	LONG_S	$9, PT_R9(sp)
+#endif
+	LONG_S	$10, PT_R10(sp)
+	LONG_S	$11, PT_R11(sp)
+	LONG_S	$12, PT_R12(sp)
+#if __mips_isa_rev < 6
+	LONG_S	v1, PT_HI(sp)
+	mflo	v1
+#endif
+	LONG_S	$13, PT_R13(sp)
+	LONG_S	$14, PT_R14(sp)
+	LONG_S	$15, PT_R15(sp)
+	LONG_S	$24, PT_R24(sp)
+#if __mips_isa_rev < 6
+	LONG_S	v1, PT_LO(sp)
+#endif
+	.endm
+
+	.macro	SAVE_STATIC
+	LONG_S	$16, PT_R16(sp)
+	LONG_S	$17, PT_R17(sp)
+	LONG_S	$18, PT_R18(sp)
+	LONG_S	$19, PT_R19(sp)
+	LONG_S	$20, PT_R20(sp)
+	LONG_S	$21, PT_R21(sp)
+	LONG_S	$22, PT_R22(sp)
+	LONG_S	$23, PT_R23(sp)
+	LONG_S	$30, PT_R30(sp)
+	.endm
+
+	.macro	SAVE_SOME
+	.set	push
+	.set	noat
+	PTR_SUBU k1, sp, PT_SIZE
+	LONG_S	sp, PT_R29(k1)
+	move	sp, k1
+
+	LONG_S	$3, PT_R3(sp)
+	LONG_S	$0, PT_R0(sp)
+	mfc0	v1, CP0_STATUS
+	LONG_S	$2, PT_R2(sp)
+	LONG_S	v1, PT_STATUS(sp)
+	LONG_S	$4, PT_R4(sp)
+	mfc0	v1, CP0_CAUSE
+	LONG_S	$5, PT_R5(sp)
+	LONG_S	v1, PT_CAUSE(sp)
+	LONG_S	$6, PT_R6(sp)
+	MFC0	v1, CP0_EPC
+	LONG_S	$7, PT_R7(sp)
+#ifdef CONFIG_64BIT
+	LONG_S	$8, PT_R8(sp)
+	LONG_S	$9, PT_R9(sp)
+#endif
+	LONG_S	v1, PT_EPC(sp)
+	LONG_S	$25, PT_R25(sp)
+	LONG_S	$28, PT_R28(sp)
+	LONG_S	$31, PT_R31(sp)
+	.set	pop
+	.endm
+
+	.macro	RESTORE_AT
+	.set	push
+	.set	noat
+	LONG_L	$1,  PT_R1(sp)
+	.set	pop
+	.endm
+
+	.macro	RESTORE_TEMP
+#if __mips_isa_rev < 6
+	LONG_L	$24, PT_LO(sp)
+	mtlo	$24
+	LONG_L	$24, PT_HI(sp)
+	mthi	$24
+#endif
+#ifdef CONFIG_32BIT
+	LONG_L	$8, PT_R8(sp)
+	LONG_L	$9, PT_R9(sp)
+#endif
+	LONG_L	$10, PT_R10(sp)
+	LONG_L	$11, PT_R11(sp)
+	LONG_L	$12, PT_R12(sp)
+	LONG_L	$13, PT_R13(sp)
+	LONG_L	$14, PT_R14(sp)
+	LONG_L	$15, PT_R15(sp)
+	LONG_L	$24, PT_R24(sp)
+	.endm
+
+	.macro	RESTORE_STATIC
+	LONG_L	$16, PT_R16(sp)
+	LONG_L	$17, PT_R17(sp)
+	LONG_L	$18, PT_R18(sp)
+	LONG_L	$19, PT_R19(sp)
+	LONG_L	$20, PT_R20(sp)
+	LONG_L	$21, PT_R21(sp)
+	LONG_L	$22, PT_R22(sp)
+	LONG_L	$23, PT_R23(sp)
+	LONG_L	$30, PT_R30(sp)
+	.endm
+
+	.macro	RESTORE_SOME
+	.set	push
+	.set	reorder
+	.set	noat
+	mfc0	a0, CP0_STATUS
+	ori	a0, STATMASK
+	xori	a0, STATMASK
+	mtc0	a0, CP0_STATUS
+	li	v1, ST0_CU1 | ST0_FR | ST0_IM
+	and	a0, v1
+	LONG_L	v0, PT_STATUS(sp)
+	nor	v1, $0, v1
+	and	v0, v1
+	or	v0, a0
+	mtc0	v0, CP0_STATUS
+	LONG_L	v1, PT_EPC(sp)
+	MTC0	v1, CP0_EPC
+	LONG_L	$31, PT_R31(sp)
+	LONG_L	$28, PT_R28(sp)
+	LONG_L	$25, PT_R25(sp)
+#ifdef CONFIG_64BIT
+	LONG_L	$8, PT_R8(sp)
+	LONG_L	$9, PT_R9(sp)
+#endif
+	LONG_L	$7,  PT_R7(sp)
+	LONG_L	$6,  PT_R6(sp)
+	LONG_L	$5,  PT_R5(sp)
+	LONG_L	$4,  PT_R4(sp)
+	LONG_L	$3,  PT_R3(sp)
+	LONG_L	$2,  PT_R2(sp)
+	.set	pop
+	.endm
+
+	.macro	RESTORE_SP
+	LONG_L	sp, PT_R29(sp)
+	.endm
+
+NESTED(except_vec3_generic, 0, sp)
+	PTR_LA	k1, handle_reserved
+	jr	k1
+	 nop
+	END(except_vec3_generic)
+
+NESTED(except_vec_ejtag_debug, 0, sp)
+	PTR_LA	k1, handle_ejtag_debug
+	jr	k1
+	 nop
+	END(except_vec_ejtag_debug)
+
+NESTED(handle_reserved, PT_SIZE, sp)
+	SAVE_SOME
+	SAVE_AT
+	SAVE_TEMP
+	SAVE_STATIC
+
+	PTR_LA	t9, do_reserved
+	jr	t9
+	 move	a0, sp
+	END(handle_reserved)
+
+NESTED(handle_ejtag_debug, PT_SIZE, sp)
+	.set	push
+	.set	noat
+	MTC0	k1, CP0_DESAVE
+
+	/* Check for SDBBP */
+	MFC0	k1, CP0_DEBUG
+	sll	k1, k1, 30
+	bgez	k1, ejtag_return
+	 nop
+
+	SAVE_SOME
+	SAVE_AT
+	SAVE_TEMP
+	SAVE_STATIC
+
+	PTR_LA	t9, do_ejtag_debug
+	jalr	t9
+	 move	a0, sp
+
+	RESTORE_TEMP
+	RESTORE_STATIC
+	RESTORE_AT
+	RESTORE_SOME
+	RESTORE_SP
+
+ejtag_return:
+	MFC0	k1, CP0_DESAVE
+	deret
+	.set pop
+	END(handle_ejtag_debug)

+ 19 - 0
arch/mips/lib/stack.c

@@ -0,0 +1,19 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int arch_reserve_stacks(void)
+{
+	/* reserve space for exception vector table */
+	gd->start_addr_sp -= 0x500;
+	gd->start_addr_sp &= ~0xFFF;
+	gd->irq_sp = gd->start_addr_sp;
+	debug("Reserving %d Bytes for exception vector at: %08lx\n",
+	      0x500, gd->start_addr_sp);
+
+	return 0;
+}

+ 106 - 0
arch/mips/lib/traps.c

@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 1994 - 1999, 2000, 01, 06 Ralf Baechle
+ * Copyright (C) 1995, 1996 Paul M. Antoine
+ * Copyright (C) 1998 Ulf Carlsson
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002, 2003, 2004, 2005, 2007  Maciej W. Rozycki
+ * Copyright (C) 2000, 2001, 2012 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2014, Imagination Technologies Ltd.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/system.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void show_regs(const struct pt_regs *regs)
+{
+	const int field = 2 * sizeof(unsigned long);
+	unsigned int cause = regs->cp0_cause;
+	unsigned int exccode;
+	int i;
+
+	/*
+	 * Saved main processor registers
+	 */
+	for (i = 0; i < 32; ) {
+		if ((i % 4) == 0)
+			printf("$%2d   :", i);
+		if (i == 0)
+			printf(" %0*lx", field, 0UL);
+		else if (i == 26 || i == 27)
+			printf(" %*s", field, "");
+		else
+			printf(" %0*lx", field, regs->regs[i]);
+
+		i++;
+		if ((i % 4) == 0)
+			puts("\n");
+	}
+
+	printf("Hi    : %0*lx\n", field, regs->hi);
+	printf("Lo    : %0*lx\n", field, regs->lo);
+
+	/*
+	 * Saved cp0 registers
+	 */
+	printf("epc   : %0*lx (text %0*lx)\n", field, regs->cp0_epc,
+	       field, regs->cp0_epc - gd->reloc_off);
+	printf("ra    : %0*lx (text %0*lx)\n", field, regs->regs[31],
+	       field, regs->regs[31] - gd->reloc_off);
+
+	printf("Status: %08x\n", (uint32_t) regs->cp0_status);
+
+	exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE;
+	printf("Cause : %08x (ExcCode %02x)\n", cause, exccode);
+
+	if (1 <= exccode && exccode <= 5)
+		printf("BadVA : %0*lx\n", field, regs->cp0_badvaddr);
+
+	printf("PrId  : %08x\n", read_c0_prid());
+}
+
+void do_reserved(const struct pt_regs *regs)
+{
+	puts("\nOoops:\n");
+	show_regs(regs);
+	hang();
+}
+
+void do_ejtag_debug(const struct pt_regs *regs)
+{
+	const int field = 2 * sizeof(unsigned long);
+	unsigned long depc;
+	unsigned int debug;
+
+	depc = read_c0_depc();
+	debug = read_c0_debug();
+
+	printf("SDBBP EJTAG debug exception: c0_depc = %0*lx, DEBUG = %08x\n",
+	       field, depc, debug);
+}
+
+static void set_handler(unsigned long offset, void *addr, unsigned long size)
+{
+	unsigned long ebase = gd->irq_sp;
+
+	memcpy((void *)(ebase + offset), addr, size);
+	flush_cache(ebase + offset, size);
+}
+
+void trap_init(ulong reloc_addr)
+{
+	unsigned long ebase = gd->irq_sp;
+
+	set_handler(0x180, &except_vec3_generic, 0x80);
+	set_handler(0x280, &except_vec_ejtag_debug, 0x80);
+
+	write_c0_ebase(ebase);
+	clear_c0_status(ST0_BEV);
+	execution_hazard_barrier();
+}

+ 2 - 0
arch/mips/mach-ath79/Kconfig

@@ -9,6 +9,7 @@ config SOC_AR933X
 	select SUPPORTS_BIG_ENDIAN
 	select SUPPORTS_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
 	select SUPPORTS_CPU_MIPS32_R2
+	select ROM_EXCEPTION_VECTORS
 	select MIPS_TUNE_24KC
 	select MIPS_TUNE_24KC
 	help
 	help
 	  This supports QCA/Atheros ar933x family SOCs.
 	  This supports QCA/Atheros ar933x family SOCs.
@@ -27,6 +28,7 @@ config SOC_QCA953X
 	select SUPPORTS_BIG_ENDIAN
 	select SUPPORTS_BIG_ENDIAN
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
 	select SUPPORTS_CPU_MIPS32_R2
+	select ROM_EXCEPTION_VECTORS
 	select MIPS_TUNE_24KC
 	select MIPS_TUNE_24KC
 	help
 	help
 	  This supports QCA/Atheros qca953x family SOCs.
 	  This supports QCA/Atheros qca953x family SOCs.

+ 1 - 0
arch/mips/mach-pic32/Kconfig

@@ -14,6 +14,7 @@ config SOC_PIC32MZDA
 	select SUPPORTS_CPU_MIPS32_R2
 	select SUPPORTS_CPU_MIPS32_R2
 	select MIPS_L1_CACHE_SHIFT_4
 	select MIPS_L1_CACHE_SHIFT_4
 	select SYS_MIPS_CACHE_INIT_RAM_LOAD
 	select SYS_MIPS_CACHE_INIT_RAM_LOAD
+	select ROM_EXCEPTION_VECTORS
 	help
 	help
 	  This supports Microchip PIC32MZ[DA] family of microcontrollers.
 	  This supports Microchip PIC32MZ[DA] family of microcontrollers.
 
 

+ 2 - 2
common/board_r.c

@@ -191,7 +191,7 @@ static int initr_serial(void)
 	return 0;
 	return 0;
 }
 }
 
 
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
+#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS)
 static int initr_trap(void)
 static int initr_trap(void)
 {
 {
 	/*
 	/*
@@ -807,7 +807,7 @@ init_fnc_t init_sequence_r[] = {
 #ifdef CONFIG_NEEDS_MANUAL_RELOC
 #ifdef CONFIG_NEEDS_MANUAL_RELOC
 	initr_manual_reloc_cmdtable,
 	initr_manual_reloc_cmdtable,
 #endif
 #endif
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
+#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS)
 	initr_trap,
 	initr_trap,
 #endif
 #endif
 #ifdef CONFIG_ADDR_MAP
 #ifdef CONFIG_ADDR_MAP