aboutsummaryrefslogtreecommitdiff
path: root/target-i386/smm_helper.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-05-15 15:38:39 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-05-15 15:38:40 +0100
commitef3cb5ca82c341e575ee5cb9a9dd8edc6aa96b1b (patch)
tree1ec45abf7d4bcadc6bfa97e2be4d23e549d02eec /target-i386/smm_helper.c
parent06e33c1c3c193074574eb3813eded91bff0fc86f (diff)
parent4700a316df7d2cdcd256dcd64a10cec643f4dfa1 (diff)
Merge remote-tracking branch 'remotes/kvm/uq/master' into staging
* remotes/kvm/uq/master: pc: port 92 reset requires a low->high transition cpu: make CPU_INTERRUPT_RESET available on all targets apic: do not accept SIPI on the bootstrap processor target-i386: preserve FPU and MSR state on INIT target-i386: fix set of registers zeroed on reset kvm: forward INIT signals coming from the chipset kvm: reset state from the CPU's reset method target-i386: the x86 CPL is stored in CS.selector - auto update hflags accordingly. target-i386: set eflags prior to calling cpu_x86_load_seg_cache() in seg_helper.c target-i386: set eflags and cr0 prior to calling cpu_x86_load_seg_cache() in smm_helper.c target-i386: set eflags prior to calling svm_load_seg_cache() in svm_helper.c pci-assign: limit # of msix vectors pci-assign: Fix a bug when map MSI-X table memory failed kvm: make one_reg helpers available for everyone target-i386: Remove unused data from local array Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-i386/smm_helper.c')
-rw-r--r--target-i386/smm_helper.c34
1 files changed, 17 insertions, 17 deletions
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 35901c9e89..4841d53b24 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -163,6 +163,13 @@ void do_smm_enter(X86CPU *cpu)
cpu_load_eflags(env, 0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C |
DF_MASK));
env->eip = 0x00008000;
+ cpu_x86_update_cr0(env,
+ env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK |
+ CR0_PG_MASK));
+ cpu_x86_update_cr4(env, 0);
+ env->dr[7] = 0x00000400;
+ CC_OP = CC_OP_EFLAGS;
+
cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
0xffffffff, 0);
cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff, 0);
@@ -170,13 +177,6 @@ void do_smm_enter(X86CPU *cpu)
cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff, 0);
cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff, 0);
cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff, 0);
-
- cpu_x86_update_cr0(env,
- env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK |
- CR0_PG_MASK));
- cpu_x86_update_cr4(env, 0);
- env->dr[7] = 0x00000400;
- CC_OP = CC_OP_EFLAGS;
}
void helper_rsm(CPUX86State *env)
@@ -191,16 +191,6 @@ void helper_rsm(CPUX86State *env)
#ifdef TARGET_X86_64
cpu_load_efer(env, ldq_phys(cs->as, sm_state + 0x7ed0));
- for (i = 0; i < 6; i++) {
- offset = 0x7e00 + i * 16;
- cpu_x86_load_seg_cache(env, i,
- lduw_phys(cs->as, sm_state + offset),
- ldq_phys(cs->as, sm_state + offset + 8),
- ldl_phys(cs->as, sm_state + offset + 4),
- (lduw_phys(cs->as, sm_state + offset + 2) &
- 0xf0ff) << 8);
- }
-
env->gdt.base = ldq_phys(cs->as, sm_state + 0x7e68);
env->gdt.limit = ldl_phys(cs->as, sm_state + 0x7e64);
@@ -238,6 +228,16 @@ void helper_rsm(CPUX86State *env)
cpu_x86_update_cr3(env, ldl_phys(cs->as, sm_state + 0x7f50));
cpu_x86_update_cr0(env, ldl_phys(cs->as, sm_state + 0x7f58));
+ for (i = 0; i < 6; i++) {
+ offset = 0x7e00 + i * 16;
+ cpu_x86_load_seg_cache(env, i,
+ lduw_phys(cs->as, sm_state + offset),
+ ldq_phys(cs->as, sm_state + offset + 8),
+ ldl_phys(cs->as, sm_state + offset + 4),
+ (lduw_phys(cs->as, sm_state + offset + 2) &
+ 0xf0ff) << 8);
+ }
+
val = ldl_phys(cs->as, sm_state + 0x7efc); /* revision ID */
if (val & 0x20000) {
env->smbase = ldl_phys(cs->as, sm_state + 0x7f00) & ~0x7fff;