utility.cc revision 7811
110923SN/A/* 210923SN/A * Copyright (c) 2007 The Hewlett-Packard Development Company 310923SN/A * All rights reserved. 410923SN/A * 510923SN/A * The license below extends only to copyright in the software and shall 610923SN/A * not be construed as granting a license to any other intellectual 710923SN/A * property including but not limited to intellectual property relating 810923SN/A * to a hardware implementation of the functionality of the software 910923SN/A * licensed hereunder. You may use the software subject to the license 1010923SN/A * terms below provided that you ensure that this notice is replicated 1110923SN/A * unmodified and in its entirety in all distributions of the software, 1210923SN/A * modified or unmodified, in source code or in binary form. 1310923SN/A * 1410923SN/A * Redistribution and use in source and binary forms, with or without 1510923SN/A * modification, are permitted provided that the following conditions are 1610923SN/A * met: redistributions of source code must retain the above copyright 1710923SN/A * notice, this list of conditions and the following disclaimer; 1810923SN/A * redistributions in binary form must reproduce the above copyright 1910923SN/A * notice, this list of conditions and the following disclaimer in the 2010923SN/A * documentation and/or other materials provided with the distribution; 2110923SN/A * neither the name of the copyright holders nor the names of its 2210923SN/A * contributors may be used to endorse or promote products derived from 2310923SN/A * this software without specific prior written permission. 2410923SN/A * 2510923SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610923SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710923SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810923SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910923SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010923SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110923SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210923SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310923SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410923SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510923SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610923SN/A * 3710923SN/A * Authors: Gabe Black 3811290Sgabor.dozsa@arm.com */ 3910923SN/A 4010923SN/A#include "config/full_system.hh" 4110923SN/A 4211290Sgabor.dozsa@arm.com#if FULL_SYSTEM 4310923SN/A#include "arch/x86/interrupts.hh" 4410923SN/A#endif 4511263Sandreas.sandberg@arm.com#include "arch/x86/regs/int.hh" 4610923SN/A#include "arch/x86/regs/misc.hh" 4710923SN/A#include "arch/x86/regs/segment.hh" 4810923SN/A#include "arch/x86/utility.hh" 4911290Sgabor.dozsa@arm.com#include "arch/x86/x86_traits.hh" 5010923SN/A#include "cpu/base.hh" 5110923SN/A#include "sim/system.hh" 5210923SN/A 5310923SN/Anamespace X86ISA { 5410923SN/A 5510923SN/Auint64_t 5611290Sgabor.dozsa@arm.comgetArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) 5710923SN/A{ 5810923SN/A#if FULL_SYSTEM 5911290Sgabor.dozsa@arm.com panic("getArgument() not implemented for x86!\n"); 6011290Sgabor.dozsa@arm.com#else 6111290Sgabor.dozsa@arm.com panic("getArgument() only implemented for FULL_SYSTEM\n"); 6211290Sgabor.dozsa@arm.com M5_DUMMY_RETURN 6311290Sgabor.dozsa@arm.com#endif 6411290Sgabor.dozsa@arm.com} 6511290Sgabor.dozsa@arm.com 6611290Sgabor.dozsa@arm.com# if FULL_SYSTEM 6710923SN/Avoid initCPU(ThreadContext *tc, int cpuId) 6810923SN/A{ 6910923SN/A // This function is essentially performing a reset. The actual INIT 7010923SN/A // interrupt does a subset of this, so we'll piggyback on some of its 7110923SN/A // functionality. 7210923SN/A InitInterrupt init(0); 7310923SN/A init.invoke(tc); 7410923SN/A 7510923SN/A PCState pc = tc->pcState(); 7610923SN/A pc.upc(0); 7711290Sgabor.dozsa@arm.com pc.nupc(1); 7810923SN/A tc->pcState(pc); 7911290Sgabor.dozsa@arm.com 8011290Sgabor.dozsa@arm.com // These next two loops zero internal microcode and implicit registers. 8110923SN/A // They aren't specified by the ISA but are used internally by M5's 8210923SN/A // implementation. 8311290Sgabor.dozsa@arm.com for (int index = 0; index < NumMicroIntRegs; index++) { 8411290Sgabor.dozsa@arm.com tc->setIntReg(INTREG_MICRO(index), 0); 8511290Sgabor.dozsa@arm.com } 8611290Sgabor.dozsa@arm.com 8711290Sgabor.dozsa@arm.com for (int index = 0; index < NumImplicitIntRegs; index++) { 8811290Sgabor.dozsa@arm.com tc->setIntReg(INTREG_IMPLICIT(index), 0); 8911290Sgabor.dozsa@arm.com } 9011290Sgabor.dozsa@arm.com 9111290Sgabor.dozsa@arm.com // Set integer register EAX to 0 to indicate that the optional BIST 9211290Sgabor.dozsa@arm.com // passed. No BIST actually runs, but software may still check this 9311290Sgabor.dozsa@arm.com // register for errors. 9411290Sgabor.dozsa@arm.com tc->setIntReg(INTREG_RAX, 0); 9511290Sgabor.dozsa@arm.com 9611290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_CR0, 0x0000000060000010ULL); 9711290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_CR8, 0); 9811290Sgabor.dozsa@arm.com 9911290Sgabor.dozsa@arm.com // TODO initialize x87, 64 bit, and 128 bit media state 10011290Sgabor.dozsa@arm.com 10111290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MTRRCAP, 0x0508); 10211290Sgabor.dozsa@arm.com for (int i = 0; i < 8; i++) { 10311290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MTRR_PHYS_BASE(i), 0); 10411290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MTRR_PHYS_MASK(i), 0); 10511290Sgabor.dozsa@arm.com } 10611290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MTRR_FIX_64K_00000, 0); 10711290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MTRR_FIX_16K_80000, 0); 10811290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MTRR_FIX_16K_A0000, 0); 10911290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MTRR_FIX_4K_C0000, 0); 11011290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MTRR_FIX_4K_C8000, 0); 11111290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MTRR_FIX_4K_D0000, 0); 11211290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MTRR_FIX_4K_D8000, 0); 11311290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MTRR_FIX_4K_E0000, 0); 11411290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MTRR_FIX_4K_E8000, 0); 11511290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MTRR_FIX_4K_F0000, 0); 11611290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MTRR_FIX_4K_F8000, 0); 11711290Sgabor.dozsa@arm.com 11811290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_DEF_TYPE, 0); 11911290Sgabor.dozsa@arm.com 12011290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MCG_CAP, 0x104); 12111290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MCG_STATUS, 0); 12211290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MCG_CTL, 0); 12311290Sgabor.dozsa@arm.com 12411290Sgabor.dozsa@arm.com for (int i = 0; i < 5; i++) { 12511290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MC_CTL(i), 0); 12611290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MC_STATUS(i), 0); 12711290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MC_ADDR(i), 0); 12811290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_MC_MISC(i), 0); 12911290Sgabor.dozsa@arm.com } 13011290Sgabor.dozsa@arm.com 13111290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_TSC, 0); 13211290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_TSC_AUX, 0); 13311290Sgabor.dozsa@arm.com 13411290Sgabor.dozsa@arm.com for (int i = 0; i < 4; i++) { 13511290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_PERF_EVT_SEL(i), 0); 13611290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_PERF_EVT_CTR(i), 0); 13711290Sgabor.dozsa@arm.com } 13811290Sgabor.dozsa@arm.com 13911290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_STAR, 0); 14011290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_LSTAR, 0); 14111290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_CSTAR, 0); 14211290Sgabor.dozsa@arm.com 14311290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_SF_MASK, 0); 14411290Sgabor.dozsa@arm.com 14511290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_KERNEL_GS_BASE, 0); 14611290Sgabor.dozsa@arm.com 14711290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_SYSENTER_CS, 0); 14811290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_SYSENTER_ESP, 0); 14911290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_SYSENTER_EIP, 0); 15011290Sgabor.dozsa@arm.com 15111290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_PAT, 0x0007040600070406ULL); 15211290Sgabor.dozsa@arm.com 15311290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_SYSCFG, 0x20601); 15411290Sgabor.dozsa@arm.com 15511290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_IORR_BASE0, 0); 15611290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_IORR_BASE1, 0); 15711290Sgabor.dozsa@arm.com 15811290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_IORR_MASK0, 0); 15911290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_IORR_MASK1, 0); 16011290Sgabor.dozsa@arm.com 16111290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_TOP_MEM, 0x4000000); 16211290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_TOP_MEM2, 0x0); 16311290Sgabor.dozsa@arm.com 16411290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_DEBUG_CTL_MSR, 0); 16511290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_LAST_BRANCH_FROM_IP, 0); 16611290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_LAST_BRANCH_TO_IP, 0); 16711290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_LAST_EXCEPTION_FROM_IP, 0); 16811290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_LAST_EXCEPTION_TO_IP, 0); 16911290Sgabor.dozsa@arm.com 17011290Sgabor.dozsa@arm.com // Invalidate the caches (this should already be done for us) 17111290Sgabor.dozsa@arm.com 17211290Sgabor.dozsa@arm.com LocalApicBase lApicBase = 0; 17311290Sgabor.dozsa@arm.com lApicBase.base = 0xFEE00000 >> 12; 17411290Sgabor.dozsa@arm.com lApicBase.enable = 1; 17511290Sgabor.dozsa@arm.com lApicBase.bsp = (cpuId == 0); 17611290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_APIC_BASE, lApicBase); 17711290Sgabor.dozsa@arm.com 17811290Sgabor.dozsa@arm.com Interrupts * interrupts = dynamic_cast<Interrupts *>( 17911290Sgabor.dozsa@arm.com tc->getCpuPtr()->getInterruptController()); 18011290Sgabor.dozsa@arm.com assert(interrupts); 18111290Sgabor.dozsa@arm.com 18211290Sgabor.dozsa@arm.com interrupts->setRegNoEffect(APIC_ID, cpuId << 24); 18311290Sgabor.dozsa@arm.com 18411290Sgabor.dozsa@arm.com interrupts->setRegNoEffect(APIC_VERSION, (5 << 16) | 0x14); 18511290Sgabor.dozsa@arm.com 18611290Sgabor.dozsa@arm.com interrupts->setClock(tc->getCpuPtr()->ticks(16)); 18711290Sgabor.dozsa@arm.com 18811290Sgabor.dozsa@arm.com // TODO Set the SMRAM base address (SMBASE) to 0x00030000 18911290Sgabor.dozsa@arm.com 19011290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_VM_CR, 0); 19111290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_IGNNE, 0); 19211290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_SMM_CTL, 0); 19311290Sgabor.dozsa@arm.com tc->setMiscReg(MISCREG_VM_HSAVE_PA, 0); 19411290Sgabor.dozsa@arm.com} 19511290Sgabor.dozsa@arm.com 19611290Sgabor.dozsa@arm.com#endif 19711290Sgabor.dozsa@arm.com 19811290Sgabor.dozsa@arm.comvoid startupCPU(ThreadContext *tc, int cpuId) 19911290Sgabor.dozsa@arm.com{ 20011290Sgabor.dozsa@arm.com#if FULL_SYSTEM 20111290Sgabor.dozsa@arm.com if (cpuId == 0) { 20211290Sgabor.dozsa@arm.com tc->activate(0); 20311290Sgabor.dozsa@arm.com } else { 20411290Sgabor.dozsa@arm.com // This is an application processor (AP). It should be initialized to 20511290Sgabor.dozsa@arm.com // look like only the BIOS POST has run on it and put then put it into 20611290Sgabor.dozsa@arm.com // a halted state. 20711290Sgabor.dozsa@arm.com tc->suspend(0); 20811290Sgabor.dozsa@arm.com } 20911290Sgabor.dozsa@arm.com#else 21011290Sgabor.dozsa@arm.com tc->activate(0); 21111290Sgabor.dozsa@arm.com#endif 21211290Sgabor.dozsa@arm.com} 21311290Sgabor.dozsa@arm.com 21411290Sgabor.dozsa@arm.comvoid 21511290Sgabor.dozsa@arm.comcopyMiscRegs(ThreadContext *src, ThreadContext *dest) 21611290Sgabor.dozsa@arm.com{ 21711290Sgabor.dozsa@arm.com warn("copyMiscRegs is naively implemented for x86\n"); 21811290Sgabor.dozsa@arm.com for (int i = 0; i < NUM_MISCREGS; ++i) { 21911290Sgabor.dozsa@arm.com if ( ( i != MISCREG_CR1 && 22011290Sgabor.dozsa@arm.com !(i > MISCREG_CR4 && i < MISCREG_CR8) && 22111290Sgabor.dozsa@arm.com !(i > MISCREG_CR8 && i <= MISCREG_CR15) ) == false) { 22210923SN/A continue; 22310923SN/A } 22411290Sgabor.dozsa@arm.com dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); 22510923SN/A } 22611290Sgabor.dozsa@arm.com} 22710923SN/A 22811290Sgabor.dozsa@arm.comvoid 22911290Sgabor.dozsa@arm.comcopyRegs(ThreadContext *src, ThreadContext *dest) 23010923SN/A{ 23111290Sgabor.dozsa@arm.com panic("copyRegs not implemented for x86!\n"); 23211290Sgabor.dozsa@arm.com //copy int regs 23311290Sgabor.dozsa@arm.com //copy float regs 23410923SN/A copyMiscRegs(src, dest); 23511290Sgabor.dozsa@arm.com 23611290Sgabor.dozsa@arm.com dest->pcState(src->pcState()); 23711290Sgabor.dozsa@arm.com} 23811290Sgabor.dozsa@arm.com 23910923SN/Avoid 24011290Sgabor.dozsa@arm.comskipFunction(ThreadContext *tc) 24111290Sgabor.dozsa@arm.com{ 24211290Sgabor.dozsa@arm.com panic("Not implemented for x86\n"); 24310923SN/A} 24411290Sgabor.dozsa@arm.com 24511290Sgabor.dozsa@arm.com 24610923SN/A} // namespace X86_ISA 24711290Sgabor.dozsa@arm.com