[SerialICE] New patch to review for serialice: c1ca197 SerialICE: Change lua call API for MSR

Kyösti Mälkki (kyosti.malkki@gmail.com) gerrit at coreboot.org
Sun May 6 19:16:52 CEST 2012


Kyösti Mälkki (kyosti.malkki at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1015

-gerrit

commit c1ca1973610e6e540eb3e242f9055d84a967509c
Author: Kyösti Mälkki <kyosti.malkki at gmail.com>
Date:   Sun May 6 17:50:36 2012 +0300

    SerialICE: Change lua call API for MSR
    
    With the change it is possible to divert MSRs to Qemu or apply
    a bitmask on the rdmsr result.
    
    Change-Id: Id25f2ede4480b45f231efd2e9a089c6b41731ff6
    Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
---
 qemu-0.15.x/serialice.c             |  150 +++++++++++++++++------------------
 qemu-0.15.x/target-i386/cpu.h       |    3 +
 qemu-0.15.x/target-i386/op_helper.c |   94 ++++++++++++----------
 3 files changed, 127 insertions(+), 120 deletions(-)

diff --git a/qemu-0.15.x/serialice.c b/qemu-0.15.x/serialice.c
index d90aba8..655c72f 100644
--- a/qemu-0.15.x/serialice.c
+++ b/qemu-0.15.x/serialice.c
@@ -419,37 +419,47 @@ static int serialice_memory_write_filter(uint32_t addr, int size,
     return ret;
 }
 
-#define FILTER_READ	0
-#define FILTER_WRITE	1
-
-static int serialice_msr_filter(int flags, uint32_t addr, uint32_t * hi,
-                                uint32_t * lo)
+static int serialice_wrmsr_filter(uint32_t addr, uint32_t * hi, uint32_t * lo)
 {
-    int ret, result;
-
-    if (flags & FILTER_WRITE) {
-        lua_getglobal(L, "SerialICE_msr_write_filter");
-    } else {
-        lua_getglobal(L, "SerialICE_msr_read_filter");
-    }
+    int ret = 0, result;
 
+    lua_getglobal(L, "SerialICE_msr_write_filter");
     lua_pushinteger(L, addr);   // port
     lua_pushinteger(L, *hi);    // high
     lua_pushinteger(L, *lo);    // low
-    result = lua_pcall(L, 3, 3, 0);
+
+    result = lua_pcall(L, 3, 4, 0);
     if (result) {
         fprintf(stderr,
-                "Failed to run function SerialICE_msr_%s_filter: %s\n",
-                (flags & FILTER_WRITE) ? "write" : "read", lua_tostring(L, -1));
+                "Failed to run function SerialICE_msr_write_filter: %s\n", lua_tostring(L, -1));
         exit(1);
     }
-    ret = lua_toboolean(L, -3);
-    if (ret) {
-        *hi = lua_tointeger(L, -1);
-        *lo = lua_tointeger(L, -2);
+
+    *lo = lua_tointeger(L, -1);
+    *hi = lua_tointeger(L, -2);
+    ret |= lua_toboolean(L, -3) ? WRITE_TO_QEMU : 0;
+    ret |= lua_toboolean(L, -4) ? WRITE_TO_SERIALICE : 0;
+    lua_pop(L, 4);
+    return ret;
+}
+
+static int serialice_rdmsr_filter(uint32_t addr)
+{
+    int ret = 0, result;
+
+    lua_getglobal(L, "SerialICE_msr_read_filter");
+    lua_pushinteger(L, addr);
+
+    result = lua_pcall(L, 1, 2, 0);
+    if (result) {
+        fprintf(stderr,
+                "Failed to run function SerialICE_msr_read_filter: %s\n", lua_tostring(L, -1));
+        exit(1);
     }
-    lua_pop(L, 3);
 
+    ret |= lua_toboolean(L, -1) ? WRITE_TO_QEMU : 0;
+    ret |= lua_toboolean(L, -2) ? WRITE_TO_SERIALICE : 0;
+    lua_pop(L, 2);
     return ret;
 }
 
@@ -538,31 +548,6 @@ static void serialice_write_log(int flags)
     }
 }
 
