utility.cc revision 9751
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 395654Sgblack@eecs.umich.edu */ 405389Sgblack@eecs.umich.edu 415389Sgblack@eecs.umich.edu#include "arch/x86/interrupts.hh" 425478Snate@binkert.org#include "arch/x86/registers.hh" 435643Sgblack@eecs.umich.edu#include "arch/x86/tlb.hh" 445636Sgblack@eecs.umich.edu#include "arch/x86/utility.hh" 455830Sgblack@eecs.umich.edu#include "arch/x86/x86_traits.hh" 465389Sgblack@eecs.umich.edu#include "cpu/base.hh" 475637Sgblack@eecs.umich.edu#include "sim/system.hh" 485389Sgblack@eecs.umich.edu 495389Sgblack@eecs.umich.edunamespace X86ISA { 505389Sgblack@eecs.umich.edu 515389Sgblack@eecs.umich.eduuint64_t 525389Sgblack@eecs.umich.edugetArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) 535638Sgblack@eecs.umich.edu{ 545389Sgblack@eecs.umich.edu panic("getArgument() not implemented for x86!\n"); 555389Sgblack@eecs.umich.edu M5_DUMMY_RETURN 565446Sgblack@eecs.umich.edu} 575389Sgblack@eecs.umich.edu 585389Sgblack@eecs.umich.eduvoid initCPU(ThreadContext *tc, int cpuId) 595389Sgblack@eecs.umich.edu{ 605389Sgblack@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 625638Sgblack@eecs.umich.edu // functionality. 635446Sgblack@eecs.umich.edu InitInterrupt init(0); 645446Sgblack@eecs.umich.edu init.invoke(tc); 655643Sgblack@eecs.umich.edu 665643Sgblack@eecs.umich.edu PCState pc = tc->pcState(); 675643Sgblack@eecs.umich.edu pc.upc(0); 685643Sgblack@eecs.umich.edu pc.nupc(1); 695636Sgblack@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 735446Sgblack@eecs.umich.edu // implementation. 745446Sgblack@eecs.umich.edu for (int index = 0; index < NumMicroIntRegs; index++) { 755635Sgblack@eecs.umich.edu tc->setIntReg(INTREG_MICRO(index), 0); 765635Sgblack@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 835654Sgblack@eecs.umich.edu // passed. No BIST actually runs, but software may still check this 845643Sgblack@eecs.umich.edu // register for errors. 855643Sgblack@eecs.umich.edu tc->setIntReg(INTREG_RAX, 0); 865643Sgblack@eecs.umich.edu 875829Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, 0x0000000060000010ULL); 885829Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR8, 0); 895829Sgblack@eecs.umich.edu 905829Sgblack@eecs.umich.edu // TODO initialize x87, 64 bit, and 128 bit media state 915829Sgblack@eecs.umich.edu 925829Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRRCAP, 0x0508); 935829Sgblack@eecs.umich.edu for (int i = 0; i < 8; i++) { 945829Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_PHYS_BASE(i), 0); 955829Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_PHYS_MASK(i), 0); 965829Sgblack@eecs.umich.edu } 975829Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_64K_00000, 0); 985829Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_16K_80000, 0); 995829Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_16K_A0000, 0); 1005829Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_C0000, 0); 1015829Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_C8000, 0); 1025829Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_D0000, 0); 1035829Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_D8000, 0); 1045446Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_E0000, 0); 1055446Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_E8000, 0); 1065389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_F0000, 0); 1075638Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MTRR_FIX_4K_F8000, 0); 1085389Sgblack@eecs.umich.edu 1095389Sgblack@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); 1145638Sgblack@eecs.umich.edu 1155389Sgblack@eecs.umich.edu for (int i = 0; i < 5; i++) { 1165830Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_MC_CTL(i), 0); 1175830Sgblack@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); 1285638Sgblack@eecs.umich.edu } 1295389Sgblack@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 1345638Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SF_MASK, 0); 1355389Sgblack@eecs.umich.edu 1365389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_KERNEL_GS_BASE, 0); 1375389Sgblack@eecs.umich.edu 1385389Sgblack@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 1425389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_PAT, 0x0007040600070406ULL); 1435389Sgblack@eecs.umich.edu 1445389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SYSCFG, 0x20601); 1455389Sgblack@eecs.umich.edu 1465389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_IORR_BASE0, 0); 1475389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_IORR_BASE1, 0); 1485638Sgblack@eecs.umich.edu 1495389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_IORR_MASK0, 0); 1505389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_IORR_MASK1, 0); 1515389Sgblack@eecs.umich.edu 1525389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TOP_MEM, 0x4000000); 1535389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TOP_MEM2, 0x0); 1545389Sgblack@eecs.umich.edu 1555389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_DEBUG_CTL_MSR, 0); 1565638Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_LAST_BRANCH_FROM_IP, 0); 1575638Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_LAST_BRANCH_TO_IP, 0); 1585389Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_LAST_EXCEPTION_FROM_IP, 0); 1595638Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_LAST_EXCEPTION_TO_IP, 0); 1605389Sgblack@eecs.umich.edu 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 // TODO Set the SMRAM base address (SMBASE) to 0x00030000 178 179 tc->setMiscReg(MISCREG_VM_CR, 0); 180 tc->setMiscReg(MISCREG_IGNNE, 0); 181 tc->setMiscReg(MISCREG_SMM_CTL, 0); 182 tc->setMiscReg(MISCREG_VM_HSAVE_PA, 0); 183} 184 185void startupCPU(ThreadContext *tc, int cpuId) 186{ 187 if (cpuId == 0 || !FullSystem) { 188 tc->activate(Cycles(0)); 189 } else { 190 // This is an application processor (AP). It should be initialized to 191 // look like only the BIOS POST has run on it and put then put it into 192 // a halted state. 193 tc->suspend(Cycles(0)); 194 } 195} 196 197void 198copyMiscRegs(ThreadContext *src, ThreadContext *dest) 199{ 200 // This function assumes no side effects other than TLB invalidation 201 // need to be considered while copying state. That will likely not be 202 // true in the future. 203 for (int i = 0; i < NUM_MISCREGS; ++i) { 204 if ( ( i != MISCREG_CR1 && 205 !(i > MISCREG_CR4 && i < MISCREG_CR8) && 206 !(i > MISCREG_CR8 && i <= MISCREG_CR15) ) == false) { 207 continue; 208 } 209 dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); 210 } 211 212 // The TSC has to be updated with side-effects if the CPUs in a 213 // CPU switch have different frequencies. 214 dest->setMiscReg(MISCREG_TSC, src->readMiscReg(MISCREG_TSC)); 215 216 dest->getITBPtr()->flushAll(); 217 dest->getDTBPtr()->flushAll(); 218} 219 220void 221copyRegs(ThreadContext *src, ThreadContext *dest) 222{ 223 //copy int regs 224 for (int i = 0; i < NumIntRegs; ++i) 225 dest->setIntReg(i, src->readIntReg(i)); 226 //copy float regs 227 for (int i = 0; i < NumFloatRegs; ++i) 228 dest->setFloatRegBits(i, src->readFloatRegBits(i)); 229 copyMiscRegs(src, dest); 230 dest->pcState(src->pcState()); 231} 232 233void 234skipFunction(ThreadContext *tc) 235{ 236 panic("Not implemented for x86\n"); 237} 238 239 240} // namespace X86_ISA 241