Statistics
| Branch: | Revision:

root / target-i386 / misc_helper.c @ 5b50e790

History | View | Annotate | Download (15.9 kB)

1 f7b2429f Blue Swirl
/*
2 f7b2429f Blue Swirl
 *  x86 misc helpers
3 f7b2429f Blue Swirl
 *
4 f7b2429f Blue Swirl
 *  Copyright (c) 2003 Fabrice Bellard
5 f7b2429f Blue Swirl
 *
6 f7b2429f Blue Swirl
 * This library is free software; you can redistribute it and/or
7 f7b2429f Blue Swirl
 * modify it under the terms of the GNU Lesser General Public
8 f7b2429f Blue Swirl
 * License as published by the Free Software Foundation; either
9 f7b2429f Blue Swirl
 * version 2 of the License, or (at your option) any later version.
10 f7b2429f Blue Swirl
 *
11 f7b2429f Blue Swirl
 * This library is distributed in the hope that it will be useful,
12 f7b2429f Blue Swirl
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 f7b2429f Blue Swirl
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 f7b2429f Blue Swirl
 * Lesser General Public License for more details.
15 f7b2429f Blue Swirl
 *
16 f7b2429f Blue Swirl
 * You should have received a copy of the GNU Lesser General Public
17 f7b2429f Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 f7b2429f Blue Swirl
 */
