18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
38c2ecf20Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
48c2ecf20Sopenharmony_ci * for more details.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 2006 Cavium Networks
78c2ecf20Sopenharmony_ci * Cache error handler
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <asm/asm.h>
118c2ecf20Sopenharmony_ci#include <asm/regdef.h>
128c2ecf20Sopenharmony_ci#include <asm/mipsregs.h>
138c2ecf20Sopenharmony_ci#include <asm/stackframe.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci/*
168c2ecf20Sopenharmony_ci * Handle cache error. Indicate to the second level handler whether
178c2ecf20Sopenharmony_ci * the exception is recoverable.
188c2ecf20Sopenharmony_ci */
198c2ecf20Sopenharmony_ci	LEAF(except_vec2_octeon)
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci	.set	push
228c2ecf20Sopenharmony_ci	.set	mips64r2
238c2ecf20Sopenharmony_ci	.set	noreorder
248c2ecf20Sopenharmony_ci	.set	noat
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci	/* due to an errata we need to read the COP0 CacheErr (Dcache)
288c2ecf20Sopenharmony_ci	 * before any cache/DRAM access	 */
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	rdhwr	k0, $0	      /* get core_id */
318c2ecf20Sopenharmony_ci	PTR_LA	k1, cache_err_dcache
328c2ecf20Sopenharmony_ci	sll	k0, k0, 3
338c2ecf20Sopenharmony_ci	PTR_ADDU k1, k0, k1    /* k1 = &cache_err_dcache[core_id] */
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	dmfc0	k0, CP0_CACHEERR, 1
368c2ecf20Sopenharmony_ci	sd	k0, (k1)
378c2ecf20Sopenharmony_ci	dmtc0	$0, CP0_CACHEERR, 1
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	/* check whether this is a nested exception */
408c2ecf20Sopenharmony_ci	mfc0	k1, CP0_STATUS
418c2ecf20Sopenharmony_ci	andi	k1, k1, ST0_EXL
428c2ecf20Sopenharmony_ci	beqz	k1, 1f
438c2ecf20Sopenharmony_ci	 nop
448c2ecf20Sopenharmony_ci	j	cache_parity_error_octeon_non_recoverable
458c2ecf20Sopenharmony_ci	 nop
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	/* exception is recoverable */
488c2ecf20Sopenharmony_ci1:	j	handle_cache_err
498c2ecf20Sopenharmony_ci	 nop
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	.set	pop
528c2ecf20Sopenharmony_ci	END(except_vec2_octeon)
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci /* We need to jump to handle_cache_err so that the previous handler
558c2ecf20Sopenharmony_ci  * can fit within 0x80 bytes. We also move from 0xFFFFFFFFAXXXXXXX
568c2ecf20Sopenharmony_ci  * space (uncached) to the 0xFFFFFFFF8XXXXXXX space (cached).	*/
578c2ecf20Sopenharmony_ci	LEAF(handle_cache_err)
588c2ecf20Sopenharmony_ci	.set	push
598c2ecf20Sopenharmony_ci	.set	noreorder
608c2ecf20Sopenharmony_ci	.set	noat
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	SAVE_ALL
638c2ecf20Sopenharmony_ci	KMODE
648c2ecf20Sopenharmony_ci	jal	cache_parity_error_octeon_recoverable
658c2ecf20Sopenharmony_ci	nop
668c2ecf20Sopenharmony_ci	j	ret_from_exception
678c2ecf20Sopenharmony_ci	nop
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	.set pop
708c2ecf20Sopenharmony_ci	END(handle_cache_err)
71