* [Qemu-devel] [PATCH] x86 MTRR access dumping
@ 2008-11-21 21:30 Carl-Daniel Hailfinger
2008-11-23 1:26 ` Carl-Daniel Hailfinger
0 siblings, 1 reply; 2+ messages in thread
From: Carl-Daniel Hailfinger @ 2008-11-21 21:30 UTC (permalink / raw)
To: qemu-devel
Some x86 BIOS and lots of x86 operating systems use MSRs not currently
implemented in Qemu. The most notable unimplemented MSRs are the MTRRs
(Memory Type Range Registers). This patch against latest svn dumps any
accesses to unhandled MSRs and decodes the MTRR accesses.
I used this code to check MTRR accesses of coreboot (a replacement
firmware for x86 BIOS) inside qemu and the patch works fine.
Of course, writing these MTRRs should be persistent, so their state
needs to be saved somehow.
I thought I'd post my current code and ask for comments before I continue.
Any comments on coding style, technical restrictions and other stuff are
appreciated.
Regards,
Carl-Daniel
Index: qemu/target-i386/cpu.h
===================================================================
--- qemu/target-i386/cpu.h (Revision 5765)
+++ qemu/target-i386/cpu.h (Arbeitskopie)
@@ -261,8 +261,25 @@
#define MSR_IA32_PERF_STATUS 0x198
+#define MSR_MTRRphysBase(reg) (0x200 + 2 * (reg))
+#define MSR_MTRRphysMask(reg) (0x200 + 2 * (reg) + 1)
+
+#define MSR_MTRRfix64K_00000 0x250
+#define MSR_MTRRfix16K_80000 0x258
+#define MSR_MTRRfix16K_A0000 0x259
+#define MSR_MTRRfix4K_C0000 0x268
+#define MSR_MTRRfix4K_C8000 0x269
+#define MSR_MTRRfix4K_D0000 0x26a
+#define MSR_MTRRfix4K_D8000 0x26b
+#define MSR_MTRRfix4K_E0000 0x26c
+#define MSR_MTRRfix4K_E8000 0x26d
+#define MSR_MTRRfix4K_F0000 0x26e
+#define MSR_MTRRfix4K_F8000 0x26f
+
#define MSR_PAT 0x277
+#define MSR_MTRRdefType 0x2ff
+
#define MSR_EFER 0xc0000080
#define MSR_EFER_SCE (1 << 0)
Index: qemu/target-i386/op_helper.c
===================================================================
--- qemu/target-i386/op_helper.c (Revision 5765)
+++ qemu/target-i386/op_helper.c (Arbeitskopie)
@@ -3008,6 +3008,7 @@
void helper_wrmsr(void)
{
uint64_t val;
+ uint32_t mtrrstart, mtrrsize, i;
helper_svm_check_intercept_param(SVM_EXIT_MSR, 1);
@@ -3073,8 +3074,100 @@
env->kernelgsbase = val;
break;
#endif
+ case MSR_MTRRphysBase(0):
+ case MSR_MTRRphysBase(1):
+ case MSR_MTRRphysBase(2):
+ case MSR_MTRRphysBase(3):
+ case MSR_MTRRphysBase(4):
+ case MSR_MTRRphysBase(5):
+ case MSR_MTRRphysBase(6):
+ case MSR_MTRRphysBase(7):
+ printf("MTRRphysBase%i was written: 0x%016llx, ",
+ ((uint32_t)ECX & 0xf) >> 1, val);
+ if (val & ~ 0xfffffffffffff0ffULL)
+ printf("reserved bits %016llx were set!, ", val & ~ 0xfffffffffffff0ffULL);
+ printf("Base address %016llx, Type %02x\n", val & 0xfffffffffffff000ULL,
+ (uint32_t)val & 0xff);
+ break;
+ case MSR_MTRRphysMask(0):
+ case MSR_MTRRphysMask(1):
+ case MSR_MTRRphysMask(2):
+ case MSR_MTRRphysMask(3):
+ case MSR_MTRRphysMask(4):
+ case MSR_MTRRphysMask(5):
+ case MSR_MTRRphysMask(6):
+ case MSR_MTRRphysMask(7):
+ printf("MTRRphysMask%i was written: 0x%016llx, ",
+ ((uint32_t)ECX & 0xf) >> 1, val);
+ if (val & ~ 0xfffffffffffff800ULL)
+ printf("reserved bits %016llx were set!, ", val & ~ 0xfffffffffffff800ULL);
+ printf("Mask %016llx, MTRR is %svalid\n", val & 0xfffffffffffff000ULL,
+ (val & (1 << 11)) ? "" : "in");
+ break;
+ case MSR_MTRRfix64K_00000:
+ mtrrstart = 0x00000;
+ mtrrsize = 64 * 1024;
+ goto mtrr_out;
+ case MSR_MTRRfix16K_80000:
+ mtrrstart = 0x80000;
+ mtrrsize = 16 * 1024;
+ goto mtrr_out;
+ case MSR_MTRRfix16K_A0000:
+ mtrrstart = 0xA0000;
+ mtrrsize = 16 * 1024;
+ goto mtrr_out;
+ case MSR_MTRRfix4K_C0000:
+ mtrrstart = 0xC0000;
+ mtrrsize = 4 * 1024;
+ goto mtrr_out;
+ case MSR_MTRRfix4K_C8000:
+ mtrrstart = 0xC8000;
+ mtrrsize = 4 * 1024;
+ goto mtrr_out;
+ case MSR_MTRRfix4K_D0000:
+ mtrrstart = 0xD0000;
+ mtrrsize = 4 * 1024;
+ goto mtrr_out;
+ case MSR_MTRRfix4K_D8000:
+ mtrrstart = 0xD8000;
+ mtrrsize = 4 * 1024;
+ goto mtrr_out;
+ case MSR_MTRRfix4K_E0000:
+ mtrrstart = 0xE0000;
+ mtrrsize = 4 * 1024;
+ goto mtrr_out;
+ case MSR_MTRRfix4K_E8000:
+ mtrrstart = 0xE8000;
+ mtrrsize = 4 * 1024;
+ goto mtrr_out;
+ case MSR_MTRRfix4K_F0000:
+ mtrrstart = 0xF0000;
+ mtrrsize = 4 * 1024;
+ goto mtrr_out;
+ case MSR_MTRRfix4K_F8000:
+ mtrrstart = 0xF8000;
+ mtrrsize = 4 * 1024;
+ mtrr_out:
+ /* FIXME: Check if cache is disabled. If not, behaviour is undefined. */
+ printf("Fixed MTRR 0x%08x was written: 0x%016llx\n", (uint32_t)ECX, val);
+ for (i = 0; i < 8; i++)
+ printf("Region 0x%08x-0x%08x has type 0x%02x\n",
+ mtrrstart + mtrrsize * i,
+ mtrrstart + mtrrsize * (i + 1) - 1,
+ (uint32_t)(val >> (i * 8)) & 0xff);
+ break;
+ case MSR_MTRRdefType:
+ printf("MTRRdefType was written: 0x%016llx, ", val);
+ if (val & ~ 0xcff)
+ printf("reserved bits %016llx were set!, ", val & ~ 0xcff);
+ printf("MTRRs %sabled, Fixed MTRRS %sabled, default type %02x\n",
+ (val & (1 << 11)) ? "en" : "dis",
+ (val & (1 << 10)) ? "en" : "dis",
+ (uint32_t)val & 0xff);
+ break;
default:
/* XXX: exception ? */
+ printf("Unhandled MSR 0x%08x was written: 0x%016llx\n", (uint32_t)ECX, val);
break;
}
}
@@ -3145,8 +3238,45 @@
}
break;
#endif
+ case MSR_MTRRphysBase(0):
+ case MSR_MTRRphysBase(1):
+ case MSR_MTRRphysBase(2):
+ case MSR_MTRRphysBase(3):
+ case MSR_MTRRphysBase(4):
+ case MSR_MTRRphysBase(5):
+ case MSR_MTRRphysBase(6):
+ case MSR_MTRRphysBase(7):
+ printf("MTRRphysBase%i was read\n", ((uint32_t)ECX & 0xf) >> 1);
+ val = 0;
+ break;
+ case MSR_MTRRphysMask(0):
+ case MSR_MTRRphysMask(1):
+ case MSR_MTRRphysMask(2):
+ case MSR_MTRRphysMask(3):
+ case MSR_MTRRphysMask(4):
+ case MSR_MTRRphysMask(5):
+ case MSR_MTRRphysMask(6):
+ case MSR_MTRRphysMask(7):
+ printf("MTRRphysMask%i was read\n", ((uint32_t)ECX & 0xf) >> 1);
+ val = 0;
+ break;
+ case MSR_MTRRfix64K_00000:
+ case MSR_MTRRfix16K_80000:
+ case MSR_MTRRfix16K_A0000:
+ case MSR_MTRRfix4K_C0000:
+ case MSR_MTRRfix4K_C8000:
+ case MSR_MTRRfix4K_D0000:
+ case MSR_MTRRfix4K_D8000:
+ case MSR_MTRRfix4K_E0000:
+ case MSR_MTRRfix4K_E8000:
+ case MSR_MTRRfix4K_F0000:
+ case MSR_MTRRfix4K_F8000:
+ printf("MTRR 0x%08x was read\n", (uint32_t)ECX);
+ val = 0;
+ break;
default:
/* XXX: exception ? */
+ printf("Unhandled MSR 0x%08x was read\n", (uint32_t)ECX);
val = 0;
break;
}
--
http://www.hailfinger.org/
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [Qemu-devel] [PATCH] x86 MTRR access dumping
2008-11-21 21:30 [Qemu-devel] [PATCH] x86 MTRR access dumping Carl-Daniel Hailfinger
@ 2008-11-23 1:26 ` Carl-Daniel Hailfinger
0 siblings, 0 replies; 2+ messages in thread
From: Carl-Daniel Hailfinger @ 2008-11-23 1:26 UTC (permalink / raw)
To: qemu-devel
On 21.11.2008 22:30, Carl-Daniel Hailfinger wrote:
> Some x86 BIOS and lots of x86 operating systems use MSRs not currently
> implemented in Qemu. The most notable unimplemented MSRs are the MTRRs
> (Memory Type Range Registers). This patch against latest svn dumps any
> accesses to unhandled MSRs and decodes the MTRR accesses.
>
> I used this code to check MTRR accesses of coreboot (a replacement
> firmware for x86 BIOS) inside qemu and the patch works fine.
>
> Of course, writing these MTRRs should be persistent, so their state
> needs to be saved somehow.
>
> I thought I'd post my current code and ask for comments before I continue.
> Any comments on coding style, technical restrictions and other stuff are
> appreciated.
>
Sample output from a recent ReactOS boot:
Unhandled MSR 0x0000008b was written: 0x0000000000000000
Unhandled MSR 0x0000008b was read
Regards,
Carl-Daniel
--
http://www.hailfinger.org/
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-11-23 1:26 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-21 21:30 [Qemu-devel] [PATCH] x86 MTRR access dumping Carl-Daniel Hailfinger
2008-11-23 1:26 ` Carl-Daniel Hailfinger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).