19 f7b2429f Blue Swirl
20 f7b2429f Blue Swirl
#include "cpu.h"
21 022c62cb Paolo Bonzini
#include "exec/ioport.h"
22 f7b2429f Blue Swirl
#include "helper.h"
23 f7b2429f Blue Swirl
24 92fc4b58 Blue Swirl
#if !defined(CONFIG_USER_ONLY)
25 022c62cb Paolo Bonzini
#include "exec/softmmu_exec.h"
26 92fc4b58 Blue Swirl
#endif /* !defined(CONFIG_USER_ONLY) */
27 92fc4b58 Blue Swirl
28 f7b2429f Blue Swirl
/* check if Port I/O is allowed in TSS */
29 4a7443be Blue Swirl
static inline void check_io(CPUX86State *env, int addr, int size)
30 f7b2429f Blue Swirl
{
31 f7b2429f Blue Swirl
    int io_offset, val, mask;
32 f7b2429f Blue Swirl
33 f7b2429f Blue Swirl
    /* TSS must be a valid 32 bit one */
34 f7b2429f Blue Swirl
    if (!(env->tr.flags & DESC_P_MASK) ||
35 f7b2429f Blue Swirl
        ((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 ||
36 f7b2429f Blue Swirl
        env->tr.limit < 103) {
37 f7b2429f Blue Swirl
        goto fail;
38 f7b2429f Blue Swirl
    }
39 4a7443be Blue Swirl
    io_offset = cpu_lduw_kernel(env, env->tr.base + 0x66);
40 f7b2429f Blue Swirl
    io_offset += (addr >> 3);
41 f7b2429f Blue Swirl
    /* Note: the check needs two bytes */
42 f7b2429f Blue Swirl
    if ((io_offset + 1) > env->tr.limit) {
43 f7b2429f Blue Swirl
        goto fail;
44 f7b2429f Blue Swirl
    }
45 4a7443be Blue Swirl
    val = cpu_lduw_kernel(env, env->tr.base + io_offset);
46 f7b2429f Blue Swirl
    val >>= (addr & 7);
47 f7b2429f Blue Swirl
    mask = (1 << size) - 1;
48 f7b2429f Blue Swirl
    /* all bits must be zero to allow the I/O */
49 f7b2429f Blue Swirl
    if ((val & mask) != 0) {
50 f7b2429f Blue Swirl
    fail:
51 f7b2429f Blue Swirl
        raise_exception_err(env, EXCP0D_GPF, 0);
52 f7b2429f Blue Swirl
    }
53 f7b2429f Blue Swirl
}
54 f7b2429f Blue Swirl
55 4a7443be Blue Swirl
void helper_check_iob(CPUX86State *env, uint32_t t0)
56 f7b2429f Blue Swirl
{
57 4a7443be Blue Swirl
    check_io(env, t0, 1);
58 f7b2429f Blue Swirl
}
59 f7b2429f Blue Swirl
60 4a7443be Blue Swirl
void helper_check_iow(CPUX86State *env, uint32_t t0)
61 f7b2429f Blue Swirl
{
62 4a7443be Blue Swirl
    check_io(env, t0, 2);
63 f7b2429f Blue Swirl
}
64 f7b2429f Blue Swirl
65 4a7443be Blue Swirl
void helper_check_iol(CPUX86State *env, uint32_t t0)
66 f7b2429f Blue Swirl
{
67 4a7443be Blue Swirl
    check_io(env, t0, 4);
68 f7b2429f Blue Swirl
}
69 f7b2429f Blue Swirl
70 f7b2429f Blue Swirl
void helper_outb(uint32_t port, uint32_t data)
71 f7b2429f Blue Swirl
{
72 f7b2429f Blue Swirl
    cpu_outb(port, data & 0xff);
73 f7b2429f Blue Swirl
}
74 f7b2429f Blue Swirl
75 f7b2429f Blue Swirl
target_ulong helper_inb(uint32_t port)
76 f7b2429f Blue Swirl
{
77 f7b2429f Blue Swirl
    return cpu_inb(port);
78 f7b2429f Blue Swirl
}
79 f7b2429f Blue Swirl
80 f7b2429f Blue Swirl
void helper_outw(uint32_t port, uint32_t data)
81 f7b2429f Blue Swirl
{
82 f7b2429f Blue Swirl
    cpu_outw(port, data & 0xffff);
83 f7b2429f Blue Swirl
}
84 f7b2429f Blue Swirl
85 f7b2429f Blue Swirl
target_ulong helper_inw(uint32_t port)
86 f7b2429f Blue Swirl
{
87 f7b2429f Blue Swirl
    return cpu_inw(port);
88 f7b2429f Blue Swirl
}
89 f7b2429f Blue Swirl
90 f7b2429f Blue Swirl
void helper_outl(uint32_t port, uint32_t data)
91 f7b2429f Blue Swirl
{
92 f7b2429f Blue Swirl
    cpu_outl(port, data);
93 f7b2429f Blue Swirl
}
94 f7b2429f Blue Swirl
95 f7b2429f Blue Swirl
target_ulong helper_inl(uint32_t port)
96 f7b2429f Blue Swirl
{
97 f7b2429f Blue Swirl
    return cpu_inl(port);
98 f7b2429f Blue Swirl
}
99 f7b2429f Blue Swirl
100 4a7443be Blue Swirl
void helper_into(CPUX86State *env, int next_eip_addend)
101 f7b2429f Blue Swirl
{
102 f7b2429f Blue Swirl
    int eflags;
103 f7b2429f Blue Swirl
104 f0967a1a Blue Swirl
    eflags = cpu_cc_compute_all(env, CC_OP);
105 f7b2429f Blue Swirl
    if (eflags & CC_O) {
106 f7b2429f Blue Swirl
        raise_interrupt(env, EXCP04_INTO, 1, 0, next_eip_addend);
107 f7b2429f Blue Swirl
    }
108 f7b2429f Blue Swirl
}
109 f7b2429f Blue Swirl
110 4a7443be Blue Swirl
void helper_single_step(CPUX86State *env)
111 f7b2429f Blue Swirl
{
112 f7b2429f Blue Swirl
#ifndef CONFIG_USER_ONLY
113 e175bce5 liguang
    check_hw_breakpoints(env, true);
114 f7b2429f Blue Swirl
    env->dr[6] |= DR6_BS;
115 f7b2429f Blue Swirl
#endif
116 f7b2429f Blue Swirl
    raise_exception(env, EXCP01_DB);
117 f7b2429f Blue Swirl
}
118 f7b2429f Blue Swirl
119 4a7443be Blue Swirl
void helper_cpuid(CPUX86State *env)
120 f7b2429f Blue Swirl
{
121 f7b2429f Blue Swirl
    uint32_t eax, ebx, ecx, edx;
122 f7b2429f Blue Swirl
123 f7b2429f Blue Swirl
    cpu_svm_check_intercept_param(env, SVM_EXIT_CPUID, 0);
124 f7b2429f Blue Swirl
125 90a2541b liguang
    cpu_x86_cpuid(env, (uint32_t)env->regs[R_EAX], (uint32_t)env->regs[R_ECX],
126 90a2541b liguang
                  &eax, &ebx, &ecx, &edx);
127 4b34e3ad liguang
    env->regs[R_EAX] = eax;
128 70b51365 liguang
    env->regs[R_EBX] = ebx;
129 a4165610 liguang
    env->regs[R_ECX] = ecx;
130 00f5e6f2 liguang
    env->regs[R_EDX] = edx;
131 f7b2429f Blue Swirl
}
132 f7b2429f Blue Swirl
133 f7b2429f Blue Swirl
#if defined(CONFIG_USER_ONLY)
134 4a7443be Blue Swirl
target_ulong helper_read_crN(CPUX86State *env, int reg)
135 f7b2429f Blue Swirl
{
136 f7b2429f Blue Swirl
    return 0;
137 f7b2429f Blue Swirl
}
138 f7b2429f Blue Swirl
139 4a7443be Blue Swirl
void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
140 f7b2429f Blue Swirl
{
141 f7b2429f Blue Swirl
}
142 f7b2429f Blue Swirl
143 4a7443be Blue Swirl
void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
144 f7b2429f Blue Swirl
{
145 f7b2429f Blue Swirl
}
146 f7b2429f Blue Swirl
#else
147 4a7443be Blue Swirl
target_ulong helper_read_crN(CPUX86State *env, int reg)
148 f7b2429f Blue Swirl
{
149 f7b2429f Blue Swirl
    target_ulong val;
150 f7b2429f Blue Swirl
151 f7b2429f Blue Swirl
    cpu_svm_check_intercept_param(env, SVM_EXIT_READ_CR0 + reg, 0);
152 f7b2429f Blue Swirl
    switch (reg) {
153 f7b2429f Blue Swirl
    default:
154 f7b2429f Blue Swirl
        val = env->cr[reg];
155 f7b2429f Blue Swirl
        break;
156 f7b2429f Blue Swirl
    case 8:
157 f7b2429f Blue Swirl
        if (!(env->hflags2 & HF2_VINTR_MASK)) {
158 f7b2429f Blue Swirl
            val = cpu_get_apic_tpr(env->apic_state);
159 f7b2429f Blue Swirl
        } else {
160 f7b2429f Blue Swirl
            val = env->v_tpr;
161 f7b2429f Blue Swirl
        }
162 f7b2429f Blue Swirl
        break;
163 f7b2429f Blue Swirl
    }
164 f7b2429f Blue Swirl
    return val;
165 f7b2429f Blue Swirl
}
166 f7b2429f Blue Swirl
167 4a7443be Blue Swirl
void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
168 f7b2429f Blue Swirl
{
169 f7b2429f Blue Swirl
    cpu_svm_check_intercept_param(env, SVM_EXIT_WRITE_CR0 + reg, 0);
170 f7b2429f Blue Swirl
    switch (reg) {
171 f7b2429f Blue Swirl
    case 0:
172 f7b2429f Blue Swirl
        cpu_x86_update_cr0(env, t0);
173 f7b2429f Blue Swirl
        break;
174 f7b2429f Blue Swirl
    case 3:
175 f7b2429f Blue Swirl
        cpu_x86_update_cr3(env, t0);
176 f7b2429f Blue Swirl
        break;
177 f7b2429f Blue Swirl
    case 4:
178 f7b2429f Blue Swirl
        cpu_x86_update_cr4(env, t0);
179 f7b2429f Blue Swirl
        break;
180 f7b2429f Blue Swirl
    case 8:
181 f7b2429f Blue Swirl
        if (!(env->hflags2 & HF2_VINTR_MASK)) {
182 f7b2429f Blue Swirl
            cpu_set_apic_tpr(env->apic_state, t0);
183 f7b2429f Blue Swirl
        }
184 f7b2429f Blue Swirl
        env->v_tpr = t0 & 0x0f;
185 f7b2429f Blue Swirl
        break;
186 f7b2429f Blue Swirl
    default:
187 f7b2429f Blue Swirl
        env->cr[reg] = t0;
188 f7b2429f Blue Swirl
        break;
189 f7b2429f Blue Swirl
    }
190 f7b2429f Blue Swirl
}
191 f7b2429f Blue Swirl
192 4a7443be Blue Swirl
void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
193 f7b2429f Blue Swirl
{
194 f7b2429f Blue Swirl
    int i;
195 f7b2429f Blue Swirl
196 f7b2429f Blue Swirl
    if (reg < 4) {
197 f7b2429f Blue Swirl
        hw_breakpoint_remove(env, reg);
198 f7b2429f Blue Swirl
        env->dr[reg] = t0;
199 f7b2429f Blue Swirl
        hw_breakpoint_insert(env, reg);
200 f7b2429f Blue Swirl
    } else if (reg == 7) {
201 428065ce liguang
        for (i = 0; i < DR7_MAX_BP; i++) {
202 f7b2429f Blue Swirl
            hw_breakpoint_remove(env, i);
203 f7b2429f Blue Swirl
        }
204 f7b2429f Blue Swirl
        env->dr[7] = t0;
205 428065ce liguang
        for (i = 0; i < DR7_MAX_BP; i++) {
206 f7b2429f Blue Swirl
            hw_breakpoint_insert(env, i);
207 f7b2429f Blue Swirl
        }
208 f7b2429f Blue Swirl
    } else {
209 f7b2429f Blue Swirl
        env->dr[reg] = t0;
210 f7b2429f Blue Swirl
    }
211 f7b2429f Blue Swirl
}
212 f7b2429f Blue Swirl
#endif
213 f7b2429f Blue Swirl
214 4a7443be Blue Swirl
void helper_lmsw(CPUX86State *env, target_ulong t0)
215 f7b2429f Blue Swirl
{
216 f7b2429f Blue Swirl
    /* only 4 lower bits of CR0 are modified. PE cannot be set to zero
217 f7b2429f Blue Swirl
       if already set to one. */
218 f7b2429f Blue Swirl
    t0 = (env->cr[0] & ~0xe) | (t0 & 0xf);
219 4a7443be Blue Swirl
    helper_write_crN(env, 0, t0);
220 f7b2429f Blue Swirl
}
221 f7b2429f Blue Swirl
222 4a7443be Blue Swirl
void helper_invlpg(CPUX86State *env, target_ulong addr)
223 f7b2429f Blue Swirl
{
224 f7b2429f Blue Swirl
    cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPG, 0);
225 f7b2429f Blue Swirl
    tlb_flush_page(env, addr);
226 f7b2429f Blue Swirl
}
227 f7b2429f Blue Swirl
228 4a7443be Blue Swirl
void helper_rdtsc(CPUX86State *env)
229 f7b2429f Blue Swirl
{
230 f7b2429f Blue Swirl
    uint64_t val;
231 f7b2429f Blue Swirl
232 f7b2429f Blue Swirl
    if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
233 f7b2429f Blue Swirl
        raise_exception(env, EXCP0D_GPF);
234 f7b2429f Blue Swirl
    }
235 f7b2429f Blue Swirl
    cpu_svm_check_intercept_param(env, SVM_EXIT_RDTSC, 0);
236 f7b2429f Blue Swirl
237 f7b2429f Blue Swirl
    val = cpu_get_tsc(env) + env->tsc_offset;
238 4b34e3ad liguang
    env->regs[R_EAX] = (uint32_t)(val);
239 00f5e6f2 liguang
    env->regs[R_EDX] = (uint32_t)(val >> 32);
240 f7b2429f Blue Swirl
}
241 f7b2429f Blue Swirl
242 4a7443be Blue Swirl
void helper_rdtscp(CPUX86State *env)
243 f7b2429f Blue Swirl
{
244 4a7443be Blue Swirl
    helper_rdtsc(env);
245 a4165610 liguang
    env->regs[R_ECX] = (uint32_t)(env->tsc_aux);
246 f7b2429f Blue Swirl
}
247 f7b2429f Blue Swirl
248 4a7443be Blue Swirl
void helper_rdpmc(CPUX86State *env)
249 f7b2429f Blue Swirl
{
250 f7b2429f Blue Swirl
    if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
251 f7b2429f Blue Swirl
        raise_exception(env, EXCP0D_GPF);
252 f7b2429f Blue Swirl
    }
