tlbex-r4k.s

来自「linux-2.4.29操作系统的源码」· S 代码 · 共 224 行

S
224
字号
/* * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 2000 Silicon Graphics, Inc. * Written by Ulf Carlsson (ulfc@engr.sgi.com) * Copyright (C) 2002  Maciej W. Rozycki */#include <linux/config.h>#include <linux/init.h>#include <linux/threads.h>#include <asm/asm.h>#include <asm/hazards.h>#include <asm/regdef.h>#include <asm/mipsregs.h>#include <asm/pgtable.h>#include <asm/stackframe.h>#include <asm/war.h>#define PGD_INDX_MASK	((_PTRS_PER_PGD - 1) << _PGD_T_LOG2)#define PMD_INDX_MASK	((_PTRS_PER_PMD - 1) << _PMD_T_LOG2)#define PTE_INDX_MASK	((_PTRS_PER_PTE - 1) << _PTE_T_LOG2)#define PTEP_INDX_MASK	((_PTRS_PER_PTE >> 1 - 1) << (_PTE_T_LOG2 + 1))	.data	.comm	pgd_current, NR_CPUS * 8, 8	/*	 * After this macro runs we have a pointer to the pte of the address	 * that caused the fault in PTR.	 */	.macro	LOAD_PTE2, ptr, tmp, kaddr#ifdef CONFIG_SMP	dmfc0	\ptr, CP0_CONTEXT	dmfc0	\tmp, CP0_BADVADDR	dsra	\ptr, 23			# get pgd_current[cpu]#else	dmfc0	\tmp, CP0_BADVADDR	dla	\ptr, pgd_current#endif	bltz	\tmp, \kaddr	 ld	\ptr, (\ptr)	dsrl	\tmp, PGDIR_SHIFT - 3		# get pgd offset in bytes	andi	\tmp, PGD_INDX_MASK	daddu	\ptr, \tmp			# add in pgd offset	dmfc0	\tmp, CP0_BADVADDR	ld	\ptr, (\ptr)			# get pmd pointer	dsrl	\tmp, PMD_SHIFT - 3		# get pmd offset in bytes	andi	\tmp, PMD_INDX_MASK	daddu	\ptr, \tmp			# add in pmd offset	dmfc0	\tmp, CP0_XCONTEXT	ld	\ptr, (\ptr)			# get pte pointer	andi	\tmp, PTEP_INDX_MASK		# get pte offset	daddu	\ptr, \tmp	.endm	/*	 * Ditto for the kernel table.	 */	.macro	LOAD_KPTE2, ptr, tmp, not_vmalloc	/*	 * First, determine that the address is in/above vmalloc range.	 */	dmfc0	\tmp, CP0_BADVADDR	dli	\ptr, VMALLOC_START	/*	 * Now find offset into kptbl.	 */	dsubu	\tmp, \tmp, \ptr	dla	\ptr, kptbl	dsrl	\tmp, _PAGE_SHIFT + 1		# get vpn2	dsll	\tmp, 4				# byte offset of pte	daddu	\ptr, \ptr, \tmp	/*	 * Determine that fault address is within vmalloc range.	 */	dla	\tmp, ekptbl	slt	\tmp, \ptr, \tmp	beqz	\tmp, \not_vmalloc		# not vmalloc	 nop	.endm	/*	 * This places the even/odd pte pair in the page table at the pte	 * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1.	 */	.macro	PTE_RELOAD, pte0, pte1	dsrl	\pte0, 6			# convert to entrylo0	dmtc0	\pte0, CP0_ENTRYLO0		# load it	dsrl	\pte1, 6			# convert to entrylo1	dmtc0	\pte1, CP0_ENTRYLO1		# load it	.endm	.text	.set	noreorder	.set	mips3	__INIT	.align	5LEAF(except_vec0_generic)	.set	noat	PANIC("Unused vector called")1:	b	1b	 nopEND(except_vec0_generic)	/*	 * TLB refill handlers for the R4000 and SB1.	 * Attention:  We may only use 32 instructions / 128 bytes.	 */	.align  5LEAF(except_vec1_r4k)	.set    noat	dla     k0, handle_vec1_r4k	jr      k0	 nopEND(except_vec1_r4k)LEAF(except_vec1_sb1)#if BCM1250_M3_WAR	dmfc0	k0, CP0_BADVADDR	dmfc0	k1, CP0_ENTRYHI	xor	k0, k1	dsrl	k0, k0, _PAGE_SHIFT + 1	bnez	k0, 1f#endif	.set    noat	dla     k0, handle_vec1_r4k	jr      k0	 nop1:	eret	nopEND(except_vec1_sb1)	__FINIT	.align  5LEAF(handle_vec1_r4k)	.set    noat	LOAD_PTE2 k1 k0 9f	ld	k0, 0(k1)			# get even pte	ld	k1, 8(k1)			# get odd pte	PTE_RELOAD k0 k1	rm9000_tlb_hazard	b	1f	 tlbwr1:	nop	rm9000_tlb_hazard	eret9:						# handle the vmalloc range	LOAD_KPTE2 k1 k0 invalid_vmalloc_address	ld	k0, 0(k1)			# get even pte	ld	k1, 8(k1)			# get odd pte	PTE_RELOAD k0 k1	rm9000_tlb_hazard	b	1f	 tlbwr1:	nop	rm9000_tlb_hazard	eretEND(handle_vec1_r4k)	__INIT	/*	 * TLB refill handler for the R10000.	 * Attention:  We may only use 32 instructions / 128 bytes.	 */	.align	5LEAF(except_vec1_r10k)	.set    noat	dla     k0, handle_vec1_r10k	jr      k0	 nopEND(except_vec1_r10k)	__FINIT	.align	5LEAF(handle_vec1_r10k)	.set	noat	LOAD_PTE2 k1 k0 9f	ld	k0, 0(k1)			# get even pte	ld	k1, 8(k1)			# get odd pte	PTE_RELOAD k0 k1	rm9000_tlb_hazard	nop	tlbwr	rm9000_tlb_hazard	eret9:						# handle the vmalloc range	LOAD_KPTE2 k1 k0 invalid_vmalloc_address	ld	k0, 0(k1)			# get even pte	ld	k1, 8(k1)			# get odd pte	PTE_RELOAD k0 k1	rm9000_tlb_hazard	nop	tlbwr	rm9000_tlb_hazard	eretEND(handle_vec1_r10k)	.align	5LEAF(invalid_vmalloc_address)	.set	noat	PANIC("Invalid kernel address")1:	b	1b	 nopEND(invalid_vmalloc_address)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?