utility.cc revision 8791
15389Sgblack@eecs.umich.edu/* 25446Sgblack@eecs.umich.edu * Copyright (c) 2007 The Hewlett-Packard Development Company 35389Sgblack@eecs.umich.edu * Copyright (c) 2011 Advanced Micro Devices, Inc. 45389Sgblack@eecs.umich.edu * All rights reserved. 55389Sgblack@eecs.umich.edu * 65389Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 75389Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 85389Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 95389Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 105389Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 115389Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 125389Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 135389Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 145389Sgblack@eecs.umich.edu * 155389Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 165389Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 175389Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 185389Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 195389Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 205389Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 215389Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 225389Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 235389Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 245389Sgblack@eecs.umich.edu * this software without specific prior written permission. 255389Sgblack@eecs.umich.edu * 265389Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 275389Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 285389Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 295389Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 305389Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 315389Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 325389Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 335389Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 345389Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 355389Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 365389Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 375389Sgblack@eecs.umich.edu * 385389Sgblack@eecs.umich.edu * Authors: Gabe Black 395389Sgblack@eecs.umich.edu */ 405389Sgblack@eecs.umich.edu 415478Snate@binkert.org#include "arch/x86/interrupts.hh" 425643Sgblack@eecs.umich.edu#include "arch/x86/registers.hh" 435636Sgblack@eecs.umich.edu#include "arch/x86/tlb.hh" 445389Sgblack@eecs.umich.edu#include "arch/x86/utility.hh" 455637Sgblack@eecs.umich.edu#include "arch/x86/x86_traits.hh" 465389Sgblack@eecs.umich.edu#include "cpu/base.hh" 475389Sgblack@eecs.umich.edu#include "sim/system.hh" 485389Sgblack@eecs.umich.edu 495389Sgblack@eecs.umich.edunamespace X86ISA { 505389Sgblack@eecs.umich.edu 515638Sgblack@eecs.umich.eduuint64_t 525389Sgblack@eecs.umich.edugetArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) 535389Sgblack@eecs.umich.edu{ 545446Sgblack@eecs.umich.edu panic("getArgument() not implemented for x86!\n"); 555389Sgblack@eecs.umich.edu M5_DUMMY_RETURN 565389Sgblack@eecs.umich.edu} 575389Sgblack@eecs.umich.edu 585389Sgblack@eecs.umich.eduvoid initCPU(ThreadContext *tc, int cpuId) 595446Sgblack@eecs.umich.edu{ 605638Sgblack@eecs.umich.edu // This function is essentially performing a reset. The actual INIT 615446Sgblack@eecs.umich.edu // interrupt does a subset of this, so we'll piggyback on some of its 625446Sgblack@eecs.umich.edu // functionality. 635643Sgblack@eecs.umich.edu InitInterrupt init(0); 645643Sgblack@eecs.umich.edu init.invoke(tc); 655643Sgblack@eecs.umich.edu 665643Sgblack@eecs.umich.edu PCState pc = tc->pcState(); 675636Sgblack@eecs.umich.edu pc.upc(0); 685446Sgblack@eecs.umich.edu pc.nupc(1); 695446Sgblack@eecs.umich.edu tc->pcState(pc); 705446Sgblack@eecs.umich.edu 715446Sgblack@eecs.umich.edu // These next two loops zero internal microcode and implicit registers. 725446Sgblack@eecs.umich.edu // They aren't specified by the ISA but are used internally by M5's 735635Sgblack@eecs.umich.edu // implementation. 745635Sgblack@eecs.umich.edu for (int index = 0; index < NumMicroIntRegs; index++) { 755643Sgblack@eecs.umich.edu tc->setIntReg(INTREG_MICRO(index), 0); 765643Sgblack@eecs.umich.edu } 775643Sgblack@eecs.umich.edu 785643Sgblack@eecs.umich.edu for (int index = 0; index < NumImplicitIntRegs; index++) { 795643Sgblack@eecs.umich.edu tc->setIntReg(INTREG_IMPLICIT(index), 0); 805643Sgblack@eecs.umich.edu } 815643Sgblack@eecs.umich.edu 825643Sgblack@eecs.umich.edu // Set integer register EAX to 0 to indicate that the optional BIST 835643Sgblack@eecs.umich.edu // passed. No BIST actually runs, but software may still check this 845643Sgblack@eecs.umich.edu // register for errors. 855446Sgblack@eecs.umich.edu tc->setIntReg(INTREG_RAX, 0); 865446Sgblack@eecs.umich.edu 875389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, 0x0000000060000010ULL); 885638Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR8, 0); 895389Sgblack@eecs.umich.edu 905389Sgblack@eecs.umich.edu // TODO initialize x87, 64 bit, and 128 bit media state 915389Sgblack@eecs.umich.edu 925389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRRCAP, 0x0508); 935389Sgblack@eecs.umich.edu for (int i = 0; i < 8; i++) { 945389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_PHYS_BASE(i), 0); 955638Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_PHYS_MASK(i), 0); 965389Sgblack@eecs.umich.edu } 975389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_64K_00000, 0); 985389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_16K_80000, 0); 995389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_16K_A0000, 0); 1005389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_C0000, 0); 1015389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_C8000, 0); 1025638Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_D0000, 0); 1035389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_D8000, 0); 1045389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_E0000, 0); 1055389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_E8000, 0); 1065389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_F0000, 0); 1075389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_F8000, 0); 1085389Sgblack@eecs.umich.edu 1095638Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_DEF_TYPE, 0); 1105389Sgblack@eecs.umich.edu 1115389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MCG_CAP, 0x104); 1125389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MCG_STATUS, 0); 1135389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MCG_CTL, 0); 1145389Sgblack@eecs.umich.edu 1155638Sgblack@eecs.umich.edu for (int i = 0; i < 5; i++) { 1165389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MC_CTL(i), 0); 1175389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MC_STATUS(i), 0); 1185389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MC_ADDR(i), 0); 1195389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MC_MISC(i), 0); 1205389Sgblack@eecs.umich.edu } 1215638Sgblack@eecs.umich.edu 1225389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSC, 0); 1235389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSC_AUX, 0); 1245389Sgblack@eecs.umich.edu 1255389Sgblack@eecs.umich.edu for (int i = 0; i < 4; i++) { 1265389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_PERF_EVT_SEL(i), 0); 1275389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_PERF_EVT_CTR(i), 0); 1285389Sgblack@eecs.umich.edu } 1295638Sgblack@eecs.umich.edu 1305389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_STAR, 0); 1315389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_LSTAR, 0); 1325389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CSTAR, 0); 1335389Sgblack@eecs.umich.edu 1345389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SF_MASK, 0); 1355389Sgblack@eecs.umich.edu 1365389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_KERNEL_GS_BASE, 0); 1375638Sgblack@eecs.umich.edu 1385638Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SYSENTER_CS, 0); 1395389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SYSENTER_ESP, 0); 1405638Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SYSENTER_EIP, 0); 1415389Sgblack@eecs.umich.edu 142 tc->setMiscReg(MISCREG_PAT, 0x0007040600070406ULL); 143 144 tc->setMiscReg(MISCREG_SYSCFG, 0x20601); 145 146 tc->setMiscReg(MISCREG_IORR_BASE0, 0); 147 tc->setMiscReg(MISCREG_IORR_BASE1, 0); 148 149 tc->setMiscReg(MISCREG_IORR_MASK0, 0); 150 tc->setMiscReg(MISCREG_IORR_MASK1, 0); 151 152 tc->setMiscReg(MISCREG_TOP_MEM, 0x4000000); 153 tc->setMiscReg(MISCREG_TOP_MEM2, 0x0); 154 155 tc->setMiscReg(MISCREG_DEBUG_CTL_MSR, 0); 156 tc->setMiscReg(MISCREG_LAST_BRANCH_FROM_IP, 0); 157 tc->setMiscReg(MISCREG_LAST_BRANCH_TO_IP, 0); 158 tc->setMiscReg(MISCREG_LAST_EXCEPTION_FROM_IP, 0); 159 tc->setMiscReg(MISCREG_LAST_EXCEPTION_TO_IP, 0); 160 161 // Invalidate the caches (this should already be done for us) 162 163 LocalApicBase lApicBase = 0; 164 lApicBase.base = 0xFEE00000 >> 12; 165 lApicBase.enable = 1; 166 lApicBase.bsp = (cpuId == 0); 167 tc->setMiscReg(MISCREG_APIC_BASE, lApicBase); 168 169 Interrupts * interrupts = dynamic_cast<Interrupts *>( 170 tc->getCpuPtr()->getInterruptController()); 171 assert(interrupts); 172 173 interrupts->setRegNoEffect(APIC_ID, cpuId << 24); 174 175 interrupts->setRegNoEffect(APIC_VERSION, (5 << 16) | 0x14); 176 177 interrupts->setClock(tc->getCpuPtr()->ticks(16)); 178 179 // TODO Set the SMRAM base address (SMBASE) to 0x00030000 180 181 tc->setMiscReg(MISCREG_VM_CR, 0); 182 tc->setMiscReg(MISCREG_IGNNE, 0); 183 tc->setMiscReg(MISCREG_SMM_CTL, 0); 184 tc->setMiscReg(MISCREG_VM_HSAVE_PA, 0); 185} 186 187void startupCPU(ThreadContext *tc, int cpuId) 188{ 189 if (cpuId == 0 || !FullSystem) { 190 tc->activate(0); 191 } else { 192 // This is an application processor (AP). It should be initialized to 193 // look like only the BIOS POST has run on it and put then put it into 194 // a halted state. 195 tc->suspend(0); 196 } 197} 198 199void 200copyMiscRegs(ThreadContext *src, ThreadContext *dest) 201{ 202 // This function assumes no side effects other than TLB invalidation 203 // need to be considered while copying state. That will likely not be 204 // true in the future. 205 for (int i = 0; i < NUM_MISCREGS; ++i) { 206 if ( ( i != MISCREG_CR1 && 207 !(i > MISCREG_CR4 && i < MISCREG_CR8) && 208 !(i > MISCREG_CR8 && i <= MISCREG_CR15) ) == false) { 209 continue; 210 } 211 dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); 212 } 213 214 dest->getITBPtr()->invalidateAll(); 215 dest->getDTBPtr()->invalidateAll(); 216} 217 218void 219copyRegs(ThreadContext *src, ThreadContext *dest) 220{ 221 //copy int regs 222 for (int i = 0; i < NumIntRegs; ++i) 223 dest->setIntReg(i, src->readIntReg(i)); 224 //copy float regs 225 for (int i = 0; i < NumFloatRegs; ++i) 226 dest->setFloatRegBits(i, src->readFloatRegBits(i)); 227 copyMiscRegs(src, dest); 228 dest->pcState(src->pcState()); 229} 230 231void 232skipFunction(ThreadContext *tc) 233{ 234 panic("Not implemented for x86\n"); 235} 236 237 238} // namespace X86_ISA 239