-
-
-static void serialice_msr_log(int flags, uint32_t addr, uint32_t hi,
-                              uint32_t lo, int filtered)
-{
-    int result;
-
-    if (flags & LOG_WRITE) {
-        lua_getglobal(L, "SerialICE_msr_write_log");
-    } else {                    // if (!(flags & LOG_WRITE))
-        lua_getglobal(L, "SerialICE_msr_read_log");
-    }
-
-    lua_pushinteger(L, addr);   // addr/port
-    lua_pushinteger(L, hi);     // datasize
-    lua_pushinteger(L, lo);     // data
-    lua_pushboolean(L, filtered);       // data
-    result = lua_pcall(L, 4, 0, 0);
-    if (result) {
-        fprintf(stderr, "Failed to run function SerialICE_msr_%s_log: %s\n",
-                (flags & LOG_WRITE) ? "write" : "read", lua_tostring(L, -1));
-        exit(1);
-    }
-}
-
 static void serialice_cpuid_log(uint32_t eax, uint32_t ecx, cpuid_regs_t res,
                                 int filtered)
 {
@@ -585,6 +570,26 @@ static void serialice_cpuid_log(uint32_t eax, uint32_t ecx, cpuid_regs_t res,
     }
 }
 
+static void serialice_rdmsr_log(uint32_t *hi, uint32_t *lo)
+{
+    int result;
+
+    lua_getglobal(L, "SerialICE_msr_read_log");
+    lua_pushinteger(L, *hi);
+    lua_pushinteger(L, *lo);
+
+    result = lua_pcall(L, 2, 2, 0);
+    if (result) {
+        fprintf(stderr, "Failed to run function SerialICE_msr_read_log: %s\n",
+			lua_tostring(L, -1));
+        exit(1);
+    }
+
+    *hi = lua_tointeger(L, -2);
+    *lo = lua_tointeger(L, -1);
+    lua_pop(L, 2);
+}
+
 // **************************************************************************
 // low level communication with the SerialICE shell (serial communication)
 
@@ -749,53 +754,46 @@ static void serialice_get_mainboard(void)
     printf("%s\n", serialice_mainboard);
 }
 