253 f7b2429f Blue Swirl
    cpu_svm_check_intercept_param(env, SVM_EXIT_RDPMC, 0);
254 f7b2429f Blue Swirl
255 f7b2429f Blue Swirl
    /* currently unimplemented */
256 f7b2429f Blue Swirl
    qemu_log_mask(LOG_UNIMP, "x86: unimplemented rdpmc\n");
257 f7b2429f Blue Swirl
    raise_exception_err(env, EXCP06_ILLOP, 0);
258 f7b2429f Blue Swirl
}
259 f7b2429f Blue Swirl
260 f7b2429f Blue Swirl
#if defined(CONFIG_USER_ONLY)
261 4a7443be Blue Swirl
void helper_wrmsr(CPUX86State *env)
262 f7b2429f Blue Swirl
{
263 f7b2429f Blue Swirl
}
264 f7b2429f Blue Swirl
265 4a7443be Blue Swirl
void helper_rdmsr(CPUX86State *env)
266 f7b2429f Blue Swirl
{
267 f7b2429f Blue Swirl
}
268 f7b2429f Blue Swirl
#else
269 4a7443be Blue Swirl
void helper_wrmsr(CPUX86State *env)
270 f7b2429f Blue Swirl
{
271 f7b2429f Blue Swirl
    uint64_t val;
272 f7b2429f Blue Swirl
273 f7b2429f Blue Swirl
    cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1);
