1 /////////////////////////////////////////////////////////////////////////
2 // $Id: crregs.h,v 1.12 2008/12/06 10:21:55 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (c) 2007 Stanislav Shwartsman
6 // Written by Stanislav Shwartsman [sshwarts at sourceforge net]
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /////////////////////////////////////////////////////////////////////////
28 Bit32u val32
; // 32bit value of register
30 // Accessors for all cr0 bitfields.
31 #define IMPLEMENT_CRREG_ACCESSORS(name,bitnum) \
32 BX_CPP_INLINE bx_bool get_##name () { \
33 return 1 & (val32 >> bitnum); \
35 BX_CPP_INLINE void set_##name (Bit8u val) { \
36 val32 = (val32&~(1<<bitnum)) | (val ? (1<<bitnum) : 0); \
40 // Each x86 level has its own quirks regarding how it handles
41 // reserved bits. I used DOS DEBUG.EXE in real mode on the
42 // following processors, tried to clear bits 1..30, then tried
43 // to set bits 1..30, to see how these bits are handled.
44 // I found the following:
46 // Processor try to clear bits 1..30 try to set bits 1..30
47 // 386 7FFFFFF0 7FFFFFFE
48 // 486DX2 00000010 6005003E
49 // Pentium 00000010 7FFFFFFE
50 // Pentium-II 00000010 6005003E
53 // All processors: bit 4 is hardwired to 1 (not true on all clones)
54 // 386: bits 5..30 of CR0 are also hardwired to 1
55 // Pentium: reserved bits retain value set using mov cr0, reg32
56 // 486DX2/Pentium-II: reserved bits are hardwired to 0
58 IMPLEMENT_CRREG_ACCESSORS(PE
, 0);
59 IMPLEMENT_CRREG_ACCESSORS(MP
, 1);
60 IMPLEMENT_CRREG_ACCESSORS(EM
, 2);
61 IMPLEMENT_CRREG_ACCESSORS(TS
, 3);
63 IMPLEMENT_CRREG_ACCESSORS(ET
, 4);
64 IMPLEMENT_CRREG_ACCESSORS(NE
, 5);
65 IMPLEMENT_CRREG_ACCESSORS(WP
, 16);
66 IMPLEMENT_CRREG_ACCESSORS(AM
, 18);
67 IMPLEMENT_CRREG_ACCESSORS(CD
, 29);
68 IMPLEMENT_CRREG_ACCESSORS(NW
, 30);
70 IMPLEMENT_CRREG_ACCESSORS(PG
, 31);
72 BX_CPP_INLINE Bit32u
get32() { return val32
; }
73 // ET is hardwired bit in CR0
74 BX_CPP_INLINE
void set32(Bit32u val
) { val32
= val
| 0x10; }
79 Bit32u val32
; // 32bit value of register
82 IMPLEMENT_CRREG_ACCESSORS(VME
, 0);
83 IMPLEMENT_CRREG_ACCESSORS(PVI
, 1);
85 IMPLEMENT_CRREG_ACCESSORS(TSD
, 2);
86 IMPLEMENT_CRREG_ACCESSORS(DE
, 3);
87 IMPLEMENT_CRREG_ACCESSORS(PSE
, 4);
88 IMPLEMENT_CRREG_ACCESSORS(PAE
, 5);
89 IMPLEMENT_CRREG_ACCESSORS(MCE
, 6);
90 IMPLEMENT_CRREG_ACCESSORS(PGE
, 7);
91 IMPLEMENT_CRREG_ACCESSORS(PCE
, 8);
92 IMPLEMENT_CRREG_ACCESSORS(OSFXSR
, 9);
93 IMPLEMENT_CRREG_ACCESSORS(OSXMMEXCPT
, 10);
95 IMPLEMENT_CRREG_ACCESSORS(OSXSAVE
, 18);
98 BX_CPP_INLINE Bit32u
get32() { return val32
; }
99 BX_CPP_INLINE
void set32(Bit32u val
) { val32
= val
; }
101 #endif // #if BX_CPU_LEVEL >= 4
104 #define CR4_VME_ENABLED (BX_CPU_THIS_PTR cr4.get_VME())
106 #define CR4_VME_ENABLED (0)
109 #if BX_SUPPORT_X86_64
112 Bit32u val32
; // 32bit value of register
114 IMPLEMENT_CRREG_ACCESSORS(SCE
, 0);
115 IMPLEMENT_CRREG_ACCESSORS(LME
, 8);
116 IMPLEMENT_CRREG_ACCESSORS(LMA
, 10);
117 IMPLEMENT_CRREG_ACCESSORS(NXE
, 11);
118 IMPLEMENT_CRREG_ACCESSORS(FFXSR
, 14);
120 BX_CPP_INLINE Bit32u
get32() { return val32
; }
121 BX_CPP_INLINE
void set32(Bit32u val
) { val32
= val
; }
124 #define BX_EFER_LMA_MASK (1<<10)
125 #define BX_EFER_SUPPORTED_BITS BX_CONST64(0x00004d01)
131 Bit32u val32
; // 32bit value of register
133 #define BX_XCR0_SUPPORTED_BITS 0x3
135 #define BX_XCR0_FPU_BIT 0
136 #define BX_XCR0_FPU_MASK (1<<BX_XCR0_FPU_BIT)
137 #define BX_XCR0_SSE_BIT 1
138 #define BX_XCR0_SSE_MASK (1<<BX_XCR0_SSE_BIT)
140 IMPLEMENT_CRREG_ACCESSORS(FPU
, BX_XCR0_FPU_BIT
);
142 IMPLEMENT_CRREG_ACCESSORS(SSE
, BX_XCR0_SSE_BIT
);
145 BX_CPP_INLINE Bit32u
get32() { return val32
; }
146 BX_CPP_INLINE
void set32(Bit32u val
) { val32
= val
; }
150 #undef IMPLEMENT_CRREG_ACCESSORS
153 Bit32u index
; // MSR index
154 Bit64u val64
; // current MSR value
155 Bit64u reset_value
; // reset value
156 Bit64u write_mask
; // r/o bits mask
157 Bit64u hardwired_bits
; // hardwired bits mask
159 msr(unsigned idx
, Bit64u reset_val
= 0, Bit64u wmask
= 0, Bit64u hmask
= 0):
160 index(idx
), val64(reset_val
), reset_value(reset_val
),
161 write_mask(wmask
), hardwired_bits(hmask
) {}
163 BX_CPP_INLINE
void reset() { val64
= reset_value
; }
165 BX_CPP_INLINE Bit64u
get64() { return val64
; }
166 BX_CPP_INLINE bx_bool
set64(Bit64u new_val
) {
167 new_val
= (new_val
& ~hardwired_bits
) | (val64
& hardwired_bits
);
168 if ((val64
^ new_val
) & write_mask
) return 0;