1*4882a593Smuzhiyun/* 2*4882a593Smuzhiyun * This file is subject to the terms and conditions of the GNU General Public 3*4882a593Smuzhiyun * License. See the file "COPYING" in the main directory of this archive 4*4882a593Smuzhiyun * for more details. 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * Copyright (C) 2006 Cavium Networks 7*4882a593Smuzhiyun * Cache error handler 8*4882a593Smuzhiyun */ 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun#include <asm/asm.h> 11*4882a593Smuzhiyun#include <asm/regdef.h> 12*4882a593Smuzhiyun#include <asm/mipsregs.h> 13*4882a593Smuzhiyun#include <asm/stackframe.h> 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun/* 16*4882a593Smuzhiyun * Handle cache error. Indicate to the second level handler whether 17*4882a593Smuzhiyun * the exception is recoverable. 18*4882a593Smuzhiyun */ 19*4882a593Smuzhiyun LEAF(except_vec2_octeon) 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun .set push 22*4882a593Smuzhiyun .set mips64r2 23*4882a593Smuzhiyun .set noreorder 24*4882a593Smuzhiyun .set noat 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun /* due to an errata we need to read the COP0 CacheErr (Dcache) 28*4882a593Smuzhiyun * before any cache/DRAM access */ 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun rdhwr k0, $0 /* get core_id */ 31*4882a593Smuzhiyun PTR_LA k1, cache_err_dcache 32*4882a593Smuzhiyun sll k0, k0, 3 33*4882a593Smuzhiyun PTR_ADDU k1, k0, k1 /* k1 = &cache_err_dcache[core_id] */ 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun dmfc0 k0, CP0_CACHEERR, 1 36*4882a593Smuzhiyun sd k0, (k1) 37*4882a593Smuzhiyun dmtc0 $0, CP0_CACHEERR, 1 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun /* check whether this is a nested exception */ 40*4882a593Smuzhiyun mfc0 k1, CP0_STATUS 41*4882a593Smuzhiyun andi k1, k1, ST0_EXL 42*4882a593Smuzhiyun beqz k1, 1f 43*4882a593Smuzhiyun nop 44*4882a593Smuzhiyun j cache_parity_error_octeon_non_recoverable 45*4882a593Smuzhiyun nop 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun /* exception is recoverable */ 48*4882a593Smuzhiyun1: j handle_cache_err 49*4882a593Smuzhiyun nop 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun .set pop 52*4882a593Smuzhiyun END(except_vec2_octeon) 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun /* We need to jump to handle_cache_err so that the previous handler 55*4882a593Smuzhiyun * can fit within 0x80 bytes. We also move from 0xFFFFFFFFAXXXXXXX 56*4882a593Smuzhiyun * space (uncached) to the 0xFFFFFFFF8XXXXXXX space (cached). */ 57*4882a593Smuzhiyun LEAF(handle_cache_err) 58*4882a593Smuzhiyun .set push 59*4882a593Smuzhiyun .set noreorder 60*4882a593Smuzhiyun .set noat 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun SAVE_ALL 63*4882a593Smuzhiyun KMODE 64*4882a593Smuzhiyun jal cache_parity_error_octeon_recoverable 65*4882a593Smuzhiyun nop 66*4882a593Smuzhiyun j ret_from_exception 67*4882a593Smuzhiyun nop 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun .set pop 70*4882a593Smuzhiyun END(handle_cache_err) 71