274 f7b2429f Blue Swirl
275 90a2541b liguang
    val = ((uint32_t)env->regs[R_EAX]) |
276 90a2541b liguang
        ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
277 f7b2429f Blue Swirl
278 a4165610 liguang
    switch ((uint32_t)env->regs[R_ECX]) {
279 f7b2429f Blue Swirl
    case MSR_IA32_SYSENTER_CS:
280 f7b2429f Blue Swirl
        env->sysenter_cs = val & 0xffff;
281 f7b2429f Blue Swirl
        break;
282 f7b2429f Blue Swirl
    case MSR_IA32_SYSENTER_ESP:
283 f7b2429f Blue Swirl
        env->sysenter_esp = val;
284 f7b2429f Blue Swirl
        break;
285 f7b2429f Blue Swirl
    case MSR_IA32_SYSENTER_EIP:
286 f7b2429f Blue Swirl
        env->sysenter_eip = val;
287 f7b2429f Blue Swirl
        break;
288 f7b2429f Blue Swirl
    case MSR_IA32_APICBASE:
289 f7b2429f Blue Swirl
        cpu_set_apic_base(env->apic_state, val);
290 f7b2429f Blue Swirl
        break;
291 f7b2429f Blue Swirl
    case MSR_EFER:
292 f7b2429f Blue Swirl
        {
293 f7b2429f Blue Swirl
            uint64_t update_mask;
294 f7b2429f Blue Swirl
295 f7b2429f Blue Swirl
            update_mask = 0;
296 0514ef2f Eduardo Habkost
            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_SYSCALL) {
297 f7b2429f Blue Swirl
                update_mask |= MSR_EFER_SCE;
298 f7b2429f Blue Swirl
            }
299 0514ef2f Eduardo Habkost
            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
300 f7b2429f Blue Swirl
                update_mask |= MSR_EFER_LME;
301 f7b2429f Blue Swirl
            }
