Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/sh/mm/tlb-urb.c
10817 views
1
/*
2
* arch/sh/mm/tlb-urb.c
3
*
4
* TLB entry wiring helpers for URB-equipped parts.
5
*
6
* Copyright (C) 2010 Matt Fleming
7
*
8
* This file is subject to the terms and conditions of the GNU General Public
9
* License. See the file "COPYING" in the main directory of this archive
10
* for more details.
11
*/
12
#include <linux/mm.h>
13
#include <linux/io.h>
14
#include <asm/tlb.h>
15
#include <asm/mmu_context.h>
16
17
/*
18
* Load the entry for 'addr' into the TLB and wire the entry.
19
*/
20
void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
21
{
22
unsigned long status, flags;
23
int urb;
24
25
local_irq_save(flags);
26
27
status = __raw_readl(MMUCR);
28
urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT;
29
status &= ~MMUCR_URC;
30
31
/*
32
* Make sure we're not trying to wire the last TLB entry slot.
33
*/
34
BUG_ON(!--urb);
35
36
urb = urb % MMUCR_URB_NENTRIES;
37
38
/*
39
* Insert this entry into the highest non-wired TLB slot (via
40
* the URC field).
41
*/
42
status |= (urb << MMUCR_URC_SHIFT);
43
__raw_writel(status, MMUCR);
44
ctrl_barrier();
45
46
/* Load the entry into the TLB */
47
__update_tlb(vma, addr, pte);
48
49
/* ... and wire it up. */
50
status = __raw_readl(MMUCR);
51
52
status &= ~MMUCR_URB;
53
status |= (urb << MMUCR_URB_SHIFT);
54
55
__raw_writel(status, MMUCR);
56
ctrl_barrier();
57
58
local_irq_restore(flags);
59
}
60
61
/*
62
* Unwire the last wired TLB entry.
63
*
64
* It should also be noted that it is not possible to wire and unwire
65
* TLB entries in an arbitrary order. If you wire TLB entry N, followed
66
* by entry N+1, you must unwire entry N+1 first, then entry N. In this
67
* respect, it works like a stack or LIFO queue.
68
*/
69
void tlb_unwire_entry(void)
70
{
71
unsigned long status, flags;
72
int urb;
73
74
local_irq_save(flags);
75
76
status = __raw_readl(MMUCR);
77
urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT;
78
status &= ~MMUCR_URB;
79
80
/*
81
* Make sure we're not trying to unwire a TLB entry when none
82
* have been wired.
83
*/
84
BUG_ON(urb++ == MMUCR_URB_NENTRIES);
85
86
urb = urb % MMUCR_URB_NENTRIES;
87
88
status |= (urb << MMUCR_URB_SHIFT);
89
__raw_writel(status, MMUCR);
90
ctrl_barrier();
91
92
local_irq_restore(flags);
93
}
94
95