1/* 2 * Copyright (c) 2009 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#include "arch/x86/decoder.hh" 32#include "arch/x86/isa.hh" 33#include "arch/x86/tlb.hh" 34#include "cpu/base.hh" 35#include "cpu/thread_context.hh" 36#include "params/X86ISA.hh" 37#include "sim/serialize.hh" 38 39namespace X86ISA 40{ 41 42void 43ISA::updateHandyM5Reg(Efer efer, CR0 cr0, 44 SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags, 45 ThreadContext *tc) 46{ 47 HandyM5Reg m5reg = 0; 48 if (efer.lma) { 49 m5reg.mode = LongMode; 50 if (csAttr.longMode) 51 m5reg.submode = SixtyFourBitMode; 52 else 53 m5reg.submode = CompatabilityMode; 54 } else { 55 m5reg.mode = LegacyMode; 56 if (cr0.pe) { 57 if (rflags.vm) 58 m5reg.submode = Virtual8086Mode; 59 else 60 m5reg.submode = ProtectedMode; 61 } else { 62 m5reg.submode = RealMode; 63 } 64 } 65 m5reg.cpl = csAttr.dpl; 66 m5reg.paging = cr0.pg; 67 m5reg.prot = cr0.pe; 68 69 // Compute the default and alternate operand size. 70 if (m5reg.submode == SixtyFourBitMode || csAttr.defaultSize) { 71 m5reg.defOp = 2; 72 m5reg.altOp = 1; 73 } else { 74 m5reg.defOp = 1; 75 m5reg.altOp = 2; 76 } 77 78 // Compute the default and alternate address size. 79 if (m5reg.submode == SixtyFourBitMode) { 80 m5reg.defAddr = 3; 81 m5reg.altAddr = 2; 82 } else if (csAttr.defaultSize) { 83 m5reg.defAddr = 2; 84 m5reg.altAddr = 1; 85 } else { 86 m5reg.defAddr = 1; 87 m5reg.altAddr = 2; 88 } 89 90 // Compute the stack size 91 if (m5reg.submode == SixtyFourBitMode) { 92 m5reg.stack = 3; 93 } else if (ssAttr.defaultSize) { 94 m5reg.stack = 2; 95 } else { 96 m5reg.stack = 1; 97 } 98 99 regVal[MISCREG_M5_REG] = m5reg; 100 if (tc) 101 tc->getDecoderPtr()->setM5Reg(m5reg); 102} 103 104void 105ISA::clear() 106{ 107 // Blank everything. 0 might not be an appropriate value for some things, 108 // but it is for most. 109 memset(regVal, 0, NumMiscRegs * sizeof(MiscReg)); 110 regVal[MISCREG_DR6] = (mask(8) << 4) | (mask(16) << 16); 111 regVal[MISCREG_DR7] = 1 << 10; 112} 113 114ISA::ISA(Params *p) 115 : SimObject(p) 116{ 117 clear(); 118} 119 120const X86ISAParams * 121ISA::params() const 122{ 123 return dynamic_cast<const Params *>(_params); 124} 125 126MiscReg 127ISA::readMiscRegNoEffect(int miscReg) const 128{ 129 // Make sure we're not dealing with an illegal control register. 130 // Instructions should filter out these indexes, and nothing else should 131 // attempt to read them directly.
| 1/* 2 * Copyright (c) 2009 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#include "arch/x86/decoder.hh" 32#include "arch/x86/isa.hh" 33#include "arch/x86/tlb.hh" 34#include "cpu/base.hh" 35#include "cpu/thread_context.hh" 36#include "params/X86ISA.hh" 37#include "sim/serialize.hh" 38 39namespace X86ISA 40{ 41 42void 43ISA::updateHandyM5Reg(Efer efer, CR0 cr0, 44 SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags, 45 ThreadContext *tc) 46{ 47 HandyM5Reg m5reg = 0; 48 if (efer.lma) { 49 m5reg.mode = LongMode; 50 if (csAttr.longMode) 51 m5reg.submode = SixtyFourBitMode; 52 else 53 m5reg.submode = CompatabilityMode; 54 } else { 55 m5reg.mode = LegacyMode; 56 if (cr0.pe) { 57 if (rflags.vm) 58 m5reg.submode = Virtual8086Mode; 59 else 60 m5reg.submode = ProtectedMode; 61 } else { 62 m5reg.submode = RealMode; 63 } 64 } 65 m5reg.cpl = csAttr.dpl; 66 m5reg.paging = cr0.pg; 67 m5reg.prot = cr0.pe; 68 69 // Compute the default and alternate operand size. 70 if (m5reg.submode == SixtyFourBitMode || csAttr.defaultSize) { 71 m5reg.defOp = 2; 72 m5reg.altOp = 1; 73 } else { 74 m5reg.defOp = 1; 75 m5reg.altOp = 2; 76 } 77 78 // Compute the default and alternate address size. 79 if (m5reg.submode == SixtyFourBitMode) { 80 m5reg.defAddr = 3; 81 m5reg.altAddr = 2; 82 } else if (csAttr.defaultSize) { 83 m5reg.defAddr = 2; 84 m5reg.altAddr = 1; 85 } else { 86 m5reg.defAddr = 1; 87 m5reg.altAddr = 2; 88 } 89 90 // Compute the stack size 91 if (m5reg.submode == SixtyFourBitMode) { 92 m5reg.stack = 3; 93 } else if (ssAttr.defaultSize) { 94 m5reg.stack = 2; 95 } else { 96 m5reg.stack = 1; 97 } 98 99 regVal[MISCREG_M5_REG] = m5reg; 100 if (tc) 101 tc->getDecoderPtr()->setM5Reg(m5reg); 102} 103 104void 105ISA::clear() 106{ 107 // Blank everything. 0 might not be an appropriate value for some things, 108 // but it is for most. 109 memset(regVal, 0, NumMiscRegs * sizeof(MiscReg)); 110 regVal[MISCREG_DR6] = (mask(8) << 4) | (mask(16) << 16); 111 regVal[MISCREG_DR7] = 1 << 10; 112} 113 114ISA::ISA(Params *p) 115 : SimObject(p) 116{ 117 clear(); 118} 119 120const X86ISAParams * 121ISA::params() const 122{ 123 return dynamic_cast<const Params *>(_params); 124} 125 126MiscReg 127ISA::readMiscRegNoEffect(int miscReg) const 128{ 129 // Make sure we're not dealing with an illegal control register. 130 // Instructions should filter out these indexes, and nothing else should 131 // attempt to read them directly.
|
132 assert( miscReg != MISCREG_CR1 && 133 !(miscReg > MISCREG_CR4 && 134 miscReg < MISCREG_CR8) && 135 !(miscReg > MISCREG_CR8 && 136 miscReg <= MISCREG_CR15));
| 132 assert(miscReg >= MISCREG_CR0 && 133 miscReg < NUM_MISCREGS && 134 miscReg != MISCREG_CR1 && 135 !(miscReg > MISCREG_CR4 && 136 miscReg < MISCREG_CR8) && 137 !(miscReg > MISCREG_CR8 && 138 miscReg <= MISCREG_CR15));
|
137 138 return regVal[miscReg]; 139} 140 141MiscReg 142ISA::readMiscReg(int miscReg, ThreadContext * tc) 143{ 144 if (miscReg == MISCREG_TSC) { 145 return regVal[MISCREG_TSC] + tc->getCpuPtr()->curCycle(); 146 } 147 148 if (miscReg == MISCREG_FSW) { 149 MiscReg fsw = regVal[MISCREG_FSW]; 150 MiscReg top = regVal[MISCREG_X87_TOP]; 151 return (fsw & (~(7ULL << 11))) + (top << 11); 152 } 153 154 return readMiscRegNoEffect(miscReg); 155} 156 157void 158ISA::setMiscRegNoEffect(int miscReg, MiscReg val) 159{ 160 // Make sure we're not dealing with an illegal control register. 161 // Instructions should filter out these indexes, and nothing else should 162 // attempt to write to them directly.
| 139 140 return regVal[miscReg]; 141} 142 143MiscReg 144ISA::readMiscReg(int miscReg, ThreadContext * tc) 145{ 146 if (miscReg == MISCREG_TSC) { 147 return regVal[MISCREG_TSC] + tc->getCpuPtr()->curCycle(); 148 } 149 150 if (miscReg == MISCREG_FSW) { 151 MiscReg fsw = regVal[MISCREG_FSW]; 152 MiscReg top = regVal[MISCREG_X87_TOP]; 153 return (fsw & (~(7ULL << 11))) + (top << 11); 154 } 155 156 return readMiscRegNoEffect(miscReg); 157} 158 159void 160ISA::setMiscRegNoEffect(int miscReg, MiscReg val) 161{ 162 // Make sure we're not dealing with an illegal control register. 163 // Instructions should filter out these indexes, and nothing else should 164 // attempt to write to them directly.
|
163 assert( miscReg != MISCREG_CR1 && 164 !(miscReg > MISCREG_CR4 && 165 miscReg < MISCREG_CR8) && 166 !(miscReg > MISCREG_CR8 && 167 miscReg <= MISCREG_CR15));
| 165 assert(miscReg >= MISCREG_CR0 && 166 miscReg < NUM_MISCREGS && 167 miscReg != MISCREG_CR1 && 168 !(miscReg > MISCREG_CR4 && 169 miscReg < MISCREG_CR8) && 170 !(miscReg > MISCREG_CR8 && 171 miscReg <= MISCREG_CR15)); 172 173 HandyM5Reg m5Reg = readMiscRegNoEffect(MISCREG_M5_REG); 174 switch (miscReg) { 175 case MISCREG_FSW: 176 val &= (1ULL << 16) - 1; 177 regVal[miscReg] = val; 178 miscReg = MISCREG_X87_TOP; 179 val <<= 11; 180 case MISCREG_X87_TOP: 181 val &= (1ULL << 3) - 1; 182 break; 183 case MISCREG_FTW: 184 val &= (1ULL << 8) - 1; 185 break; 186 case MISCREG_FCW: 187 case MISCREG_FOP: 188 val &= (1ULL << 16) - 1; 189 break; 190 case MISCREG_MXCSR: 191 val &= (1ULL << 32) - 1; 192 break; 193 case MISCREG_FISEG: 194 case MISCREG_FOSEG: 195 if (m5Reg.submode != SixtyFourBitMode) 196 val &= (1ULL << 16) - 1; 197 break; 198 case MISCREG_FIOFF: 199 case MISCREG_FOOFF: 200 if (m5Reg.submode != SixtyFourBitMode) 201 val &= (1ULL << 32) - 1; 202 break; 203 default: 204 break; 205 } 206
|
168 regVal[miscReg] = val; 169} 170 171void 172ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc) 173{ 174 MiscReg newVal = val; 175 switch(miscReg) 176 { 177 case MISCREG_CR0: 178 { 179 CR0 toggled = regVal[miscReg] ^ val; 180 CR0 newCR0 = val; 181 Efer efer = regVal[MISCREG_EFER]; 182 if (toggled.pg && efer.lme) { 183 if (newCR0.pg) { 184 //Turning on long mode 185 efer.lma = 1; 186 regVal[MISCREG_EFER] = efer; 187 } else { 188 //Turning off long mode 189 efer.lma = 0; 190 regVal[MISCREG_EFER] = efer; 191 } 192 } 193 if (toggled.pg) { 194 tc->getITBPtr()->flushAll(); 195 tc->getDTBPtr()->flushAll(); 196 } 197 //This must always be 1. 198 newCR0.et = 1; 199 newVal = newCR0; 200 updateHandyM5Reg(regVal[MISCREG_EFER], 201 newCR0, 202 regVal[MISCREG_CS_ATTR], 203 regVal[MISCREG_SS_ATTR], 204 regVal[MISCREG_RFLAGS], 205 tc); 206 } 207 break; 208 case MISCREG_CR2: 209 break; 210 case MISCREG_CR3: 211 tc->getITBPtr()->flushNonGlobal(); 212 tc->getDTBPtr()->flushNonGlobal(); 213 break; 214 case MISCREG_CR4: 215 { 216 CR4 toggled = regVal[miscReg] ^ val; 217 if (toggled.pae || toggled.pse || toggled.pge) { 218 tc->getITBPtr()->flushAll(); 219 tc->getDTBPtr()->flushAll(); 220 } 221 } 222 break; 223 case MISCREG_CR8: 224 break; 225 case MISCREG_CS_ATTR: 226 { 227 SegAttr toggled = regVal[miscReg] ^ val; 228 SegAttr newCSAttr = val; 229 if (toggled.longMode) { 230 if (newCSAttr.longMode) { 231 regVal[MISCREG_ES_EFF_BASE] = 0; 232 regVal[MISCREG_CS_EFF_BASE] = 0; 233 regVal[MISCREG_SS_EFF_BASE] = 0; 234 regVal[MISCREG_DS_EFF_BASE] = 0; 235 } else { 236 regVal[MISCREG_ES_EFF_BASE] = regVal[MISCREG_ES_BASE]; 237 regVal[MISCREG_CS_EFF_BASE] = regVal[MISCREG_CS_BASE]; 238 regVal[MISCREG_SS_EFF_BASE] = regVal[MISCREG_SS_BASE]; 239 regVal[MISCREG_DS_EFF_BASE] = regVal[MISCREG_DS_BASE]; 240 } 241 } 242 updateHandyM5Reg(regVal[MISCREG_EFER], 243 regVal[MISCREG_CR0], 244 newCSAttr, 245 regVal[MISCREG_SS_ATTR], 246 regVal[MISCREG_RFLAGS], 247 tc); 248 } 249 break; 250 case MISCREG_SS_ATTR: 251 updateHandyM5Reg(regVal[MISCREG_EFER], 252 regVal[MISCREG_CR0], 253 regVal[MISCREG_CS_ATTR], 254 val, 255 regVal[MISCREG_RFLAGS], 256 tc); 257 break; 258 // These segments always actually use their bases, or in other words 259 // their effective bases must stay equal to their actual bases. 260 case MISCREG_FS_BASE: 261 case MISCREG_GS_BASE: 262 case MISCREG_HS_BASE: 263 case MISCREG_TSL_BASE: 264 case MISCREG_TSG_BASE: 265 case MISCREG_TR_BASE: 266 case MISCREG_IDTR_BASE: 267 regVal[MISCREG_SEG_EFF_BASE(miscReg - MISCREG_SEG_BASE_BASE)] = val; 268 break; 269 // These segments ignore their bases in 64 bit mode. 270 // their effective bases must stay equal to their actual bases. 271 case MISCREG_ES_BASE: 272 case MISCREG_CS_BASE: 273 case MISCREG_SS_BASE: 274 case MISCREG_DS_BASE: 275 { 276 Efer efer = regVal[MISCREG_EFER]; 277 SegAttr csAttr = regVal[MISCREG_CS_ATTR]; 278 if (!efer.lma || !csAttr.longMode) // Check for non 64 bit mode. 279 regVal[MISCREG_SEG_EFF_BASE(miscReg - 280 MISCREG_SEG_BASE_BASE)] = val; 281 } 282 break; 283 case MISCREG_TSC: 284 regVal[MISCREG_TSC] = val - tc->getCpuPtr()->curCycle(); 285 return; 286 case MISCREG_DR0: 287 case MISCREG_DR1: 288 case MISCREG_DR2: 289 case MISCREG_DR3: 290 /* These should eventually set up breakpoints. */ 291 break; 292 case MISCREG_DR4: 293 miscReg = MISCREG_DR6; 294 /* Fall through to have the same effects as DR6. */ 295 case MISCREG_DR6: 296 { 297 DR6 dr6 = regVal[MISCREG_DR6]; 298 DR6 newDR6 = val; 299 dr6.b0 = newDR6.b0; 300 dr6.b1 = newDR6.b1; 301 dr6.b2 = newDR6.b2; 302 dr6.b3 = newDR6.b3; 303 dr6.bd = newDR6.bd; 304 dr6.bs = newDR6.bs; 305 dr6.bt = newDR6.bt; 306 newVal = dr6; 307 } 308 break; 309 case MISCREG_DR5: 310 miscReg = MISCREG_DR7; 311 /* Fall through to have the same effects as DR7. */ 312 case MISCREG_DR7: 313 { 314 DR7 dr7 = regVal[MISCREG_DR7]; 315 DR7 newDR7 = val; 316 dr7.l0 = newDR7.l0; 317 dr7.g0 = newDR7.g0; 318 if (dr7.l0 || dr7.g0) { 319 panic("Debug register breakpoints not implemented.\n"); 320 } else { 321 /* Disable breakpoint 0. */ 322 } 323 dr7.l1 = newDR7.l1; 324 dr7.g1 = newDR7.g1; 325 if (dr7.l1 || dr7.g1) { 326 panic("Debug register breakpoints not implemented.\n"); 327 } else { 328 /* Disable breakpoint 1. */ 329 } 330 dr7.l2 = newDR7.l2; 331 dr7.g2 = newDR7.g2; 332 if (dr7.l2 || dr7.g2) { 333 panic("Debug register breakpoints not implemented.\n"); 334 } else { 335 /* Disable breakpoint 2. */ 336 } 337 dr7.l3 = newDR7.l3; 338 dr7.g3 = newDR7.g3; 339 if (dr7.l3 || dr7.g3) { 340 panic("Debug register breakpoints not implemented.\n"); 341 } else { 342 /* Disable breakpoint 3. */ 343 } 344 dr7.gd = newDR7.gd; 345 dr7.rw0 = newDR7.rw0; 346 dr7.len0 = newDR7.len0; 347 dr7.rw1 = newDR7.rw1; 348 dr7.len1 = newDR7.len1; 349 dr7.rw2 = newDR7.rw2; 350 dr7.len2 = newDR7.len2; 351 dr7.rw3 = newDR7.rw3; 352 dr7.len3 = newDR7.len3; 353 } 354 break; 355 case MISCREG_M5_REG: 356 // Writing anything to the m5reg with side effects makes it update 357 // based on the current values of the relevant registers. The actual 358 // value written is discarded. 359 updateHandyM5Reg(regVal[MISCREG_EFER], 360 regVal[MISCREG_CR0], 361 regVal[MISCREG_CS_ATTR], 362 regVal[MISCREG_SS_ATTR], 363 regVal[MISCREG_RFLAGS], 364 tc); 365 return; 366 default: 367 break; 368 } 369 setMiscRegNoEffect(miscReg, newVal); 370} 371 372void 373ISA::serialize(std::ostream & os) 374{ 375 SERIALIZE_ARRAY(regVal, NumMiscRegs); 376} 377 378void 379ISA::unserialize(Checkpoint * cp, const std::string & section) 380{ 381 UNSERIALIZE_ARRAY(regVal, NumMiscRegs); 382 updateHandyM5Reg(regVal[MISCREG_EFER], 383 regVal[MISCREG_CR0], 384 regVal[MISCREG_CS_ATTR], 385 regVal[MISCREG_SS_ATTR], 386 regVal[MISCREG_RFLAGS], 387 NULL); 388} 389 390void 391ISA::startup(ThreadContext *tc) 392{ 393 tc->getDecoderPtr()->setM5Reg(regVal[MISCREG_M5_REG]); 394} 395 396} 397 398X86ISA::ISA * 399X86ISAParams::create() 400{ 401 return new X86ISA::ISA(this); 402}
| 207 regVal[miscReg] = val; 208} 209 210void 211ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc) 212{ 213 MiscReg newVal = val; 214 switch(miscReg) 215 { 216 case MISCREG_CR0: 217 { 218 CR0 toggled = regVal[miscReg] ^ val; 219 CR0 newCR0 = val; 220 Efer efer = regVal[MISCREG_EFER]; 221 if (toggled.pg && efer.lme) { 222 if (newCR0.pg) { 223 //Turning on long mode 224 efer.lma = 1; 225 regVal[MISCREG_EFER] = efer; 226 } else { 227 //Turning off long mode 228 efer.lma = 0; 229 regVal[MISCREG_EFER] = efer; 230 } 231 } 232 if (toggled.pg) { 233 tc->getITBPtr()->flushAll(); 234 tc->getDTBPtr()->flushAll(); 235 } 236 //This must always be 1. 237 newCR0.et = 1; 238 newVal = newCR0; 239 updateHandyM5Reg(regVal[MISCREG_EFER], 240 newCR0, 241 regVal[MISCREG_CS_ATTR], 242 regVal[MISCREG_SS_ATTR], 243 regVal[MISCREG_RFLAGS], 244 tc); 245 } 246 break; 247 case MISCREG_CR2: 248 break; 249 case MISCREG_CR3: 250 tc->getITBPtr()->flushNonGlobal(); 251 tc->getDTBPtr()->flushNonGlobal(); 252 break; 253 case MISCREG_CR4: 254 { 255 CR4 toggled = regVal[miscReg] ^ val; 256 if (toggled.pae || toggled.pse || toggled.pge) { 257 tc->getITBPtr()->flushAll(); 258 tc->getDTBPtr()->flushAll(); 259 } 260 } 261 break; 262 case MISCREG_CR8: 263 break; 264 case MISCREG_CS_ATTR: 265 { 266 SegAttr toggled = regVal[miscReg] ^ val; 267 SegAttr newCSAttr = val; 268 if (toggled.longMode) { 269 if (newCSAttr.longMode) { 270 regVal[MISCREG_ES_EFF_BASE] = 0; 271 regVal[MISCREG_CS_EFF_BASE] = 0; 272 regVal[MISCREG_SS_EFF_BASE] = 0; 273 regVal[MISCREG_DS_EFF_BASE] = 0; 274 } else { 275 regVal[MISCREG_ES_EFF_BASE] = regVal[MISCREG_ES_BASE]; 276 regVal[MISCREG_CS_EFF_BASE] = regVal[MISCREG_CS_BASE]; 277 regVal[MISCREG_SS_EFF_BASE] = regVal[MISCREG_SS_BASE]; 278 regVal[MISCREG_DS_EFF_BASE] = regVal[MISCREG_DS_BASE]; 279 } 280 } 281 updateHandyM5Reg(regVal[MISCREG_EFER], 282 regVal[MISCREG_CR0], 283 newCSAttr, 284 regVal[MISCREG_SS_ATTR], 285 regVal[MISCREG_RFLAGS], 286 tc); 287 } 288 break; 289 case MISCREG_SS_ATTR: 290 updateHandyM5Reg(regVal[MISCREG_EFER], 291 regVal[MISCREG_CR0], 292 regVal[MISCREG_CS_ATTR], 293 val, 294 regVal[MISCREG_RFLAGS], 295 tc); 296 break; 297 // These segments always actually use their bases, or in other words 298 // their effective bases must stay equal to their actual bases. 299 case MISCREG_FS_BASE: 300 case MISCREG_GS_BASE: 301 case MISCREG_HS_BASE: 302 case MISCREG_TSL_BASE: 303 case MISCREG_TSG_BASE: 304 case MISCREG_TR_BASE: 305 case MISCREG_IDTR_BASE: 306 regVal[MISCREG_SEG_EFF_BASE(miscReg - MISCREG_SEG_BASE_BASE)] = val; 307 break; 308 // These segments ignore their bases in 64 bit mode. 309 // their effective bases must stay equal to their actual bases. 310 case MISCREG_ES_BASE: 311 case MISCREG_CS_BASE: 312 case MISCREG_SS_BASE: 313 case MISCREG_DS_BASE: 314 { 315 Efer efer = regVal[MISCREG_EFER]; 316 SegAttr csAttr = regVal[MISCREG_CS_ATTR]; 317 if (!efer.lma || !csAttr.longMode) // Check for non 64 bit mode. 318 regVal[MISCREG_SEG_EFF_BASE(miscReg - 319 MISCREG_SEG_BASE_BASE)] = val; 320 } 321 break; 322 case MISCREG_TSC: 323 regVal[MISCREG_TSC] = val - tc->getCpuPtr()->curCycle(); 324 return; 325 case MISCREG_DR0: 326 case MISCREG_DR1: 327 case MISCREG_DR2: 328 case MISCREG_DR3: 329 /* These should eventually set up breakpoints. */ 330 break; 331 case MISCREG_DR4: 332 miscReg = MISCREG_DR6; 333 /* Fall through to have the same effects as DR6. */ 334 case MISCREG_DR6: 335 { 336 DR6 dr6 = regVal[MISCREG_DR6]; 337 DR6 newDR6 = val; 338 dr6.b0 = newDR6.b0; 339 dr6.b1 = newDR6.b1; 340 dr6.b2 = newDR6.b2; 341 dr6.b3 = newDR6.b3; 342 dr6.bd = newDR6.bd; 343 dr6.bs = newDR6.bs; 344 dr6.bt = newDR6.bt; 345 newVal = dr6; 346 } 347 break; 348 case MISCREG_DR5: 349 miscReg = MISCREG_DR7; 350 /* Fall through to have the same effects as DR7. */ 351 case MISCREG_DR7: 352 { 353 DR7 dr7 = regVal[MISCREG_DR7]; 354 DR7 newDR7 = val; 355 dr7.l0 = newDR7.l0; 356 dr7.g0 = newDR7.g0; 357 if (dr7.l0 || dr7.g0) { 358 panic("Debug register breakpoints not implemented.\n"); 359 } else { 360 /* Disable breakpoint 0. */ 361 } 362 dr7.l1 = newDR7.l1; 363 dr7.g1 = newDR7.g1; 364 if (dr7.l1 || dr7.g1) { 365 panic("Debug register breakpoints not implemented.\n"); 366 } else { 367 /* Disable breakpoint 1. */ 368 } 369 dr7.l2 = newDR7.l2; 370 dr7.g2 = newDR7.g2; 371 if (dr7.l2 || dr7.g2) { 372 panic("Debug register breakpoints not implemented.\n"); 373 } else { 374 /* Disable breakpoint 2. */ 375 } 376 dr7.l3 = newDR7.l3; 377 dr7.g3 = newDR7.g3; 378 if (dr7.l3 || dr7.g3) { 379 panic("Debug register breakpoints not implemented.\n"); 380 } else { 381 /* Disable breakpoint 3. */ 382 } 383 dr7.gd = newDR7.gd; 384 dr7.rw0 = newDR7.rw0; 385 dr7.len0 = newDR7.len0; 386 dr7.rw1 = newDR7.rw1; 387 dr7.len1 = newDR7.len1; 388 dr7.rw2 = newDR7.rw2; 389 dr7.len2 = newDR7.len2; 390 dr7.rw3 = newDR7.rw3; 391 dr7.len3 = newDR7.len3; 392 } 393 break; 394 case MISCREG_M5_REG: 395 // Writing anything to the m5reg with side effects makes it update 396 // based on the current values of the relevant registers. The actual 397 // value written is discarded. 398 updateHandyM5Reg(regVal[MISCREG_EFER], 399 regVal[MISCREG_CR0], 400 regVal[MISCREG_CS_ATTR], 401 regVal[MISCREG_SS_ATTR], 402 regVal[MISCREG_RFLAGS], 403 tc); 404 return; 405 default: 406 break; 407 } 408 setMiscRegNoEffect(miscReg, newVal); 409} 410 411void 412ISA::serialize(std::ostream & os) 413{ 414 SERIALIZE_ARRAY(regVal, NumMiscRegs); 415} 416 417void 418ISA::unserialize(Checkpoint * cp, const std::string & section) 419{ 420 UNSERIALIZE_ARRAY(regVal, NumMiscRegs); 421 updateHandyM5Reg(regVal[MISCREG_EFER], 422 regVal[MISCREG_CR0], 423 regVal[MISCREG_CS_ATTR], 424 regVal[MISCREG_SS_ATTR], 425 regVal[MISCREG_RFLAGS], 426 NULL); 427} 428 429void 430ISA::startup(ThreadContext *tc) 431{ 432 tc->getDecoderPtr()->setM5Reg(regVal[MISCREG_M5_REG]); 433} 434 435} 436 437X86ISA::ISA * 438X86ISAParams::create() 439{ 440 return new X86ISA::ISA(this); 441}
|