- added instructions how to update the online documentation
[bochs-mirror.git] / cpu / crregs.h
bloba0b930dbf9abd1418f88017d5ee969c9f9bdd98f
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: crregs.h,v 1.12 2008/12/06 10:21:55 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (c) 2007 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.
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 /////////////////////////////////////////////////////////////////////////
24 #ifndef BX_CRREGS
25 #define BX_CRREGS
27 struct bx_cr0_t {
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); \
34 } \
35 BX_CPP_INLINE void set_##name (Bit8u val) { \
36 val32 = (val32&~(1<<bitnum)) | (val ? (1<<bitnum) : 0); \
39 // CR0 notes:
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
52 // My assumptions:
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);
62 #if BX_CPU_LEVEL >= 4
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);
69 #endif
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; }
77 #if BX_CPU_LEVEL >= 4
78 struct bx_cr4_t {
79 Bit32u val32; // 32bit value of register
81 #if BX_SUPPORT_VME
82 IMPLEMENT_CRREG_ACCESSORS(VME, 0);
83 IMPLEMENT_CRREG_ACCESSORS(PVI, 1);
84 #endif
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);
94 #if BX_SUPPORT_XSAVE
95 IMPLEMENT_CRREG_ACCESSORS(OSXSAVE, 18);
96 #endif
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
103 #if BX_SUPPORT_VME
104 #define CR4_VME_ENABLED (BX_CPU_THIS_PTR cr4.get_VME())
105 #else
106 #define CR4_VME_ENABLED (0)
107 #endif
109 #if BX_SUPPORT_X86_64
111 struct bx_efer_t {
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)
127 #endif
129 #if BX_SUPPORT_XSAVE
130 struct xcr0_t {
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);
141 #if BX_SUPPORT_SSE
142 IMPLEMENT_CRREG_ACCESSORS(SSE, BX_XCR0_SSE_BIT);
143 #endif
145 BX_CPP_INLINE Bit32u get32() { return val32; }
146 BX_CPP_INLINE void set32(Bit32u val) { val32 = val; }
148 #endif
150 #undef IMPLEMENT_CRREG_ACCESSORS
152 typedef struct msr {
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;
169 val64 = new_val;
170 return 1;
172 } MSR;
174 #endif