-
-
 uint64_t serialice_rdmsr(uint32_t addr, uint32_t key)
 {
-    uint32_t hi, lo;
-    uint64_t ret;
-    int filtered;
+    uint32_t hi = 0, lo = 0;
+    uint64_t data;
 
-    filtered = serialice_msr_filter(FILTER_READ, addr, &hi, &lo);
-    if (!filtered) {
-        sprintf(s->command, "*rc%08x.%08x", addr, key);
+    int source = serialice_rdmsr_filter(addr);
 
-        // command read back: "\n00000000.00000000" (18 characters)
-        serialice_command(s->command, 18);
+    if (source & READ_FROM_SERIALICE)
+        serialice_rdmsr_wrapper(addr, key, &hi, &lo);
 
-        s->buffer[9] = 0;       // . -> \0
-        hi = (uint32_t) strtoul(s->buffer + 1, (char **)NULL, 16);
-        lo = (uint32_t) strtoul(s->buffer + 10, (char **)NULL, 16);
+    if (source & READ_FROM_QEMU) {
+        data = cpu_rdmsr(addr);
+        hi = (data >> 32);
+        lo = (data & 0xffffffff);
     }
 
-    ret = hi;
-    ret <<= 32;
-    ret |= lo;
-
-    serialice_msr_log(LOG_READ, addr, hi, lo, filtered);
-
-    return ret;
+    serialice_rdmsr_log(&hi, &lo);
+    data = hi;
+    data <<= 32;
+    data |= lo;
+    return data;
 }
 
 void serialice_wrmsr(uint64_t data, uint32_t addr, uint32_t key)
 {
-    uint32_t hi, lo;
-    int filtered;
-
-    hi = (data >> 32);
-    lo = (data & 0xffffffff);
+    uint32_t hi = (data >> 32);
+    uint32_t lo = (data & 0xffffffff);
 
-    filtered = serialice_msr_filter(FILTER_WRITE, addr, &hi, &lo);
+    int target = serialice_wrmsr_filter(addr, &hi, &lo);
 
-    if (!filtered) {
-        sprintf(s->command, "*wc%08x.%08x=%08x.%08x", addr, key, hi, lo);
-        serialice_command(s->command, 0);
+    if (target & WRITE_TO_SERIALICE)
+        serialice_wrmsr_wrapper(addr, key, hi, lo);
+    if (target & WRITE_TO_QEMU) {
+        data = lo | ((uint64_t)hi)<<32;
+        cpu_wrmsr(addr, data);
     }
-
-    serialice_msr_log(LOG_WRITE, addr, hi, lo, filtered);
+    serialice_write_log(LOG_MSR);
 }
 
+
 cpuid_regs_t serialice_cpuid(uint32_t eax, uint32_t ecx)
 {
     cpuid_regs_t ret;
diff --git a/qemu-0.15.x/target-i386/cpu.h b/qemu-0.15.x/target-i386/cpu.h
index 9819b5f..e919129 100644
--- a/qemu-0.15.x/target-i386/cpu.h
+++ b/qemu-0.15.x/target-i386/cpu.h
@@ -1055,6 +1055,9 @@ void do_smm_enter(CPUState *env1);
 
 void svm_check_intercept(CPUState *env1, uint32_t type);
 
+void cpu_wrmsr(uint64_t val, uint32_t addr);
+uint64_t cpu_rdmsr(uint32_t addr);
+
 uint32_t cpu_cc_compute_all(CPUState *env1, int op);
 
 #endif /* CPU_I386_H */
diff --git a/qemu-0.15.x/target-i386/op_helper.c b/qemu-0.15.x/target-i386/op_helper.c
index 1650bba..695a307 100644
--- a/qemu-0.15.x/target-i386/op_helper.c
+++ b/qemu-0.15.x/target-i386/op_helper.c
@@ -3091,22 +3091,10 @@ void helper_rdmsr(void)
 {
 }
 #else
-void helper_wrmsr(void)
-{
-    uint64_t val;
-
-    helper_svm_check_intercept_param(SVM_EXIT_MSR, 1);
-
-    val = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
-
-#ifdef CONFIG_SERIALICE
-    if (serialice_active) {
-        serialice_wrmsr(val, (uint32_t) ECX, (uint32_t) EDI);
-        return;
-    }
-#endif
 
-    switch((uint32_t)ECX) {
+void cpu_wrmsr(uint64_t val, uint32_t addr)
+{
+    switch(addr) {
     case MSR_IA32_SYSENTER_CS:
         env->sysenter_cs = val & 0xffff;
         break;
@@ -3176,7 +3164,7 @@ void helper_wrmsr(void)
     case MSR_MTRRphysBase(5):
     case MSR_MTRRphysBase(6):
     case MSR_MTRRphysBase(7):
-        env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysBase(0)) / 2].base = val;
+        env->mtrr_var[(addr - MSR_MTRRphysBase(0)) / 2].base = val;
         break;
     case MSR_MTRRphysMask(0):
     case MSR_MTRRphysMask(1):
@@ -3186,14 +3174,14 @@ void helper_wrmsr(void)
     case MSR_MTRRphysMask(5):
     case MSR_MTRRphysMask(6):
     case MSR_MTRRphysMask(7):
-        env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysMask(0)) / 2].mask = val;
+        env->mtrr_var[(addr - MSR_MTRRphysMask(0)) / 2].mask = val;
         break;
     case MSR_MTRRfix64K_00000:
-        env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix64K_00000] = val;
+        env->mtrr_fixed[addr - MSR_MTRRfix64K_00000] = val;
         break;
     case MSR_MTRRfix16K_80000:
     case MSR_MTRRfix16K_A0000:
-        env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix16K_80000 + 1] = val;
+        env->mtrr_fixed[addr - MSR_MTRRfix16K_80000 + 1] = val;
         break;
     case MSR_MTRRfix4K_C0000:
     case MSR_MTRRfix4K_C8000:
@@ -3203,7 +3191,7 @@ void helper_wrmsr(void)
     case MSR_MTRRfix4K_E8000:
     case MSR_MTRRfix4K_F0000:
     case MSR_MTRRfix4K_F8000:
-        env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix4K_C0000 + 3] = val;
+        env->mtrr_fixed[addr - MSR_MTRRfix4K_C0000 + 3] = val;
         break;
     case MSR_MTRRdefType:
         env->mtrr_deftype = val;
@@ -3220,9 +3208,9 @@ void helper_wrmsr(void)
         env->tsc_aux = val;
         break;
     default:
