200 lines
		
	
	
	
		
			4 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
		
		
			
		
	
	
			200 lines
		
	
	
	
		
			4 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * arch/score/mm/tlbex.S
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Score Processor version.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
							 | 
						||
| 
								 | 
							
								 *  Lennox Wu <lennox.wu@sunplusct.com>
							 | 
						||
| 
								 | 
							
								 *  Chen Liqin <liqin.chen@sunplusct.com>
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This program is free software; you can redistribute it and/or modify
							 | 
						||
| 
								 | 
							
								 * it under the terms of the GNU General Public License as published by
							 | 
						||
| 
								 | 
							
								 * the Free Software Foundation; either version 2 of the License, or
							 | 
						||
| 
								 | 
							
								 * (at your option) any later version.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This program is distributed in the hope that it will be useful,
							 | 
						||
| 
								 | 
							
								 * but WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						||
| 
								 | 
							
								 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
							 | 
						||
| 
								 | 
							
								 * GNU General Public License for more details.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * You should have received a copy of the GNU General Public License
							 | 
						||
| 
								 | 
							
								 * along with this program; if not, see the file COPYING, or write
							 | 
						||
| 
								 | 
							
								 * to the Free Software Foundation, Inc.,
							 | 
						||
| 
								 | 
							
								 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <asm/asmmacro.h>
							 | 
						||
| 
								 | 
							
								#include <asm/pgtable-bits.h>
							 | 
						||
| 
								 | 
							
								#include <asm/scoreregs.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								* After this macro runs, the pte faulted on is
							 | 
						||
| 
								 | 
							
								* in register PTE, a ptr into the table in which
							 | 
						||
| 
								 | 
							
								* the pte belongs is in PTR.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
									.macro	load_pte, pte, ptr
							 | 
						||
| 
								 | 
							
									la	\ptr, pgd_current
							 | 
						||
| 
								 | 
							
									lw	\ptr, [\ptr, 0]
							 | 
						||
| 
								 | 
							
									mfcr	\pte, cr6
							 | 
						||
| 
								 | 
							
									srli	\pte, \pte, 22
							 | 
						||
| 
								 | 
							
									slli	\pte, \pte, 2
							 | 
						||
| 
								 | 
							
									add	\ptr, \ptr, \pte
							 | 
						||
| 
								 | 
							
									lw	\ptr, [\ptr, 0]
							 | 
						||
| 
								 | 
							
									mfcr	\pte, cr6
							 | 
						||
| 
								 | 
							
									srli	\pte, \pte, 10
							 | 
						||
| 
								 | 
							
									andi	\pte, 0xffc
							 | 
						||
| 
								 | 
							
									add	\ptr, \ptr, \pte
							 | 
						||
| 
								 | 
							
									lw	\pte, [\ptr, 0]
							 | 
						||
| 
								 | 
							
									.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									.macro	pte_reload, ptr
							 | 
						||
| 
								 | 
							
									lw	\ptr, [\ptr, 0]
							 | 
						||
| 
								 | 
							
									mtcr	\ptr, cr12
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									.macro do_fault, write
							 | 
						||
| 
								 | 
							
									SAVE_ALL
							 | 
						||
| 
								 | 
							
									mfcr	r6, cr6
							 | 
						||
| 
								 | 
							
									mv	r4, r0
							 | 
						||
| 
								 | 
							
									ldi	r5, \write
							 | 
						||
| 
								 | 
							
									la	r8, do_page_fault
							 | 
						||
| 
								 | 
							
									brl	r8
							 | 
						||
| 
								 | 
							
									j	ret_from_exception
							 | 
						||
| 
								 | 
							
									.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									.macro	pte_writable, pte, ptr, label
							 | 
						||
| 
								 | 
							
									andi	\pte, 0x280
							 | 
						||
| 
								 | 
							
									cmpi.c	\pte, 0x280
							 | 
						||
| 
								 | 
							
									bne	\label
							 | 
						||
| 
								 | 
							
									lw	\pte, [\ptr, 0]		/*reload PTE*/
							 | 
						||
| 
								 | 
							
									.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Make PTE writable, update software status bits as well,
							 | 
						||
| 
								 | 
							
								 * then store at PTR.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
									.macro	pte_makewrite, pte, ptr
							 | 
						||
| 
								 | 
							
									ori	\pte, 0x426
							 | 
						||
| 
								 | 
							
									sw	\pte, [\ptr, 0]
							 | 
						||
| 
								 | 
							
									.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									.text
							 | 
						||
| 
								 | 
							
								ENTRY(score7_FTLB_refill_Handler)
							 | 
						||
| 
								 | 
							
									la	r31, pgd_current	/* get pgd pointer */
							 | 
						||
| 
								 | 
							
									lw	r31, [r31, 0]		/* get the address of PGD */
							 | 
						||
