2005-04-17 02:20:36 +04:00
/*
* arch / sh / mm / tlb - sh3 . c
*
* SH - 3 specific TLB operations
*
* Copyright ( C ) 1999 Niibe Yutaka
* Copyright ( C ) 2002 Paul Mundt
*
* Released under the terms of the GNU GPL v2 .0 .
*/
2007-03-05 13:46:47 +03:00
# include <linux/signal.h>
# include <linux/sched.h>
# include <linux/kernel.h>
# include <linux/errno.h>
# include <linux/string.h>
# include <linux/types.h>
# include <linux/ptrace.h>
# include <linux/mman.h>
# include <linux/mm.h>
# include <linux/smp.h>
# include <linux/interrupt.h>
2005-04-17 02:20:36 +04:00
# include <asm/system.h>
2007-03-05 13:46:47 +03:00
# include <asm/io.h>
# include <asm/uaccess.h>
# include <asm/pgalloc.h>
2005-04-17 02:20:36 +04:00
# include <asm/mmu_context.h>
2007-03-05 13:46:47 +03:00
# include <asm/cacheflush.h>
2009-07-28 19:12:17 +04:00
void __update_tlb ( struct vm_area_struct * vma , unsigned long address , pte_t pte )
2007-03-05 13:46:47 +03:00
{
2009-07-28 19:12:17 +04:00
unsigned long flags , pteval , vpn ;
2007-03-05 13:46:47 +03:00
2009-07-28 19:12:17 +04:00
/*
* Handle debugger faulting in for debugee .
*/
2009-07-29 17:06:58 +04:00
if ( vma & & current - > active_mm ! = vma - > vm_mm )
2007-03-05 13:46:47 +03:00
return ;
local_irq_save ( flags ) ;
/* Set PTEH register */
vpn = ( address & MMU_VPN_MASK ) | get_asid ( ) ;
ctrl_outl ( vpn , MMU_PTEH ) ;
pteval = pte_val ( pte ) ;
/* Set PTEL register */
pteval & = _PAGE_FLAGS_HARDWARE_MASK ; /* drop software flags */
/* conveniently, we want all the software flags to be 0 anyway */
ctrl_outl ( pteval , MMU_PTEL ) ;
/* Load the TLB */
asm volatile ( " ldtlb " : /* no output */ : /* no input */ : " memory " ) ;
local_irq_restore ( flags ) ;
}
2005-04-17 02:20:36 +04:00
2006-12-25 13:28:54 +03:00
void local_flush_tlb_one ( unsigned long asid , unsigned long page )
2005-04-17 02:20:36 +04:00
{
unsigned long addr , data ;
int i , ways = MMU_NTLB_WAYS ;
/*
* NOTE : PTEH . ASID should be set to this MM
* _AND_ we need to write ASID to the array .
*
* It would be simple if we didn ' t need to set PTEH . ASID . . .
*/
addr = MMU_TLB_ADDRESS_ARRAY | ( page & 0x1F000 ) ;
data = ( page & 0xfffe0000 ) | asid ; /* VALID bit is off */
2005-11-07 11:58:28 +03:00
2006-12-25 04:19:56 +03:00
if ( ( current_cpu_data . flags & CPU_HAS_MMU_PAGE_ASSOC ) ) {
2005-04-17 02:20:36 +04:00
addr | = MMU_PAGE_ASSOC_BIT ;
ways = 1 ; /* we already know the way .. */
}
for ( i = 0 ; i < ways ; i + + )
ctrl_outl ( data , addr + ( i < < 8 ) ) ;
}