Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_Tte.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: SS_Tte.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 __SS_Tte_h__
24#define __SS_Tte_h__
25
26#include "SS_Types.h"
27#include "SS_State.h"
28
29class SS_Tte;
30
31class SS_Tte
32{
33 public:
34 SS_Tte() : tte_is_real(0), tte_is_virt(0), usage_count(0), tte_flags(0) {}
35
36 // The first part of the SS_Tte object, the virt/phys_page/mask is for caching the TTE
37 // and applying fast matching (match()) and translation (trans()). All the TTE specifics
38 // should have been tested by the inst_mmu or data_mmu functions respectively in the strand.
39 // The adapt() function is used when the tag or taddr ( translated address) is updated.
40
41 SS_Vaddr virt_page;
42 SS_Vaddr virt_mask;
43 SS_Paddr phys_page;
44 SS_Paddr phys_mask;
45
46 bool match( SS_Vaddr a ) const { return (a & virt_mask) == virt_page; }
47 SS_Paddr trans( SS_Vaddr a ) const { return (a &~ phys_mask) | phys_page; }
48
49 void adapt()
50 {
51 virt_mask = ~SS_Vaddr(0) << (tte_page_size * 3 + 13);
52 virt_page = tte_tag & virt_mask;
53 phys_page = tte_taddr & virt_mask;
54 phys_mask = virt_mask;
55 }
56
57 SS_Tte* next; // Next pointer in the free tte list in the tlb class
58 uint_t index; // The index in the TLB where this tte is located.
59
60 // The usage_count is 1 when the TTE is valid. Just before a TTE is demapped
61 // we set the usage_count to the number of strands that might use the TTE.
62 // When we are in tracing mode the usage_count is bumped to 2 and back to 1,
63 // this to prevent accidental cases where the TTE is being demapped and we
64 // we need it to produce trace output.
65
66 int_t usage_count; // A count used to hold on to the TTE
67
68 // The third part of the TTE is the actual TTE information as per architecture.
69 // E.g all the associated bits.
70
71 enum Flags
72 {
73 INVALID = 0x0000,
74 PRIVILEGED = 0x0001, // p
75 EXECUTABLE = 0x0002, // x (ep)
76 WRITEABLE = 0x0004, // w
77 NONFAULT = 0x0008, // nfo
78 INV_ENDIAN = 0x0010, // ie
79 CP = 0x0020, // cp
80 CV = 0x0040, // cv
81 SIDE_EFFECT = 0x0080, // e
82 TAG_PARITY = 0x0100, // tag parity
83 DATA_PARITY = 0x0200, // data parity
84 VALID_BIT = 0x0400, // v
85 REAL_BIT = 0x0800, // r
86 LOCK_BIT = 0x1000, // l
87 MULTI_HIT = 0x2000, // a condition that is set when TTE is looked up
88 VALID_ERROR = 0x4000 // duplicated valid bit mismatch
89 };
90
91 int valid() { return tte_is_real || tte_is_virt; }
92 int is_real() { return tte_is_real; }
93 int is_virt() { return tte_is_virt; }
94 uint8_t pid() { return tte_pid; }
95 uint16_t context() { return tte_context; }
96 uint8_t page_size() { return tte_page_size; }
97 SS_Vaddr tag() { return tte_tag; }
98 SS_Paddr taddr() { return tte_taddr; }
99
100 private:
101 void assign_flag( Flags bit, int val ) { if (val) tte_flags |= bit; else tte_flags &= ~bit; }
102 int test_flag( Flags bit ) { return 0 != (tte_flags & bit); }
103
104 public:
105 int p() { return test_flag(PRIVILEGED); }
106 int x() { return test_flag(EXECUTABLE); }
107 int w() { return test_flag(WRITEABLE); }
108 int nfo() { return test_flag(NONFAULT); }
109 int ie() { return test_flag(INV_ENDIAN); }
110 int cp() { return test_flag(CP); }
111 int cv() { return test_flag(CV); }
112 int e() { return test_flag(SIDE_EFFECT); }
113 int lock() { return test_flag(LOCK_BIT); }
114 int valid_bit() { return test_flag(VALID_BIT); }
115 int real_bit() { return test_flag(REAL_BIT); }
116 int multi_hit() { return test_flag(MULTI_HIT); }
117 int tag_parity_error() { return test_flag(TAG_PARITY); }
118 int data_parity_error() { return test_flag(DATA_PARITY); }
119 int valid_bit_error() { return test_flag(VALID_ERROR); }
120
121 void p( int f ) { assign_flag(PRIVILEGED,f); }
122 void x( int f ) { assign_flag(EXECUTABLE,f); }
123 void w( int f ) { assign_flag(WRITEABLE,f); }
124 void nfo( int f ) { assign_flag(NONFAULT,f); }
125 void ie( int f ) { assign_flag(INV_ENDIAN,f); }
126 void cp( int f ) { assign_flag(CP,f); }
127 void cv( int f ) { assign_flag(CV,f); }
128 void e( int f ) { assign_flag(SIDE_EFFECT,f); }
129 void lock( int f ) { assign_flag(LOCK_BIT,f); }
130 void valid_bit( int f ) { assign_flag(VALID_BIT,f); virt_real_update(); }
131 void real_bit( int f ) { assign_flag(REAL_BIT,f); virt_real_update(); }
132 void multi_hit( int f ) { assign_flag(MULTI_HIT,f); }
133 void tag_parity_error( int f ) { assign_flag(TAG_PARITY,f); }
134 void data_parity_error( int f ) { assign_flag(DATA_PARITY,f); }
135 void valid_bit_error( int f ) { assign_flag(VALID_ERROR,f); }
136
137 void virt_real_update()
138 {
139 // We keep two one hot bits for faster checking for
140 // valid real or valid virt TTEs. However for interface reasons
141 // we need to keep the valid and real bit as is. Just internally
142 // we use the one bit test is_real, is_virt flags.
143
144 if (valid_bit())
145 {
146 if (real_bit())
147 {
148 tte_is_real = true;
149 tte_is_virt = false;
150 }
151 else
152 {
153 tte_is_real = false;
154 tte_is_virt = true;
155 }
156 }
157 else
158 {
159 tte_is_real = false;
160 tte_is_virt = false;
161 }
162 }
163
164 void virt( int v ) { tte_is_virt = v; }
165 void real( int r ) { tte_is_real = r; }
166 void pid( uint8_t p ) { tte_pid = p; }
167 void context( uint16_t c ) { tte_context = c; }
168 void page_size( uint8_t p ) { tte_page_size = p; adapt(); }
169 void tag( SS_Vaddr t ) { tte_tag = t; adapt(); }
170 void taddr( SS_Paddr t ) { tte_taddr = t; adapt(); }
171
172 void set_real( uint16_t pid, uint8_t ps, SS_Vaddr tag, SS_Paddr dst )
173 {
174 valid_bit(true);
175 real_bit(true);
176 tte_pid = pid;
177 tte_page_size = ps;
178 tte_tag = tag;
179 tte_taddr = dst;
180 adapt();
181 }
182
183 void set_virt( uint16_t pid, uint16_t context, uint8_t ps, SS_Vaddr tag, SS_Paddr dst )
184 {
185 valid_bit(true);
186 real_bit(false);
187 tte_pid = pid;
188 tte_page_size = ps;
189 tte_tag = tag;
190 tte_context = context;
191 tte_taddr = dst;
192 adapt();
193 }
194
195 bool match_real( SS_Vaddr ra, uint_t pid ) const
196 {
197 return tte_is_real && match(ra) && (tte_pid == pid);
198 }
199
200 bool match_virt( SS_Vaddr va, uint64_t ctxt, uint_t pid ) const
201 {
202 return tte_is_virt && (tte_context == ctxt) && match(va) && (tte_pid == pid);
203 }
204
205 bool match_virt( SS_Vaddr va, uint64_t ctxt0, uint64_t ctxt1, uint_t pid ) const
206 {
207 return tte_is_virt && ((tte_context == ctxt0) || (tte_context == ctxt1)) && match(va) && (tte_pid == pid);
208 }
209
210 // This routine checks if there is a multi hit error or a tag parity error or data parity error
211 bool has_errors()
212 {
213 return multi_hit() | tag_parity_error() | data_parity_error() | valid_bit_error();
214 }
215
216 // insert_tsb_tte() inserts a sun4v TTE into this TTE. The vpn of the TTE is extended
217 // with bits 21:13 of the va, as the vpn in the TSB only has bit 63:22.
218 void insert_tsb_tte( uint16_t pid, uint64_t tag, uint64_t data, SS_Vaddr addr )
219 {
220 SS_TsbTteTag tsb_tag;
221 SS_TsbTteData tsb_data;
222
223 tte_flags = 0;
224
225 tsb_tag = tag;
226 tsb_data = data;
227
228 real_bit(0);
229 valid_bit(tsb_data.v());
230
231 tte_pid = pid;
232 tte_context = tsb_tag.context();
233 tte_page_size = tsb_data.size();
234
235 p( tsb_data.p());
236 x( tsb_data.x());
237 w( tsb_data.w());
238 nfo(tsb_data.nfo());
239 ie( tsb_data.ie());
240 cp( tsb_data.cp());
241 cv( tsb_data.cv());
242 e( tsb_data.e());
243
244 tte_tag = ((tsb_tag.va() << 9) | ((addr >> 13) & 0x1ff)) << 13;
245 tte_taddr = tsb_data.pa() << 13;
246
247 adapt();
248 }
249
250 // insert_sun4u_tsb_tte() inserts a sun4u TTE into the TTE. The vpn of the TTE is extended
251 // with bits 21:13 of the va, as the vpn in the TSB only has bit 63:22.
252 void insert_sun4u_tsb_tte( uint16_t pid, uint64_t tag, uint64_t data, SS_Vaddr addr )
253 {
254 // TODO for Ch and N1, see above
255 }
256
257 void snapshot( SS_SnapShot& ss, const char* prefix );
258 void dump(FILE *fp=stdout);
259
260 protected:
261 uint8_t tte_is_real; // Nonzero for valid real TTE
262 uint8_t tte_is_virt; // Nonzero for valid virt TTE
263 uint8_t tte_pid; // The partition for which this TTE is valid
264 uint8_t tte_page_size; // 0=8Kb, 1=64Kb, ...
265 uint16_t tte_context; // The context for virt TTE
266 uint16_t tte_flags; // The flags p,w,x,ie,nfo ...
267 SS_Vaddr tte_tag; // The TTE tag (va or ra)
268 SS_Paddr tte_taddr; // The TTE target address (pa or ra)
269};
270
271#endif
272