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