302 0514ef2f Eduardo Habkost
            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) {
303 f7b2429f Blue Swirl
                update_mask |= MSR_EFER_FFXSR;
304 f7b2429f Blue Swirl
            }
305 0514ef2f Eduardo Habkost
            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_NX) {
306 f7b2429f Blue Swirl
                update_mask |= MSR_EFER_NXE;
307 f7b2429f Blue Swirl
            }
308 0514ef2f Eduardo Habkost
            if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
309 f7b2429f Blue Swirl
                update_mask |= MSR_EFER_SVME;
310 f7b2429f Blue Swirl
            }
311 0514ef2f Eduardo Habkost
            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) {
312 f7b2429f Blue Swirl
                update_mask |= MSR_EFER_FFXSR;
313 f7b2429f Blue Swirl
            }
314 f7b2429f Blue Swirl
            cpu_load_efer(env, (env->efer & ~update_mask) |
315 f7b2429f Blue Swirl
                          (val & update_mask));
316 f7b2429f Blue Swirl
        }
317 f7b2429f Blue Swirl
        break;
318 f7b2429f Blue Swirl
    case MSR_STAR:
319 f7b2429f Blue Swirl
        env->star = val;
320 f7b2429f Blue Swirl
        break;
321 f7b2429f Blue Swirl
    case MSR_PAT:
322 f7b2429f Blue Swirl
        env->pat = val;
323 f7b2429f Blue Swirl
        break;
324 f7b2429f Blue Swirl
    case MSR_VM_HSAVE_PA:
325 f7b2429f Blue Swirl
        env->vm_hsave = val;
326 f7b2429f Blue Swirl
        break;
327 f7b2429f Blue Swirl
#ifdef TARGET_X86_64
328 f7b2429f Blue Swirl
    case MSR_LSTAR:
329 f7b2429f Blue Swirl
        env->lstar = val;
330 f7b2429f Blue Swirl
        break;
331 f7b2429f Blue Swirl
    case MSR_CSTAR:
332 f7b2429f Blue Swirl
        env->cstar = val;
333 f7b2429f Blue Swirl
        break;
334 f7b2429f Blue Swirl
    case MSR_FMASK:
335 f7b2429f Blue Swirl
        env->fmask = val;
336 f7b2429f Blue Swirl
        break;
337 f7b2429f Blue Swirl
    case MSR_FSBASE:
338 f7b2429f Blue Swirl
        env->segs[R_FS].base = val;
339 f7b2429f Blue Swirl
        break;
340 f7b2429f Blue Swirl
    case MSR_GSBASE:
341 f7b2429f Blue Swirl
        env->segs[R_GS].base = val;
342 f7b2429f Blue Swirl
        break;
343 f7b2429f Blue Swirl
    case MSR_KERNELGSBASE:
344 f7b2429f Blue Swirl
        env->kernelgsbase = val;
345 f7b2429f Blue Swirl
        break;
346 f7b2429f Blue Swirl
#endif
347 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(0):
348 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(1):
349 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(2):
350 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(3):
351 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(4):
352 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(5):
353 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(6):
354 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(7):
355 90a2541b liguang
        env->mtrr_var[((uint32_t)env->regs[R_ECX] -
356 90a2541b liguang
                       MSR_MTRRphysBase(0)) / 2].base = val;
357 f7b2429f Blue Swirl
        break;
358 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(0):
359 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(1):
360 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(2):
361 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(3):
362 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(4):
363 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(5):
364 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(6):
365 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(7):
366 90a2541b liguang
        env->mtrr_var[((uint32_t)env->regs[R_ECX] -
367 90a2541b liguang
                       MSR_MTRRphysMask(0)) / 2].mask = val;
368 f7b2429f Blue Swirl
        break;
369 f7b2429f Blue Swirl
    case MSR_MTRRfix64K_00000:
370 90a2541b liguang
        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
371 90a2541b liguang
                        MSR_MTRRfix64K_00000] = val;
372 f7b2429f Blue Swirl
        break;
373 f7b2429f Blue Swirl
    case MSR_MTRRfix16K_80000:
374 f7b2429f Blue Swirl
    case MSR_MTRRfix16K_A0000:
375 90a2541b liguang
        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
376 90a2541b liguang
                        MSR_MTRRfix16K_80000 + 1] = val;
377 f7b2429f Blue Swirl
        break;
378 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_C0000:
379 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_C8000:
380 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_D0000:
381 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_D8000:
382 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_E0000:
383 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_E8000:
384 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_F0000:
385 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_F8000:
386 90a2541b liguang
        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
