root / target-i386 / smm_helper.c @ 45724d6d
History | View | Annotate | Download (10.1 kB)
1 | ab109e59 | Blue Swirl | /*
|
---|---|---|---|
2 | ab109e59 | Blue Swirl | * x86 SMM helpers
|
3 | ab109e59 | Blue Swirl | *
|
4 | ab109e59 | Blue Swirl | * Copyright (c) 2003 Fabrice Bellard
|
5 | ab109e59 | Blue Swirl | *
|
6 | ab109e59 | Blue Swirl | * This library is free software; you can redistribute it and/or
|
7 | ab109e59 | Blue Swirl | * modify it under the terms of the GNU Lesser General Public
|
8 | ab109e59 | Blue Swirl | * License as published by the Free Software Foundation; either
|
9 | ab109e59 | Blue Swirl | * version 2 of the License, or (at your option) any later version.
|
10 | ab109e59 | Blue Swirl | *
|
11 | ab109e59 | Blue Swirl | * This library is distributed in the hope that it will be useful,
|
12 | ab109e59 | Blue Swirl | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | ab109e59 | Blue Swirl | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | ab109e59 | Blue Swirl | * Lesser General Public License for more details.
|
15 | ab109e59 | Blue Swirl | *
|
16 | ab109e59 | Blue Swirl | * You should have received a copy of the GNU Lesser General Public
|
17 | ab109e59 | Blue Swirl | * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
18 | ab109e59 | Blue Swirl | */
|
19 | ab109e59 | Blue Swirl | |
20 | ab109e59 | Blue Swirl | #include "cpu.h" |
21 | ab109e59 | Blue Swirl | #include "helper.h" |
22 | ab109e59 | Blue Swirl | |
23 | ab109e59 | Blue Swirl | /* SMM support */
|
24 | ab109e59 | Blue Swirl | |
25 | ab109e59 | Blue Swirl | #if defined(CONFIG_USER_ONLY)
|
26 | ab109e59 | Blue Swirl | |
27 | 608badfc | Blue Swirl | void do_smm_enter(CPUX86State *env)
|
28 | ab109e59 | Blue Swirl | { |
29 | ab109e59 | Blue Swirl | } |
30 | ab109e59 | Blue Swirl | |
31 | 608badfc | Blue Swirl | void helper_rsm(CPUX86State *env)
|
32 | ab109e59 | Blue Swirl | { |
33 | ab109e59 | Blue Swirl | } |
34 | ab109e59 | Blue Swirl | |
35 | ab109e59 | Blue Swirl | #else
|
36 | ab109e59 | Blue Swirl | |
37 | ab109e59 | Blue Swirl | #ifdef TARGET_X86_64
|
38 | ab109e59 | Blue Swirl | #define SMM_REVISION_ID 0x00020064 |
39 | ab109e59 | Blue Swirl | #else
|
40 | ab109e59 | Blue Swirl | #define SMM_REVISION_ID 0x00020000 |
41 | ab109e59 | Blue Swirl | #endif
|
42 | ab109e59 | Blue Swirl | |
43 | 608badfc | Blue Swirl | void do_smm_enter(CPUX86State *env)
|
44 | ab109e59 | Blue Swirl | { |
45 | ab109e59 | Blue Swirl | target_ulong sm_state; |
46 | ab109e59 | Blue Swirl | SegmentCache *dt; |
47 | ab109e59 | Blue Swirl | int i, offset;
|
48 | ab109e59 | Blue Swirl | |
49 | ab109e59 | Blue Swirl | qemu_log_mask(CPU_LOG_INT, "SMM: enter\n");
|
50 | ab109e59 | Blue Swirl | log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP); |
51 | ab109e59 | Blue Swirl | |
52 | ab109e59 | Blue Swirl | env->hflags |= HF_SMM_MASK; |
53 | ab109e59 | Blue Swirl | cpu_smm_update(env); |
54 | ab109e59 | Blue Swirl | |
55 | ab109e59 | Blue Swirl | sm_state = env->smbase + 0x8000;
|
56 | ab109e59 | Blue Swirl | |
57 | ab109e59 | Blue Swirl | #ifdef TARGET_X86_64
|
58 | ab109e59 | Blue Swirl | for (i = 0; i < 6; i++) { |
59 | ab109e59 | Blue Swirl | dt = &env->segs[i]; |
60 | ab109e59 | Blue Swirl | offset = 0x7e00 + i * 16; |
61 | ab109e59 | Blue Swirl | stw_phys(sm_state + offset, dt->selector); |
62 | ab109e59 | Blue Swirl | stw_phys(sm_state + offset + 2, (dt->flags >> 8) & 0xf0ff); |
63 | ab109e59 | Blue Swirl | stl_phys(sm_state + offset + 4, dt->limit);
|
64 | ab109e59 | Blue Swirl | stq_phys(sm_state + offset + 8, dt->base);
|
65 | ab109e59 | Blue Swirl | } |
66 | ab109e59 | Blue Swirl | |
67 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7e68, env->gdt.base);
|
68 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7e64, env->gdt.limit);
|
69 | ab109e59 | Blue Swirl | |
70 | ab109e59 | Blue Swirl | stw_phys(sm_state + 0x7e70, env->ldt.selector);
|
71 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7e78, env->ldt.base);
|
72 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7e74, env->ldt.limit);
|
73 | ab109e59 | Blue Swirl | stw_phys(sm_state + 0x7e72, (env->ldt.flags >> 8) & 0xf0ff); |
74 | ab109e59 | Blue Swirl | |
75 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7e88, env->idt.base);
|
76 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7e84, env->idt.limit);
|
77 | ab109e59 | Blue Swirl | |
78 | ab109e59 | Blue Swirl | stw_phys(sm_state + 0x7e90, env->tr.selector);
|
79 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7e98, env->tr.base);
|
80 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7e94, env->tr.limit);
|
81 | ab109e59 | Blue Swirl | stw_phys(sm_state + 0x7e92, (env->tr.flags >> 8) & 0xf0ff); |
82 | ab109e59 | Blue Swirl | |
83 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7ed0, env->efer);
|
84 | ab109e59 | Blue Swirl | |
85 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7ff8, EAX);
|
86 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7ff0, ECX);
|
87 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7fe8, EDX);
|
88 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7fe0, EBX);
|
89 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7fd8, ESP);
|
90 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7fd0, EBP);
|
91 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7fc8, ESI);
|
92 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7fc0, EDI);
|
93 | ab109e59 | Blue Swirl | for (i = 8; i < 16; i++) { |
94 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7ff8 - i * 8, env->regs[i]); |
95 | ab109e59 | Blue Swirl | } |
96 | ab109e59 | Blue Swirl | stq_phys(sm_state + 0x7f78, env->eip);
|
97 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f70, cpu_compute_eflags(env));
|
98 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f68, env->dr[6]); |
99 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f60, env->dr[7]); |
100 | ab109e59 | Blue Swirl | |
101 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f48, env->cr[4]); |
102 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f50, env->cr[3]); |
103 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f58, env->cr[0]); |
104 | ab109e59 | Blue Swirl | |
105 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7efc, SMM_REVISION_ID);
|
106 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f00, env->smbase);
|
107 | ab109e59 | Blue Swirl | #else
|
108 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7ffc, env->cr[0]); |
109 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7ff8, env->cr[3]); |
110 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7ff4, cpu_compute_eflags(env));
|
111 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7ff0, env->eip);
|
112 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7fec, EDI);
|
113 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7fe8, ESI);
|
114 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7fe4, EBP);
|
115 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7fe0, ESP);
|
116 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7fdc, EBX);
|
117 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7fd8, EDX);
|
118 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7fd4, ECX);
|
119 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7fd0, EAX);
|
120 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7fcc, env->dr[6]); |
121 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7fc8, env->dr[7]); |
122 | ab109e59 | Blue Swirl | |
123 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7fc4, env->tr.selector);
|
124 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f64, env->tr.base);
|
125 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f60, env->tr.limit);
|
126 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f5c, (env->tr.flags >> 8) & 0xf0ff); |
127 | ab109e59 | Blue Swirl | |
128 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7fc0, env->ldt.selector);
|
129 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f80, env->ldt.base);
|
130 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f7c, env->ldt.limit);
|
131 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f78, (env->ldt.flags >> 8) & 0xf0ff); |
132 | ab109e59 | Blue Swirl | |
133 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f74, env->gdt.base);
|
134 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f70, env->gdt.limit);
|
135 | ab109e59 | Blue Swirl | |
136 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f58, env->idt.base);
|
137 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f54, env->idt.limit);
|
138 | ab109e59 | Blue Swirl | |
139 | ab109e59 | Blue Swirl | for (i = 0; i < 6; i++) { |
140 | ab109e59 | Blue Swirl | dt = &env->segs[i]; |
141 | ab109e59 | Blue Swirl | if (i < 3) { |
142 | ab109e59 | Blue Swirl | offset = 0x7f84 + i * 12; |
143 | ab109e59 | Blue Swirl | } else {
|
144 | ab109e59 | Blue Swirl | offset = 0x7f2c + (i - 3) * 12; |
145 | ab109e59 | Blue Swirl | } |
146 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7fa8 + i * 4, dt->selector); |
147 | ab109e59 | Blue Swirl | stl_phys(sm_state + offset + 8, dt->base);
|
148 | ab109e59 | Blue Swirl | stl_phys(sm_state + offset + 4, dt->limit);
|
149 | ab109e59 | Blue Swirl | stl_phys(sm_state + offset, (dt->flags >> 8) & 0xf0ff); |
150 | ab109e59 | Blue Swirl | } |
151 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7f14, env->cr[4]); |
152 | ab109e59 | Blue Swirl | |
153 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7efc, SMM_REVISION_ID);
|
154 | ab109e59 | Blue Swirl | stl_phys(sm_state + 0x7ef8, env->smbase);
|
155 | ab109e59 | Blue Swirl | #endif
|
156 | ab109e59 | Blue Swirl | /* init SMM cpu state */
|
157 | ab109e59 | Blue Swirl | |
158 | ab109e59 | Blue Swirl | #ifdef TARGET_X86_64
|
159 | ab109e59 | Blue Swirl | cpu_load_efer(env, 0);
|
160 | ab109e59 | Blue Swirl | #endif
|
161 | ab109e59 | Blue Swirl | cpu_load_eflags(env, 0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C |
|
162 | ab109e59 | Blue Swirl | DF_MASK)); |
163 | ab109e59 | Blue Swirl | env->eip = 0x00008000;
|
164 | ab109e59 | Blue Swirl | cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase, |
165 | ab109e59 | Blue Swirl | 0xffffffff, 0); |
166 | ab109e59 | Blue Swirl | cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff, 0); |
167 | ab109e59 | Blue Swirl | cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff, 0); |
168 | ab109e59 | Blue Swirl | cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff, 0); |
169 | ab109e59 | Blue Swirl | cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff, 0); |
170 | ab109e59 | Blue Swirl | cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff, 0); |
171 | ab109e59 | Blue Swirl | |
172 | ab109e59 | Blue Swirl | cpu_x86_update_cr0(env, |
173 | ab109e59 | Blue Swirl | env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK |
|
174 | ab109e59 | Blue Swirl | CR0_PG_MASK)); |
175 | ab109e59 | Blue Swirl | cpu_x86_update_cr4(env, 0);
|
176 | ab109e59 | Blue Swirl | env->dr[7] = 0x00000400; |
177 | ab109e59 | Blue Swirl | CC_OP = CC_OP_EFLAGS; |
178 | ab109e59 | Blue Swirl | } |
179 | ab109e59 | Blue Swirl | |
180 | 608badfc | Blue Swirl | void helper_rsm(CPUX86State *env)
|
181 | ab109e59 | Blue Swirl | { |
182 | ab109e59 | Blue Swirl | target_ulong sm_state; |
183 | ab109e59 | Blue Swirl | int i, offset;
|
184 | ab109e59 | Blue Swirl | uint32_t val; |
185 | ab109e59 | Blue Swirl | |
186 | ab109e59 | Blue Swirl | sm_state = env->smbase + 0x8000;
|
187 | ab109e59 | Blue Swirl | #ifdef TARGET_X86_64
|
188 | ab109e59 | Blue Swirl | cpu_load_efer(env, ldq_phys(sm_state + 0x7ed0));
|
189 | ab109e59 | Blue Swirl | |
190 | ab109e59 | Blue Swirl | for (i = 0; i < 6; i++) { |
191 | ab109e59 | Blue Swirl | offset = 0x7e00 + i * 16; |
192 | ab109e59 | Blue Swirl | cpu_x86_load_seg_cache(env, i, |
193 | ab109e59 | Blue Swirl | lduw_phys(sm_state + offset), |
194 | ab109e59 | Blue Swirl | ldq_phys(sm_state + offset + 8),
|
195 | ab109e59 | Blue Swirl | ldl_phys(sm_state + offset + 4),
|
196 | ab109e59 | Blue Swirl | (lduw_phys(sm_state + offset + 2) &
|
197 | ab109e59 | Blue Swirl | 0xf0ff) << 8); |
198 | ab109e59 | Blue Swirl | } |
199 | ab109e59 | Blue Swirl | |
200 | ab109e59 | Blue Swirl | env->gdt.base = ldq_phys(sm_state + 0x7e68);
|
201 | ab109e59 | Blue Swirl | env->gdt.limit = ldl_phys(sm_state + 0x7e64);
|
202 | ab109e59 | Blue Swirl | |
203 | ab109e59 | Blue Swirl | env->ldt.selector = lduw_phys(sm_state + 0x7e70);
|
204 | ab109e59 | Blue Swirl | env->ldt.base = ldq_phys(sm_state + 0x7e78);
|
205 | ab109e59 | Blue Swirl | env->ldt.limit = ldl_phys(sm_state + 0x7e74);
|
206 | ab109e59 | Blue Swirl | env->ldt.flags = (lduw_phys(sm_state + 0x7e72) & 0xf0ff) << 8; |
207 | ab109e59 | Blue Swirl | |
208 | ab109e59 | Blue Swirl | env->idt.base = ldq_phys(sm_state + 0x7e88);
|
209 | ab109e59 | Blue Swirl | env->idt.limit = ldl_phys(sm_state + 0x7e84);
|
210 | ab109e59 | Blue Swirl | |
211 | ab109e59 | Blue Swirl | env->tr.selector = lduw_phys(sm_state + 0x7e90);
|
212 | ab109e59 | Blue Swirl | env->tr.base = ldq_phys(sm_state + 0x7e98);
|
213 | ab109e59 | Blue Swirl | env->tr.limit = ldl_phys(sm_state + 0x7e94);
|
214 | ab109e59 | Blue Swirl | env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8; |
215 | ab109e59 | Blue Swirl | |
216 | ab109e59 | Blue Swirl | EAX = ldq_phys(sm_state + 0x7ff8);
|
217 | ab109e59 | Blue Swirl | ECX = ldq_phys(sm_state + 0x7ff0);
|
218 | ab109e59 | Blue Swirl | EDX = ldq_phys(sm_state + 0x7fe8);
|
219 | ab109e59 | Blue Swirl | EBX = ldq_phys(sm_state + 0x7fe0);
|
220 | ab109e59 | Blue Swirl | ESP = ldq_phys(sm_state + 0x7fd8);
|
221 | ab109e59 | Blue Swirl | EBP = ldq_phys(sm_state + 0x7fd0);
|
222 | ab109e59 | Blue Swirl | ESI = ldq_phys(sm_state + 0x7fc8);
|
223 | ab109e59 | Blue Swirl | EDI = ldq_phys(sm_state + 0x7fc0);
|
224 | ab109e59 | Blue Swirl | for (i = 8; i < 16; i++) { |
225 | ab109e59 | Blue Swirl | env->regs[i] = ldq_phys(sm_state + 0x7ff8 - i * 8); |
226 | ab109e59 | Blue Swirl | } |
227 | ab109e59 | Blue Swirl | env->eip = ldq_phys(sm_state + 0x7f78);
|
228 | ab109e59 | Blue Swirl | cpu_load_eflags(env, ldl_phys(sm_state + 0x7f70),
|
229 | ab109e59 | Blue Swirl | ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); |
230 | ab109e59 | Blue Swirl | env->dr[6] = ldl_phys(sm_state + 0x7f68); |
231 | ab109e59 | Blue Swirl | env->dr[7] = ldl_phys(sm_state + 0x7f60); |
232 | ab109e59 | Blue Swirl | |
233 | ab109e59 | Blue Swirl | cpu_x86_update_cr4(env, ldl_phys(sm_state + 0x7f48));
|
234 | ab109e59 | Blue Swirl | cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7f50));
|
235 | ab109e59 | Blue Swirl | cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7f58));
|
236 | ab109e59 | Blue Swirl | |
237 | ab109e59 | Blue Swirl | val = ldl_phys(sm_state + 0x7efc); /* revision ID */ |
238 | ab109e59 | Blue Swirl | if (val & 0x20000) { |
239 | ab109e59 | Blue Swirl | env->smbase = ldl_phys(sm_state + 0x7f00) & ~0x7fff; |
240 | ab109e59 | Blue Swirl | } |
241 | ab109e59 | Blue Swirl | #else
|
242 | ab109e59 | Blue Swirl | cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7ffc));
|
243 | ab109e59 | Blue Swirl | cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7ff8));
|
244 | ab109e59 | Blue Swirl | cpu_load_eflags(env, ldl_phys(sm_state + 0x7ff4),
|
245 | ab109e59 | Blue Swirl | ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); |
246 | ab109e59 | Blue Swirl | env->eip = ldl_phys(sm_state + 0x7ff0);
|
247 | ab109e59 | Blue Swirl | EDI = ldl_phys(sm_state + 0x7fec);
|
248 | ab109e59 | Blue Swirl | ESI = ldl_phys(sm_state + 0x7fe8);
|
249 | ab109e59 | Blue Swirl | EBP = ldl_phys(sm_state + 0x7fe4);
|
250 | ab109e59 | Blue Swirl | ESP = ldl_phys(sm_state + 0x7fe0);
|
251 | ab109e59 | Blue Swirl | EBX = ldl_phys(sm_state + 0x7fdc);
|
252 | ab109e59 | Blue Swirl | EDX = ldl_phys(sm_state + 0x7fd8);
|
253 | ab109e59 | Blue Swirl | ECX = ldl_phys(sm_state + 0x7fd4);
|
254 | ab109e59 | Blue Swirl | EAX = ldl_phys(sm_state + 0x7fd0);
|
255 | ab109e59 | Blue Swirl | env->dr[6] = ldl_phys(sm_state + 0x7fcc); |
256 | ab109e59 | Blue Swirl | env->dr[7] = ldl_phys(sm_state + 0x7fc8); |
257 | ab109e59 | Blue Swirl | |
258 | ab109e59 | Blue Swirl | env->tr.selector = ldl_phys(sm_state + 0x7fc4) & 0xffff; |
259 | ab109e59 | Blue Swirl | env->tr.base = ldl_phys(sm_state + 0x7f64);
|
260 | ab109e59 | Blue Swirl | env->tr.limit = ldl_phys(sm_state + 0x7f60);
|
261 | ab109e59 | Blue Swirl | env->tr.flags = (ldl_phys(sm_state + 0x7f5c) & 0xf0ff) << 8; |
262 | ab109e59 | Blue Swirl | |
263 | ab109e59 | Blue Swirl | env->ldt.selector = ldl_phys(sm_state + 0x7fc0) & 0xffff; |
264 | ab109e59 | Blue Swirl | env->ldt.base = ldl_phys(sm_state + 0x7f80);
|
265 | ab109e59 | Blue Swirl | env->ldt.limit = ldl_phys(sm_state + 0x7f7c);
|
266 | ab109e59 | Blue Swirl | env->ldt.flags = (ldl_phys(sm_state + 0x7f78) & 0xf0ff) << 8; |
267 | ab109e59 | Blue Swirl | |
268 | ab109e59 | Blue Swirl | env->gdt.base = ldl_phys(sm_state + 0x7f74);
|
269 | ab109e59 | Blue Swirl | env->gdt.limit = ldl_phys(sm_state + 0x7f70);
|
270 | ab109e59 | Blue Swirl | |
271 | ab109e59 | Blue Swirl | env->idt.base = ldl_phys(sm_state + 0x7f58);
|
272 | ab109e59 | Blue Swirl | env->idt.limit = ldl_phys(sm_state + 0x7f54);
|
273 | ab109e59 | Blue Swirl | |
274 | ab109e59 | Blue Swirl | for (i = 0; i < 6; i++) { |
275 | ab109e59 | Blue Swirl | if (i < 3) { |
276 | ab109e59 | Blue Swirl | offset = 0x7f84 + i * 12; |
277 | ab109e59 | Blue Swirl | } else {
|
278 | ab109e59 | Blue Swirl | offset = 0x7f2c + (i - 3) * 12; |
279 | ab109e59 | Blue Swirl | } |
280 | ab109e59 | Blue Swirl | cpu_x86_load_seg_cache(env, i, |
281 | ab109e59 | Blue Swirl | ldl_phys(sm_state + 0x7fa8 + i * 4) & 0xffff, |
282 | ab109e59 | Blue Swirl | ldl_phys(sm_state + offset + 8),
|
283 | ab109e59 | Blue Swirl | ldl_phys(sm_state + offset + 4),
|
284 | ab109e59 | Blue Swirl | (ldl_phys(sm_state + offset) & 0xf0ff) << 8); |
285 | ab109e59 | Blue Swirl | } |
286 | ab109e59 | Blue Swirl | cpu_x86_update_cr4(env, ldl_phys(sm_state + 0x7f14));
|
287 | ab109e59 | Blue Swirl | |
288 | ab109e59 | Blue Swirl | val = ldl_phys(sm_state + 0x7efc); /* revision ID */ |
289 | ab109e59 | Blue Swirl | if (val & 0x20000) { |
290 | ab109e59 | Blue Swirl | env->smbase = ldl_phys(sm_state + 0x7ef8) & ~0x7fff; |
291 | ab109e59 | Blue Swirl | } |
292 | ab109e59 | Blue Swirl | #endif
|
293 | ab109e59 | Blue Swirl | CC_OP = CC_OP_EFLAGS; |
294 | ab109e59 | Blue Swirl | env->hflags &= ~HF_SMM_MASK; |
295 | ab109e59 | Blue Swirl | cpu_smm_update(env); |
296 | ab109e59 | Blue Swirl | |
297 | ab109e59 | Blue Swirl | qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n");
|
298 | ab109e59 | Blue Swirl | log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP); |
299 | ab109e59 | Blue Swirl | } |
300 | ab109e59 | Blue Swirl | |
301 | ab109e59 | Blue Swirl | #endif /* !CONFIG_USER_ONLY */ |