| 
								 | 
							
									mfcr	r30, cr6
							 | 
						||
| 
								 | 
							
									srli	r30, r30, 22		/* PGDIR_SHIFT = 22*/
							 | 
						||
| 
								 | 
							
									slli	r30, r30, 2
							 | 
						||
| 
								 | 
							
									add	r31, r31, r30
							 | 
						||
| 
								 | 
							
									lw	r31, [r31, 0]		/* get the address of the start address of PTE table */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									mfcr	r30, cr9
							 | 
						||
| 
								 | 
							
									andi	r30, 0xfff 		/* equivalent to get PET index and right shift 2 bits */
							 | 
						||
| 
								 | 
							
									add	r31, r31, r30
							 | 
						||
| 
								 | 
							
									lw	r30, [r31, 0]		/* load pte entry */
							 | 
						||
| 
								 | 
							
									mtcr	r30, cr12
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									mtrtlb
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									rte				/* 6 cycles to make sure tlb entry works */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ENTRY(score7_KSEG_refill_Handler)
							 | 
						||
| 
								 | 
							
									la	r31, pgd_current	/* get pgd pointer */
							 | 
						||
| 
								 | 
							
									lw	r31, [r31, 0]		/* get the address of PGD */
							 | 
						||
| 
								 | 
							
									mfcr	r30, cr6
							 | 
						||
| 
								 | 
							
									srli	r30, r30, 22		/* PGDIR_SHIFT = 22 */
							 | 
						||
| 
								 | 
							
									slli	r30, r30, 2
							 | 
						||
| 
								 | 
							
									add	r31, r31, r30
							 | 
						||
| 
								 | 
							
									lw	r31, [r31, 0]		/* get the address of the start address of PTE table */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									mfcr	r30, cr6		/* get Bad VPN */
							 | 
						||
| 
								 | 
							
									srli	r30, r30, 10
							 | 
						||
| 
								 | 
							
									andi	r30, 0xffc		/* PTE VPN mask (bit 11~2) */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									add	r31, r31, r30
							 | 
						||
| 
								 | 
							
									lw	r30, [r31, 0]		/* load pte entry */
							 | 
						||
| 
								 | 
							
									mtcr	r30, cr12
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									mtrtlb
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									rte				/* 6 cycles to make sure tlb entry works */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								nopage_tlbl:
							 | 
						||
| 
								 | 
							
									do_fault	0		/* Read */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ENTRY(handle_tlb_refill)
							 | 
						||
| 
								 | 
							
									load_pte	r30, r31
							 | 
						||
| 
								 | 
							
									pte_writable	r30, r31, handle_tlb_refill_nopage
							 | 
						||
| 
								 | 
							
									pte_makewrite	r30, r31	/* Access|Modify|Dirty|Valid */
							 | 
						||
| 
								 | 
							
									pte_reload	r31
							 | 
						||
| 
								 | 
							
									mtrtlb
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									rte
							 | 
						||
| 
								 | 
							
								handle_tlb_refill_nopage:
							 | 
						||
| 
								 | 
							
									do_fault	0		/* Read */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ENTRY(handle_tlb_invaild)
							 | 
						||
| 
								 | 
							
									load_pte	r30, r31
							 | 
						||
| 
								 | 
							
									stlb				/* find faulting entry */
							 | 
						||
| 
								 | 
							
									pte_writable	r30, r31, handle_tlb_invaild_nopage
							 | 
						||
| 
								 | 
							
									pte_makewrite	r30, r31	/* Access|Modify|Dirty|Valid */
							 | 
						||
| 
								 | 
							
									pte_reload	r31
							 | 
						||
| 
								 | 
							
									mtptlb
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									rte
							 | 
						||
| 
								 | 
							
								handle_tlb_invaild_nopage:
							 | 
						||
| 
								 | 
							
									do_fault	0		/* Read */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ENTRY(handle_mod)
							 | 
						||
| 
								 | 
							
									load_pte	r30, r31
							 | 
						||
| 
								 | 
							
									stlb				/* find faulting entry */
							 | 
						||
| 
								 | 
							
									andi	r30, _PAGE_WRITE	/* Writable? */
							 | 
						||
| 
								 | 
							
									cmpz.c	r30
							 | 
						||
| 
								 | 
							
									beq	nowrite_mod
							 | 
						||
| 
								 | 
							
									lw	r30, [r31, 0]		/* reload into r30 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Present and writable bits set, set accessed and dirty bits. */
							 | 
						||
| 
								 | 
							
									pte_makewrite	r30, r31
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Now reload the entry into the tlb. */
							 | 
						||
| 
								 | 
							
									pte_reload	r31
							 | 
						||
| 
								 | 
							
									mtptlb
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									nop
							 | 
						||
| 
								 | 
							
									rte
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								nowrite_mod:
							 | 
						||
| 
								 | 
							
									do_fault	1	/* Write */
							 |