387 90a2541b liguang
                        MSR_MTRRfix4K_C0000 + 3] = val;
388 f7b2429f Blue Swirl
        break;
389 f7b2429f Blue Swirl
    case MSR_MTRRdefType:
390 f7b2429f Blue Swirl
        env->mtrr_deftype = val;
391 f7b2429f Blue Swirl
        break;
392 f7b2429f Blue Swirl
    case MSR_MCG_STATUS:
393 f7b2429f Blue Swirl
        env->mcg_status = val;
394 f7b2429f Blue Swirl
        break;
395 f7b2429f Blue Swirl
    case MSR_MCG_CTL:
396 f7b2429f Blue Swirl
        if ((env->mcg_cap & MCG_CTL_P)
397 f7b2429f Blue Swirl
            && (val == 0 || val == ~(uint64_t)0)) {
398 f7b2429f Blue Swirl
            env->mcg_ctl = val;
399 f7b2429f Blue Swirl
        }
400 f7b2429f Blue Swirl
        break;
401 f7b2429f Blue Swirl
    case MSR_TSC_AUX:
402 f7b2429f Blue Swirl
        env->tsc_aux = val;
403 f7b2429f Blue Swirl
        break;
404 f7b2429f Blue Swirl
    case MSR_IA32_MISC_ENABLE:
405 f7b2429f Blue Swirl
        env->msr_ia32_misc_enable = val;
406 f7b2429f Blue Swirl
        break;
407 f7b2429f Blue Swirl
    default:
408 a4165610 liguang
        if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
409 90a2541b liguang
            && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL +
410 90a2541b liguang
            (4 * env->mcg_cap & 0xff)) {
411 a4165610 liguang
            uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
412 f7b2429f Blue Swirl
            if ((offset & 0x3) != 0
413 f7b2429f Blue Swirl
                || (val == 0 || val == ~(uint64_t)0)) {
414 f7b2429f Blue Swirl
                env->mce_banks[offset] = val;
415 f7b2429f Blue Swirl
            }
416 f7b2429f Blue Swirl
            break;
417 f7b2429f Blue Swirl
        }
418 f7b2429f Blue Swirl
        /* XXX: exception? */
419 f7b2429f Blue Swirl
        break;
420 f7b2429f Blue Swirl
    }
421 f7b2429f Blue Swirl
}
422 f7b2429f Blue Swirl
423 4a7443be Blue Swirl
void helper_rdmsr(CPUX86State *env)
424 f7b2429f Blue Swirl
{
425 f7b2429f Blue Swirl
    uint64_t val;
426 f7b2429f Blue Swirl
427 f7b2429f Blue Swirl
    cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0);
428 f7b2429f Blue Swirl
429 a4165610 liguang
    switch ((uint32_t)env->regs[R_ECX]) {
430 f7b2429f Blue Swirl
    case MSR_IA32_SYSENTER_CS:
431 f7b2429f Blue Swirl
        val = env->sysenter_cs;
432 f7b2429f Blue Swirl
        break;
433 f7b2429f Blue Swirl
    case MSR_IA32_SYSENTER_ESP:
434 f7b2429f Blue Swirl
        val = env->sysenter_esp;
435 f7b2429f Blue Swirl
        break;
436 f7b2429f Blue Swirl
    case MSR_IA32_SYSENTER_EIP:
437 f7b2429f Blue Swirl
        val = env->sysenter_eip;
438 f7b2429f Blue Swirl
        break;
439 f7b2429f Blue Swirl
    case MSR_IA32_APICBASE:
440 f7b2429f Blue Swirl
        val = cpu_get_apic_base(env->apic_state);
441 f7b2429f Blue Swirl
        break;
442 f7b2429f Blue Swirl
    case MSR_EFER:
443 f7b2429f Blue Swirl
        val = env->efer;
444 f7b2429f Blue Swirl
        break;
445 f7b2429f Blue Swirl
    case MSR_STAR:
446 f7b2429f Blue Swirl
        val = env->star;
447 f7b2429f Blue Swirl
        break;
448 f7b2429f Blue Swirl
    case MSR_PAT:
449 f7b2429f Blue Swirl
        val = env->pat;
450 f7b2429f Blue Swirl
        break;
451 f7b2429f Blue Swirl
    case MSR_VM_HSAVE_PA:
452 f7b2429f Blue Swirl
        val = env->vm_hsave;
453 f7b2429f Blue Swirl
        break;
454 f7b2429f Blue Swirl
    case MSR_IA32_PERF_STATUS:
455 f7b2429f Blue Swirl
        /* tsc_increment_by_tick */
456 f7b2429f Blue Swirl
        val = 1000ULL;
457 f7b2429f Blue Swirl
        /* CPU multiplier */
458 f7b2429f Blue Swirl
        val |= (((uint64_t)4ULL) << 40);
459 f7b2429f Blue Swirl
        break;
460 f7b2429f Blue Swirl
#ifdef TARGET_X86_64
461 f7b2429f Blue Swirl
    case MSR_LSTAR:
462 f7b2429f Blue Swirl
        val = env->lstar;
463 f7b2429f Blue Swirl
        break;
464 f7b2429f Blue Swirl
    case MSR_CSTAR:
465 f7b2429f Blue Swirl
        val = env->cstar;
466 f7b2429f Blue Swirl
        break;
467 f7b2429f Blue Swirl
    case MSR_FMASK:
468 f7b2429f Blue Swirl
        val = env->fmask;
469 f7b2429f Blue Swirl
        break;
470 f7b2429f Blue Swirl
    case MSR_FSBASE:
471 f7b2429f Blue Swirl
        val = env->segs[R_FS].base;
472 f7b2429f Blue Swirl
        break;
473 f7b2429f Blue Swirl
    case MSR_GSBASE:
474 f7b2429f Blue Swirl
        val = env->segs[R_GS].base;
475 f7b2429f Blue Swirl
        break;
476 f7b2429f Blue Swirl
    case MSR_KERNELGSBASE:
477 f7b2429f Blue Swirl
        val = env->kernelgsbase;
478 f7b2429f Blue Swirl
        break;
479 f7b2429f Blue Swirl
    case MSR_TSC_AUX:
480 f7b2429f Blue Swirl
        val = env->tsc_aux;
481 f7b2429f Blue Swirl
        break;
482 f7b2429f Blue Swirl
#endif
483 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(0):
484 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(1):
485 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(2):
486 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(3):
487 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(4):
488 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(5):
489 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(6):
490 f7b2429f Blue Swirl
    case MSR_MTRRphysBase(7):
491 90a2541b liguang
        val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
492 90a2541b liguang
                             MSR_MTRRphysBase(0)) / 2].base;
