gem5  v22.1.0.0
isa.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 The Regents of The University of Michigan
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "arch/x86/isa.hh"
30 
31 #include "arch/x86/decoder.hh"
32 #include "arch/x86/mmu.hh"
33 #include "arch/x86/regs/ccr.hh"
34 #include "arch/x86/regs/float.hh"
35 #include "arch/x86/regs/int.hh"
36 #include "arch/x86/regs/misc.hh"
37 #include "base/compiler.hh"
38 #include "cpu/base.hh"
39 #include "cpu/thread_context.hh"
40 #include "params/X86ISA.hh"
41 #include "sim/serialize.hh"
42 
43 namespace gem5
44 {
45 
46 namespace X86ISA
47 {
48 
49 void
51  SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags)
52 {
53  HandyM5Reg m5reg = 0;
54  if (efer.lma) {
55  m5reg.mode = LongMode;
56  if (csAttr.longMode)
57  m5reg.submode = SixtyFourBitMode;
58  else
59  m5reg.submode = CompatabilityMode;
60  } else {
61  m5reg.mode = LegacyMode;
62  if (cr0.pe) {
63  if (rflags.vm)
64  m5reg.submode = Virtual8086Mode;
65  else
66  m5reg.submode = ProtectedMode;
67  } else {
68  m5reg.submode = RealMode;
69  }
70  }
71  m5reg.cpl = csAttr.dpl;
72  m5reg.paging = cr0.pg;
73  m5reg.prot = cr0.pe;
74 
75  // Compute the default and alternate operand size.
76  if (m5reg.submode == SixtyFourBitMode || csAttr.defaultSize) {
77  m5reg.defOp = 2;
78  m5reg.altOp = 1;
79  } else {
80  m5reg.defOp = 1;
81  m5reg.altOp = 2;
82  }
83 
84  // Compute the default and alternate address size.
85  if (m5reg.submode == SixtyFourBitMode) {
86  m5reg.defAddr = 3;
87  m5reg.altAddr = 2;
88  } else if (csAttr.defaultSize) {
89  m5reg.defAddr = 2;
90  m5reg.altAddr = 1;
91  } else {
92  m5reg.defAddr = 1;
93  m5reg.altAddr = 2;
94  }
95 
96  // Compute the stack size
97  if (m5reg.submode == SixtyFourBitMode) {
98  m5reg.stack = 3;
99  } else if (ssAttr.defaultSize) {
100  m5reg.stack = 2;
101  } else {
102  m5reg.stack = 1;
103  }
104 
105  regVal[misc_reg::M5Reg] = m5reg;
106  if (tc)
107  tc->getDecoderPtr()->as<Decoder>().setM5Reg(m5reg);
108 }
109 
110 void
112 {
113  // Blank everything. 0 might not be an appropriate value for some things,
114  // but it is for most.
115  memset(regVal, 0, misc_reg::NumRegs * sizeof(RegVal));
116 
117  // If some state should be non-zero after a reset, set those values here.
118  regVal[misc_reg::Cr0] = 0x0000000060000010ULL;
119 
120  regVal[misc_reg::Mtrrcap] = 0x0508;
121 
122  regVal[misc_reg::McgCap] = 0x104;
123 
124  regVal[misc_reg::Pat] = 0x0007040600070406ULL;
125 
126  regVal[misc_reg::Syscfg] = 0x20601;
127 
128  regVal[misc_reg::TopMem] = 0x4000000;
129 
130  regVal[misc_reg::Dr6] = (mask(8) << 4) | (mask(16) << 16);
131  regVal[misc_reg::Dr7] = 1 << 10;
132 
133  LocalApicBase lApicBase = 0;
134  lApicBase.base = 0xFEE00000 >> 12;
135  lApicBase.enable = 1;
136  // The "bsp" bit will be set when this register is read, since then we'll
137  // have a ThreadContext to check the contextId from.
138  regVal[misc_reg::ApicBase] = lApicBase;
139 }
140 
141 namespace
142 {
143 
144 /* Not applicable to X86 */
145 RegClass vecRegClass(VecRegClass, VecRegClassName, 1, debug::IntRegs);
148  debug::IntRegs);
149 
150 } // anonymous namespace
151 
152 ISA::ISA(const X86ISAParams &p) : BaseISA(p), vendorString(p.vendor_string)
153 {
154  fatal_if(vendorString.size() != 12,
155  "CPUID vendor string must be 12 characters\n");
156 
157  _regClasses.push_back(&flatIntRegClass);
158  _regClasses.push_back(&flatFloatRegClass);
159  _regClasses.push_back(&vecRegClass);
160  _regClasses.push_back(&vecElemClass);
161  _regClasses.push_back(&vecPredRegClass);
162  _regClasses.push_back(&ccRegClass);
163  _regClasses.push_back(&miscRegClass);
164 
165  clear();
166 }
167 
168 static void
170 {
171  // This function assumes no side effects other than TLB invalidation
172  // need to be considered while copying state. That will likely not be
173  // true in the future.
174  for (int i = 0; i < misc_reg::NumRegs; ++i) {
175  if (!misc_reg::isValid(i))
176  continue;
177 
179  }
180 
181  // The TSC has to be updated with side-effects if the CPUs in a
182  // CPU switch have different frequencies.
184 
185  dest->getMMUPtr()->flushAll();
186 }
187 
188 void
190 {
191  //copy int regs
192  for (auto &id: flatIntRegClass)
193  tc->setReg(id, src->getReg(id));
194  //copy float regs
195  for (auto &id: flatFloatRegClass)
196  tc->setReg(id, src->getReg(id));
197  //copy condition-code regs
198  for (auto &id: ccRegClass)
199  tc->setReg(id, src->getReg(id));
200  copyMiscRegs(src, tc);
201  tc->pcState(src->pcState());
202 }
203 
204 RegVal
206 {
207  // Make sure we're not dealing with an illegal control register.
208  // Instructions should filter out these indexes, and nothing else should
209  // attempt to read them directly.
210  assert(misc_reg::isValid(idx));
211 
212  return regVal[idx];
213 }
214 
215 RegVal
217 {
218  if (idx == misc_reg::Tsc) {
219  return regVal[misc_reg::Tsc] + tc->getCpuPtr()->curCycle();
220  }
221 
222  if (idx == misc_reg::Fsw) {
223  RegVal fsw = regVal[misc_reg::Fsw];
225  return insertBits(fsw, 13, 11, top);
226  }
227 
228  if (idx == misc_reg::ApicBase) {
229  LocalApicBase base = regVal[misc_reg::ApicBase];
230  base.bsp = (tc->contextId() == 0);
231  return base;
232  }
233 
234  return readMiscRegNoEffect(idx);
235 }
236 
237 void
239 {
240  // Make sure we're not dealing with an illegal control register.
241  // Instructions should filter out these indexes, and nothing else should
242  // attempt to write to them directly.
243  assert(misc_reg::isValid(idx));
244 
245  HandyM5Reg m5Reg = regVal[misc_reg::M5Reg];
246  int reg_width = 64;
247  switch (idx) {
248  case misc_reg::X87Top:
249  reg_width = 3;
250  break;
251  case misc_reg::Ftw:
252  reg_width = 8;
253  break;
254  case misc_reg::Fsw:
255  case misc_reg::Fcw:
256  case misc_reg::Fop:
257  reg_width = 16;
258  break;
259  case misc_reg::Mxcsr:
260  reg_width = 32;
261  break;
262  case misc_reg::Fiseg:
263  case misc_reg::Foseg:
264  if (m5Reg.submode != SixtyFourBitMode)
265  reg_width = 16;
266  break;
267  case misc_reg::Fioff:
268  case misc_reg::Fooff:
269  if (m5Reg.submode != SixtyFourBitMode)
270  reg_width = 32;
271  break;
272  default:
273  break;
274  }
275 
276  regVal[idx] = val & mask(reg_width);
277 }
278 
279 void
281 {
282  RegVal newVal = val;
283  switch (idx) {
284  case misc_reg::Cr0:
285  {
286  CR0 toggled = regVal[idx] ^ val;
287  CR0 newCR0 = val;
288  Efer efer = regVal[misc_reg::Efer];
289  if (toggled.pg && efer.lme) {
290  if (newCR0.pg) {
291  //Turning on long mode
292  efer.lma = 1;
293  regVal[misc_reg::Efer] = efer;
294  } else {
295  //Turning off long mode
296  efer.lma = 0;
297  regVal[misc_reg::Efer] = efer;
298  }
299  }
300  if (toggled.pg) {
301  tc->getMMUPtr()->flushAll();
302  }
303  //This must always be 1.
304  newCR0.et = 1;
305  newVal = newCR0;
307  newCR0,
311  }
312  break;
313  case misc_reg::Cr2:
314  break;
315  case misc_reg::Cr3:
316  static_cast<MMU *>(tc->getMMUPtr())->flushNonGlobal();
317  break;
318  case misc_reg::Cr4:
319  {
320  CR4 toggled = regVal[idx] ^ val;
321  if (toggled.pae || toggled.pse || toggled.pge) {
322  tc->getMMUPtr()->flushAll();
323  }
324  }
325  break;
326  case misc_reg::Cr8:
327  break;
328  case misc_reg::Rflags:
329  {
330  RFLAGS rflags = val;
331  panic_if(rflags.vm, "Virtual 8086 mode is not supported.");
332  break;
333  }
334  case misc_reg::CsAttr:
335  {
336  SegAttr toggled = regVal[idx] ^ val;
337  SegAttr newCSAttr = val;
338  if (toggled.longMode) {
339  if (newCSAttr.longMode) {
344  } else {
349  }
350  }
353  newCSAttr,
356  }
357  break;
358  case misc_reg::SsAttr:
362  val,
364  break;
365  // These segments always actually use their bases, or in other words
366  // their effective bases must stay equal to their actual bases.
367  case misc_reg::FsBase:
368  case misc_reg::GsBase:
369  case misc_reg::HsBase:
370  case misc_reg::TslBase:
371  case misc_reg::TsgBase:
372  case misc_reg::TrBase:
373  case misc_reg::IdtrBase:
375  break;
376  // These segments ignore their bases in 64 bit mode.
377  // their effective bases must stay equal to their actual bases.
378  case misc_reg::EsBase:
379  case misc_reg::CsBase:
380  case misc_reg::SsBase:
381  case misc_reg::DsBase:
382  {
383  Efer efer = regVal[misc_reg::Efer];
384  SegAttr csAttr = regVal[misc_reg::CsAttr];
385  if (!efer.lma || !csAttr.longMode) // Check for non 64 bit mode.
388  }
389  break;
390  case misc_reg::Tsc:
392  return;
393  case misc_reg::Dr0:
394  case misc_reg::Dr1:
395  case misc_reg::Dr2:
396  case misc_reg::Dr3:
397  /* These should eventually set up breakpoints. */
398  break;
399  case misc_reg::Dr4:
400  idx = misc_reg::Dr6;
401  [[fallthrough]];
402  case misc_reg::Dr6:
403  {
404  DR6 dr6 = regVal[misc_reg::Dr6];
405  DR6 newDR6 = val;
406  dr6.b0 = newDR6.b0;
407  dr6.b1 = newDR6.b1;
408  dr6.b2 = newDR6.b2;
409  dr6.b3 = newDR6.b3;
410  dr6.bd = newDR6.bd;
411  dr6.bs = newDR6.bs;
412  dr6.bt = newDR6.bt;
413  newVal = dr6;
414  }
415  break;
416  case misc_reg::Dr5:
417  idx = misc_reg::Dr7;
418  [[fallthrough]];
419  case misc_reg::Dr7:
420  {
421  DR7 dr7 = regVal[misc_reg::Dr7];
422  DR7 newDR7 = val;
423  dr7.l0 = newDR7.l0;
424  dr7.g0 = newDR7.g0;
425  if (dr7.l0 || dr7.g0) {
426  panic("Debug register breakpoints not implemented.\n");
427  } else {
428  /* Disable breakpoint 0. */
429  }
430  dr7.l1 = newDR7.l1;
431  dr7.g1 = newDR7.g1;
432  if (dr7.l1 || dr7.g1) {
433  panic("Debug register breakpoints not implemented.\n");
434  } else {
435  /* Disable breakpoint 1. */
436  }
437  dr7.l2 = newDR7.l2;
438  dr7.g2 = newDR7.g2;
439  if (dr7.l2 || dr7.g2) {
440  panic("Debug register breakpoints not implemented.\n");
441  } else {
442  /* Disable breakpoint 2. */
443  }
444  dr7.l3 = newDR7.l3;
445  dr7.g3 = newDR7.g3;
446  if (dr7.l3 || dr7.g3) {
447  panic("Debug register breakpoints not implemented.\n");
448  } else {
449  /* Disable breakpoint 3. */
450  }
451  dr7.gd = newDR7.gd;
452  dr7.rw0 = newDR7.rw0;
453  dr7.len0 = newDR7.len0;
454  dr7.rw1 = newDR7.rw1;
455  dr7.len1 = newDR7.len1;
456  dr7.rw2 = newDR7.rw2;
457  dr7.len2 = newDR7.len2;
458  dr7.rw3 = newDR7.rw3;
459  dr7.len3 = newDR7.len3;
460  }
461  break;
462  case misc_reg::M5Reg:
463  // Writing anything to the m5reg with side effects makes it update
464  // based on the current values of the relevant registers. The actual
465  // value written is discarded.
471  return;
472  default:
473  break;
474  }
475  setMiscRegNoEffect(idx, newVal);
476 }
477 
478 void
480 {
482 }
483 
484 void
486 {
493 }
494 
495 void
497 {
499  tc->getDecoderPtr()->as<Decoder>().setM5Reg(regVal[misc_reg::M5Reg]);
500 }
501 
502 std::string
504 {
505  return vendorString;
506 }
507 
508 } // namespace X86ISA
509 } // namespace gem5
ThreadContext * tc
Definition: isa.hh:65
RegClasses _regClasses
Definition: isa.hh:67
virtual void setThreadContext(ThreadContext *_tc)
Definition: isa.hh:80
virtual void flushAll()
Definition: mmu.cc:81
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
Type & as()
Definition: decoder.hh:71
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
virtual RegVal getReg(const RegId &reg) const
virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val)=0
virtual const PCStateBase & pcState() const =0
virtual void setReg(const RegId &reg, RegVal val)
virtual InstDecoder * getDecoderPtr()=0
virtual BaseCPU * getCpuPtr()=0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
virtual ContextID contextId() const =0
virtual BaseMMU * getMMUPtr()=0
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: isa.cc:479
std::string vendorString
Definition: isa.hh:60
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: isa.cc:485
RegVal readMiscReg(RegIndex idx) override
Definition: isa.cc:216
void updateHandyM5Reg(Efer efer, CR0 cr0, SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags)
Definition: isa.cc:50
std::string getVendorString() const
Definition: isa.cc:503
ISA(const Params &p)
Definition: isa.cc:152
void setMiscReg(RegIndex idx, RegVal val) override
Definition: isa.cc:280
void setThreadContext(ThreadContext *_tc) override
Definition: isa.cc:496
void setMiscRegNoEffect(RegIndex idx, RegVal val) override
Definition: isa.cc:238
void clear() override
Definition: isa.cc:111
RegVal readMiscRegNoEffect(RegIndex idx) const override
Definition: isa.cc:205
void copyRegsFrom(ThreadContext *src) override
Definition: isa.cc:189
RegVal regVal[misc_reg::NumRegs]
Definition: isa.hh:56
Definition: test.h:63
constexpr T insertBits(T val, unsigned first, unsigned last, B bit_val)
Returns val with bits first to last set to the LSBs of bit_val.
Definition: bitfield.hh:166
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:226
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:204
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:618
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:610
Bitfield< 7 > i
Definition: misc_types.hh:67
constexpr RegClass vecElemClass
Definition: vec.hh:105
constexpr RegClass vecPredRegClass
Definition: vec.hh:109
constexpr RegClass vecRegClass
Definition: vec.hh:101
static bool isValid(int index)
Definition: misc.hh:412
static RegIndex segEffBase(int index)
Definition: misc.hh:519
Bitfield< 51, 12 > base
Definition: pagetable.hh:141
Bitfield< 63 > val
Definition: misc.hh:776
constexpr RegClass miscRegClass(MiscRegClass, MiscRegClassName, misc_reg::NumRegs, debug::MiscRegs)
constexpr RegClass flatFloatRegClass
Definition: float.hh:131
Bitfield< 0 > p
Definition: pagetable.hh:151
static void copyMiscRegs(ThreadContext *src, ThreadContext *dest)
Definition: isa.cc:169
@ Virtual8086Mode
Definition: types.hh:207
@ SixtyFourBitMode
Definition: types.hh:204
@ ProtectedMode
Definition: types.hh:206
@ CompatabilityMode
Definition: types.hh:205
constexpr RegClass flatIntRegClass
Definition: int.hh:112
constexpr RegClass ccRegClass(CCRegClass, CCRegClassName, cc_reg::NumRegs, debug::CCRegs)
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
uint16_t RegIndex
Definition: types.hh:176
constexpr char VecPredRegClassName[]
Definition: reg_class.hh:77
std::ostream CheckpointOut
Definition: serialize.hh:66
constexpr char VecRegClassName[]
Definition: reg_class.hh:75
uint64_t RegVal
Definition: types.hh:173
@ VecPredRegClass
Definition: reg_class.hh:66
@ VecRegClass
Vector Register.
Definition: reg_class.hh:63
@ VecElemClass
Vector Register Native Elem lane.
Definition: reg_class.hh:65
constexpr char VecElemClassName[]
Definition: reg_class.hh:76

Generated on Wed Dec 21 2022 10:22:23 for gem5 by doxygen 1.9.1