xref: /OK3568_Linux_fs/kernel/arch/mips/mm/cex-oct.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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