mmu-context.c revision 492e675116003b99dfcf0fa70084027e86bc0161
1/* MN10300 MMU context allocation and management 2 * 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public Licence 8 * as published by the Free Software Foundation; either version 9 * 2 of the Licence, or (at your option) any later version. 10 */ 11#include <linux/sched.h> 12#include <linux/mm.h> 13#include <asm/mmu_context.h> 14#include <asm/tlbflush.h> 15 16/* 17 * list of the MMU contexts last allocated on each CPU 18 */ 19unsigned long mmu_context_cache[NR_CPUS] = { 20 [0 ... NR_CPUS - 1] = MMU_CONTEXT_FIRST_VERSION * 2 - 1, 21}; 22 23/* 24 * flush the specified TLB entry 25 */ 26void local_flush_tlb_page(struct mm_struct *mm, unsigned long addr) 27{ 28 unsigned long pteu, cnx, flags; 29 30 addr &= PAGE_MASK; 31 32 /* make sure the context doesn't migrate and defend against 33 * interference from vmalloc'd regions */ 34 local_irq_save(flags); 35 36 cnx = mm_context(mm); 37 38 if (cnx != MMU_NO_CONTEXT) { 39 pteu = addr | (cnx & 0x000000ffUL); 40 IPTEU = pteu; 41 DPTEU = pteu; 42 if (IPTEL & xPTEL_V) 43 IPTEL = 0; 44 if (DPTEL & xPTEL_V) 45 DPTEL = 0; 46 } 47 48 local_irq_restore(flags); 49} 50 51/* 52 * preemptively set a TLB entry 53 */ 54void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) 55{ 56 unsigned long pteu, ptel, cnx, flags; 57 pte_t pte = *ptep; 58 59 addr &= PAGE_MASK; 60 ptel = pte_val(pte) & ~(xPTEL_UNUSED1 | xPTEL_UNUSED2); 61 62 /* make sure the context doesn't migrate and defend against 63 * interference from vmalloc'd regions */ 64 local_irq_save(flags); 65 66 cnx = mm_context(vma->vm_mm); 67 68 if (cnx != MMU_NO_CONTEXT) { 69 pteu = addr | (cnx & 0x000000ffUL); 70 if (!(pte_val(pte) & _PAGE_NX)) { 71 IPTEU = pteu; 72 if (IPTEL & xPTEL_V) 73 IPTEL = ptel; 74 } 75 DPTEU = pteu; 76 if (DPTEL & xPTEL_V) 77 DPTEL = ptel; 78 } 79 80 local_irq_restore(flags); 81} 82