gem5 v24.0.0.0
Loading...
Searching...
No Matches
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"
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 "debug/MatRegs.hh"
41#include "params/X86ISA.hh"
42#include "sim/serialize.hh"
43
44namespace gem5
45{
46
47namespace X86ISA
48{
49
50void
51ISA::updateHandyM5Reg(Efer efer, CR0 cr0,
52 SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags)
53{
54 HandyM5Reg m5reg = 0;
55 if (efer.lma) {
56 m5reg.mode = LongMode;
57 if (csAttr.longMode)
58 m5reg.submode = SixtyFourBitMode;
59 else
60 m5reg.submode = CompatabilityMode;
61 } else {
62 m5reg.mode = LegacyMode;
63 if (cr0.pe) {
64 if (rflags.vm)
65 m5reg.submode = Virtual8086Mode;
66 else
67 m5reg.submode = ProtectedMode;
68 } else {
69 m5reg.submode = RealMode;
70 }
71 }
72 m5reg.cpl = csAttr.dpl;
73 m5reg.paging = cr0.pg;
74 m5reg.prot = cr0.pe;
75
76 // Compute the default and alternate operand size.
77 if (m5reg.submode == SixtyFourBitMode || csAttr.defaultSize) {
78 m5reg.defOp = 2;
79 m5reg.altOp = 1;
80 } else {
81 m5reg.defOp = 1;
82 m5reg.altOp = 2;
83 }
84
85 // Compute the default and alternate address size.
86 if (m5reg.submode == SixtyFourBitMode) {
87 m5reg.defAddr = 3;
88 m5reg.altAddr = 2;
89 } else if (csAttr.defaultSize) {
90 m5reg.defAddr = 2;
91 m5reg.altAddr = 1;
92 } else {
93 m5reg.defAddr = 1;
94 m5reg.altAddr = 2;
95 }
96
97 // Compute the stack size
98 if (m5reg.submode == SixtyFourBitMode) {
99 m5reg.stack = 3;
100 } else if (ssAttr.defaultSize) {
101 m5reg.stack = 2;
102 } else {
103 m5reg.stack = 1;
104 }
105
106 regVal[misc_reg::M5Reg] = m5reg;
107 if (tc)
108 tc->getDecoderPtr()->as<Decoder>().setM5Reg(m5reg);
109}
110
111void
113{
114 // Blank everything. 0 might not be an appropriate value for some things,
115 // but it is for most.
116 memset(regVal, 0, misc_reg::NumRegs * sizeof(RegVal));
117
118 // If some state should be non-zero after a reset, set those values here.
119 regVal[misc_reg::Cr0] = 0x0000000060000010ULL;
120
121 regVal[misc_reg::Mtrrcap] = 0x0508;
122
123 regVal[misc_reg::McgCap] = 0x104;
124
125 regVal[misc_reg::Pat] = 0x0007040600070406ULL;
126
127 regVal[misc_reg::Syscfg] = 0x20601;
128
129 regVal[misc_reg::TopMem] = 0x4000000;
130
131 regVal[misc_reg::Dr6] = (mask(8) << 4) | (mask(16) << 16);
132 regVal[misc_reg::Dr7] = 1 << 10;
133
134 LocalApicBase lApicBase = 0;
135 lApicBase.base = 0xFEE00000 >> 12;
136 lApicBase.enable = 1;
137 // The "bsp" bit will be set when this register is read, since then we'll
138 // have a ThreadContext to check the contextId from.
139 regVal[misc_reg::ApicBase] = lApicBase;
140}
141
142namespace
143{
144
145/* Not applicable to X86 */
149 debug::IntRegs);
151
152} // anonymous namespace
153
154ISA::ISA(const X86ISAParams &p)
155 : BaseISA(p, "x86"), cpuid(new X86CPUID(p.vendor_string, p.name_string))
156{
157 cpuid->addStandardFunc(FamilyModelStepping, p.FamilyModelStepping);
158 cpuid->addStandardFunc(CacheParams, p.CacheParams);
159 cpuid->addStandardFunc(ExtendedFeatures, p.ExtendedFeatures);
160 cpuid->addStandardFunc(ExtendedState, p.ExtendedState);
161
163 p.FamilyModelSteppingBrandFeatures);
164 cpuid->addExtendedFunc(L1CacheAndTLB, p.L1CacheAndTLB);
165 cpuid->addExtendedFunc(L2L3CacheAndL2TLB, p.L2L3CacheAndL2TLB);
166 cpuid->addExtendedFunc(APMInfo, p.APMInfo);
167 cpuid->addExtendedFunc(LongModeAddressSize, p.LongModeAddressSize);
168
169 _regClasses.push_back(&flatIntRegClass);
170 _regClasses.push_back(&flatFloatRegClass);
171 _regClasses.push_back(&vecRegClass);
172 _regClasses.push_back(&vecElemClass);
173 _regClasses.push_back(&vecPredRegClass);
174 _regClasses.push_back(&matRegClass);
175 _regClasses.push_back(&ccRegClass);
176 _regClasses.push_back(&miscRegClass);
177
178 clear();
179}
180
181static void
183{
184 // This function assumes no side effects other than TLB invalidation
185 // need to be considered while copying state. That will likely not be
186 // true in the future.
187 for (int i = 0; i < misc_reg::NumRegs; ++i) {
188 if (!misc_reg::isValid(i))
189 continue;
190
192 }
193
194 // The TSC has to be updated with side-effects if the CPUs in a
195 // CPU switch have different frequencies.
197
198 dest->getMMUPtr()->flushAll();
199}
200
201void
203{
204 //copy int regs
205 for (auto &id: flatIntRegClass)
206 tc->setReg(id, src->getReg(id));
207 //copy float regs
208 for (auto &id: flatFloatRegClass)
209 tc->setReg(id, src->getReg(id));
210 //copy condition-code regs
211 for (auto &id: ccRegClass)
212 tc->setReg(id, src->getReg(id));
213 copyMiscRegs(src, tc);
214 tc->pcState(src->pcState());
215}
216
217RegVal
219{
220 // Make sure we're not dealing with an illegal control register.
221 // Instructions should filter out these indexes, and nothing else should
222 // attempt to read them directly.
223 assert(misc_reg::isValid(idx));
224
225 return regVal[idx];
226}
227
228RegVal
230{
231 if (idx == misc_reg::Tsc) {
232 return regVal[misc_reg::Tsc] + tc->getCpuPtr()->curCycle();
233 }
234
235 if (idx == misc_reg::Fsw) {
238 return insertBits(fsw, 13, 11, top);
239 }
240
241 if (idx == misc_reg::ApicBase) {
242 LocalApicBase base = regVal[misc_reg::ApicBase];
243 base.bsp = (tc->contextId() == 0);
244 return base;
245 }
246
247 if (idx == misc_reg::Xcr0) {
248 return regVal[idx] | 1;
249 }
250
251 return readMiscRegNoEffect(idx);
252}
253
254void
256{
257 // Make sure we're not dealing with an illegal control register.
258 // Instructions should filter out these indexes, and nothing else should
259 // attempt to write to them directly.
260 assert(misc_reg::isValid(idx));
261
262 HandyM5Reg m5Reg = regVal[misc_reg::M5Reg];
263 int reg_width = 64;
264 switch (idx) {
265 case misc_reg::X87Top:
266 reg_width = 3;
267 break;
268 case misc_reg::Ftw:
269 reg_width = 16;
270 break;
271 case misc_reg::Fsw:
272 case misc_reg::Fcw:
273 case misc_reg::Fop:
274 reg_width = 16;
275 break;
276 case misc_reg::Mxcsr:
277 reg_width = 32;
278 break;
279 case misc_reg::Fiseg:
280 case misc_reg::Foseg:
281 if (m5Reg.submode != SixtyFourBitMode)
282 reg_width = 16;
283 break;
284 case misc_reg::Fioff:
285 case misc_reg::Fooff:
286 if (m5Reg.submode != SixtyFourBitMode)
287 reg_width = 32;
288 break;
289 default:
290 break;
291 }
292
293 regVal[idx] = val & mask(reg_width);
294}
295
296void
298{
299 RegVal newVal = val;
300 switch (idx) {
301 case misc_reg::Cr0:
302 {
303 CR0 toggled = regVal[idx] ^ val;
304 CR0 newCR0 = val;
305 Efer efer = regVal[misc_reg::Efer];
306 if (toggled.pg && efer.lme) {
307 if (newCR0.pg) {
308 //Turning on long mode
309 efer.lma = 1;
310 regVal[misc_reg::Efer] = efer;
311 } else {
312 //Turning off long mode
313 efer.lma = 0;
314 regVal[misc_reg::Efer] = efer;
315 }
316 }
317 if (toggled.pg) {
318 tc->getMMUPtr()->flushAll();
319 }
320 //This must always be 1.
321 newCR0.et = 1;
322 newVal = newCR0;
324 newCR0,
328 }
329 break;
330 case misc_reg::Cr2:
331 break;
332 case misc_reg::Cr3:
333 static_cast<MMU *>(tc->getMMUPtr())->flushNonGlobal();
334 break;
335 case misc_reg::Cr4:
336 {
337 CR4 toggled = regVal[idx] ^ val;
338 if (toggled.pae || toggled.pse || toggled.pge) {
339 tc->getMMUPtr()->flushAll();
340 }
341 }
342 break;
343 case misc_reg::Cr8:
344 break;
345 case misc_reg::Xcr0:
346 break;
347 case misc_reg::Rflags:
348 {
349 RFLAGS rflags = val;
350 panic_if(rflags.vm, "Virtual 8086 mode is not supported.");
351 break;
352 }
353 case misc_reg::CsAttr:
354 {
355 SegAttr toggled = regVal[idx] ^ val;
356 SegAttr newCSAttr = val;
357 if (toggled.longMode) {
358 if (newCSAttr.longMode) {
363 } else {
368 }
369 }
372 newCSAttr,
375 }
376 break;
377 case misc_reg::SsAttr:
381 val,
383 break;
384 // These segments always actually use their bases, or in other words
385 // their effective bases must stay equal to their actual bases.
386 case misc_reg::FsBase:
387 case misc_reg::GsBase:
388 case misc_reg::HsBase:
391 case misc_reg::TrBase:
394 break;
395 // These segments ignore their bases in 64 bit mode.
396 // their effective bases must stay equal to their actual bases.
397 case misc_reg::EsBase:
398 case misc_reg::CsBase:
399 case misc_reg::SsBase:
400 case misc_reg::DsBase:
401 {
402 Efer efer = regVal[misc_reg::Efer];
403 SegAttr csAttr = regVal[misc_reg::CsAttr];
404 if (!efer.lma || !csAttr.longMode) // Check for non 64 bit mode.
407 }
408 break;
409 case misc_reg::Tsc:
411 return;
412 case misc_reg::Dr0:
413 case misc_reg::Dr1:
414 case misc_reg::Dr2:
415 case misc_reg::Dr3:
416 /* These should eventually set up breakpoints. */
417 break;
418 case misc_reg::Dr4:
419 idx = misc_reg::Dr6;
420 [[fallthrough]];
421 case misc_reg::Dr6:
422 {
423 DR6 dr6 = regVal[misc_reg::Dr6];
424 DR6 newDR6 = val;
425 dr6.b0 = newDR6.b0;
426 dr6.b1 = newDR6.b1;
427 dr6.b2 = newDR6.b2;
428 dr6.b3 = newDR6.b3;
429 dr6.bd = newDR6.bd;
430 dr6.bs = newDR6.bs;
431 dr6.bt = newDR6.bt;
432 newVal = dr6;
433 }
434 break;
435 case misc_reg::Dr5:
436 idx = misc_reg::Dr7;
437 [[fallthrough]];
438 case misc_reg::Dr7:
439 {
440 DR7 dr7 = regVal[misc_reg::Dr7];
441 DR7 newDR7 = val;
442 dr7.l0 = newDR7.l0;
443 dr7.g0 = newDR7.g0;
444 if (dr7.l0 || dr7.g0) {
445 panic("Debug register breakpoints not implemented.\n");
446 } else {
447 /* Disable breakpoint 0. */
448 }
449 dr7.l1 = newDR7.l1;
450 dr7.g1 = newDR7.g1;
451 if (dr7.l1 || dr7.g1) {
452 panic("Debug register breakpoints not implemented.\n");
453 } else {
454 /* Disable breakpoint 1. */
455 }
456 dr7.l2 = newDR7.l2;
457 dr7.g2 = newDR7.g2;
458 if (dr7.l2 || dr7.g2) {
459 panic("Debug register breakpoints not implemented.\n");
460 } else {
461 /* Disable breakpoint 2. */
462 }
463 dr7.l3 = newDR7.l3;
464 dr7.g3 = newDR7.g3;
465 if (dr7.l3 || dr7.g3) {
466 panic("Debug register breakpoints not implemented.\n");
467 } else {
468 /* Disable breakpoint 3. */
469 }
470 dr7.gd = newDR7.gd;
471 dr7.rw0 = newDR7.rw0;
472 dr7.len0 = newDR7.len0;
473 dr7.rw1 = newDR7.rw1;
474 dr7.len1 = newDR7.len1;
475 dr7.rw2 = newDR7.rw2;
476 dr7.len2 = newDR7.len2;
477 dr7.rw3 = newDR7.rw3;
478 dr7.len3 = newDR7.len3;
479 }
480 break;
481 case misc_reg::M5Reg:
482 // Writing anything to the m5reg with side effects makes it update
483 // based on the current values of the relevant registers. The actual
484 // value written is discarded.
490 return;
491 default:
492 break;
493 }
494 setMiscRegNoEffect(idx, newVal);
495}
496
497void
504
505void
515
516void
522
523std::string
525{
526 return vendorString;
527}
528
529} // namespace X86ISA
530} // namespace gem5
ThreadContext * tc
Definition isa.hh:68
RegClasses _regClasses
Definition isa.hh:70
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition isa.hh:136
virtual void setThreadContext(ThreadContext *_tc)
Definition isa.hh:85
virtual void flushAll()
Definition mmu.cc:81
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
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 BaseCPU * getCpuPtr()=0
virtual void setReg(const RegId &reg, RegVal val)
virtual InstDecoder * getDecoderPtr()=0
virtual const PCStateBase & pcState() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
virtual BaseMMU * getMMUPtr()=0
virtual ContextID contextId() const =0
std::unique_ptr< X86CPUID > cpuid
Definition isa.hh:98
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition isa.cc:498
std::string vendorString
Definition isa.hh:61
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition isa.cc:506
RegVal readMiscReg(RegIndex idx) override
Definition isa.cc:229
void updateHandyM5Reg(Efer efer, CR0 cr0, SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags)
Definition isa.cc:51
std::string getVendorString() const
Definition isa.cc:524
ISA(const Params &p)
Definition isa.cc:154
void setMiscReg(RegIndex idx, RegVal val) override
Definition isa.cc:297
void setThreadContext(ThreadContext *_tc) override
Definition isa.cc:517
void setMiscRegNoEffect(RegIndex idx, RegVal val) override
Definition isa.cc:255
void clear() override
Definition isa.cc:112
RegVal readMiscRegNoEffect(RegIndex idx) const override
Definition isa.cc:218
void copyRegsFrom(ThreadContext *src) override
Definition isa.cc:202
RegVal regVal[misc_reg::NumRegs]
Definition isa.hh:57
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:185
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:214
#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 matRegClass
Definition mat.hh:92
constexpr RegClass vecElemClass
Definition vec.hh:105
constexpr RegClass vecPredRegClass
Definition vec.hh:109
constexpr RegClass ccRegClass
Definition cc.hh:87
constexpr RegClass miscRegClass
Definition misc.hh:2937
constexpr RegClass vecRegClass
Definition vec.hh:101
Bitfield< 28, 21 > cpuid
static bool isValid(int index)
Definition misc.hh:415
static RegIndex segEffBase(int index)
Definition misc.hh:529
@ LongModeAddressSize
Definition cpuid.hh:69
@ FamilyModelSteppingBrandFeatures
Definition cpuid.hh:62
@ L1CacheAndTLB
Definition cpuid.hh:66
@ L2L3CacheAndL2TLB
Definition cpuid.hh:67
Bitfield< 51, 12 > base
Definition pagetable.hh:141
Bitfield< 63 > val
Definition misc.hh:804
constexpr RegClass flatFloatRegClass
Definition float.hh:131
@ FamilyModelStepping
Definition cpuid.hh:48
@ ExtendedFeatures
Definition cpuid.hh:54
@ CacheParams
Definition cpuid.hh:51
@ ExtendedState
Definition cpuid.hh:55
Bitfield< 0 > p
Definition pagetable.hh:151
static void copyMiscRegs(ThreadContext *src, ThreadContext *dest)
Definition isa.cc:182
@ 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
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
uint16_t RegIndex
Definition types.hh:176
uint64_t RegVal
Definition types.hh:173
constexpr char VecPredRegClassName[]
Definition reg_class.hh:79
std::ostream CheckpointOut
Definition serialize.hh:66
constexpr char VecRegClassName[]
Definition reg_class.hh:77
constexpr char MatRegClassName[]
Definition reg_class.hh:80
@ VecPredRegClass
Definition reg_class.hh:67
@ MatRegClass
Matrix Register.
Definition reg_class.hh:68
@ VecRegClass
Vector Register.
Definition reg_class.hh:64
@ VecElemClass
Vector Register Native Elem lane.
Definition reg_class.hh:66
constexpr char VecElemClassName[]
Definition reg_class.hh:78

Generated on Tue Jun 18 2024 16:23:57 for gem5 by doxygen 1.11.0