summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/arch/mips/common/src/exception.S
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/arch/mips/common/src/exception.S')
-rw-r--r--cfe/cfe/arch/mips/common/src/exception.S546
1 files changed, 546 insertions, 0 deletions
diff --git a/cfe/cfe/arch/mips/common/src/exception.S b/cfe/cfe/arch/mips/common/src/exception.S
new file mode 100644
index 0000000..8036b35
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/exception.S
@@ -0,0 +1,546 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * Exception Handler File: exception.S
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+
+#include "sbmips.h"
+#include "exception.h"
+#include "mipsmacros.h"
+#include "cpu_config.h" /* for definition of HAZARD and ERET */
+#include "bsp_config.h"
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#ifdef _MIPSREGS32_
+#define LREG lw
+#define SREG sw
+#define SRL srl
+#define SLL sll
+#else
+#define LREG ld
+#define SREG sd
+#define SRL dsrl
+#define SLL dsll
+#endif
+
+
+/* *********************************************************************
+ * Data
+ ********************************************************************* */
+
+ .sdata
+
+ .globl _exc_vectab
+_exc_vectab: _LONG_ 0 # XTYPE_RESET
+ _LONG_ 0 # XTYPE_TLBFILL (not used)
+ _LONG_ 0 # XTYPE_XTLBFILL
+ _LONG_ 0 # XTYPE_CACHEERR (not used)
+ _LONG_ 0 # XTYPE_EXCEPTION
+ _LONG_ 0 # XTYPE_INTERRUPT
+ _LONG_ 0 # XTYPE_EJTAG
+
+/* *********************************************************************
+ * Common Data
+ ********************************************************************* */
+
+ .bss
+
+
+/* *********************************************************************
+ * Code
+ ********************************************************************* */
+
+ .text
+
+#define R_EXC_CERR_TEMPLATE _TBLIDX(0)
+#define R_EXC_CERR_TEMPLATE_END _TBLIDX(1)
+
+ .globl _exc_cerr_htable
+_exc_cerr_htable:
+ _LONG_ _exc_cerr_template
+ _LONG_ _exc_cerr_template_end
+
+
+/* *********************************************************************
+ * _exc_cerr_template
+ *
+ * This is a template routine for our cache error handler.
+ * We save a couple of registers in our magic save area, then
+ * dispatch to code elsewhere in CFE.
+ *
+ * This code is copied right to the vector address, so it has
+ * to be kept tiny!
+ *
+ * Input parameters:
+ * nothing - running uncached, all registers trashed
+ *
+ * Return value:
+ * might return, might not
+ ********************************************************************* */
+
+LEAF(_exc_cerr_template)
+
+ /*
+ * Magic! When the cache error handler is running,
+ * we are in a very special state, running uncached
+ * and with translations turned off. We can use offsets
+ * from r0(zero) to store registers we need to use
+ * during the error handler.
+ */
+
+ .set push ; .set noreorder
+
+ SR k0,CFE_LOCORE_GLOBAL_K0TMP(zero)
+ SR k1,CFE_LOCORE_GLOBAL_K1TMP(zero)
+ SR ra,CFE_LOCORE_GLOBAL_RATMP(zero)
+ SR gp,CFE_LOCORE_GLOBAL_GPTMP(zero)
+
+ LR k0,CFE_LOCORE_GLOBAL_CERRH(zero)
+ jal k0
+ nop
+
+ LR k0,CFE_LOCORE_GLOBAL_K0TMP(zero)
+ LR k1,CFE_LOCORE_GLOBAL_K1TMP(zero)
+ LR ra,CFE_LOCORE_GLOBAL_RATMP(zero)
+ LR gp,CFE_LOCORE_GLOBAL_GPTMP(zero)
+ ERET
+
+ .set pop
+
+ /*
+ * Note: make sure this routine does not exceed 128 bytes
+ */
+
+_exc_cerr_template_end:
+
+END(_exc_cerr_template)
+
+/* *********************************************************************
+ * _exc_setup_locore(cerrh)
+ *
+ * Set global data into the low-memory region. We do this in
+ * assembly language so it's easier to deal with the 32-bit/64-bit
+ * issues that arise in the "C" code.
+ *
+ * Input parameters:
+ * a0 - cache error handler
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_setup_locore)
+
+ move t4,ra
+
+ /*
+ * Save GP for easy re-use, using uncached writes.
+ */
+
+ li t0,PHYS_TO_K1(CFE_LOCORE_GLOBAL_GP)
+ SR gp,0(t0)
+
+ /*
+ * Initialize cache error handler pointer. Make it
+ * uncached, since cache error handlers should not
+ * touch the cache.
+ */
+
+ li t1,(K0SIZE-1)
+ and a0,a0,t1 # keep just physical part
+ li t1,K1BASE
+ or a0,a0,t1 # make into an uncached address
+
+ li t0,PHYS_TO_K1(CFE_LOCORE_GLOBAL_CERRH)
+ SR a0,0(t0)
+
+ /*
+ * Move the cache error handler into low RAM.
+ */
+
+ li t0,PHYS_TO_K1(MIPS_RAM_VEC_CACHEERR)
+
+ LOADREL(t1,_exc_cerr_htable)
+ LR t2,R_EXC_CERR_TEMPLATE_END(t1)
+ LR t1,R_EXC_CERR_TEMPLATE(t1)
+
+1: lw t3,0(t1) # get a word
+ sw t3,0(t0) # write a word
+ ADD t0,4 # next word...
+ ADD t1,4
+ blt t1,t2,1b # till done
+
+ /*
+ * Now do the whole thing again, but with cached writes.
+ * Writing uncached makes sure the data is actually in memory,
+ * and writing cached makes sure we write the same
+ * stuff again when the cache is evicted.
+ * This way we don't have to bother with cacheops,
+ * a bonus on the BCM1250 with its funky L2.
+ */
+
+ li t0,PHYS_TO_K0(CFE_LOCORE_GLOBAL_GP)
+ SR gp,0(t0)
+
+ li t0,PHYS_TO_K0(CFE_LOCORE_GLOBAL_CERRH)
+ SR a0,0(t0)
+
+ li t0,PHYS_TO_K0(MIPS_RAM_VEC_CACHEERR)
+
+ LOADREL(t1,_exc_cerr_htable)
+ LR t2,R_EXC_CERR_TEMPLATE_END(t1)
+ LR t1,R_EXC_CERR_TEMPLATE(t1)
+
+1: lw t3,0(t1) # get a word
+ sw t3,0(t0) # write a word
+ ADD t0,4 # next word...
+ ADD t1,4
+ blt t1,t2,1b # till done
+
+
+ /*
+ * done!
+ */
+
+ move ra,t4
+ j ra
+
+END(_exc_setup_locore)
+
+
+
+
+/* *********************************************************************
+ * _exc_setvector(xtype,addr)
+ *
+ * Set an exception vector address
+ *
+ * Input parameters:
+ * xtype - exception vector type
+ * addr - routine address
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_setvector)
+
+ la v0,_exc_vectab
+ srl a0,3 /* convert 8-byte index to array index */
+ sll a0,BPWSIZE /* convert back to index appropriate for word size */
+ add v0,a0
+ SR a1,(v0)
+ j ra
+
+END(_exc_setvector)
+
+
+/* *********************************************************************
+ * _exc_crash_sim()
+ *
+ * Crash the GDB simulator, causing it to exit.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing - does not return
+ ********************************************************************* */
+
+
+LEAF(_exc_crash_sim)
+
+ li $2,1
+ li $3,0xdead
+ li $4,0
+ syscall 0xca
+1: b 1b
+
+END(_exc_crash_sim)
+
+
+/* *********************************************************************
+ * _exc_cache_crash_sim()
+ *
+ * As _exc_crash_sim, but distinguish cache error exception.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing - does not return
+ ********************************************************************* */
+
+
+LEAF(_exc_cache_crash_sim)
+
+ li $2,1
+ li $3,0xbadc
+ li $4,0
+ syscall 0xca
+1: b 1b
+
+END(_exc_cache_crash_sim)
+
+
+/* *********************************************************************
+ * _exc_restart()
+ *
+ * Restart the firmware at the boot address
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_restart)
+
+ li t0,0xBFC00000 # ROM restart vector
+ jr t0
+
+END(_exc_restart)
+
+/* *********************************************************************
+ * _exc_entry(k0)
+ *
+ * Main exception entry point.
+ *
+ * Input parameters:
+ * k0 - exception type
+ *
+ * Return value:
+ * ...
+ ********************************************************************* */
+
+LEAF(_exc_entry)
+
+ .set noreorder
+ .set noat
+
+ subu k1,sp,EXCEPTION_SIZE
+ SRL k1,3
+ SLL k1,3
+
+ SREG zero,XGR_ZERO(k1)
+ SREG AT,XGR_AT(k1)
+
+ SREG v0,XGR_V0(k1)
+ SREG v1,XGR_V1(k1)
+
+ SREG a0,XGR_A0(k1)
+ SREG a1,XGR_A1(k1)
+ SREG a2,XGR_A2(k1)
+ SREG a3,XGR_A3(k1)
+
+ SREG t0,XGR_T0(k1)
+ SREG t1,XGR_T1(k1)
+ SREG t2,XGR_T2(k1)
+ SREG t3,XGR_T3(k1)
+ SREG t4,XGR_T4(k1)
+ SREG t5,XGR_T5(k1)
+ SREG t6,XGR_T6(k1)
+ SREG t7,XGR_T7(k1)
+
+ SREG s0,XGR_S0(k1)
+ SREG s1,XGR_S1(k1)
+ SREG s2,XGR_S2(k1)
+ SREG s3,XGR_S3(k1)
+ SREG s4,XGR_S4(k1)
+ SREG s5,XGR_S5(k1)
+ SREG s6,XGR_S6(k1)
+ SREG s7,XGR_S7(k1)
+
+ SREG t8,XGR_T8(k1)
+ SREG t9,XGR_T9(k1)
+
+ SREG gp,XGR_GP(k1)
+ SREG sp,XGR_SP(k1)
+ SREG fp,XGR_FP(k1)
+ SREG ra,XGR_RA(k1)
+
+ mfc0 t0,C0_CAUSE
+ mfc0 t1,C0_SR
+ MFC0 t2,C0_BADVADDR
+ MFC0 t3,C0_EPC
+ mfc0 t4,C0_PRID
+ mflo t5
+ mfhi t6
+ SREG t0,XCP0_CAUSE(k1)
+ SREG t1,XCP0_SR(k1)
+ SREG t2,XCP0_VADDR(k1)
+ SREG t3,XCP0_EPC(k1)
+ SREG t4,XCP0_PRID(k1)
+ SREG t5,XGR_LO(k1)
+ SREG t6,XGR_HI(k1)
+
+#if CFG_EMBEDDED_PIC
+ la gp,PHYS_TO_K0(CFE_LOCORE_GLOBAL_GP)
+ LR gp,0(gp) # get our GP handle from low memory vector
+#else
+ la gp,_gp # Load up GP, not relocated so it's easy
+#endif
+
+ move a0,k0 # Pass exception type
+ move a1,k1 # Pass frame to exception handler
+ la t0,_exc_vectab # get base of exception vectors
+ srl k0,3 # convert 8-byte index to array index
+ sll k0,BPWSIZE # convert back to index appropriate for word size
+ addu t0,k0 # get vector address
+ LR t0,(t0) # to call handler
+
+ move sp,k1 # "C" gets fresh stack area
+
+ jalr t0 # Call exception handler
+ nop
+
+ move k1, sp
+ LREG AT,XGR_AT(k1)
+
+ LREG t0,XGR_LO(k1)
+ LREG t1,XGR_HI(k1)
+ mtlo t0
+ mthi t1
+
+ LREG a0,XGR_A0(k1)
+ LREG a1,XGR_A1(k1)
+ LREG a2,XGR_A2(k1)
+ LREG a3,XGR_A3(k1)
+
+ LREG t0,XGR_T0(k1)
+ LREG t1,XGR_T1(k1)
+ LREG t2,XGR_T2(k1)
+ LREG t3,XGR_T3(k1)
+ LREG t4,XGR_T4(k1)
+ LREG t5,XGR_T5(k1)
+ LREG t6,XGR_T6(k1)
+ LREG t7,XGR_T7(k1)
+
+ LREG s0,XGR_S0(k1)
+ LREG s1,XGR_S1(k1)
+ LREG s2,XGR_S2(k1)
+ LREG s3,XGR_S3(k1)
+ LREG s4,XGR_S4(k1)
+ LREG s5,XGR_S5(k1)
+ LREG s6,XGR_S6(k1)
+ LREG s7,XGR_S7(k1)
+
+ LREG t8,XGR_T8(k1)
+ LREG t9,XGR_T9(k1)
+
+ LREG gp,XGR_GP(k1)
+ LREG sp,XGR_SP(k1)
+ LREG fp,XGR_FP(k1)
+ LREG ra,XGR_RA(k1)
+
+/* do any CP0 cleanup here */
+
+ LREG v0,XGR_V0(k1)
+ LREG v1,XGR_V1(k1)
+
+ ERET
+
+ .set at
+ .set reorder
+
+
+END(_exc_entry)
+
+
+/* *********************************************************************
+ * _exc_clear_sr_exl()
+ *
+ * Clear SR(EXL) and return to caller.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_clear_sr_exl)
+
+ mfc0 t0,C0_SR
+ and t0,t0,~(0x02) # clear SR(EXL). Bit 1
+ mtc0 t0,C0_SR
+
+ HAZARD
+
+ j ra
+
+END(_exc_clear_sr_exl)
+
+/* *********************************************************************
+ * _exc_clear_sr_erl()
+ *
+ * Clear SR(ERL) and return to caller.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_clear_sr_erl)
+
+ mfc0 t0,C0_SR
+ and t0,t0,~(0x04) # clear SR(ERL). Bit 2
+ mtc0 t0,C0_SR
+
+ HAZARD
+
+ j ra
+
+END(_exc_clear_sr_erl)
+
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+
+