Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: N2_Tlb.h | |
5 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
7 | * | |
8 | * The above named program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public | |
10 | * License version 2 as published by the Free Software Foundation. | |
11 | * | |
12 | * The above named program is distributed in the hope that it will be | |
13 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public | |
18 | * License along with this work; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
20 | * | |
21 | * ========== Copyright Header End ============================================ | |
22 | */ | |
23 | #ifndef __N2_Tlb_h__ | |
24 | #define __N2_Tlb_h__ | |
25 | ||
26 | #include "SS_Tlb.h" | |
27 | #include "N2_TrieTlb.h" | |
28 | ||
29 | class N2_Tlb : public SS_Tlb | |
30 | { | |
31 | public: | |
32 | enum | |
33 | { | |
34 | ITLB_SIZE = 64, | |
35 | DTLB_SIZE = 128 | |
36 | }; | |
37 | ||
38 | N2_Tlb( Type type, uint_t size ); | |
39 | N2_Tlb( N2_Tlb& tlb ); | |
40 | ~N2_Tlb(); | |
41 | ||
42 | // lookup_ra2pa() does a TLB lookup for real addresses. lookup_va2pa() does it | |
43 | // for virtual addresses. The multi_hit boolean is true when a TTE is returned | |
44 | // that has overlapping smaller TTEs in the TLB. The multi_hit is false otherwise. | |
45 | // | |
46 | // lookup_va2pa() and lookup_ra2pa() don't use mutexes to make them MP safe. | |
47 | // Doing so will kill the MP performance. Read write lock aren't much better | |
48 | // either. So we code TLB insert and demap carefully and have lookup allow | |
49 | // at least one concurrent insert or demap, but no more. This is checked by | |
50 | // the tlb_access_enter() and tlb_access_leave() routines: e and l will differ | |
51 | // when lookup overlaps two or more inserts and demaps. | |
52 | ||
53 | SS_Tte* lookup_ra2pa( SS_Strand* strand, SS_Vaddr ra, uint_t pid, bool* multi_hit ) | |
54 | { | |
55 | SS_Tte* t; | |
56 | uint64_t e,l; | |
57 | do | |
58 | { | |
59 | e = tlb_access_enter(); | |
60 | t = trie.lookup(pid,ra,multi_hit); | |
61 | l = tlb_access_leave(); | |
62 | } | |
63 | while (e != l); | |
64 | return t; | |
65 | } | |
66 | ||
67 | SS_Tte* lookup_va2pa( SS_Strand* strand, SS_Vaddr va, uint64_t ctxt, uint_t pid, bool* multi_hit ) | |
68 | { | |
69 | SS_Tte* t; | |
70 | uint64_t e,l; | |
71 | do | |
72 | { | |
73 | e = tlb_access_enter(); | |
74 | t = trie.lookup(pid,ctxt,va,multi_hit); | |
75 | l = tlb_access_leave(); | |
76 | } | |
77 | while (e != l); | |
78 | return t; | |
79 | } | |
80 | ||
81 | // insert_tsb_tte() inserts a TTE into the TLB (autodemapping if neccesary). If the idx is negative | |
82 | // then the TLB will find a free spot for the TTE. Otherwise the selected index (modulo size()) is used. | |
83 | // When r is 1 the tte inserted will be marked ra2pa, else it's a va2pa TTE | |
84 | ||
85 | SS_Tte* insert_tsb_tte( SS_Strand* strand, uint16_t pid, uint64_t tag, uint64_t data, SS_Vaddr va, int idx, int r ); | |
86 | ||
87 | void demap_virt( SS_Strand* strand, uint_t pid, uint_t context, SS_Vaddr va ); | |
88 | void demap_virt( SS_Strand* strand, uint_t pid, uint_t context ); | |
89 | void demap_virt( SS_Strand* strand, uint_t pid ); | |
90 | void demap_real( SS_Strand* strand, uint_t pid, SS_Vaddr va ); | |
91 | void demap_real( SS_Strand* strand, uint_t pid ); | |
92 | void demap_all ( SS_Strand* strand, uint_t pid ); | |
93 | void demap_auto( SS_Strand* strand, SS_Tte* new_tte, uint_t new_idx ); | |
94 | ||
95 | void snapshot( SS_SnapShot& ss, const char* prefix="", const char* inst="inst" ); | |
96 | ||
97 | void insert( SS_Tte* tte ); | |
98 | ||
99 | // set_used() sets the used flag of TLB entry i | |
100 | void set_used( uint_t i ) | |
101 | { | |
102 | if (!used[i]) | |
103 | { | |
104 | used[i] = true; | |
105 | if (++used_count == tlb_size) | |
106 | clear_used(); | |
107 | } | |
108 | } | |
109 | ||
110 | // clr_used() clears the used flag of TLB entry i | |
111 | void clr_used( uint_t i ) | |
112 | { | |
113 | if (used[i]) | |
114 | { | |
115 | used[i] = false; | |
116 | --used_count; | |
117 | } | |
118 | } | |
119 | ||
120 | protected: | |
121 | N2_TrieTlb trie; | |
122 | ||
123 | static SS_Tlb* n2_clone( SS_Tlb* ); | |
124 | ||
125 | bool* used; | |
126 | uint_t used_count; | |
127 | ||
128 | void clear_used() | |
129 | { | |
130 | for (uint_t i=0; i < tlb_size; i++) | |
131 | used[i] = false; | |
132 | used_count = 0; | |
133 | } | |
134 | ||
135 | uint_t get_free_tte() | |
136 | { | |
137 | uint_t i; | |
138 | ||
139 | for (i=0; i < tlb_size; i++) | |
140 | { | |
141 | SS_Tte* tte = ptr_table[i]; | |
142 | if (!tte->valid()) | |
143 | return i; | |
144 | } | |
145 | ||
146 | for (i=0; i < tlb_size; i++) | |
147 | if (!used[i]) | |
148 | return i; | |
149 | ||
150 | clear_used(); | |
151 | ||
152 | return tlb_size - 1; | |
153 | } | |
154 | }; | |
155 | ||
156 | ||
157 | #endif |