📄 exception.s
字号:
/* ********************************************************************* * SB1250 Board Support Package * * Exception Handler File: exception.S * * Author: Mitch Lichtenberg * ********************************************************************* * * 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 "cpu_config.h" /* for definition of HAZARD and ERET */#include "exception.h"#include "bsp_config.h"#include "mipsmacros.h"/* ********************************************************************* * Check some stuff ********************************************************************* */#if ((CPUCFG_REGS32+CPUCFG_REGS64) != 1)#error "You must define exactly ONE of CPUCFG_REGS32,CPUCFG_REGS64 in cpu_config.h"#endif/* ********************************************************************* * Macros ********************************************************************* */#if CPUCFG_REGS32#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) jalr 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) la 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) la 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 raEND(_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 raEND(_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 0xca1: b 1bEND(_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 0xca1: b 1bEND(_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 t0END(_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_RELOC) 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 t9,(t0) # to call handler move sp,k1 # "C" gets fresh stack area jalr t9 # Call exception handler nop # use reg 't9' for SVR4 compat 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 reorderEND(_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 ********************************************************************* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -