Merge branch 'master' of git://git.denx.de/u-boot-mips
authorTom Rini <trini@konsulko.com>
Wed, 30 Nov 2016 19:08:28 +0000 (14:08 -0500)
committerTom Rini <trini@konsulko.com>
Thu, 1 Dec 2016 00:31:17 +0000 (19:31 -0500)
17 files changed:
arch/mips/Kconfig
arch/mips/cpu/start.S
arch/mips/include/asm/asm-offsets.h [new file with mode: 0644]
arch/mips/include/asm/cache.h
arch/mips/include/asm/io.h
arch/mips/include/asm/mipsregs.h
arch/mips/include/asm/system.h
arch/mips/include/asm/u-boot-mips.h
arch/mips/lib/Makefile
arch/mips/lib/asm-offsets.c [new file with mode: 0644]
arch/mips/lib/bootm.c
arch/mips/lib/genex.S [new file with mode: 0644]
arch/mips/lib/stack.c [new file with mode: 0644]
arch/mips/lib/traps.c [new file with mode: 0644]
arch/mips/mach-ath79/Kconfig
arch/mips/mach-pic32/Kconfig
common/board_r.c

index 097ad587c1cf643c769b7c071d27615b48578da9..d97930e577bb057a45ce62249871244440c9bdcf 100644 (file)
@@ -20,6 +20,7 @@ config TARGET_QEMU_MIPS
        select SUPPORTS_CPU_MIPS32_R2
        select SUPPORTS_CPU_MIPS64_R1
        select SUPPORTS_CPU_MIPS64_R2
+       select ROM_EXCEPTION_VECTORS
 
 config TARGET_MALTA
        bool "Support malta"
@@ -40,6 +41,7 @@ config TARGET_MALTA
        select SUPPORTS_CPU_MIPS64_R6
        select SWAP_IO_SPACE
        select MIPS_L1_CACHE_SHIFT_6
+       select ROM_EXCEPTION_VECTORS
 
 config TARGET_VCT
        bool "Support vct"
@@ -47,6 +49,7 @@ config TARGET_VCT
        select SUPPORTS_CPU_MIPS32_R1
        select SUPPORTS_CPU_MIPS32_R2
        select SYS_MIPS_CACHE_INIT_RAM_LOAD
+       select ROM_EXCEPTION_VECTORS
 
 config TARGET_DBAU1X00
        bool "Support dbau1x00"
@@ -55,6 +58,7 @@ config TARGET_DBAU1X00
        select SUPPORTS_CPU_MIPS32_R1
        select SUPPORTS_CPU_MIPS32_R2
        select SYS_MIPS_CACHE_INIT_RAM_LOAD
+       select ROM_EXCEPTION_VECTORS
        select MIPS_TUNE_4KC
 
 config TARGET_PB1X00
@@ -63,6 +67,7 @@ config TARGET_PB1X00
        select SUPPORTS_CPU_MIPS32_R1
        select SUPPORTS_CPU_MIPS32_R2
        select SYS_MIPS_CACHE_INIT_RAM_LOAD
+       select ROM_EXCEPTION_VECTORS
        select MIPS_TUNE_4KC
 
 config ARCH_ATH79
@@ -91,6 +96,7 @@ config TARGET_BOSTON
        select SUPPORTS_CPU_MIPS64_R1
        select SUPPORTS_CPU_MIPS64_R2
        select SUPPORTS_CPU_MIPS64_R6
+       select ROM_EXCEPTION_VECTORS
 
 config TARGET_XILFPGA
        bool "Support Imagination Xilfpga"
@@ -103,6 +109,7 @@ config TARGET_XILFPGA
        select SUPPORTS_CPU_MIPS32_R1
        select SUPPORTS_CPU_MIPS32_R2
        select MIPS_L1_CACHE_SHIFT_4
+       select ROM_EXCEPTION_VECTORS
        help
          This supports IMGTEC MIPSfpga platform
 
@@ -192,6 +199,20 @@ config CPU_MIPS64_R6
 
 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"
 
 config MIPS_BOOT_CMDLINE_LEGACY
@@ -281,6 +302,17 @@ config SWAP_IO_SPACE
 config SYS_MIPS_CACHE_INIT_RAM_LOAD
        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
        int
        default 0
