utility.cc revision 8768
1/* 2 * Copyright (c) 2007 The Hewlett-Packard Development Company 3 * Copyright (c) 2011 Advanced Micro Devices, Inc. 4 * All rights reserved. 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating 9 * to a hardware implementation of the functionality of the software 10 * licensed hereunder. You may use the software subject to the license 11 * terms below provided that you ensure that this notice is replicated 12 * unmodified and in its entirety in all distributions of the software, 13 * modified or unmodified, in source code or in binary form. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions are 17 * met: redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer; 19 * redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution; 22 * neither the name of the copyright holders nor the names of its 23 * contributors may be used to endorse or promote products derived from 24 * this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 * 38 * Authors: Gabe Black 39 */ 40 41#include "arch/x86/interrupts.hh" 42#include "arch/x86/registers.hh" 43#include "arch/x86/tlb.hh" 44#include "arch/x86/utility.hh" 45#include "arch/x86/x86_traits.hh" 46#include "cpu/base.hh" 47#include "sim/system.hh" 48 49namespace X86ISA { 50 51uint64_t 52getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) 53{ 54 panic("getArgument() not implemented for x86!\n"); 55 M5_DUMMY_RETURN 56} 57 58void initCPU(ThreadContext *tc, int cpuId) 59{ 60 // This function is essentially performing a reset. The actual INIT 61 // interrupt does a subset of this, so we'll piggyback on some of its 62 // functionality. 63 InitInterrupt init(0); 64 init.invoke(tc); 65 66 PCState pc = tc->pcState(); 67 pc.upc(0); 68 pc.nupc(1); 69 tc->pcState(pc); 70 71 // These next two loops zero internal microcode and implicit registers. 72 // They aren't specified by the ISA but are used internally by M5's 73 // implementation. 74 for (int index = 0; index < NumMicroIntRegs; index++) { 75 tc->setIntReg(INTREG_MICRO(index), 0); 76 } 77 78 for (int index = 0; index < NumImplicitIntRegs; index++) { 79 tc->setIntReg(INTREG_IMPLICIT(index), 0); 80 } 81 82 // Set integer register EAX to 0 to indicate that the optional BIST 83 // passed. No BIST actually runs, but software may still check this 84 // register for errors. 85 tc->setIntReg(INTREG_RAX, 0); 86 87 tc->setMiscReg(MISCREG_CR0, 0x0000000060000010ULL); 88 tc->setMiscReg(MISCREG_CR8, 0); 89 90 // TODO initialize x87, 64 bit, and 128 bit media state 91 92 tc->setMiscReg(MISCREG_MTRRCAP, 0x0508); 93 for (int i = 0; i < 8; i++) { 94 tc->setMiscReg(MISCREG_MTRR_PHYS_BASE(i), 0); 95 tc->setMiscReg(MISCREG_MTRR_PHYS_MASK(i), 0); 96 } 97 tc->setMiscReg(MISCREG_MTRR_FIX_64K_00000, 0); 98 tc->setMiscReg(MISCREG_MTRR_FIX_16K_80000, 0); 99 tc->setMiscReg(MISCREG_MTRR_FIX_16K_A0000, 0); 100 tc->setMiscReg(MISCREG_MTRR_FIX_4K_C0000, 0); 101 tc->setMiscReg(MISCREG_MTRR_FIX_4K_C8000, 0); 102 tc->setMiscReg(MISCREG_MTRR_FIX_4K_D0000, 0); 103 tc->setMiscReg(MISCREG_MTRR_FIX_4K_D8000, 0); 104 tc->setMiscReg(MISCREG_MTRR_FIX_4K_E0000, 0); 105 tc->setMiscReg(MISCREG_MTRR_FIX_4K_E8000, 0); 106 tc->setMiscReg(MISCREG_MTRR_FIX_4K_F0000, 0); 107 tc->setMiscReg(MISCREG_MTRR_FIX_4K_F8000, 0); 108 109 tc->setMiscReg(MISCREG_DEF_TYPE, 0); 110 111 tc->setMiscReg(MISCREG_MCG_CAP, 0x104); 112 tc->setMiscReg(MISCREG_MCG_STATUS, 0); 113 tc->setMiscReg(MISCREG_MCG_CTL, 0); 114 115 for (int i = 0; i < 5; i++) { 116 tc->setMiscReg(MISCREG_MC_CTL(i), 0); 117 tc->setMiscReg(MISCREG_MC_STATUS(i), 0); 118 tc->setMiscReg(MISCREG_MC_ADDR(i), 0); 119 tc->setMiscReg(MISCREG_MC_MISC(i), 0); 120 } 121 122 tc->setMiscReg(MISCREG_TSC, 0); 123 tc->setMiscReg(MISCREG_TSC_AUX, 0); 124 125 for (int i = 0; i < 4; i++) { 126 tc->setMiscReg(MISCREG_PERF_EVT_SEL(i), 0); 127 tc->setMiscReg(MISCREG_PERF_EVT_CTR(i), 0); 128 } 129 130 tc->setMiscReg(MISCREG_STAR, 0); 131 tc->setMiscReg(MISCREG_LSTAR, 0); 132 tc->setMiscReg(MISCREG_CSTAR, 0); 133 134 tc->setMiscReg(MISCREG_SF_MASK, 0); 135 136 tc->setMiscReg(MISCREG_KERNEL_GS_BASE, 0); 137 138 tc->setMiscReg(MISCREG_SYSENTER_CS, 0); 139 tc->setMiscReg(MISCREG_SYSENTER_ESP, 0); 140 tc->setMiscReg(MISCREG_SYSENTER_EIP, 0); 141 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