• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/tile/include/asm/
1/*
2 * Copyright 2010 Tilera Corporation. All Rights Reserved.
3 *
4 *   This program is free software; you can redistribute it and/or
5 *   modify it under the terms of the GNU General Public License
6 *   as published by the Free Software Foundation, version 2.
7 *
8 *   This program is distributed in the hope that it will be useful, but
9 *   WITHOUT ANY WARRANTY; without even the implied warranty of
10 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 *   NON INFRINGEMENT.  See the GNU General Public License for
12 *   more details.
13 */
14
15#ifndef _ASM_TILE_TLBFLUSH_H
16#define _ASM_TILE_TLBFLUSH_H
17
18#include <linux/mm.h>
19#include <linux/sched.h>
20#include <linux/smp.h>
21#include <asm/cacheflush.h>
22#include <asm/page.h>
23#include <hv/hypervisor.h>
24
25DECLARE_PER_CPU(int, current_asid);
26
27/* The hypervisor tells us what ASIDs are available to us. */
28extern int min_asid, max_asid;
29
30static inline unsigned long hv_page_size(const struct vm_area_struct *vma)
31{
32	return (vma->vm_flags & VM_HUGETLB) ? HPAGE_SIZE : PAGE_SIZE;
33}
34
35/* Pass as vma pointer for non-executable mapping, if no vma available. */
36#define FLUSH_NONEXEC ((const struct vm_area_struct *)-1UL)
37
38/* Flush a single user page on this cpu. */
39static inline void local_flush_tlb_page(const struct vm_area_struct *vma,
40					unsigned long addr,
41					unsigned long page_size)
42{
43	int rc = hv_flush_page(addr, page_size);
44	if (rc < 0)
45		panic("hv_flush_page(%#lx,%#lx) failed: %d",
46		      addr, page_size, rc);
47	if (!vma || (vma != FLUSH_NONEXEC && (vma->vm_flags & VM_EXEC)))
48		__flush_icache();
49}
50
51/* Flush range of user pages on this cpu. */
52static inline void local_flush_tlb_pages(const struct vm_area_struct *vma,
53					 unsigned long addr,
54					 unsigned long page_size,
55					 unsigned long len)
56{
57	int rc = hv_flush_pages(addr, page_size, len);
58	if (rc < 0)
59		panic("hv_flush_pages(%#lx,%#lx,%#lx) failed: %d",
60		      addr, page_size, len, rc);
61	if (!vma || (vma != FLUSH_NONEXEC && (vma->vm_flags & VM_EXEC)))
62		__flush_icache();
63}
64
65/* Flush all user pages on this cpu. */
66static inline void local_flush_tlb(void)
67{
68	int rc = hv_flush_all(1);   /* preserve global mappings */
69	if (rc < 0)
70		panic("hv_flush_all(1) failed: %d", rc);
71	__flush_icache();
72}
73
74/*
75 * Global pages have to be flushed a bit differently. Not a real
76 * performance problem because this does not happen often.
77 */
78static inline void local_flush_tlb_all(void)
79{
80	int i;
81	for (i = 0; ; ++i) {
82		HV_VirtAddrRange r = hv_inquire_virtual(i);
83		if (r.size == 0)
84			break;
85		local_flush_tlb_pages(NULL, r.start, PAGE_SIZE, r.size);
86		local_flush_tlb_pages(NULL, r.start, HPAGE_SIZE, r.size);
87	}
88}
89
90/*
91 * TLB flushing:
92 *
93 *  - flush_tlb() flushes the current mm struct TLBs
94 *  - flush_tlb_all() flushes all processes TLBs
95 *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
96 *  - flush_tlb_page(vma, vmaddr) flushes one page
97 *  - flush_tlb_range(vma, start, end) flushes a range of pages
98 *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
99 *  - flush_tlb_others(cpumask, mm, va) flushes TLBs on other cpus
100 *
101 * Here (as in vm_area_struct), "end" means the first byte after
102 * our end address.
103 */
104
105extern void flush_tlb_all(void);
106extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
107extern void flush_tlb_current_task(void);
108extern void flush_tlb_mm(struct mm_struct *);
109extern void flush_tlb_page(const struct vm_area_struct *, unsigned long);
110extern void flush_tlb_page_mm(const struct vm_area_struct *,
111			      struct mm_struct *, unsigned long);
112extern void flush_tlb_range(const struct vm_area_struct *,
113			    unsigned long start, unsigned long end);
114
115#define flush_tlb()     flush_tlb_current_task()
116
117#endif /* _ASM_TILE_TLBFLUSH_H */
118