blob: c3c194d4031e6225f5243beacd97a25e8f5c7ba9 [file] [log] [blame]
David Howellsb920de12008-02-08 04:19:31 -08001/* MN10300 TLB flushing functions
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#ifndef _ASM_TLBFLUSH_H
12#define _ASM_TLBFLUSH_H
13
14#include <asm/processor.h>
15
Akira Takeuchia9bc60e2010-10-27 17:28:49 +010016struct tlb_state {
17 struct mm_struct *active_mm;
18 int state;
19};
20DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate);
21
David Howells492e6752010-10-27 17:28:49 +010022/**
23 * local_flush_tlb - Flush the current MM's entries from the local CPU's TLBs
24 */
25static inline void local_flush_tlb(void)
26{
27 int w;
28 asm volatile(
29 " mov %1,%0 \n"
30 " or %2,%0 \n"
31 " mov %0,%1 \n"
32 : "=d"(w)
33 : "m"(MMUCTR), "i"(MMUCTR_IIV|MMUCTR_DIV)
34 : "cc", "memory");
35}
David Howellsb920de12008-02-08 04:19:31 -080036
David Howells492e6752010-10-27 17:28:49 +010037/**
38 * local_flush_tlb_all - Flush all entries from the local CPU's TLBs
39 */
Akira Takeuchia9bc60e2010-10-27 17:28:49 +010040static inline void local_flush_tlb_all(void)
41{
42 local_flush_tlb();
43}
David Howells492e6752010-10-27 17:28:49 +010044
45/**
46 * local_flush_tlb_one - Flush one entry from the local CPU's TLBs
47 */
Akira Takeuchia9bc60e2010-10-27 17:28:49 +010048static inline void local_flush_tlb_one(unsigned long addr)
49{
50 local_flush_tlb();
51}
David Howells492e6752010-10-27 17:28:49 +010052
53/**
54 * local_flush_tlb_page - Flush a page's entry from the local CPU's TLBs
55 * @mm: The MM to flush for
56 * @addr: The address of the target page in RAM (not its page struct)
57 */
Akira Takeuchia9bc60e2010-10-27 17:28:49 +010058static inline
59void local_flush_tlb_page(struct mm_struct *mm, unsigned long addr)
60{
61 unsigned long pteu, flags, cnx;
David Howellsb920de12008-02-08 04:19:31 -080062
Akira Takeuchia9bc60e2010-10-27 17:28:49 +010063 addr &= PAGE_MASK;
64
65 local_irq_save(flags);
66
67 cnx = 1;
68#ifdef CONFIG_MN10300_TLB_USE_PIDR
69 cnx = mm->context.tlbpid[smp_processor_id()];
70#endif
71 if (cnx) {
72 pteu = addr;
73#ifdef CONFIG_MN10300_TLB_USE_PIDR
74 pteu |= cnx & xPTEU_PID;
75#endif
76 IPTEU = pteu;
77 DPTEU = pteu;
78 if (IPTEL & xPTEL_V)
79 IPTEL = 0;
80 if (DPTEL & xPTEL_V)
81 DPTEL = 0;
82 }
83 local_irq_restore(flags);
84}
David Howellsb920de12008-02-08 04:19:31 -080085
86/*
87 * TLB flushing:
88 *
89 * - flush_tlb() flushes the current mm struct TLBs
90 * - flush_tlb_all() flushes all processes TLBs
91 * - flush_tlb_mm(mm) flushes the specified mm context TLB's
92 * - flush_tlb_page(vma, vmaddr) flushes one page
93 * - flush_tlb_range(mm, start, end) flushes a range of pages
94 * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
95 */
96#define flush_tlb_all() \
97do { \
98 preempt_disable(); \
David Howells492e6752010-10-27 17:28:49 +010099 local_flush_tlb_all(); \
David Howellsb920de12008-02-08 04:19:31 -0800100 preempt_enable(); \
101} while (0)
102
103#define flush_tlb_mm(mm) \
104do { \
105 preempt_disable(); \
David Howells492e6752010-10-27 17:28:49 +0100106 local_flush_tlb_all(); \
David Howellsb920de12008-02-08 04:19:31 -0800107 preempt_enable(); \
108} while (0)
109
110#define flush_tlb_range(vma, start, end) \
111do { \
112 unsigned long __s __attribute__((unused)) = (start); \
113 unsigned long __e __attribute__((unused)) = (end); \
114 preempt_disable(); \
David Howells492e6752010-10-27 17:28:49 +0100115 local_flush_tlb_all(); \
David Howellsb920de12008-02-08 04:19:31 -0800116 preempt_enable(); \
117} while (0)
118
David Howells492e6752010-10-27 17:28:49 +0100119#define flush_tlb_page(vma, addr) local_flush_tlb_page((vma)->vm_mm, addr)
120#define flush_tlb() flush_tlb_all()
David Howellsb920de12008-02-08 04:19:31 -0800121
David Howellsb920de12008-02-08 04:19:31 -0800122#define flush_tlb_kernel_range(start, end) \
123do { \
124 unsigned long __s __attribute__((unused)) = (start); \
125 unsigned long __e __attribute__((unused)) = (end); \
126 flush_tlb_all(); \
127} while (0)
128
David Howellsb920de12008-02-08 04:19:31 -0800129#define flush_tlb_pgtables(mm, start, end) do {} while (0)
130
131#endif /* _ASM_TLBFLUSH_H */