ARM: Don't downconvert ExtMachInsts to MachInsts.
[gem5.git] / src / arch / x86 / miscregfile.cc
1 /*
2 * Copyright (c) 2003-2006, 2008 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Gabe Black
29 */
30
31 /*
32 * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
33 * All rights reserved.
34 *
35 * Redistribution and use of this software in source and binary forms,
36 * with or without modification, are permitted provided that the
37 * following conditions are met:
38 *
39 * The software must be used only for Non-Commercial Use which means any
40 * use which is NOT directed to receiving any direct monetary
41 * compensation for, or commercial advantage from such use. Illustrative
42 * examples of non-commercial use are academic research, personal study,
43 * teaching, education and corporate research & development.
44 * Illustrative examples of commercial use are distributing products for
45 * commercial advantage and providing services using the software for
46 * commercial advantage.
47 *
48 * If you wish to use this software or functionality therein that may be
49 * covered by patents for commercial use, please contact:
50 * Director of Intellectual Property Licensing
51 * Office of Strategy and Technology
52 * Hewlett-Packard Company
53 * 1501 Page Mill Road
54 * Palo Alto, California 94304
55 *
56 * Redistributions of source code must retain the above copyright notice,
57 * this list of conditions and the following disclaimer. Redistributions
58 * in binary form must reproduce the above copyright notice, this list of
59 * conditions and the following disclaimer in the documentation and/or
60 * other materials provided with the distribution. Neither the name of
61 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
62 * contributors may be used to endorse or promote products derived from
63 * this software without specific prior written permission. No right of
64 * sublicense is granted herewith. Derivatives of the software and
65 * output created using the software may be prepared, but only for
66 * Non-Commercial Uses. Derivatives of the software may be shared with
67 * others provided: (i) the others agree to abide by the list of
68 * conditions herein which includes the Non-Commercial Use restrictions;
69 * and (ii) such Derivatives of the software include the above copyright
70 * notice to acknowledge the contribution from this software where
71 * applicable, this list of conditions and the disclaimer below.
72 *
73 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
74 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
75 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
76 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
77 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
78 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
79 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
80 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
81 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
82 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
83 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
84 *
85 * Authors: Gabe Black
86 */
87
88 #include "arch/x86/miscregfile.hh"
89 #include "arch/x86/tlb.hh"
90 #include "cpu/base.hh"
91 #include "cpu/thread_context.hh"
92 #include "sim/serialize.hh"
93
94 using namespace X86ISA;
95 using namespace std;
96
97 class Checkpoint;
98
99 void MiscRegFile::updateHandyM5Reg(Efer efer, CR0 cr0,
100 SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags)
101 {
102 HandyM5Reg m5reg;
103 if (efer.lma) {
104 m5reg.mode = LongMode;
105 if (csAttr.longMode)
106 m5reg.submode = SixtyFourBitMode;
107 else
108 m5reg.submode = CompatabilityMode;
109 } else {
110 m5reg.mode = LegacyMode;
111 if (cr0.pe) {
112 if (rflags.vm)
113 m5reg.submode = Virtual8086Mode;
114 else
115 m5reg.submode = ProtectedMode;
116 } else {
117 m5reg.submode = RealMode;
118 }
119 }
120 m5reg.cpl = csAttr.dpl;
121 m5reg.paging = cr0.pg;
122 m5reg.prot = cr0.pe;
123
124 // Compute the default and alternate operand size.
125 if (m5reg.submode == SixtyFourBitMode || csAttr.defaultSize) {
126 m5reg.defOp = 2;
127 m5reg.altOp = 1;
128 } else {
129 m5reg.defOp = 1;
130 m5reg.altOp = 2;
131 }
132
133 // Compute the default and alternate address size.
134 if (m5reg.submode == SixtyFourBitMode) {
135 m5reg.defAddr = 3;
136 m5reg.altAddr = 2;
137 } else if (csAttr.defaultSize) {
138 m5reg.defAddr = 2;
139 m5reg.altAddr = 1;
140 } else {
141 m5reg.defAddr = 1;
142 m5reg.altAddr = 2;
143 }
144
145 // Compute the stack size
146 if (m5reg.submode == SixtyFourBitMode) {
147 m5reg.stack = 3;
148 } else if (ssAttr.defaultSize) {
149 m5reg.stack = 2;
150 } else {
151 m5reg.stack = 1;
152 }
153
154 regVal[MISCREG_M5_REG] = m5reg;
155 }
156
157 void MiscRegFile::clear()
158 {
159 // Blank everything. 0 might not be an appropriate value for some things,
160 // but it is for most.
161 memset(regVal, 0, NumMiscRegs * sizeof(MiscReg));
162 regVal[MISCREG_DR6] = (mask(8) << 4) | (mask(16) << 16);
163 regVal[MISCREG_DR7] = 1 << 10;
164 }
165
166 MiscReg MiscRegFile::readRegNoEffect(MiscRegIndex miscReg)
167 {
168 // Make sure we're not dealing with an illegal control register.
169 // Instructions should filter out these indexes, and nothing else should
170 // attempt to read them directly.
171 assert( miscReg != MISCREG_CR1 &&
172 !(miscReg > MISCREG_CR4 &&
173 miscReg < MISCREG_CR8) &&
174 !(miscReg > MISCREG_CR8 &&
175 miscReg <= MISCREG_CR15));
176
177 return regVal[miscReg];
178 }
179
180 MiscReg MiscRegFile::readReg(MiscRegIndex miscReg, ThreadContext * tc)
181 {
182 if (miscReg == MISCREG_TSC) {
183 return regVal[MISCREG_TSC] + tc->getCpuPtr()->curCycle();
184 }
185 return readRegNoEffect(miscReg);
186 }
187
188 void MiscRegFile::setRegNoEffect(MiscRegIndex miscReg, const MiscReg &val)
189 {
190 // Make sure we're not dealing with an illegal control register.
191 // Instructions should filter out these indexes, and nothing else should
192 // attempt to write to them directly.
193 assert( miscReg != MISCREG_CR1 &&
194 !(miscReg > MISCREG_CR4 &&
195 miscReg < MISCREG_CR8) &&
196 !(miscReg > MISCREG_CR8 &&
197 miscReg <= MISCREG_CR15));
198 regVal[miscReg] = val;
199 }
200
201 void MiscRegFile::setReg(MiscRegIndex miscReg,
202 const MiscReg &val, ThreadContext * tc)
203 {
204 MiscReg newVal = val;
205 switch(miscReg)
206 {
207 case MISCREG_CR0:
208 {
209 CR0 toggled = regVal[miscReg] ^ val;
210 CR0 newCR0 = val;
211 Efer efer = regVal[MISCREG_EFER];
212 if (toggled.pg && efer.lme) {
213 if (newCR0.pg) {
214 //Turning on long mode
215 efer.lma = 1;
216 regVal[MISCREG_EFER] = efer;
217 } else {
218 //Turning off long mode
219 efer.lma = 0;
220 regVal[MISCREG_EFER] = efer;
221 }
222 }
223 if (toggled.pg) {
224 tc->getITBPtr()->invalidateAll();
225 tc->getDTBPtr()->invalidateAll();
226 }
227 //This must always be 1.
228 newCR0.et = 1;
229 newVal = newCR0;
230 updateHandyM5Reg(regVal[MISCREG_EFER],
231 newCR0,
232 regVal[MISCREG_CS_ATTR],
233 regVal[MISCREG_SS_ATTR],
234 regVal[MISCREG_RFLAGS]);
235 }
236 break;
237 case MISCREG_CR2:
238 break;
239 case MISCREG_CR3:
240 tc->getITBPtr()->invalidateNonGlobal();
241 tc->getDTBPtr()->invalidateNonGlobal();
242 break;
243 case MISCREG_CR4:
244 {
245 CR4 toggled = regVal[miscReg] ^ val;
246 if (toggled.pae || toggled.pse || toggled.pge) {
247 tc->getITBPtr()->invalidateAll();
248 tc->getDTBPtr()->invalidateAll();
249 }
250 }
251 break;
252 case MISCREG_CR8:
253 break;
254 case MISCREG_CS_ATTR:
255 {
256 SegAttr toggled = regVal[miscReg] ^ val;
257 SegAttr newCSAttr = val;
258 if (toggled.longMode) {
259 if (newCSAttr.longMode) {
260 regVal[MISCREG_ES_EFF_BASE] = 0;
261 regVal[MISCREG_CS_EFF_BASE] = 0;
262 regVal[MISCREG_SS_EFF_BASE] = 0;
263 regVal[MISCREG_DS_EFF_BASE] = 0;
264 } else {
265 regVal[MISCREG_ES_EFF_BASE] = regVal[MISCREG_ES_BASE];
266 regVal[MISCREG_CS_EFF_BASE] = regVal[MISCREG_CS_BASE];
267 regVal[MISCREG_SS_EFF_BASE] = regVal[MISCREG_SS_BASE];
268 regVal[MISCREG_DS_EFF_BASE] = regVal[MISCREG_DS_BASE];
269 }
270 }
271 updateHandyM5Reg(regVal[MISCREG_EFER],
272 regVal[MISCREG_CR0],
273 newCSAttr,
274 regVal[MISCREG_SS_ATTR],
275 regVal[MISCREG_RFLAGS]);
276 }
277 break;
278 case MISCREG_SS_ATTR:
279 updateHandyM5Reg(regVal[MISCREG_EFER],
280 regVal[MISCREG_CR0],
281 regVal[MISCREG_CS_ATTR],
282 val,
283 regVal[MISCREG_RFLAGS]);
284 break;
285 // These segments always actually use their bases, or in other words
286 // their effective bases must stay equal to their actual bases.
287 case MISCREG_FS_BASE:
288 case MISCREG_GS_BASE:
289 case MISCREG_HS_BASE:
290 case MISCREG_TSL_BASE:
291 case MISCREG_TSG_BASE:
292 case MISCREG_TR_BASE:
293 case MISCREG_IDTR_BASE:
294 regVal[MISCREG_SEG_EFF_BASE(miscReg - MISCREG_SEG_BASE_BASE)] = val;
295 break;
296 // These segments ignore their bases in 64 bit mode.
297 // their effective bases must stay equal to their actual bases.
298 case MISCREG_ES_BASE:
299 case MISCREG_CS_BASE:
300 case MISCREG_SS_BASE:
301 case MISCREG_DS_BASE:
302 {
303 Efer efer = regVal[MISCREG_EFER];
304 SegAttr csAttr = regVal[MISCREG_CS_ATTR];
305 if (!efer.lma || !csAttr.longMode) // Check for non 64 bit mode.
306 regVal[MISCREG_SEG_EFF_BASE(miscReg -
307 MISCREG_SEG_BASE_BASE)] = val;
308 }
309 break;
310 case MISCREG_TSC:
311 regVal[MISCREG_TSC] = val - tc->getCpuPtr()->curCycle();
312 return;
313 case MISCREG_DR0:
314 case MISCREG_DR1:
315 case MISCREG_DR2:
316 case MISCREG_DR3:
317 /* These should eventually set up breakpoints. */
318 break;
319 case MISCREG_DR4:
320 miscReg = MISCREG_DR6;
321 /* Fall through to have the same effects as DR6. */
322 case MISCREG_DR6:
323 {
324 DR6 dr6 = regVal[MISCREG_DR6];
325 DR6 newDR6 = val;
326 dr6.b0 = newDR6.b0;
327 dr6.b1 = newDR6.b1;
328 dr6.b2 = newDR6.b2;
329 dr6.b3 = newDR6.b3;
330 dr6.bd = newDR6.bd;
331 dr6.bs = newDR6.bs;
332 dr6.bt = newDR6.bt;
333 newVal = dr6;
334 }
335 break;
336 case MISCREG_DR5:
337 miscReg = MISCREG_DR7;
338 /* Fall through to have the same effects as DR7. */
339 case MISCREG_DR7:
340 {
341 DR7 dr7 = regVal[MISCREG_DR7];
342 DR7 newDR7 = val;
343 dr7.l0 = newDR7.l0;
344 dr7.g0 = newDR7.g0;
345 if (dr7.l0 || dr7.g0) {
346 panic("Debug register breakpoints not implemented.\n");
347 } else {
348 /* Disable breakpoint 0. */
349 }
350 dr7.l1 = newDR7.l1;
351 dr7.g1 = newDR7.g1;
352 if (dr7.l1 || dr7.g1) {
353 panic("Debug register breakpoints not implemented.\n");
354 } else {
355 /* Disable breakpoint 1. */
356 }
357 dr7.l2 = newDR7.l2;
358 dr7.g2 = newDR7.g2;
359 if (dr7.l2 || dr7.g2) {
360 panic("Debug register breakpoints not implemented.\n");
361 } else {
362 /* Disable breakpoint 2. */
363 }
364 dr7.l3 = newDR7.l3;
365 dr7.g3 = newDR7.g3;
366 if (dr7.l3 || dr7.g3) {
367 panic("Debug register breakpoints not implemented.\n");
368 } else {
369 /* Disable breakpoint 3. */
370 }
371 dr7.gd = newDR7.gd;
372 dr7.rw0 = newDR7.rw0;
373 dr7.len0 = newDR7.len0;
374 dr7.rw1 = newDR7.rw1;
375 dr7.len1 = newDR7.len1;
376 dr7.rw2 = newDR7.rw2;
377 dr7.len2 = newDR7.len2;
378 dr7.rw3 = newDR7.rw3;
379 dr7.len3 = newDR7.len3;
380 }
381 break;
382 case MISCREG_M5_REG:
383 // Writing anything to the m5reg with side effects makes it update
384 // based on the current values of the relevant registers. The actual
385 // value written is discarded.
386 updateHandyM5Reg(regVal[MISCREG_EFER],
387 regVal[MISCREG_CR0],
388 regVal[MISCREG_CS_ATTR],
389 regVal[MISCREG_SS_ATTR],
390 regVal[MISCREG_RFLAGS]);
391 return;
392 default:
393 break;
394 }
395 setRegNoEffect(miscReg, newVal);
396 }
397
398 void MiscRegFile::serialize(std::ostream & os)
399 {
400 SERIALIZE_ARRAY(regVal, NumMiscRegs);
401 }
402
403 void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
404 {
405 UNSERIALIZE_ARRAY(regVal, NumMiscRegs);
406 }