gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
utility.cc
Go to the documentation of this file.
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/utility.hh"
42 
43 #include "arch/x86/interrupts.hh"
44 #include "arch/x86/registers.hh"
45 #include "arch/x86/x86_traits.hh"
46 #include "cpu/base.hh"
47 #include "fputils/fp80.h"
48 #include "sim/full_system.hh"
49 
50 namespace X86ISA {
51 
52 uint64_t
53 getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
54 {
55  if (fp) {
56  panic("getArgument(): Floating point arguments not implemented\n");
57  } else if (size != 8) {
58  panic("getArgument(): Can only handle 64-bit arguments.\n");
59  }
60 
61  // The first 6 integer arguments are passed in registers, the rest
62  // are passed on the stack.
63  const int int_reg_map[] = {
64  INTREG_RDI, INTREG_RSI, INTREG_RDX,
65  INTREG_RCX, INTREG_R8, INTREG_R9
66  };
67  if (number < sizeof(int_reg_map) / sizeof(*int_reg_map)) {
68  return tc->readIntReg(int_reg_map[number]);
69  } else {
70  panic("getArgument(): Don't know how to handle stack arguments.\n");
71  }
72 }
73 
74 void initCPU(ThreadContext *tc, int cpuId)
75 {
76  // This function is essentially performing a reset. The actual INIT
77  // interrupt does a subset of this, so we'll piggyback on some of its
78  // functionality.
80  init.invoke(tc);
81 
82  PCState pc = tc->pcState();
83  pc.upc(0);
84  pc.nupc(1);
85  tc->pcState(pc);
86 
87  // These next two loops zero internal microcode and implicit registers.
88  // They aren't specified by the ISA but are used internally by M5's
89  // implementation.
90  for (int index = 0; index < NumMicroIntRegs; index++) {
91  tc->setIntReg(INTREG_MICRO(index), 0);
92  }
93 
94  for (int index = 0; index < NumImplicitIntRegs; index++) {
96  }
97 
98  // Set integer register EAX to 0 to indicate that the optional BIST
99  // passed. No BIST actually runs, but software may still check this
100  // register for errors.
101  tc->setIntReg(INTREG_RAX, 0);
102 
103  tc->setMiscReg(MISCREG_CR0, 0x0000000060000010ULL);
104  tc->setMiscReg(MISCREG_CR8, 0);
105 
106  // TODO initialize x87, 64 bit, and 128 bit media state
107 
108  tc->setMiscReg(MISCREG_MTRRCAP, 0x0508);
109  for (int i = 0; i < 8; i++) {
112  }
124 
126 
127  tc->setMiscReg(MISCREG_MCG_CAP, 0x104);
129  tc->setMiscReg(MISCREG_MCG_CTL, 0);
130 
131  for (int i = 0; i < 5; i++) {
132  tc->setMiscReg(MISCREG_MC_CTL(i), 0);
133  tc->setMiscReg(MISCREG_MC_STATUS(i), 0);
134  tc->setMiscReg(MISCREG_MC_ADDR(i), 0);
135  tc->setMiscReg(MISCREG_MC_MISC(i), 0);
136  }
137 
138  tc->setMiscReg(MISCREG_TSC, 0);
139  tc->setMiscReg(MISCREG_TSC_AUX, 0);
140 
141  for (int i = 0; i < 4; i++) {
144  }
145 
146  tc->setMiscReg(MISCREG_STAR, 0);
147  tc->setMiscReg(MISCREG_LSTAR, 0);
148  tc->setMiscReg(MISCREG_CSTAR, 0);
149 
150  tc->setMiscReg(MISCREG_SF_MASK, 0);
151 
153 
157 
158  tc->setMiscReg(MISCREG_PAT, 0x0007040600070406ULL);
159 
160  tc->setMiscReg(MISCREG_SYSCFG, 0x20601);
161 
164 
167 
168  tc->setMiscReg(MISCREG_TOP_MEM, 0x4000000);
169  tc->setMiscReg(MISCREG_TOP_MEM2, 0x0);
170 
176 
177  // Invalidate the caches (this should already be done for us)
178 
179  LocalApicBase lApicBase = 0;
180  lApicBase.base = 0xFEE00000 >> 12;
181  lApicBase.enable = 1;
182  lApicBase.bsp = (cpuId == 0);
183  tc->setMiscReg(MISCREG_APIC_BASE, lApicBase);
184 
185  Interrupts * interrupts = dynamic_cast<Interrupts *>(
186  tc->getCpuPtr()->getInterruptController(0));
187  assert(interrupts);
188 
189  interrupts->setRegNoEffect(APIC_ID, cpuId << 24);
190 
191  interrupts->setRegNoEffect(APIC_VERSION, (5 << 16) | 0x14);
192 
193  // TODO Set the SMRAM base address (SMBASE) to 0x00030000
194 
195  tc->setMiscReg(MISCREG_VM_CR, 0);
196  tc->setMiscReg(MISCREG_IGNNE, 0);
197  tc->setMiscReg(MISCREG_SMM_CTL, 0);
199 }
200 
201 void startupCPU(ThreadContext *tc, int cpuId)
202 {
203  if (cpuId == 0 || !FullSystem) {
204  tc->activate();
205  } else {
206  // This is an application processor (AP). It should be initialized to
207  // look like only the BIOS POST has run on it and put then put it into
208  // a halted state.
209  tc->suspend();
210  }
211 }
212 
213 void
215 {
216  // This function assumes no side effects other than TLB invalidation
217  // need to be considered while copying state. That will likely not be
218  // true in the future.
219  for (int i = 0; i < NUM_MISCREGS; ++i) {
220  if (!isValidMiscReg(i))
221  continue;
222 
224  }
225 
226  // The TSC has to be updated with side-effects if the CPUs in a
227  // CPU switch have different frequencies.
229 
230  dest->getITBPtr()->flushAll();
231  dest->getDTBPtr()->flushAll();
232 }
233 
234 void
236 {
237  //copy int regs
238  for (int i = 0; i < NumIntRegs; ++i)
239  dest->setIntRegFlat(i, src->readIntRegFlat(i));
240  //copy float regs
241  for (int i = 0; i < NumFloatRegs; ++i)
243  //copy condition-code regs
244  for (int i = 0; i < NumCCRegs; ++i)
245  dest->setCCRegFlat(i, src->readCCRegFlat(i));
246  copyMiscRegs(src, dest);
247  dest->pcState(src->pcState());
248 }
249 
250 void
252 {
253  panic("Not implemented for x86\n");
254 }
255 
256 uint64_t
258 {
259  const uint64_t ncc_flags(tc->readMiscRegNoEffect(MISCREG_RFLAGS));
260  const uint64_t cc_flags(tc->readCCReg(X86ISA::CCREG_ZAPS));
261  const uint64_t cfof_bits(tc->readCCReg(X86ISA::CCREG_CFOF));
262  const uint64_t df_bit(tc->readCCReg(X86ISA::CCREG_DF));
263  // ecf (PSEUDO(3)) & ezf (PSEUDO(4)) are only visible to
264  // microcode, so we can safely ignore them.
265 
266  // Reconstruct the real rflags state, mask out internal flags, and
267  // make sure reserved bits have the expected values.
268  return ((ncc_flags | cc_flags | cfof_bits | df_bit) & 0x3F7FD5)
269  | 0x2;
270 }
271 
272 void
274 {
277  tc->setCCReg(X86ISA::CCREG_DF, val & DFBit);
278 
279  // Internal microcode registers (ECF & EZF)
280  tc->setCCReg(X86ISA::CCREG_ECF, 0);
281  tc->setCCReg(X86ISA::CCREG_EZF, 0);
282 
283  // Update the RFLAGS misc reg with whatever didn't go into the
284  // magic registers.
285  tc->setMiscReg(MISCREG_RFLAGS, val & ~(ccFlagMask | cfofMask | DFBit));
286 }
287 
288 uint8_t
289 convX87TagsToXTags(uint16_t ftw)
290 {
291  uint8_t ftwx(0);
292  for (int i = 0; i < 8; ++i) {
293  // Extract the tag for the current element on the FP stack
294  const unsigned tag((ftw >> (2 * i)) & 0x3);
295 
296  /*
297  * Check the type of the current FP element. Valid values are:
298  * 0 == Valid
299  * 1 == Zero
300  * 2 == Special (Nan, unsupported, infinity, denormal)
301  * 3 == Empty
302  */
303  // The xsave version of the tag word only keeps track of
304  // whether the element is empty or not. Set the corresponding
305  // bit in the ftwx if it's not empty,
306  if (tag != 0x3)
307  ftwx |= 1 << i;
308  }
309 
310  return ftwx;
311 }
312 
313 uint16_t
314 convX87XTagsToTags(uint8_t ftwx)
315 {
316  uint16_t ftw(0);
317  for (int i = 0; i < 8; ++i) {
318  const unsigned xtag(((ftwx >> i) & 0x1));
319 
320  // The xtag for an x87 stack position is 0 for empty stack positions.
321  if (!xtag) {
322  // Set the tag word to 3 (empty) for the current element.
323  ftw |= 0x3 << (2 * i);
324  } else {
325  // TODO: We currently assume that non-empty elements are
326  // valid (0x0), but we should ideally reconstruct the full
327  // state (valid/zero/special).
328  }
329  }
330 
331  return ftw;
332 }
333 
334 uint16_t
335 genX87Tags(uint16_t ftw, uint8_t top, int8_t spm)
336 {
337  const uint8_t new_top((top + spm + 8) % 8);
338 
339  if (spm > 0) {
340  // Removing elements from the stack. Flag the elements as empty.
341  for (int i = top; i != new_top; i = (i + 1 + 8) % 8)
342  ftw |= 0x3 << (2 * i);
343  } else if (spm < 0) {
344  // Adding elements to the stack. Flag the new elements as
345  // valid. We should ideally decode them and "do the right
346  // thing".
347  for (int i = new_top; i != top; i = (i + 1 + 8) % 8)
348  ftw &= ~(0x3 << (2 * i));
349  }
350 
351  return ftw;
352 }
353 
354 double
355 loadFloat80(const void *_mem)
356 {
357  fp80_t fp80;
358  memcpy(fp80.bits, _mem, 10);
359 
360  return fp80_cvtd(fp80);
361 }
362 
363 void
364 storeFloat80(void *_mem, double value)
365 {
366  fp80_t fp80 = fp80_cvfd(value);
367  memcpy(_mem, fp80.bits, 10);
368 }
369 
370 } // namespace X86_ISA
void skipFunction(ThreadContext *tc)
Definition: utility.cc:251
uint64_t getRFlags(ThreadContext *tc)
Reconstruct the rflags register from the internal gem5 register state.
Definition: utility.cc:257
static MiscRegIndex MISCREG_PERF_EVT_CTR(int index)
Definition: misc.hh:482
Bitfield< 5, 3 > index
Definition: types.hh:95
void copyMiscRegs(ThreadContext *src, ThreadContext *dest)
Definition: utility.cc:214
Bitfield< 7 > i
Definition: miscregs.hh:1378
#define panic(...)
Definition: misc.hh:153
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
Definition: faults.cc:177
virtual CCReg readCCReg(int reg_idx)=0
virtual void setFloatRegBitsFlat(int idx, FloatRegBits val)=0
void setRegNoEffect(ApicRegIndex reg, uint32_t val)
Definition: interrupts.hh:261
virtual uint64_t readIntRegFlat(int idx)=0
Flat register interfaces.
Bitfield< 0 > fp
virtual MiscReg readMiscRegNoEffect(int misc_reg) const =0
virtual FloatRegBits readFloatRegBitsFlat(int idx)=0
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:146
virtual void setMiscReg(int misc_reg, const MiscReg &val)=0
virtual void setIntRegFlat(int idx, uint64_t val)=0
virtual void setIntReg(int reg_idx, uint64_t val)=0
virtual BaseCPU * getCpuPtr()=0
void storeFloat80(void *_mem, double value)
Convert and store a double as an 80-bit float.
Definition: utility.cc:364
virtual TheISA::PCState pcState()=0
Bitfield< 19 > pc
Definition: misc.hh:806
static bool isValidMiscReg(int index)
Definition: misc.hh:403
const int NumFloatRegs
Definition: registers.hh:65
ThreadContext is the external interface to all thread state for anything outside of the CPU...
Bitfield< 63 > val
Definition: misc.hh:770
virtual CCReg readCCRegFlat(int idx)=0
virtual void setCCReg(int reg_idx, CCReg val)=0
virtual uint64_t readIntReg(int reg_idx)=0
MicroPC upc() const
Definition: types.hh:195
virtual TheISA::TLB * getDTBPtr()=0
void copyRegs(ThreadContext *src, ThreadContext *dest)
Definition: utility.cc:235
uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
Definition: utility.cc:53
virtual void suspend()=0
Set the status to Suspended.
uint16_t convX87XTagsToTags(uint8_t ftwx)
Convert an x87 xtag word to normal tags format.
Definition: utility.cc:314
void setRFlags(ThreadContext *tc, uint64_t val)
Set update the rflags register and internal gem5 state.
Definition: utility.cc:273
static MiscRegIndex MISCREG_MTRR_PHYS_BASE(int index)
Definition: misc.hh:426
virtual void activate()=0
Set the status to Active.
const int NumImplicitIntRegs
Definition: x86_traits.hh:49
const int NumCCRegs
Definition: registers.hh:59
virtual void setCCRegFlat(int idx, CCReg val)=0
const int NumMicroIntRegs
Definition: x86_traits.hh:47
virtual MiscReg readMiscReg(int misc_reg)=0
void initCPU(ThreadContext *tc, int cpuId)
Definition: utility.cc:74
uint16_t genX87Tags(uint16_t ftw, uint8_t top, int8_t spm)
Generate and updated x87 tag register after a push/pop operation.
Definition: utility.cc:335
int size()
Definition: pagetable.hh:146
uint8_t convX87TagsToXTags(uint16_t ftw)
Convert an x87 tag word to abridged tag format.
Definition: utility.cc:289
static MiscRegIndex MISCREG_MTRR_PHYS_MASK(int index)
Definition: misc.hh:434
static MiscRegIndex MISCREG_PERF_EVT_SEL(int index)
Definition: misc.hh:474
static IntRegIndex INTREG_IMPLICIT(int index)
Definition: int.hh:162
const int NumIntRegs
Definition: registers.hh:58
static MiscRegIndex MISCREG_MC_ADDR(int index)
Definition: misc.hh:458
static IntRegIndex INTREG_MICRO(int index)
Definition: int.hh:156
static MiscRegIndex MISCREG_MC_CTL(int index)
Definition: misc.hh:442
MicroPC nupc() const
Definition: types.hh:198
const uint32_t ccFlagMask
Definition: misc.hh:68
double loadFloat80(const void *_mem)
Load an 80-bit float from memory and convert it to double.
Definition: utility.cc:355
static MiscRegIndex MISCREG_MC_MISC(int index)
Definition: misc.hh:466
static MiscRegIndex MISCREG_MC_STATUS(int index)
Definition: misc.hh:450
virtual void setMiscRegNoEffect(int misc_reg, const MiscReg &val)=0
const uint32_t cfofMask
Definition: misc.hh:67
const FlagsType init
This Stat is Initialized.
Definition: info.hh:45
virtual TheISA::TLB * getITBPtr()=0
void startupCPU(ThreadContext *tc, int cpuId)
Definition: utility.cc:201

Generated on Fri Jun 9 2017 13:03:37 for gem5 by doxygen 1.8.6