isa.cc revision 12406
12SN/A/* 21762SN/A * Copyright (c) 2009 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Gabe Black 292SN/A */ 302SN/A 312439SN/A#include "arch/x86/isa.hh" 322984Sgblack@eecs.umich.edu 33146SN/A#include "arch/x86/decoder.hh" 34146SN/A#include "arch/x86/tlb.hh" 35146SN/A#include "cpu/base.hh" 36146SN/A#include "cpu/thread_context.hh" 37146SN/A#include "params/X86ISA.hh" 38146SN/A#include "sim/serialize.hh" 391717SN/A 40146SN/Anamespace X86ISA 411717SN/A{ 42146SN/A 431977SN/Avoid 442623SN/AISA::updateHandyM5Reg(Efer efer, CR0 cr0, 452683Sktlim@umich.edu SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags, 461717SN/A ThreadContext *tc) 47146SN/A{ 482683Sktlim@umich.edu HandyM5Reg m5reg = 0; 493348Sbinkertn@umich.edu if (efer.lma) { 502683Sktlim@umich.edu m5reg.mode = LongMode; 512036SN/A if (csAttr.longMode) 52146SN/A m5reg.submode = SixtyFourBitMode; 5356SN/A else 5456SN/A m5reg.submode = CompatabilityMode; 5556SN/A } else { 56695SN/A m5reg.mode = LegacyMode; 572901Ssaidi@eecs.umich.edu if (cr0.pe) { 582SN/A if (rflags.vm) 591858SN/A m5reg.submode = Virtual8086Mode; 603565Sgblack@eecs.umich.edu else 613565Sgblack@eecs.umich.edu m5reg.submode = ProtectedMode; 622171SN/A } else { 632170SN/A m5reg.submode = RealMode; 643562Sgblack@eecs.umich.edu } 65146SN/A } 662462SN/A m5reg.cpl = csAttr.dpl; 67146SN/A m5reg.paging = cr0.pg; 682SN/A m5reg.prot = cr0.pe; 692SN/A 702449SN/A // Compute the default and alternate operand size. 711355SN/A if (m5reg.submode == SixtyFourBitMode || csAttr.defaultSize) { 722623SN/A m5reg.defOp = 2; 733402Sktlim@umich.edu m5reg.altOp = 1; 74224SN/A } else { 751858SN/A m5reg.defOp = 1; 762683Sktlim@umich.edu m5reg.altOp = 2; 772420SN/A } 782683Sktlim@umich.edu 793402Sktlim@umich.edu // Compute the default and alternate address size. 802420SN/A if (m5reg.submode == SixtyFourBitMode) { 812SN/A m5reg.defAddr = 3; 822683Sktlim@umich.edu m5reg.altAddr = 2; 832672Sktlim@umich.edu } else if (csAttr.defaultSize) { 842683Sktlim@umich.edu m5reg.defAddr = 2; 852SN/A m5reg.altAddr = 1; 862SN/A } else { 87334SN/A m5reg.defAddr = 1; 88140SN/A m5reg.altAddr = 2; 89334SN/A } 902SN/A 912SN/A // Compute the stack size 922SN/A if (m5reg.submode == SixtyFourBitMode) { 932680Sktlim@umich.edu m5reg.stack = 3; 942SN/A } else if (ssAttr.defaultSize) { 952SN/A m5reg.stack = 2; 962623SN/A } else { 972SN/A m5reg.stack = 1; 982SN/A } 992SN/A 100180SN/A regVal[MISCREG_M5_REG] = m5reg; 1012623SN/A if (tc) 102393SN/A tc->getDecoderPtr()->setM5Reg(m5reg); 103393SN/A} 104393SN/A 105393SN/Avoid 106384SN/AISA::clear() 107384SN/A{ 108393SN/A // Blank everything. 0 might not be an appropriate value for some things, 1092623SN/A // but it is for most. 110393SN/A memset(regVal, 0, NumMiscRegs * sizeof(MiscReg)); 111393SN/A regVal[MISCREG_DR6] = (mask(8) << 4) | (mask(16) << 16); 112393SN/A regVal[MISCREG_DR7] = 1 << 10; 113393SN/A} 114384SN/A 115189SN/AISA::ISA(Params *p) 116189SN/A : SimObject(p) 1172623SN/A{ 1182SN/A clear(); 119729SN/A} 120334SN/A 1212SN/Aconst X86ISAParams * 1222SN/AISA::params() const 1232SN/A{ 1242SN/A return dynamic_cast<const Params *>(_params); 1252SN/A} 1262SN/A 1272SN/AMiscReg 1282SN/AISA::readMiscRegNoEffect(int miscReg) const 1292SN/A{ 1302SN/A // Make sure we're not dealing with an illegal control register. 1312SN/A // Instructions should filter out these indexes, and nothing else should 1322SN/A // attempt to read them directly. 1331001SN/A assert(isValidMiscReg(miscReg)); 1341001SN/A 1351001SN/A return regVal[miscReg]; 1361001SN/A} 1371001SN/A 1382SN/AMiscReg 1392SN/AISA::readMiscReg(int miscReg, ThreadContext * tc) 1402SN/A{ 1412SN/A if (miscReg == MISCREG_TSC) { 1422SN/A return regVal[MISCREG_TSC] + tc->getCpuPtr()->curCycle(); 1432SN/A } 1442SN/A 1452SN/A if (miscReg == MISCREG_FSW) { 1462SN/A MiscReg fsw = regVal[MISCREG_FSW]; 1472SN/A MiscReg top = regVal[MISCREG_X87_TOP]; 1482SN/A return insertBits(fsw, 11, 13, top); 1492SN/A } 1502SN/A 1512SN/A return readMiscRegNoEffect(miscReg); 1522SN/A} 1532SN/A 1542SN/Avoid 1552390SN/AISA::setMiscRegNoEffect(int miscReg, MiscReg val) 1562390SN/A{ 1572390SN/A // Make sure we're not dealing with an illegal control register. 1582390SN/A // Instructions should filter out these indexes, and nothing else should 1592390SN/A // attempt to write to them directly. 1602390SN/A assert(isValidMiscReg(miscReg)); 1612390SN/A 1622390SN/A HandyM5Reg m5Reg = regVal[MISCREG_M5_REG]; 1632390SN/A int reg_width = 64; 1642390SN/A switch (miscReg) { 1652390SN/A case MISCREG_X87_TOP: 1662390SN/A reg_width = 3; 167385SN/A break; 1682SN/A case MISCREG_FTW: 1692SN/A reg_width = 8; 1702SN/A break; 1712623SN/A case MISCREG_FSW: 172334SN/A case MISCREG_FCW: 1732361SN/A case MISCREG_FOP: 1742623SN/A reg_width = 16; 175334SN/A break; 176334SN/A case MISCREG_MXCSR: 177334SN/A reg_width = 32; 1782623SN/A break; 1792SN/A case MISCREG_FISEG: 180921SN/A case MISCREG_FOSEG: 1812915Sktlim@umich.edu if (m5Reg.submode != SixtyFourBitMode) 1822915Sktlim@umich.edu reg_width = 16; 1832683Sktlim@umich.edu break; 1842SN/A case MISCREG_FIOFF: 1852SN/A case MISCREG_FOOFF: 1862SN/A if (m5Reg.submode != SixtyFourBitMode) 1872623SN/A reg_width = 32; 1882SN/A break; 189921SN/A default: 1902915Sktlim@umich.edu break; 1912915Sktlim@umich.edu } 1922SN/A 1932SN/A regVal[miscReg] = val & mask(reg_width); 1942SN/A} 1952SN/A 1962SN/Avoid 1972SN/AISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc) 1982SN/A{ 199595SN/A MiscReg newVal = val; 2002623SN/A switch(miscReg) 201595SN/A { 2022390SN/A case MISCREG_CR0: 2031080SN/A { 2041080SN/A CR0 toggled = regVal[miscReg] ^ val; 2051080SN/A CR0 newCR0 = val; 2061080SN/A Efer efer = regVal[MISCREG_EFER]; 2071080SN/A if (toggled.pg && efer.lme) { 2081080SN/A if (newCR0.pg) { 2091080SN/A //Turning on long mode 2101121SN/A efer.lma = 1; 2112107SN/A regVal[MISCREG_EFER] = efer; 2121089SN/A } else { 2131089SN/A //Turning off long mode 2141080SN/A efer.lma = 0; 2151080SN/A regVal[MISCREG_EFER] = efer; 2161080SN/A } 2171080SN/A } 218595SN/A if (toggled.pg) { 2192623SN/A dynamic_cast<TLB *>(tc->getITBPtr())->flushAll(); 2202683Sktlim@umich.edu dynamic_cast<TLB *>(tc->getDTBPtr())->flushAll(); 221595SN/A } 2222090SN/A //This must always be 1. 2232683Sktlim@umich.edu newCR0.et = 1; 2242683Sktlim@umich.edu newVal = newCR0; 225595SN/A updateHandyM5Reg(regVal[MISCREG_EFER], 2262205SN/A newCR0, 2272205SN/A regVal[MISCREG_CS_ATTR], 2282683Sktlim@umich.edu regVal[MISCREG_SS_ATTR], 2292683Sktlim@umich.edu regVal[MISCREG_RFLAGS], 230595SN/A tc); 231595SN/A } 2322390SN/A break; 2332423SN/A case MISCREG_CR2: 2342390SN/A break; 235595SN/A case MISCREG_CR3: 236595SN/A dynamic_cast<TLB *>(tc->getITBPtr())->flushNonGlobal(); 237595SN/A dynamic_cast<TLB *>(tc->getDTBPtr())->flushNonGlobal(); 2382623SN/A break; 239595SN/A case MISCREG_CR4: 2402390SN/A { 2411080SN/A CR4 toggled = regVal[miscReg] ^ val; 242595SN/A if (toggled.pae || toggled.pse || toggled.pge) { 2431080SN/A dynamic_cast<TLB *>(tc->getITBPtr())->flushAll(); 2441080SN/A dynamic_cast<TLB *>(tc->getDTBPtr())->flushAll(); 245595SN/A } 2462683Sktlim@umich.edu } 2471080SN/A break; 2481080SN/A case MISCREG_CR8: 2491080SN/A break; 2501121SN/A case MISCREG_CS_ATTR: 2512107SN/A { 2521089SN/A SegAttr toggled = regVal[miscReg] ^ val; 2531080SN/A SegAttr newCSAttr = val; 2541089SN/A if (toggled.longMode) { 2551080SN/A if (newCSAttr.longMode) { 2561080SN/A regVal[MISCREG_ES_EFF_BASE] = 0; 2571080SN/A regVal[MISCREG_CS_EFF_BASE] = 0; 258595SN/A regVal[MISCREG_SS_EFF_BASE] = 0; 2592683Sktlim@umich.edu regVal[MISCREG_DS_EFF_BASE] = 0; 2601080SN/A } else { 2612090SN/A regVal[MISCREG_ES_EFF_BASE] = regVal[MISCREG_ES_BASE]; 2621080SN/A regVal[MISCREG_CS_EFF_BASE] = regVal[MISCREG_CS_BASE]; 263595SN/A regVal[MISCREG_SS_EFF_BASE] = regVal[MISCREG_SS_BASE]; 2642683Sktlim@umich.edu regVal[MISCREG_DS_EFF_BASE] = regVal[MISCREG_DS_BASE]; 2652683Sktlim@umich.edu } 266595SN/A } 2672683Sktlim@umich.edu updateHandyM5Reg(regVal[MISCREG_EFER], 2681098SN/A regVal[MISCREG_CR0], 2691098SN/A newCSAttr, 2701098SN/A regVal[MISCREG_SS_ATTR], 2712683Sktlim@umich.edu regVal[MISCREG_RFLAGS], 2721098SN/A tc); 2731098SN/A } 2741098SN/A break; 2752012SN/A case MISCREG_SS_ATTR: 2761098SN/A updateHandyM5Reg(regVal[MISCREG_EFER], 2771098SN/A regVal[MISCREG_CR0], 278595SN/A regVal[MISCREG_CS_ATTR], 2792205SN/A val, 2802205SN/A regVal[MISCREG_RFLAGS], 2812205SN/A tc); 282595SN/A break; 2832390SN/A // These segments always actually use their bases, or in other words 2842420SN/A // their effective bases must stay equal to their actual bases. 2852423SN/A case MISCREG_FS_BASE: 2862390SN/A case MISCREG_GS_BASE: 287595SN/A case MISCREG_HS_BASE: 288595SN/A case MISCREG_TSL_BASE: 2891858SN/A case MISCREG_TSG_BASE: 2902SN/A case MISCREG_TR_BASE: 2912623SN/A case MISCREG_IDTR_BASE: 2922SN/A regVal[MISCREG_SEG_EFF_BASE(miscReg - MISCREG_SEG_BASE_BASE)] = val; 2932680Sktlim@umich.edu break; 2942SN/A // These segments ignore their bases in 64 bit mode. 2952SN/A // their effective bases must stay equal to their actual bases. 2962SN/A case MISCREG_ES_BASE: 2971858SN/A case MISCREG_CS_BASE: 2982SN/A case MISCREG_SS_BASE: 2992623SN/A case MISCREG_DS_BASE: 3002SN/A { 3012SN/A Efer efer = regVal[MISCREG_EFER]; 3022SN/A SegAttr csAttr = regVal[MISCREG_CS_ATTR]; 3032683Sktlim@umich.edu if (!efer.lma || !csAttr.longMode) // Check for non 64 bit mode. 3042SN/A regVal[MISCREG_SEG_EFF_BASE(miscReg - 3052683Sktlim@umich.edu MISCREG_SEG_BASE_BASE)] = val; 3062SN/A } 3072SN/A break; 3082SN/A case MISCREG_TSC: 3092SN/A regVal[MISCREG_TSC] = val - tc->getCpuPtr()->curCycle(); 3102SN/A return; 3112623SN/A case MISCREG_DR0: 3122SN/A case MISCREG_DR1: 3131858SN/A case MISCREG_DR2: 3143521Sgblack@eecs.umich.edu case MISCREG_DR3: 3153520Sgblack@eecs.umich.edu /* These should eventually set up breakpoints. */ 3162SN/A break; 3173520Sgblack@eecs.umich.edu case MISCREG_DR4: 3183633Sktlim@umich.edu miscReg = MISCREG_DR6; 3193521Sgblack@eecs.umich.edu M5_FALLTHROUGH; 3203520Sgblack@eecs.umich.edu case MISCREG_DR6: 3212SN/A { 3222SN/A DR6 dr6 = regVal[MISCREG_DR6]; 3232SN/A DR6 newDR6 = val; 3242623SN/A dr6.b0 = newDR6.b0; 3252SN/A dr6.b1 = newDR6.b1; 3262623SN/A dr6.b2 = newDR6.b2; 3272623SN/A dr6.b3 = newDR6.b3; 3282662Sstever@eecs.umich.edu dr6.bd = newDR6.bd; 3292623SN/A dr6.bs = newDR6.bs; 3302623SN/A dr6.bt = newDR6.bt; 3313093Sksewell@umich.edu newVal = dr6; 3323093Sksewell@umich.edu } 3333093Sksewell@umich.edu break; 3343093Sksewell@umich.edu case MISCREG_DR5: 3352741Sksewell@umich.edu miscReg = MISCREG_DR7; 3362741Sksewell@umich.edu M5_FALLTHROUGH; 3372741Sksewell@umich.edu case MISCREG_DR7: 3382623SN/A { 3392683Sktlim@umich.edu DR7 dr7 = regVal[MISCREG_DR7]; 3402683Sktlim@umich.edu DR7 newDR7 = val; 3412683Sktlim@umich.edu dr7.l0 = newDR7.l0; 3422623SN/A dr7.g0 = newDR7.g0; 3432683Sktlim@umich.edu if (dr7.l0 || dr7.g0) { 3442623SN/A panic("Debug register breakpoints not implemented.\n"); 3452623SN/A } else { 3462623SN/A /* Disable breakpoint 0. */ 3472623SN/A } 3482623SN/A dr7.l1 = newDR7.l1; 3492623SN/A dr7.g1 = newDR7.g1; 3502623SN/A if (dr7.l1 || dr7.g1) { 3512623SN/A panic("Debug register breakpoints not implemented.\n"); 3522SN/A } else { 3532683Sktlim@umich.edu /* Disable breakpoint 1. */ 3542427SN/A } 3552683Sktlim@umich.edu dr7.l2 = newDR7.l2; 3562427SN/A dr7.g2 = newDR7.g2; 3572SN/A if (dr7.l2 || dr7.g2) { 3582623SN/A panic("Debug register breakpoints not implemented.\n"); 3592623SN/A } else { 3602623SN/A /* Disable breakpoint 2. */ 3612SN/A } 3622683Sktlim@umich.edu dr7.l3 = newDR7.l3; 3632SN/A dr7.g3 = newDR7.g3; 3642623SN/A if (dr7.l3 || dr7.g3) { 3652623SN/A panic("Debug register breakpoints not implemented.\n"); 3662SN/A } else { 3672623SN/A /* Disable breakpoint 3. */ 3682623SN/A } 3693276Sgblack@eecs.umich.edu dr7.gd = newDR7.gd; 3703276Sgblack@eecs.umich.edu dr7.rw0 = newDR7.rw0; 3713484Sktlim@umich.edu dr7.len0 = newDR7.len0; 3723484Sktlim@umich.edu dr7.rw1 = newDR7.rw1; 3733484Sktlim@umich.edu dr7.len1 = newDR7.len1; 3743276Sgblack@eecs.umich.edu dr7.rw2 = newDR7.rw2; 3753521Sgblack@eecs.umich.edu dr7.len2 = newDR7.len2; 3763521Sgblack@eecs.umich.edu dr7.rw3 = newDR7.rw3; 3773521Sgblack@eecs.umich.edu dr7.len3 = newDR7.len3; 3783521Sgblack@eecs.umich.edu } 3793484Sktlim@umich.edu break; 3803276Sgblack@eecs.umich.edu case MISCREG_M5_REG: 3813276Sgblack@eecs.umich.edu // Writing anything to the m5reg with side effects makes it update 3823442Sgblack@eecs.umich.edu // based on the current values of the relevant registers. The actual 3833442Sgblack@eecs.umich.edu // value written is discarded. 3843280Sgblack@eecs.umich.edu updateHandyM5Reg(regVal[MISCREG_EFER], 3853280Sgblack@eecs.umich.edu regVal[MISCREG_CR0], 3863276Sgblack@eecs.umich.edu regVal[MISCREG_CS_ATTR], 3873276Sgblack@eecs.umich.edu regVal[MISCREG_SS_ATTR], 3883276Sgblack@eecs.umich.edu regVal[MISCREG_RFLAGS], 3893442Sgblack@eecs.umich.edu tc); 3903442Sgblack@eecs.umich.edu return; 3913276Sgblack@eecs.umich.edu default: 3923276Sgblack@eecs.umich.edu break; 3932470SN/A } 3943064Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, newVal); 3952683Sktlim@umich.edu} 3962623SN/A 3972623SN/Avoid 3982623SN/AISA::serialize(CheckpointOut &cp) const 3992623SN/A{ 4002623SN/A SERIALIZE_ARRAY(regVal, NumMiscRegs); 4012623SN/A} 4022683Sktlim@umich.edu 4032623SN/Avoid 4042623SN/AISA::unserialize(CheckpointIn &cp) 4052623SN/A{ 4062623SN/A UNSERIALIZE_ARRAY(regVal, NumMiscRegs); 4072623SN/A updateHandyM5Reg(regVal[MISCREG_EFER], 4082623SN/A regVal[MISCREG_CR0], 4092623SN/A regVal[MISCREG_CS_ATTR], 4102683Sktlim@umich.edu regVal[MISCREG_SS_ATTR], 4113577Sgblack@eecs.umich.edu regVal[MISCREG_RFLAGS], 4122683Sktlim@umich.edu NULL); 4132683Sktlim@umich.edu} 4142623SN/A 4152683Sktlim@umich.eduvoid 4162623SN/AISA::startup(ThreadContext *tc) 4172420SN/A{ 4182SN/A tc->getDecoderPtr()->setM5Reg(regVal[MISCREG_M5_REG]); 4192623SN/A} 4202623SN/A 4212SN/A} 4222SN/A 4232623SN/AX86ISA::ISA * 4242623SN/AX86ISAParams::create() 4252623SN/A{ 4262623SN/A return new X86ISA::ISA(this); 4272SN/A} 4282683Sktlim@umich.edu