493 f7b2429f Blue Swirl
        break;
494 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(0):
495 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(1):
496 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(2):
497 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(3):
498 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(4):
499 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(5):
500 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(6):
501 f7b2429f Blue Swirl
    case MSR_MTRRphysMask(7):
502 90a2541b liguang
        val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
503 90a2541b liguang
                             MSR_MTRRphysMask(0)) / 2].mask;
504 f7b2429f Blue Swirl
        break;
505 f7b2429f Blue Swirl
    case MSR_MTRRfix64K_00000:
506 f7b2429f Blue Swirl
        val = env->mtrr_fixed[0];
507 f7b2429f Blue Swirl
        break;
508 f7b2429f Blue Swirl
    case MSR_MTRRfix16K_80000:
509 f7b2429f Blue Swirl
    case MSR_MTRRfix16K_A0000:
510 90a2541b liguang
        val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
511 90a2541b liguang
                              MSR_MTRRfix16K_80000 + 1];
512 f7b2429f Blue Swirl
        break;
513 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_C0000:
514 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_C8000:
515 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_D0000:
516 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_D8000:
517 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_E0000:
518 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_E8000:
519 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_F0000:
520 f7b2429f Blue Swirl
    case MSR_MTRRfix4K_F8000:
521 90a2541b liguang
        val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
522 90a2541b liguang
                              MSR_MTRRfix4K_C0000 + 3];
523 f7b2429f Blue Swirl
        break;
524 f7b2429f Blue Swirl
    case MSR_MTRRdefType:
525 f7b2429f Blue Swirl
        val = env->mtrr_deftype;
526 f7b2429f Blue Swirl
        break;
527 f7b2429f Blue Swirl
    case MSR_MTRRcap:
528 0514ef2f Eduardo Habkost
        if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
529 f7b2429f Blue Swirl
            val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT |
530 f7b2429f Blue Swirl
                MSR_MTRRcap_WC_SUPPORTED;
531 f7b2429f Blue Swirl
        } else {
532 f7b2429f Blue Swirl
            /* XXX: exception? */
533 f7b2429f Blue Swirl
            val = 0;
534 f7b2429f Blue Swirl
        }
535 f7b2429f Blue Swirl
        break;
536 f7b2429f Blue Swirl
    case MSR_MCG_CAP:
537 f7b2429f Blue Swirl
        val = env->mcg_cap;
538 f7b2429f Blue Swirl
        break;
539 f7b2429f Blue Swirl
    case MSR_MCG_CTL:
540 f7b2429f Blue Swirl
        if (env->mcg_cap & MCG_CTL_P) {
541 f7b2429f Blue Swirl
            val = env->mcg_ctl;
542 f7b2429f Blue Swirl
        } else {
543 f7b2429f Blue Swirl
            val = 0;
544 f7b2429f Blue Swirl
        }
545 f7b2429f Blue Swirl
        break;
546 f7b2429f Blue Swirl
    case MSR_MCG_STATUS:
547 f7b2429f Blue Swirl
        val = env->mcg_status;
548 f7b2429f Blue Swirl
        break;
