qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] x86 MTRR access dumping


From: Carl-Daniel Hailfinger
Subject: [Qemu-devel] [PATCH] x86 MTRR access dumping
Date: Fri, 21 Nov 2008 22:30:53 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.13) Gecko/20080316 SUSE/1.1.9-1.1 SeaMonkey/1.1.9

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/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]