2005-04-16 15:20:36 -07:00
/*
* arch / sh / mm / tlb - sh4 . c
*
* SH - 4 specific TLB operations
*
* Copyright ( C ) 1999 Niibe Yutaka
2007-09-21 11:55:03 +09:00
* Copyright ( C ) 2002 - 2007 Paul Mundt
2005-04-16 15:20:36 -07:00
*
* Released under the terms of the GNU GPL v2 .0 .
*/
2007-03-05 19:46:47 +09:00
# include <linux/kernel.h>
# include <linux/mm.h>
2007-09-21 11:55:03 +09:00
# include <linux/io.h>
2005-04-16 15:20:36 -07:00
# include <asm/system.h>
# include <asm/mmu_context.h>
2007-03-05 19:46:47 +09:00
# include <asm/cacheflush.h>
2009-07-29 00:12:17 +09:00
void __update_tlb ( struct vm_area_struct * vma , unsigned long address , pte_t pte )
2007-03-05 19:46:47 +09:00
{
2009-07-29 00:12:17 +09:00
unsigned long flags , pteval , vpn ;
2007-03-05 19:46:47 +09:00
2009-07-29 00:12:17 +09:00
/*
* Handle debugger faulting in for debugee .
*/
2009-07-29 22:06:58 +09:00
if ( vma & & current - > active_mm ! = vma - > vm_mm )
2007-03-05 19:46:47 +09:00
return ;
local_irq_save ( flags ) ;
/* Set PTEH register */
vpn = ( address & MMU_VPN_MASK ) | get_asid ( ) ;
ctrl_outl ( vpn , MMU_PTEH ) ;
2007-09-21 11:55:03 +09:00
pteval = pte . pte_low ;
2007-03-05 19:46:47 +09:00
/* Set PTEA register */
2007-09-21 11:55:03 +09:00
# ifdef CONFIG_X2TLB
/*
* For the extended mode TLB this is trivial , only the ESZ and
* EPR bits need to be written out to PTEA , with the remainder of
* the protection bits ( with the exception of the compat - mode SZ
* and PR bits , which are cleared ) being written out in PTEL .
*/
ctrl_outl ( pte . pte_high , MMU_PTEA ) ;
# else
2009-08-20 13:27:44 +09:00
if ( cpu_data - > flags & CPU_HAS_PTEA ) {
/* The last 3 bits and the first one of pteval contains
* the PTEA timing control and space attribute bits
*/
ctrl_outl ( copy_ptea_attributes ( pteval ) , MMU_PTEA ) ;
}
2007-09-21 11:55:03 +09:00
# endif
2007-03-05 19:46:47 +09:00
/* Set PTEL register */
pteval & = _PAGE_FLAGS_HARDWARE_MASK ; /* drop software flags */
2007-07-31 17:07:28 +09:00
# ifdef CONFIG_CACHE_WRITETHROUGH
2007-03-05 19:46:47 +09:00
pteval | = _PAGE_WT ;
# endif
/* 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-16 15:20:36 -07:00
2007-11-30 17:06:36 +09:00
void __uses_jump_to_uncached local_flush_tlb_one ( unsigned long asid ,
unsigned long page )
2005-04-16 15:20:36 -07:00
{
unsigned long addr , data ;
/*
* 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_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT ;
data = page | asid ; /* VALID bit is off */
2007-11-30 17:06:36 +09:00
jump_to_uncached ( ) ;
2005-04-16 15:20:36 -07:00
ctrl_outl ( data , addr ) ;
2007-11-30 17:06:36 +09:00
back_to_cached ( ) ;
2005-04-16 15:20:36 -07:00
}