1 /////////////////////////////////////////////////////////////////////////
2 // $Id: crregs.h 14086 2021-01-30 08:35:35Z sshwarts $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 //   Copyright (c) 2007-2020 Stanislav Shwartsman
6 //          Written by Stanislav Shwartsman [sshwarts at sourceforge net]
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 //  You should have received a copy of the GNU Lesser General Public
19 //  License along with this library; if not, write to the Free Software
20 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
21 //
22 /////////////////////////////////////////////////////////////////////////
23 
24 #ifndef BX_CRREGS
25 #define BX_CRREGS
26 
27 #define BX_CR0_PE_MASK         (1 <<  0)
28 #define BX_CR0_MP_MASK         (1 <<  1)
29 #define BX_CR0_EM_MASK         (1 <<  2)
30 #define BX_CR0_TS_MASK         (1 <<  3)
31 #define BX_CR0_ET_MASK         (1 <<  4)
32 #define BX_CR0_NE_MASK         (1 <<  5)
33 #define BX_CR0_WP_MASK         (1 << 16)
34 #define BX_CR0_AM_MASK         (1 << 18)
35 #define BX_CR0_NW_MASK         (1 << 29)
36 #define BX_CR0_CD_MASK         (1 << 30)
37 #define BX_CR0_PG_MASK         (1 << 31)
38 
39 struct bx_cr0_t {
40   Bit32u  val32; // 32bit value of register
41 
42   // Accessors for all cr0 bitfields.
43 #define IMPLEMENT_CRREG_ACCESSORS(name, bitnum)            \
44   BX_CPP_INLINE bool get_##name() const {               \
45     return 1 & (val32 >> bitnum);                          \
46   }                                                        \
47   BX_CPP_INLINE void set_##name(Bit8u val) {               \
48     val32 = (val32 & ~(1<<bitnum)) | ((!!val) << bitnum);  \
49   }
50 
51 // CR0 notes:
52 //   Each x86 level has its own quirks regarding how it handles
53 //   reserved bits.  I used DOS DEBUG.EXE in real mode on the
54 //   following processors, tried to clear bits 1..30, then tried
55 //   to set bits 1..30, to see how these bits are handled.
56 //   I found the following:
57 //
58 //   Processor    try to clear bits 1..30    try to set bits 1..30
59 //   386          7FFFFFF0                   7FFFFFFE
60 //   486DX2       00000010                   6005003E
61 //   Pentium      00000010                   7FFFFFFE
62 //   Pentium-II   00000010                   6005003E
63 //
64 // My assumptions:
65 //   All processors: bit 4 is hardwired to 1 (not true on all clones)
66 //   386: bits 5..30 of CR0 are also hardwired to 1
67 //   Pentium: reserved bits retain value set using mov cr0, reg32
68 //   486DX2/Pentium-II: reserved bits are hardwired to 0
69 
70   IMPLEMENT_CRREG_ACCESSORS(PE, 0);
71   IMPLEMENT_CRREG_ACCESSORS(MP, 1);
72   IMPLEMENT_CRREG_ACCESSORS(EM, 2);
73   IMPLEMENT_CRREG_ACCESSORS(TS, 3);
74 #if BX_CPU_LEVEL >= 4
75   IMPLEMENT_CRREG_ACCESSORS(ET, 4);
76   IMPLEMENT_CRREG_ACCESSORS(NE, 5);
77   IMPLEMENT_CRREG_ACCESSORS(WP, 16);
78   IMPLEMENT_CRREG_ACCESSORS(AM, 18);
79   IMPLEMENT_CRREG_ACCESSORS(NW, 29);
80   IMPLEMENT_CRREG_ACCESSORS(CD, 30);
81 #endif
82   IMPLEMENT_CRREG_ACCESSORS(PG, 31);
83 
get32bx_cr0_t84   BX_CPP_INLINE Bit32u get32() const { return val32; }
85   // ET is hardwired bit in CR0
set32bx_cr0_t86   BX_CPP_INLINE void set32(Bit32u val) { val32 = val | 0x10; }
87 };
88 
89 #if BX_CPU_LEVEL >= 5
90 
91 #define BX_CR4_VME_MASK        (1 << 0)
92 #define BX_CR4_PVI_MASK        (1 << 1)
93 #define BX_CR4_TSD_MASK        (1 << 2)
94 #define BX_CR4_DE_MASK         (1 << 3)
95 #define BX_CR4_PSE_MASK        (1 << 4)
96 #define BX_CR4_PAE_MASK        (1 << 5)
97 #define BX_CR4_MCE_MASK        (1 << 6)
98 #define BX_CR4_PGE_MASK        (1 << 7)
99 #define BX_CR4_PCE_MASK        (1 << 8)
100 #define BX_CR4_OSFXSR_MASK     (1 << 9)
101 #define BX_CR4_OSXMMEXCPT_MASK (1 << 10)
102 #define BX_CR4_UMIP_MASK       (1 << 11)
103 #define BX_CR4_LA57_MASK       (1 << 12)
104 #define BX_CR4_VMXE_MASK       (1 << 13)
105 #define BX_CR4_SMXE_MASK       (1 << 14)
106 #define BX_CR4_FSGSBASE_MASK   (1 << 16)
107 #define BX_CR4_PCIDE_MASK      (1 << 17)
108 #define BX_CR4_OSXSAVE_MASK    (1 << 18)
109 #define BX_CR4_KEYLOCKER_MASK  (1 << 19)
110 #define BX_CR4_SMEP_MASK       (1 << 20)
111 #define BX_CR4_SMAP_MASK       (1 << 21)
112 #define BX_CR4_PKE_MASK        (1 << 22)
113 #define BX_CR4_CET_MASK        (1 << 23)
114 #define BX_CR4_PKS_MASK        (1 << 24)
115 
116 struct bx_cr4_t {
117   Bit32u  val32; // 32bit value of register
118 
119   IMPLEMENT_CRREG_ACCESSORS(VME, 0);
120   IMPLEMENT_CRREG_ACCESSORS(PVI, 1);
121   IMPLEMENT_CRREG_ACCESSORS(TSD, 2);
122   IMPLEMENT_CRREG_ACCESSORS(DE,  3);
123   IMPLEMENT_CRREG_ACCESSORS(PSE, 4);
124   IMPLEMENT_CRREG_ACCESSORS(PAE, 5);
125   IMPLEMENT_CRREG_ACCESSORS(MCE, 6);
126   IMPLEMENT_CRREG_ACCESSORS(PGE, 7);
127   IMPLEMENT_CRREG_ACCESSORS(PCE, 8);
128   IMPLEMENT_CRREG_ACCESSORS(OSFXSR, 9);
129   IMPLEMENT_CRREG_ACCESSORS(OSXMMEXCPT, 10);
130   IMPLEMENT_CRREG_ACCESSORS(UMIP, 11);
131   IMPLEMENT_CRREG_ACCESSORS(LA57, 12);
132 #if BX_SUPPORT_VMX
133   IMPLEMENT_CRREG_ACCESSORS(VMXE, 13);
134 #endif
135   IMPLEMENT_CRREG_ACCESSORS(SMXE, 14);
136 #if BX_SUPPORT_X86_64
137   IMPLEMENT_CRREG_ACCESSORS(FSGSBASE, 16);
138 #endif
139   IMPLEMENT_CRREG_ACCESSORS(PCIDE, 17);
140   IMPLEMENT_CRREG_ACCESSORS(OSXSAVE, 18);
141   IMPLEMENT_CRREG_ACCESSORS(KEYLOCKER, 19);
142   IMPLEMENT_CRREG_ACCESSORS(SMEP, 20);
143   IMPLEMENT_CRREG_ACCESSORS(SMAP, 21);
144   IMPLEMENT_CRREG_ACCESSORS(PKE, 22);
145   IMPLEMENT_CRREG_ACCESSORS(CET, 23);
146   IMPLEMENT_CRREG_ACCESSORS(PKS, 24);
147 
get32bx_cr4_t148   BX_CPP_INLINE Bit32u get32() const { return val32; }
set32bx_cr4_t149   BX_CPP_INLINE void set32(Bit32u val) { val32 = val; }
150 };
151 
152 const Bit32u BX_CR4_FLUSH_TLB_MASK = (BX_CR4_PSE_MASK | BX_CR4_PAE_MASK | BX_CR4_PGE_MASK | BX_CR4_PCIDE_MASK | BX_CR4_SMEP_MASK | BX_CR4_SMAP_MASK | BX_CR4_PKE_MASK | BX_CR4_CET_MASK | BX_CR4_PKS_MASK);
153 
154 #endif  // #if BX_CPU_LEVEL >= 5
155 
156 struct bx_dr6_t {
157   Bit32u val32; // 32bit value of register
158 
159   IMPLEMENT_CRREG_ACCESSORS(B0, 0);
160   IMPLEMENT_CRREG_ACCESSORS(B1, 1);
161   IMPLEMENT_CRREG_ACCESSORS(B2, 2);
162   IMPLEMENT_CRREG_ACCESSORS(B3, 3);
163 
164 #define BX_DEBUG_TRAP_HIT             (1 << 12)
165 #define BX_DEBUG_DR_ACCESS_BIT        (1 << 13)
166 #define BX_DEBUG_SINGLE_STEP_BIT      (1 << 14)
167 #define BX_DEBUG_TRAP_TASK_SWITCH_BIT (1 << 15)
168 
169   IMPLEMENT_CRREG_ACCESSORS(BD, 13);
170   IMPLEMENT_CRREG_ACCESSORS(BS, 14);
171   IMPLEMENT_CRREG_ACCESSORS(BT, 15);
172 
get32bx_dr6_t173   BX_CPP_INLINE Bit32u get32() const { return val32; }
set32bx_dr6_t174   BX_CPP_INLINE void set32(Bit32u val) { val32 = val; }
175 };
176 
177 struct bx_dr7_t {
178   Bit32u val32; // 32bit value of register
179 
180   IMPLEMENT_CRREG_ACCESSORS(L0, 0);
181   IMPLEMENT_CRREG_ACCESSORS(G0, 1);
182   IMPLEMENT_CRREG_ACCESSORS(L1, 2);
183   IMPLEMENT_CRREG_ACCESSORS(G1, 3);
184   IMPLEMENT_CRREG_ACCESSORS(L2, 4);
185   IMPLEMENT_CRREG_ACCESSORS(G2, 5);
186   IMPLEMENT_CRREG_ACCESSORS(L3, 6);
187   IMPLEMENT_CRREG_ACCESSORS(G3, 7);
188   IMPLEMENT_CRREG_ACCESSORS(LE, 8);
189   IMPLEMENT_CRREG_ACCESSORS(GE, 9);
190   IMPLEMENT_CRREG_ACCESSORS(GD, 13);
191 
192 #define IMPLEMENT_DRREG_ACCESSORS(name, bitmask, bitnum)      \
193   int get_##name() const {                                    \
194     return (val32 & (bitmask)) >> (bitnum);                   \
195   }
196 
197   IMPLEMENT_DRREG_ACCESSORS(R_W0, 0x00030000, 16);
198   IMPLEMENT_DRREG_ACCESSORS(LEN0, 0x000C0000, 18);
199   IMPLEMENT_DRREG_ACCESSORS(R_W1, 0x00300000, 20);
200   IMPLEMENT_DRREG_ACCESSORS(LEN1, 0x00C00000, 22);
201   IMPLEMENT_DRREG_ACCESSORS(R_W2, 0x03000000, 24);
202   IMPLEMENT_DRREG_ACCESSORS(LEN2, 0x0C000000, 26);
203   IMPLEMENT_DRREG_ACCESSORS(R_W3, 0x30000000, 28);
204   IMPLEMENT_DRREG_ACCESSORS(LEN3, 0xC0000000, 30);
205 
206   IMPLEMENT_DRREG_ACCESSORS(bp_enabled, 0xFF, 0);
207 
get32bx_dr7_t208   BX_CPP_INLINE Bit32u get32() const { return val32; }
set32bx_dr7_t209   BX_CPP_INLINE void set32(Bit32u val) { val32 = val; }
210 };
211 
212 #if BX_CPU_LEVEL >= 5
213 
214 #define BX_EFER_SCE_MASK       (1 <<  0)
215 #define BX_EFER_LME_MASK       (1 <<  8)
216 #define BX_EFER_LMA_MASK       (1 << 10)
217 #define BX_EFER_NXE_MASK       (1 << 11)
218 #define BX_EFER_SVME_MASK      (1 << 12)
219 #define BX_EFER_LMSLE_MASK     (1 << 13)
220 #define BX_EFER_FFXSR_MASK     (1 << 14)
221 #define BX_EFER_TCE_MASK       (1 << 15)
222 
223 struct bx_efer_t {
224   Bit32u val32; // 32bit value of register
225 
226   IMPLEMENT_CRREG_ACCESSORS(SCE,    0);
227 #if BX_SUPPORT_X86_64
228   IMPLEMENT_CRREG_ACCESSORS(LME,    8);
229   IMPLEMENT_CRREG_ACCESSORS(LMA,   10);
230 #endif
231   IMPLEMENT_CRREG_ACCESSORS(NXE,   11);
232 #if BX_SUPPORT_X86_64
233   IMPLEMENT_CRREG_ACCESSORS(SVME,  12); /* AMD Secure Virtual Machine */
234   IMPLEMENT_CRREG_ACCESSORS(LMSLE, 13); /* AMD Long Mode Segment Limit */
235   IMPLEMENT_CRREG_ACCESSORS(FFXSR, 14);
236   IMPLEMENT_CRREG_ACCESSORS(TCE,   15); /* AMD Translation Cache Extensions */
237 #endif
238 
get32bx_efer_t239   BX_CPP_INLINE Bit32u get32() const { return val32; }
set32bx_efer_t240   BX_CPP_INLINE void set32(Bit32u val) { val32 = val; }
241 };
242 
243 #endif
244 
245 #if BX_CPU_LEVEL >= 6
246 
247 const unsigned XSAVE_FPU_STATE_LEN          = 160;
248 const unsigned XSAVE_SSE_STATE_LEN          = 256;
249 const unsigned XSAVE_YMM_STATE_LEN          = 256;
250 const unsigned XSAVE_OPMASK_STATE_LEN       = 64;
251 const unsigned XSAVE_ZMM_HI256_STATE_LEN    = 512;
252 const unsigned XSAVE_HI_ZMM_STATE_LEN       = 1024;
253 const unsigned XSAVE_PKRU_STATE_LEN         = 64;
254 const unsigned XSAVE_CET_U_STATE_LEN        = 16;
255 const unsigned XSAVE_CET_S_STATE_LEN        = 24;
256 
257 const unsigned XSAVE_SSE_STATE_OFFSET       = 160;
258 const unsigned XSAVE_YMM_STATE_OFFSET       = 576;
259 const unsigned XSAVE_OPMASK_STATE_OFFSET    = 1088;
260 const unsigned XSAVE_ZMM_HI256_STATE_OFFSET = 1152;
261 const unsigned XSAVE_HI_ZMM_STATE_OFFSET    = 1664;
262 const unsigned XSAVE_PKRU_STATE_OFFSET      = 2688;
263 
264 struct xcr0_t {
265   Bit32u  val32; // 32bit value of register
266 
267   enum {
268     BX_XCR0_FPU_BIT = 0,
269     BX_XCR0_SSE_BIT = 1,
270     BX_XCR0_YMM_BIT = 2,
271     BX_XCR0_BNDREGS_BIT = 3,
272     BX_XCR0_BNDCFG_BIT = 4,
273     BX_XCR0_OPMASK_BIT = 5,
274     BX_XCR0_ZMM_HI256_BIT = 6,
275     BX_XCR0_HI_ZMM_BIT = 7,
276     BX_XCR0_PT_BIT = 8,
277     BX_XCR0_PKRU_BIT = 9,
278     BX_XCR0_CET_U_BIT = 11,
279     BX_XCR0_CET_S_BIT = 12,
280     BX_XCR0_UINTR_BIT = 14,
281     BX_XCR0_XTILECFG_BIT = 17,
282     BX_XCR0_XTILEDATA_BIT = 18,
283     BX_XCR0_LAST
284   };
285 
286 #define BX_XCR0_FPU_MASK       (1 << xcr0_t::BX_XCR0_FPU_BIT)
287 #define BX_XCR0_SSE_MASK       (1 << xcr0_t::BX_XCR0_SSE_BIT)
288 #define BX_XCR0_YMM_MASK       (1 << xcr0_t::BX_XCR0_YMM_BIT)
289 #define BX_XCR0_BNDREGS_MASK   (1 << xcr0_t::BX_XCR0_BNDREGS_BIT)
290 #define BX_XCR0_BNDCFG_MASK    (1 << xcr0_t::BX_XCR0_BNDCFG_BIT)
291 #define BX_XCR0_OPMASK_MASK    (1 << xcr0_t::BX_XCR0_OPMASK_BIT)
292 #define BX_XCR0_ZMM_HI256_MASK (1 << xcr0_t::BX_XCR0_ZMM_HI256_BIT)
293 #define BX_XCR0_HI_ZMM_MASK    (1 << xcr0_t::BX_XCR0_HI_ZMM_BIT)
294 #define BX_XCR0_PT_MASK        (1 << xcr0_t::BX_XCR0_PT_BIT)
295 #define BX_XCR0_PKRU_MASK      (1 << xcr0_t::BX_XCR0_PKRU_BIT)
296 #define BX_XCR0_CET_U_MASK     (1 << xcr0_t::BX_XCR0_CET_U_BIT)
297 #define BX_XCR0_CET_S_MASK     (1 << xcr0_t::BX_XCR0_CET_S_BIT)
298 #define BX_XCR0_UINTR_MASK     (1 << xcr0_t::BX_XCR0_UINTR_BIT)
299 #define BX_XCR0_XTILECFG_MASK  (1 << xcr0_t::BX_XCR0_XTILECFG_BIT)
300 #define BX_XCR0_XTILEDATA_MASK (1 << xcr0_t::BX_XCR0_XTILEDATA_BIT)
301 
302   IMPLEMENT_CRREG_ACCESSORS(FPU, BX_XCR0_FPU_BIT);
303   IMPLEMENT_CRREG_ACCESSORS(SSE, BX_XCR0_SSE_BIT);
304   IMPLEMENT_CRREG_ACCESSORS(YMM, BX_XCR0_YMM_BIT);
305   IMPLEMENT_CRREG_ACCESSORS(BNDREGS, BX_XCR0_BNDREGS_BIT);
306   IMPLEMENT_CRREG_ACCESSORS(BNDCFG, BX_XCR0_BNDCFG_BIT);
307   IMPLEMENT_CRREG_ACCESSORS(OPMASK, BX_XCR0_OPMASK_BIT);
308   IMPLEMENT_CRREG_ACCESSORS(ZMM_HI256, BX_XCR0_ZMM_HI256_BIT);
309   IMPLEMENT_CRREG_ACCESSORS(HI_ZMM, BX_XCR0_HI_ZMM_BIT);
310   IMPLEMENT_CRREG_ACCESSORS(PT, BX_XCR0_PT_BIT);
311   IMPLEMENT_CRREG_ACCESSORS(PKRU, BX_XCR0_PKRU_BIT);
312   IMPLEMENT_CRREG_ACCESSORS(CET_U, BX_XCR0_CET_U_BIT);
313   IMPLEMENT_CRREG_ACCESSORS(CET_S, BX_XCR0_CET_S_BIT);
314   IMPLEMENT_CRREG_ACCESSORS(XTILECFG, BX_XCR0_XTILECFG_BIT);
315   IMPLEMENT_CRREG_ACCESSORS(XTILEDATA, BX_XCR0_XTILEDATA_BIT);
316 
get32xcr0_t317   BX_CPP_INLINE Bit32u get32() const { return val32; }
set32xcr0_t318   BX_CPP_INLINE void set32(Bit32u val) { val32 = val; }
319 };
320 
321 #if BX_USE_CPU_SMF
322 typedef bool (*XSaveStateInUsePtr_tR)(void);
323 typedef void (*XSavePtr_tR)(bxInstruction_c *i, bx_address offset);
324 typedef void (*XRestorPtr_tR)(bxInstruction_c *i, bx_address offset);
325 typedef void (*XRestorInitPtr_tR)(void);
326 #else
327 typedef bool (BX_CPU_C::*XSaveStateInUsePtr_tR)(void);
328 typedef void (BX_CPU_C::*XSavePtr_tR)(bxInstruction_c *i, bx_address offset);
329 typedef void (BX_CPU_C::*XRestorPtr_tR)(bxInstruction_c *i, bx_address offset);
330 typedef void (BX_CPU_C::*XRestorInitPtr_tR)(void);
331 #endif
332 
333 struct XSaveRestoreStateHelper {
334   unsigned len;
335   unsigned offset;
336   XSaveStateInUsePtr_tR xstate_in_use_method;
337   XSavePtr_tR xsave_method;
338   XRestorPtr_tR xrstor_method;
339   XRestorInitPtr_tR xrstor_init_method;
340 };
341 
342 #endif
343 
344 #undef IMPLEMENT_CRREG_ACCESSORS
345 #undef IMPLEMENT_DRREG_ACCESSORS
346 
347 #if BX_CPU_LEVEL >= 5
348 
349 typedef struct msr {
350   unsigned index;          // MSR index
351   unsigned type;           // MSR type: 1 - lin address, 2 - phy address
352 #define BX_LIN_ADDRESS_MSR 1
353 #define BX_PHY_ADDRESS_MSR 2
354   Bit64u val64;            // current MSR value
355   Bit64u reset_value;      // reset value
356   Bit64u reserved;         // r/o bits - fault on write
357   Bit64u ignored;          // hardwired bits - ignored on write
358 
359   msr(unsigned idx, unsigned msr_type = 0, Bit64u reset_val = 0, Bit64u rsrv = 0, Bit64u ign = 0):
indexmsr360      index(idx), type(msr_type), val64(reset_val), reset_value(reset_val),
361      reserved(rsrv), ignored(ign) {}
362 
363   msr(unsigned idx, Bit64u reset_val = 0, Bit64u rsrv = 0, Bit64u ign = 0):
indexmsr364      index(idx), type(0), val64(reset_val), reset_value(reset_val),
365      reserved(rsrv), ignored(ign) {}
366 
resetmsr367   BX_CPP_INLINE void reset() { val64 = reset_value; }
get64msr368   BX_CPP_INLINE Bit64u get64() const { return val64; }
369 
set64msr370   BX_CPP_INLINE bool set64(Bit64u new_val) {
371      new_val = (new_val & ~ignored) | (val64 & ignored);
372      switch(type) {
373 #if BX_SUPPORT_X86_64
374        case BX_LIN_ADDRESS_MSR:
375          if (! IsCanonical(new_val)) return 0;
376          break;
377 #endif
378        case BX_PHY_ADDRESS_MSR:
379          if (! IsValidPhyAddr(new_val)) return 0;
380          break;
381        default:
382          if ((val64 ^ new_val) & reserved) return 0;
383          break;
384      }
385      val64 = new_val;
386      return 1;
387   }
388 } MSR;
389 
390 #endif // BX_CPU_LEVEL >= 5
391 
392 #endif
393