Commit dd5e3b1771b7c528690f2c0714c8e88be07c9bc2
1 parent
7625162c
MTRR support on x86, part 2 (Carl-Daniel Hailfinger)
Load and save MTRR state together with machine state. Add support for the MTRRcap MSR which is used by the latest Bochs BIOS and some operating systems. Fix a typo in ext2_feature_name. With this patch, MTRR emulation should be good enough to not trigger any sanity checks in well behaved BIOS/kernel code. Some corner cases for BIOS/firmware usage remain to be implemented, but that can be deferred to another patch. Also, MTRR accesses on hardware not supporting MTRRs should cause #GP. That can be enforced by another patch as well. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6472 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
34 additions
and
1 deletions
target-i386/cpu.h
@@ -251,6 +251,11 @@ | @@ -251,6 +251,11 @@ | ||
251 | #define MSR_IA32_APICBASE_ENABLE (1<<11) | 251 | #define MSR_IA32_APICBASE_ENABLE (1<<11) |
252 | #define MSR_IA32_APICBASE_BASE (0xfffff<<12) | 252 | #define MSR_IA32_APICBASE_BASE (0xfffff<<12) |
253 | 253 | ||
254 | +#define MSR_MTRRcap 0xfe | ||
255 | +#define MSR_MTRRcap_VCNT 8 | ||
256 | +#define MSR_MTRRcap_FIXRANGE_SUPPORT (1 << 8) | ||
257 | +#define MSR_MTRRcap_WC_SUPPORTED (1 << 10) | ||
258 | + | ||
254 | #define MSR_IA32_SYSENTER_CS 0x174 | 259 | #define MSR_IA32_SYSENTER_CS 0x174 |
255 | #define MSR_IA32_SYSENTER_ESP 0x175 | 260 | #define MSR_IA32_SYSENTER_ESP 0x175 |
256 | #define MSR_IA32_SYSENTER_EIP 0x176 | 261 | #define MSR_IA32_SYSENTER_EIP 0x176 |
target-i386/machine.c
@@ -134,6 +134,15 @@ void cpu_save(QEMUFile *f, void *opaque) | @@ -134,6 +134,15 @@ void cpu_save(QEMUFile *f, void *opaque) | ||
134 | qemu_put_be16s(f, &env->intercept_dr_write); | 134 | qemu_put_be16s(f, &env->intercept_dr_write); |
135 | qemu_put_be32s(f, &env->intercept_exceptions); | 135 | qemu_put_be32s(f, &env->intercept_exceptions); |
136 | qemu_put_8s(f, &env->v_tpr); | 136 | qemu_put_8s(f, &env->v_tpr); |
137 | + | ||
138 | + /* MTRRs */ | ||
139 | + for(i = 0; i < 11; i++) | ||
140 | + qemu_put_be64s(f, &env->mtrr_fixed[i]); | ||
141 | + qemu_put_be64s(f, &env->mtrr_deftype); | ||
142 | + for(i = 0; i < 8; i++) { | ||
143 | + qemu_put_be64s(f, &env->mtrr_var[i].base); | ||
144 | + qemu_put_be64s(f, &env->mtrr_var[i].mask); | ||
145 | + } | ||
137 | } | 146 | } |
138 | 147 | ||
139 | #ifdef USE_X86LDOUBLE | 148 | #ifdef USE_X86LDOUBLE |
@@ -169,7 +178,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | @@ -169,7 +178,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | ||
169 | int32_t a20_mask; | 178 | int32_t a20_mask; |
170 | 179 | ||
171 | if (version_id != 3 && version_id != 4 && version_id != 5 | 180 | if (version_id != 3 && version_id != 4 && version_id != 5 |
172 | - && version_id != 6 && version_id != 7) | 181 | + && version_id != 6 && version_id != 7 && version_id != 8) |
173 | return -EINVAL; | 182 | return -EINVAL; |
174 | for(i = 0; i < CPU_NB_REGS; i++) | 183 | for(i = 0; i < CPU_NB_REGS; i++) |
175 | qemu_get_betls(f, &env->regs[i]); | 184 | qemu_get_betls(f, &env->regs[i]); |
@@ -302,6 +311,18 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | @@ -302,6 +311,18 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | ||
302 | qemu_get_be32s(f, &env->intercept_exceptions); | 311 | qemu_get_be32s(f, &env->intercept_exceptions); |
303 | qemu_get_8s(f, &env->v_tpr); | 312 | qemu_get_8s(f, &env->v_tpr); |
304 | } | 313 | } |
314 | + | ||
315 | + if (version_id >= 8) { | ||
316 | + /* MTRRs */ | ||
317 | + for(i = 0; i < 11; i++) | ||
318 | + qemu_get_be64s(f, &env->mtrr_fixed[i]); | ||
319 | + qemu_get_be64s(f, &env->mtrr_deftype); | ||
320 | + for(i = 0; i < 8; i++) { | ||
321 | + qemu_get_be64s(f, &env->mtrr_var[i].base); | ||
322 | + qemu_get_be64s(f, &env->mtrr_var[i].mask); | ||
323 | + } | ||
324 | + } | ||
325 | + | ||
305 | /* XXX: ensure compatiblity for halted bit ? */ | 326 | /* XXX: ensure compatiblity for halted bit ? */ |
306 | /* XXX: compute redundant hflags bits */ | 327 | /* XXX: compute redundant hflags bits */ |
307 | env->hflags = hflags; | 328 | env->hflags = hflags; |
target-i386/op_helper.c
@@ -3215,6 +3215,13 @@ void helper_rdmsr(void) | @@ -3215,6 +3215,13 @@ void helper_rdmsr(void) | ||
3215 | case MSR_MTRRdefType: | 3215 | case MSR_MTRRdefType: |
3216 | val = env->mtrr_deftype; | 3216 | val = env->mtrr_deftype; |
3217 | break; | 3217 | break; |
3218 | + case MSR_MTRRcap: | ||
3219 | + if (env->cpuid_features & CPUID_MTRR) | ||
3220 | + val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT | MSR_MTRRcap_WC_SUPPORTED; | ||
3221 | + else | ||
3222 | + /* XXX: exception ? */ | ||
3223 | + val = 0; | ||
3224 | + break; | ||
3218 | default: | 3225 | default: |
3219 | /* XXX: exception ? */ | 3226 | /* XXX: exception ? */ |
3220 | val = 0; | 3227 | val = 0; |