xref: /kernel/linux/linux-6.6/arch/mips/mm/cex-oct.S (revision 62306a36)
162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
362306a36Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
462306a36Sopenharmony_ci * for more details.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 2006 Cavium Networks
762306a36Sopenharmony_ci * Cache error handler
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <asm/asm.h>
1162306a36Sopenharmony_ci#include <asm/regdef.h>
1262306a36Sopenharmony_ci#include <asm/mipsregs.h>
1362306a36Sopenharmony_ci#include <asm/stackframe.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/*
1662306a36Sopenharmony_ci * Handle cache error. Indicate to the second level handler whether
1762306a36Sopenharmony_ci * the exception is recoverable.
1862306a36Sopenharmony_ci */
1962306a36Sopenharmony_ci	LEAF(except_vec2_octeon)
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	.set	push
2262306a36Sopenharmony_ci	.set	mips64r2
2362306a36Sopenharmony_ci	.set	noreorder
2462306a36Sopenharmony_ci	.set	noat
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	/* due to an errata we need to read the COP0 CacheErr (Dcache)
2862306a36Sopenharmony_ci	 * before any cache/DRAM access	 */
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci	rdhwr	k0, $0	      /* get core_id */
3162306a36Sopenharmony_ci	PTR_LA	k1, cache_err_dcache
3262306a36Sopenharmony_ci	sll	k0, k0, 3
3362306a36Sopenharmony_ci	PTR_ADDU k1, k0, k1    /* k1 = &cache_err_dcache[core_id] */
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	dmfc0	k0, CP0_CACHEERR, 1
3662306a36Sopenharmony_ci	sd	k0, (k1)
3762306a36Sopenharmony_ci	dmtc0	$0, CP0_CACHEERR, 1
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	/* check whether this is a nested exception */
4062306a36Sopenharmony_ci	mfc0	k1, CP0_STATUS
4162306a36Sopenharmony_ci	andi	k1, k1, ST0_EXL
4262306a36Sopenharmony_ci	beqz	k1, 1f
4362306a36Sopenharmony_ci	 nop
4462306a36Sopenharmony_ci	j	cache_parity_error_octeon_non_recoverable
4562306a36Sopenharmony_ci	 nop
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	/* exception is recoverable */
4862306a36Sopenharmony_ci1:	j	handle_cache_err
4962306a36Sopenharmony_ci	 nop
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	.set	pop
5262306a36Sopenharmony_ci	END(except_vec2_octeon)
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci /* We need to jump to handle_cache_err so that the previous handler
5562306a36Sopenharmony_ci  * can fit within 0x80 bytes. We also move from 0xFFFFFFFFAXXXXXXX
5662306a36Sopenharmony_ci  * space (uncached) to the 0xFFFFFFFF8XXXXXXX space (cached).	*/
5762306a36Sopenharmony_ci	LEAF(handle_cache_err)
5862306a36Sopenharmony_ci	.set	push
5962306a36Sopenharmony_ci	.set	noreorder
6062306a36Sopenharmony_ci	.set	noat
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	SAVE_ALL
6362306a36Sopenharmony_ci	KMODE
6462306a36Sopenharmony_ci	jal	cache_parity_error_octeon_recoverable
6562306a36Sopenharmony_ci	nop
6662306a36Sopenharmony_ci	j	ret_from_exception
6762306a36Sopenharmony_ci	nop
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	.set pop
7062306a36Sopenharmony_ci	END(handle_cache_err)
71