qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [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

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).