-        if ((uint32_t)ECX >= MSR_MC0_CTL
-            && (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
-            uint32_t offset = (uint32_t)ECX - MSR_MC0_CTL;
+        if (addr >= MSR_MC0_CTL
+            && addr < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
+            uint32_t offset = addr - MSR_MC0_CTL;
             if ((offset & 0x3) != 0
                 || (val == 0 || val == ~(uint64_t)0))
                 env->mce_banks[offset] = val;
@@ -3233,22 +3221,11 @@ void helper_wrmsr(void)
     }
 }
 
-void helper_rdmsr(void)
+uint64_t cpu_rdmsr(uint32_t addr)
 {
     uint64_t val;
 
-    helper_svm_check_intercept_param(SVM_EXIT_MSR, 0);
-
-#ifdef CONFIG_SERIALICE
-    if (serialice_active) {
-        val = serialice_rdmsr((uint32_t) ECX, (uint32_t) EDI);
-        EAX = (uint32_t) (val);
-        EDX = (uint32_t) (val >> 32);
-        return;
-    }
-#endif
-
-    switch((uint32_t)ECX) {
+    switch(addr) {
     case MSR_IA32_SYSENTER_CS:
         val = env->sysenter_cs;
         break;
@@ -3310,7 +3287,7 @@ void helper_rdmsr(void)
     case MSR_MTRRphysBase(5):
     case MSR_MTRRphysBase(6):
     case MSR_MTRRphysBase(7):
-        val = env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysBase(0)) / 2].base;
+        val = env->mtrr_var[(addr - MSR_MTRRphysBase(0)) / 2].base;
         break;
     case MSR_MTRRphysMask(0):
     case MSR_MTRRphysMask(1):
@@ -3320,14 +3297,14 @@ void helper_rdmsr(void)
     case MSR_MTRRphysMask(5):
     case MSR_MTRRphysMask(6):
     case MSR_MTRRphysMask(7):
-        val = env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysMask(0)) / 2].mask;
+        val = env->mtrr_var[(addr - MSR_MTRRphysMask(0)) / 2].mask;
         break;
     case MSR_MTRRfix64K_00000:
         val = env->mtrr_fixed[0];
         break;
     case MSR_MTRRfix16K_80000:
     case MSR_MTRRfix16K_A0000:
-        val = env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix16K_80000 + 1];
+        val = env->mtrr_fixed[addr - MSR_MTRRfix16K_80000 + 1];
         break;
     case MSR_MTRRfix4K_C0000:
     case MSR_MTRRfix4K_C8000:
@@ -3337,7 +3314,7 @@ void helper_rdmsr(void)
     case MSR_MTRRfix4K_E8000:
     case MSR_MTRRfix4K_F0000:
     case MSR_MTRRfix4K_F8000:
-        val = env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix4K_C0000 + 3];
+        val = env->mtrr_fixed[addr - MSR_MTRRfix4K_C0000 + 3];
         break;
     case MSR_MTRRdefType:
         val = env->mtrr_deftype;
@@ -3362,9 +3339,9 @@ void helper_rdmsr(void)
         val = env->mcg_status;
         break;
     default:
-        if ((uint32_t)ECX >= MSR_MC0_CTL
-            && (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
-            uint32_t offset = (uint32_t)ECX - MSR_MC0_CTL;
+        if (addr >= MSR_MC0_CTL
+            && addr < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
+            uint32_t offset = addr - MSR_MC0_CTL;
             val = env->mce_banks[offset];
             break;
         }
@@ -3372,10 +3349,39 @@ void helper_rdmsr(void)
         val = 0;
         break;
     }
+    return val;
+}
+
+void helper_wrmsr(void)
+{
+    uint64_t val = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
+    helper_svm_check_intercept_param(SVM_EXIT_MSR, 1);
+#ifdef CONFIG_SERIALICE
+    if (serialice_active)
+        serialice_wrmsr(val, (uint32_t)ECX, (uint32_t) EDI);
+    else
+        cpu_wrmsr(val, (uint32_t)ECX);
+#else
+    cpu_wrmsr(val, (uint32_t)ECX);
+#endif
+}
+
+void helper_rdmsr(void)
+{
+    uint64_t val;
+    helper_svm_check_intercept_param(SVM_EXIT_MSR, 0);
+#ifdef CONFIG_SERIALICE
+    if (serialice_active)
+        val = serialice_rdmsr((uint32_t) ECX, (uint32_t) EDI);
+    else
+        val = cpu_rdmsr((uint32_t) ECX);
+#else
+    val = cpu_rdmsr((uint32_t) ECX);
+#endif
     EAX = (uint32_t)(val);
     EDX = (uint32_t)(val >> 32);
 }
-#endif
+#endif /* CONFIG_USER_ONLY */
 
 target_ulong helper_lsl(target_ulong selector1)
 {



More information about the SerialICE mailing list