Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/kern/arch/mips/vm/tlb.c
2109 views
1
#include <types.h>
2
#include <synch.h>
3
#include <kern/errno.h>
4
#include <lib.h>
5
#include <thread.h>
6
#include <cpu.h>
7
#include <spl.h>
8
#include <wchan.h>
9
#include <current.h>
10
#include <machine/coremap.h>
11
#include <vm.h>
12
#include <addrspace.h>
13
#include <machine/tlb.h>
14
15
int
16
tlb_get_free_slot() {
17
int i;
18
uint32_t tlb_hi;
19
uint32_t tlb_lo;
20
int spl;
21
22
//loop over all possible tlb entries.
23
spl = splhigh();
24
for( i = 0; i < NUM_TLB; ++i ) {
25
//read the current entry.
26
tlb_read( &tlb_hi, &tlb_lo, i );
27
28
//if it is a valid entry, continue.
29
if( tlb_lo & TLBLO_VALID )
30
continue;
31
32
//return interrupts level to what they were.
33
splx( spl );
34
35
//found a good entry.
36
return i;
37
}
38
39
splx( spl );
40
return tlb_evict();
41
}
42
43
void
44
tlb_unmap( vaddr_t vaddr ) {
45
int ix_tlb;
46
uint32_t tlb_hi;
47
uint32_t tlb_lo;
48
49
COREMAP_IS_LOCKED();
50
51
//probe the tlb for the given vaddr.
52
ix_tlb = tlb_probe( vaddr, 0 );
53
54
//if it does not exist, then there's nothing to unmap.
55
if( ix_tlb < 0 )
56
return;
57
58
//read the tlb entry.
59
tlb_read( &tlb_hi, &tlb_lo, ix_tlb );
60
61
//make sure it is a valid mapping.
62
KASSERT( tlb_lo & TLBLO_VALID );
63
64
//invalidate the entry.
65
tlb_invalidate( ix_tlb );
66
}
67
68
void
69
tlb_invalidate( int ix_tlb ) {
70
uint32_t tlb_lo;
71
uint32_t tlb_hi;
72
paddr_t paddr;
73
unsigned ix_cme;
74
75
KASSERT( ix_tlb >= 0 && ix_tlb < NUM_TLB );
76
77
COREMAP_IS_LOCKED();
78
79
//read the tlb entry given by ix_tlb.
80
tlb_read( &tlb_hi, &tlb_lo, ix_tlb );
81
82
//check to see that the entry retrieved was valid.
83
if( tlb_lo & TLBLO_VALID ) {
84
//get the physical address mapped to it.
85
paddr = tlb_lo & TLBLO_PPAGE;
86
87
//convert to coremap index.
88
ix_cme = PADDR_TO_COREMAP( paddr );
89
90
KASSERT(coremap[ix_cme].cme_tlb_ix == ix_tlb);
91
KASSERT(coremap[ix_cme].cme_cpu == curcpu->c_number);
92
93
//invalidate it.a
94
coremap[ix_cme].cme_tlb_ix = -1;
95
coremap[ix_cme].cme_cpu = 0;
96
97
tlb_write( TLBHI_INVALID( ix_tlb ), TLBLO_INVALID() , ix_tlb );
98
}
99
100
}
101
102
/**
103
* clear the current tlb, by invalidating every single entry.
104
*/
105
void
106
tlb_clear() {
107
int i;
108
109
COREMAP_IS_LOCKED();
110
for( i = 0; i < NUM_TLB; ++i )
111
tlb_invalidate( i );
112
}
113
114
115
/**
116
* Choose a random entry to evict from the tlb.
117
*/
118
int
119
tlb_evict( void ) {
120
int tlb_victim;
121
122
COREMAP_IS_LOCKED();
123
tlb_victim = random() % NUM_TLB;
124
tlb_invalidate( tlb_victim );
125
126
return tlb_victim;
127
}
128
129
/**
130
* go to sleep in wc_shootdown until someone wakes us up.
131
*/
132
void
133
tlb_shootdown_wait( ) {
134
wchan_lock( wc_shootdown );
135
UNLOCK_COREMAP();
136
wchan_sleep( wc_shootdown );
137
LOCK_COREMAP();
138
}
139
140