index 3f0fc125475271835456db3490bd47a61a3dbb1b..6740fdf9ed272eda6bc7213ad02db57fc68f7d7b 100644 (file)
 # define STATUS_SET    ST0_KX
 #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
 
-       .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)
        /* U-Boot entry point */
        b       reset
-        nop
+        mtc0   zero, CP0_COUNT # clear cp0 count for most accurate boot timing
 
-       .org 0x10
 #if defined(CONFIG_SYS_XWAY_EBU_BOOTCFG)
        /*
         * 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
         * device with correct parameters. This config option is board-specific.
         */
+       .org 0x10
        .word CONFIG_SYS_XWAY_EBU_BOOTCFG
        .word 0x0
-#elif defined(CONFIG_MALTA)
+#endif
+#if defined(CONFIG_MALTA)
        /*
         * Linux expects the Board ID here.
         */
+       .org 0x10
        .word 0x00000420        # 0x420 (Malta Board with CoreLV)
        .word 0x00000000
 #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
        /* TLB refill, 32 bit task */
-1:     b       1b
-        nop
+       uhi_mips_exception
 
        .org 0x280
        /* XTLB refill, 64 bit task */
-1:     b       1b
-        nop
+       uhi_mips_exception
 
        .org 0x300
        /* Cache error exception */
-1:     b       1b
-        nop
+       uhi_mips_exception
 
        .org 0x380
        /* General exception */
-1:     b       1b
-        nop
+       uhi_mips_exception
 
        .org 0x400
        /* Catch interrupt exceptions */
-1:     b       1b
-        nop
+       uhi_mips_exception
 
        .org 0x480
        /* EJTAG debug exception */
 1:     b       1b
         nop
 
-       .align 4
+       .org 0x500
+#endif
+
 reset:
 #if __mips_isa_rev >= 6
        mfc0    t0, CP0_CONFIG, 5
@@ -128,17 +161,51 @@ reset:
        b       3b
         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
 
-       /* WP(Watch Pending), SW0/1 should be cleared */
+wr_done:
+       /* Clear WP, IV and SW interrupts */
        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
 
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
@@ -167,6 +234,11 @@ reset:
         nop
 #endif
 
+#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
+       /* Set up initial stack and global data */
+       setup_stack_gd
+#endif
+
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
 # ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
        /* Initialize any external memory */
@@ -188,35 +260,14 @@ reset:
 # 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
 
        move    a0, zero                # a0 <-- boot_flags = 0
        PTR_LA  t9, board_init_f
+
        jr      t9
         move   ra, zero
 
diff --git a/arch/mips/include/asm/asm-offsets.h b/arch/mips/include/asm/asm-offsets.h
new file mode 100644 (file)
index 0000000..5352b1c
--- /dev/null
@@ -0,0 +1,5 @@
+/*
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <generated/asm-offsets.h>
index 669c362a52a563ab6f7dfcf43188b8559644b69d..83165d5c9705fcc2f41eb501eb363b15e556aba3 100644 (file)
@@ -19,6 +19,7 @@
  */
 #define CONFIG_SYS_CACHELINE_SIZE ARCH_DMA_MINALIGN
 
+#ifndef __ASSEMBLY__
 /**
  * mips_cache_probe() - Probe the properties of the caches
  *
@@ -27,5 +28,6 @@
  * functions such as flush_cache may be called.
  */
 void mips_cache_probe(void);
+#endif
 
 #endif /* __MIPS_CACHE_H__ */
index 5b86386bc1cb2fbd98a97581f1f44d57f78c3946..ee7a59290deb7290e2151b9905f894dfd045344c 100644 (file)
@@ -501,7 +501,7 @@ map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
        if (flags == MAP_NOCACHE)
                return ioremap(paddr, len);
 
-       return (void *)paddr;
+       return (void *)CKSEG0ADDR(paddr);
 }
 
 /*
index 9ab506361e7897fb76ad0c8cdd37ebf3e58afc7a..7a9d222aadecfc1ed32e91e12b46aefa49634511 100644 (file)
 #define         STATUSF_IP14           (_ULCAST_(1) <<  6)
 #define         STATUSB_IP15           7
 #define         STATUSF_IP15           (_ULCAST_(1) <<  7)
+#define ST0_IMPL               (_ULCAST_(3) <<  16)
 #define ST0_CH                 0x00040000
 #define ST0_NMI                        0x00080000
 #define ST0_SR                 0x00100000
index e6435cce2944247b032e6f16f090fc4b7e24b482..c9c59614627df4196a938f08e33c010c637690e6 100644 (file)
@@ -262,4 +262,12 @@ extern void __die_if_kernel(const char *, struct pt_regs *, const char *where,
 #define die_if_kernel(msg, regs)                                       \
        __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 */