549 f7b2429f Blue Swirl
    case MSR_IA32_MISC_ENABLE:
550 f7b2429f Blue Swirl
        val = env->msr_ia32_misc_enable;
551 f7b2429f Blue Swirl
        break;
552 f7b2429f Blue Swirl
    default:
553 a4165610 liguang
        if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
554 90a2541b liguang
            && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL +
555 90a2541b liguang
            (4 * env->mcg_cap & 0xff)) {
556 a4165610 liguang
            uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
557 f7b2429f Blue Swirl
            val = env->mce_banks[offset];
558 f7b2429f Blue Swirl
            break;
559 f7b2429f Blue Swirl
        }
560 f7b2429f Blue Swirl
        /* XXX: exception? */
561 f7b2429f Blue Swirl
        val = 0;
562 f7b2429f Blue Swirl
        break;
563 f7b2429f Blue Swirl
    }
564 4b34e3ad liguang
    env->regs[R_EAX] = (uint32_t)(val);
565 00f5e6f2 liguang
    env->regs[R_EDX] = (uint32_t)(val >> 32);
566 f7b2429f Blue Swirl
}
567 f7b2429f Blue Swirl
#endif
568 f7b2429f Blue Swirl
569 259186a7 Andreas Färber
static void do_hlt(X86CPU *cpu)
570 f7b2429f Blue Swirl
{
571 259186a7 Andreas Färber
    CPUState *cs = CPU(cpu);
572 259186a7 Andreas Färber
    CPUX86State *env = &cpu->env;
573 259186a7 Andreas Färber
574 f7b2429f Blue Swirl
    env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
575 259186a7 Andreas Färber
    cs->halted = 1;
576 f7b2429f Blue Swirl
    env->exception_index = EXCP_HLT;
577 f7b2429f Blue Swirl
    cpu_loop_exit(env);
578 f7b2429f Blue Swirl
}
579 f7b2429f Blue Swirl
580 4a7443be Blue Swirl
void helper_hlt(CPUX86State *env, int next_eip_addend)
581 f7b2429f Blue Swirl
{
582 259186a7 Andreas Färber
    X86CPU *cpu = x86_env_get_cpu(env);
583 259186a7 Andreas Färber
584 f7b2429f Blue Swirl
    cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0);
585 a78d0eab liguang
    env->eip += next_eip_addend;
586 f7b2429f Blue Swirl
587 259186a7 Andreas Färber
    do_hlt(cpu);
588 f7b2429f Blue Swirl
}
589 f7b2429f Blue Swirl
590 4a7443be Blue Swirl
void helper_monitor(CPUX86State *env, target_ulong ptr)
591 f7b2429f Blue Swirl
{
592 a4165610 liguang
    if ((uint32_t)env->regs[R_ECX] != 0) {
593 f7b2429f Blue Swirl
        raise_exception(env, EXCP0D_GPF);
594 f7b2429f Blue Swirl
    }
595 f7b2429f Blue Swirl
    /* XXX: store address? */
596 f7b2429f Blue Swirl
    cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0);
597 f7b2429f Blue Swirl
}
598 f7b2429f Blue Swirl
599 4a7443be Blue Swirl
void helper_mwait(CPUX86State *env, int next_eip_addend)
600 f7b2429f Blue Swirl
{
601 259186a7 Andreas Färber
    CPUState *cs;
602 259186a7 Andreas Färber
    X86CPU *cpu;
603 55e5c285 Andreas Färber
604 a4165610 liguang
    if ((uint32_t)env->regs[R_ECX] != 0) {
605 f7b2429f Blue Swirl
        raise_exception(env, EXCP0D_GPF);
606 f7b2429f Blue Swirl
    }
607 f7b2429f Blue Swirl
    cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0);
608 a78d0eab liguang
    env->eip += next_eip_addend;
609 f7b2429f Blue Swirl
610 259186a7 Andreas Färber
    cpu = x86_env_get_cpu(env);
611 259186a7 Andreas Färber
    cs = CPU(cpu);
612 f7b2429f Blue Swirl
    /* XXX: not complete but not completely erroneous */
613 182735ef Andreas Färber
    if (cs->cpu_index != 0 || cs->next_cpu != NULL) {
614 f7b2429f Blue Swirl
        /* more than one CPU: do not sleep because another CPU may
615 f7b2429f Blue Swirl
           wake this one */
616 f7b2429f Blue Swirl
    } else {
617 259186a7 Andreas Färber
        do_hlt(cpu);
618 f7b2429f Blue Swirl
    }
619 f7b2429f Blue Swirl
}
620 f7b2429f Blue Swirl
621 4a7443be Blue Swirl
void helper_debug(CPUX86State *env)
622 f7b2429f Blue Swirl
{
623 f7b2429f Blue Swirl
    env->exception_index = EXCP_DEBUG;
624 f7b2429f Blue Swirl
    cpu_loop_exit(env);
625 f7b2429f Blue Swirl
}