index 1f527bb8ec0917e977efdb9890b5c049f2f961c1..71ff41dafecfe02f98cf8f7493114d3836797648 100644 (file)
@@ -5,4 +5,8 @@
 #ifndef _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_ */
index b7ce5df7652fe5e7e808be6780e653b164b0001f..659c6ad187cdfd025caaa75e4fc000ae6d50a63b 100644 (file)
@@ -7,6 +7,9 @@
 
 obj-y  += cache.o
 obj-y  += cache_init.o
+obj-y  += genex.o
+obj-y  += stack.o
+obj-y  += traps.o
 
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
 
diff --git a/arch/mips/lib/asm-offsets.c b/arch/mips/lib/asm-offsets.c
new file mode 100644 (file)
index 0000000..9ed295a
--- /dev/null
@@ -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();
+}
index 0c6a4ab3b329ba10d889384463acc23e5d75e1d9..9fec4ad43860717263ea04d1981d0711d3c44502 100644 (file)
@@ -42,7 +42,7 @@ void arch_lmb_reserve(struct lmb *lmb)
 
        /* adjust sp by 4K to be safe */
        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)
diff --git a/arch/mips/lib/genex.S b/arch/mips/lib/genex.S
new file mode 100644 (file)
index 0000000..2d6d7b0
--- /dev/null
@@ -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)
diff --git a/arch/mips/lib/stack.c b/arch/mips/lib/stack.c
new file mode 100644 (file)
index 0000000..c80f5fe
--- /dev/null
@@ -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;
+}
diff --git a/arch/mips/lib/traps.c b/arch/mips/lib/traps.c
new file mode 100644 (file)
index 0000000..18622c2
--- /dev/null
@@ -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();
+}
index 7d483aa8dce398754df81efdba157d69e179cb75..d982b0f8e6978128d8950d6744a143b891b6a05d 100644 (file)
@@ -9,6 +9,7 @@ config SOC_AR933X
        select SUPPORTS_BIG_ENDIAN
        select SUPPORTS_CPU_MIPS32_R1
        select SUPPORTS_CPU_MIPS32_R2
+       select ROM_EXCEPTION_VECTORS
        select MIPS_TUNE_24KC
        help
          This supports QCA/Atheros ar933x family SOCs.
@@ -27,6 +28,7 @@ config SOC_QCA953X
        select SUPPORTS_BIG_ENDIAN
        select SUPPORTS_CPU_MIPS32_R1
        select SUPPORTS_CPU_MIPS32_R2
+       select ROM_EXCEPTION_VECTORS
        select MIPS_TUNE_24KC
        help
          This supports QCA/Atheros qca953x family SOCs.
index 2e38bb7ecafa84cdd1659f73c28e99d1ddee21cf..8fad4cff9126ab117479e70e7f55716c0dda812d 100644 (file)
@@ -14,6 +14,7 @@ config SOC_PIC32MZDA
        select SUPPORTS_CPU_MIPS32_R2
        select MIPS_L1_CACHE_SHIFT_4
        select SYS_MIPS_CACHE_INIT_RAM_LOAD
+       select ROM_EXCEPTION_VECTORS
        help
          This supports Microchip PIC32MZ[DA] family of microcontrollers.
 
index d959ad3c6f90ea2c2a422b6878c11a5437764a2c..5496f45cbd94d80cb8911bcaf331c1ec3eb88c32 100644 (file)
@@ -191,7 +191,7 @@ static int initr_serial(void)
        return 0;
 }
 
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
+#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS)
 static int initr_trap(void)
 {
        /*
@@ -807,7 +807,7 @@ init_fnc_t init_sequence_r[] = {
 #ifdef CONFIG_NEEDS_MANUAL_RELOC
        initr_manual_reloc_cmdtable,
 #endif
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
+#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS)
        initr_trap,
 #endif
 #ifdef CONFIG_ADDR_MAP