~ubuntu-branches/ubuntu/raring/virtualbox-ose/raring

« back to all changes in this revision

Viewing changes to src/recompiler/VBoxRecompiler.c

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-01-30 23:27:25 UTC
  • mfrom: (0.3.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20110130232725-2ouajjd2ggdet0zd
Tags: 4.0.2-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Drop ubuntu-01-fix-build-gcc45.patch, fixed upstream.
* Drop ubuntu-02-as-needed.patch, added to the Debian package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: VBoxRecompiler.c $ */
 
1
/* $Id: VBoxRecompiler.c 35346 2010-12-27 16:13:13Z vboxsync $ */
2
2
/** @file
3
3
 * VBox Recompiler - QEMU.
4
4
 */
26
26
#include "config.h"
27
27
#include "cpu-all.h"
28
28
 
29
 
#include <VBox/rem.h>
30
 
#include <VBox/vmapi.h>
31
 
#include <VBox/tm.h>
32
 
#include <VBox/ssm.h>
33
 
#include <VBox/em.h>
34
 
#include <VBox/trpm.h>
35
 
#include <VBox/iom.h>
36
 
#include <VBox/mm.h>
37
 
#include <VBox/pgm.h>
38
 
#include <VBox/pdm.h>
39
 
#include <VBox/dbgf.h>
 
29
#include <VBox/vmm/rem.h>
 
30
#include <VBox/vmm/vmapi.h>
 
31
#include <VBox/vmm/tm.h>
 
32
#include <VBox/vmm/ssm.h>
 
33
#include <VBox/vmm/em.h>
 
34
#include <VBox/vmm/trpm.h>
 
35
#include <VBox/vmm/iom.h>
 
36
#include <VBox/vmm/mm.h>
 
37
#include <VBox/vmm/pgm.h>
 
38
#include <VBox/vmm/pdm.h>
 
39
#include <VBox/vmm/dbgf.h>
40
40
#include <VBox/dbg.h>
41
 
#include <VBox/hwaccm.h>
42
 
#include <VBox/patm.h>
43
 
#include <VBox/csam.h>
 
41
#include <VBox/vmm/hwaccm.h>
 
42
#include <VBox/vmm/patm.h>
 
43
#include <VBox/vmm/csam.h>
44
44
#include "REMInternal.h"
45
 
#include <VBox/vm.h>
 
45
#include <VBox/vmm/vm.h>
46
46
#include <VBox/param.h>
47
47
#include <VBox/err.h>
48
48
 
367
367
    STAM_REG(pVM, &gStatRawCheck,           STAMTYPE_PROFILE, "/PROF/REM/RawCheck",   STAMUNIT_TICKS_PER_CALL, "Profiling timer scheduling.");
368
368
    STAM_REG(pVM, &gStatMemRead,            STAMTYPE_PROFILE, "/PROF/REM/MemRead",    STAMUNIT_TICKS_PER_CALL, "Profiling memory access.");
369
369
    STAM_REG(pVM, &gStatMemWrite,           STAMTYPE_PROFILE, "/PROF/REM/MemWrite",   STAMUNIT_TICKS_PER_CALL, "Profiling memory access.");
370
 
    STAM_REG(pVM, &gStatHCVirt2GCPhys,      STAMTYPE_PROFILE, "/PROF/REM/HCVirt2GCPhys", STAMUNIT_TICKS_PER_CALL, "Profiling memory convertion.");
371
 
    STAM_REG(pVM, &gStatGCPhys2HCVirt,      STAMTYPE_PROFILE, "/PROF/REM/GCPhys2HCVirt", STAMUNIT_TICKS_PER_CALL, "Profiling memory convertion.");
 
370
    STAM_REG(pVM, &gStatHCVirt2GCPhys,      STAMTYPE_PROFILE, "/PROF/REM/HCVirt2GCPhys", STAMUNIT_TICKS_PER_CALL, "Profiling memory conversion.");
 
371
    STAM_REG(pVM, &gStatGCPhys2HCVirt,      STAMTYPE_PROFILE, "/PROF/REM/GCPhys2HCVirt", STAMUNIT_TICKS_PER_CALL, "Profiling memory conversion.");
372
372
 
373
373
    STAM_REG(pVM, &gStatCpuGetTSC,          STAMTYPE_COUNTER, "/REM/CpuGetTSC",         STAMUNIT_OCCURENCES,     "cpu_get_tsc calls");
374
374
 
765
765
    tlb_flush(&pRem->Env, 1);
766
766
 
767
767
    /*
768
 
     * Stop ignoring ignornable notifications.
 
768
     * Stop ignoring ignorable notifications.
769
769
     */
770
770
    ASMAtomicDecU32(&pVM->rem.s.cIgnoreAll);
771
771
 
1231
1231
        Ctx.trHid.u32Limit = env->tr.limit;
1232
1232
        Ctx.trHid.Attr.u   = (env->tr.flags >> 8) & 0xF0FF;
1233
1233
 
 
1234
        Ctx.ldtr              = env->ldt.selector;
 
1235
        Ctx.ldtrHid.u64Base   = env->ldt.base;
 
1236
        Ctx.ldtrHid.u32Limit  = env->ldt.limit;
 
1237
        Ctx.ldtrHid.Attr.u    = (env->ldt.flags >> 8) & 0xF0FF;
 
1238
 
1234
1239
        Ctx.idtr.cbIdt     = env->idt.limit;
1235
1240
        Ctx.idtr.pIdt      = env->idt.base;
1236
1241
 
1290
1295
     * Here we only support 16 & 32 bits protected mode ring 3 code that has no IO privileges
1291
1296
     * or 32 bits protected mode ring 0 code
1292
1297
     *
1293
 
     * The tests are ordered by the likelyhood of being true during normal execution.
 
1298
     * The tests are ordered by the likelihood of being true during normal execution.
1294
1299
     */
1295
1300
    if (fFlags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK))
1296
1301
    {
1688
1693
 
1689
1694
 
1690
1695
/**
1691
 
 * Record trap occurance
 
1696
 * Record trap occurrence
1692
1697
 *
1693
1698
 * @returns VBox status code
1694
1699
 * @param   env             Pointer to the CPU environment.
1787
1792
 *
1788
1793
 * @remark  The caller has to check for important FFs before calling REMR3Run. REMR3State will
1789
1794
 *          no do this since the majority of the callers don't want any unnecessary of events
1790
 
 *          pending that would immediatly interrupt execution.
 
1795
 *          pending that would immediately interrupt execution.
1791
1796
 */
1792
1797
REMR3DECL(int)  REMR3State(PVM pVM, PVMCPU pVCpu)
1793
1798
{
2038
2043
    if (fHiddenSelRegsValid)
2039
2044
    {
2040
2045
        /* The hidden selector registers are valid in the CPU context. */
2041
 
        /** @note QEmu saves the 2nd dword of the descriptor; we should convert the attribute word back! */
 
2046
        /* Note! QEmu saves the 2nd dword of the descriptor; we should convert the attribute word back! */
2042
2047
 
2043
2048
        /* Set current CPL */
2044
2049
        cpu_x86_set_cpl(&pVM->rem.s.Env, uCpl);
3511
3516
    uint32_t u32 = 0;
3512
3517
    int rc = IOMMMIORead((PVM)pvVM, GCPhys, &u32, 1);
3513
3518
    AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
3514
 
    Log2(("remR3MMIOReadU8: GCPhys=%RGp -> %02x\n", GCPhys, u32));
 
3519
    Log2(("remR3MMIOReadU8: GCPhys=%RGp -> %02x\n", (RTGCPHYS)GCPhys, u32));
3515
3520
    return u32;
3516
3521
}
3517
3522
 
3521
3526
    uint32_t u32 = 0;
3522
3527
    int rc = IOMMMIORead((PVM)pvVM, GCPhys, &u32, 2);
3523
3528
    AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
3524
 
    Log2(("remR3MMIOReadU16: GCPhys=%RGp -> %04x\n", GCPhys, u32));
 
3529
    Log2(("remR3MMIOReadU16: GCPhys=%RGp -> %04x\n", (RTGCPHYS)GCPhys, u32));
3525
3530
    return u32;
3526
3531
}
3527
3532
 
3531
3536
    uint32_t u32 = 0;
3532
3537
    int rc = IOMMMIORead((PVM)pvVM, GCPhys, &u32, 4);
3533
3538
    AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
3534
 
    Log2(("remR3MMIOReadU32: GCPhys=%RGp -> %08x\n", GCPhys, u32));
 
3539
    Log2(("remR3MMIOReadU32: GCPhys=%RGp -> %08x\n", (RTGCPHYS)GCPhys, u32));
3535
3540
    return u32;
3536
3541
}
3537
3542
 
3539
3544
static void     remR3MMIOWriteU8(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
3540
3545
{
3541
3546
    int rc;
3542
 
    Log2(("remR3MMIOWriteU8: GCPhys=%RGp u32=%#x\n", GCPhys, u32));
 
3547
    Log2(("remR3MMIOWriteU8: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
3543
3548
    rc = IOMMMIOWrite((PVM)pvVM, GCPhys, u32, 1);
3544
3549
    AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
3545
3550
}
3548
3553
static void     remR3MMIOWriteU16(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
3549
3554
{
3550
3555
    int rc;
3551
 
    Log2(("remR3MMIOWriteU16: GCPhys=%RGp u32=%#x\n", GCPhys, u32));
 
3556
    Log2(("remR3MMIOWriteU16: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
3552
3557
    rc = IOMMMIOWrite((PVM)pvVM, GCPhys, u32, 2);
3553
3558
    AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
3554
3559
}
3557
3562
static void     remR3MMIOWriteU32(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
3558
3563
{
3559
3564
    int rc;
3560
 
    Log2(("remR3MMIOWriteU32: GCPhys=%RGp u32=%#x\n", GCPhys, u32));
 
3565
    Log2(("remR3MMIOWriteU32: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
3561
3566
    rc = IOMMMIOWrite((PVM)pvVM, GCPhys, u32, 4);
3562
3567
    AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
3563
3568
}
3571
3576
static uint32_t remR3HandlerReadU8(void *pvVM, target_phys_addr_t GCPhys)
3572
3577
{
3573
3578
    uint8_t u8;
3574
 
    Log2(("remR3HandlerReadU8: GCPhys=%RGp\n", GCPhys));
 
3579
    Log2(("remR3HandlerReadU8: GCPhys=%RGp\n", (RTGCPHYS)GCPhys));
3575
3580
    PGMPhysRead((PVM)pvVM, GCPhys, &u8, sizeof(u8));
3576
3581
    return u8;
3577
3582
}
3579
3584
static uint32_t remR3HandlerReadU16(void *pvVM, target_phys_addr_t GCPhys)
3580
3585
{
3581
3586
    uint16_t u16;
3582
 
    Log2(("remR3HandlerReadU16: GCPhys=%RGp\n", GCPhys));
 
3587
    Log2(("remR3HandlerReadU16: GCPhys=%RGp\n", (RTGCPHYS)GCPhys));
3583
3588
    PGMPhysRead((PVM)pvVM, GCPhys, &u16, sizeof(u16));
3584
3589
    return u16;
3585
3590
}
3587
3592
static uint32_t remR3HandlerReadU32(void *pvVM, target_phys_addr_t GCPhys)
3588
3593
{
3589
3594
    uint32_t u32;
3590
 
    Log2(("remR3HandlerReadU32: GCPhys=%RGp\n", GCPhys));
 
3595
    Log2(("remR3HandlerReadU32: GCPhys=%RGp\n", (RTGCPHYS)GCPhys));
3591
3596
    PGMPhysRead((PVM)pvVM, GCPhys, &u32, sizeof(u32));
3592
3597
    return u32;
3593
3598
}
3594
3599
 
3595
3600
static void     remR3HandlerWriteU8(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
3596
3601
{
3597
 
    Log2(("remR3HandlerWriteU8: GCPhys=%RGp u32=%#x\n", GCPhys, u32));
 
3602
    Log2(("remR3HandlerWriteU8: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
3598
3603
    PGMPhysWrite((PVM)pvVM, GCPhys, &u32, sizeof(uint8_t));
3599
3604
}
3600
3605
 
3601
3606
static void     remR3HandlerWriteU16(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
3602
3607
{
3603
 
    Log2(("remR3HandlerWriteU16: GCPhys=%RGp u32=%#x\n", GCPhys, u32));
 
3608
    Log2(("remR3HandlerWriteU16: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
3604
3609
    PGMPhysWrite((PVM)pvVM, GCPhys, &u32, sizeof(uint16_t));
3605
3610
}
3606
3611
 
3607
3612
static void     remR3HandlerWriteU32(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
3608
3613
{
3609
 
    Log2(("remR3HandlerWriteU32: GCPhys=%RGp u32=%#x\n", GCPhys, u32));
 
3614
    Log2(("remR3HandlerWriteU32: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
3610
3615
    PGMPhysWrite((PVM)pvVM, GCPhys, &u32, sizeof(uint32_t));
3611
3616
}
3612
3617
 
3721
3726
     * Disassemble to log.
3722
3727
     */
3723
3728
    if (fLog)
3724
 
        rc = DBGFR3DisasInstrCurrentLogInternal(env->pVCpu, pszPrefix);
 
3729
    {
 
3730
        PVMCPU  pVCpu = VMMGetCpu(pVM);
 
3731
        char    szBuf[256];
 
3732
        szBuf[0] = '\0';
 
3733
        int rc = DBGFR3DisasInstrEx(pVCpu->pVMR3,
 
3734
                                    pVCpu->idCpu,
 
3735
                                    0, /* Sel */
 
3736
                                    0, /* GCPtr */
 
3737
                                    DBGF_DISAS_FLAGS_CURRENT_GUEST
 
3738
                                    | DBGF_DISAS_FLAGS_DEFAULT_MODE
 
3739
                                    | DBGF_DISAS_FLAGS_HID_SEL_REGS_VALID,
 
3740
                                    szBuf,
 
3741
                                    sizeof(szBuf),
 
3742
                                    NULL);
 
3743
        if (RT_FAILURE(rc))
 
3744
            RTStrPrintf(szBuf, sizeof(szBuf), "DBGFR3DisasInstrEx failed with rc=%Rrc\n", rc);
 
3745
        if (pszPrefix && *pszPrefix)
 
3746
            RTLogPrintf("%s-CPU%d: %s\n", pszPrefix, pVCpu->idCpu, szBuf);
 
3747
        else
 
3748
            RTLogPrintf("CPU%d: %s\n", pVCpu->idCpu, szBuf);
 
3749
    }
3725
3750
 
3726
3751
    return RT_SUCCESS(rc);
3727
3752
}
3764
3789
            {
3765
3790
                DISAS_PRINTF("disas error\n");
3766
3791
                cbInstr = 1;
3767
 
#ifdef RT_ARCH_AMD64 /** @todo remove when DISInstr starts supporing 64-bit code. */
 
3792
#ifdef RT_ARCH_AMD64 /** @todo remove when DISInstr starts supporting 64-bit code. */
3768
3793
                break;
3769
3794
#endif
3770
3795
            }
3819
3844
                                        pVCpu->idCpu,
3820
3845
                                        cs,
3821
3846
                                        eip,
3822
 
                                        0,
 
3847
                                        DBGF_DISAS_FLAGS_DEFAULT_MODE,
3823
3848
                                        szBuf, sizeof(szBuf),
3824
3849
                                        &cbInstr);
3825
3850
            if (RT_SUCCESS(rc))
3945
3970
 * @param   pVM             VM Handle.
3946
3971
 * @param   pVCpuDst        The target cpu for this notification.
3947
3972
 *                          TM will not broadcast pending timer events, but use
3948
 
 *                          a decidated EMT for them. So, only interrupt REM
 
3973
 *                          a dedicated EMT for them. So, only interrupt REM
3949
3974
 *                          execution if the given CPU is executing in REM.
3950
3975
 * @thread  Any.
3951
3976
 */
4139
4164
     * In that case we can't call PDMGetInterrupt anymore, because it has already cleared the interrupt
4140
4165
     * with the (a)pic.
4141
4166
     */
4142
 
    /** @note We assume we will go directly to the recompiler to handle the pending interrupt! */
 
4167
    /* Note! We assume we will go directly to the recompiler to handle the pending interrupt! */
4143
4168
    /** @todo r=bird: In the long run we should just do the interrupt handling in EM/CPUM/TRPM/somewhere and
4144
4169
     * if we cannot execute the interrupt handler in raw-mode just reschedule to REM. Once that is done we
4145
4170
     * remove this kludge. */
4153
4178
    else
4154
4179
        rc = PDMGetInterrupt(env->pVCpu, &u8Interrupt);
4155
4180
 
4156
 
    LogFlow(("cpu_get_pic_interrupt: u8Interrupt=%d rc=%Rrc\n", u8Interrupt, rc));
 
4181
    LogFlow(("cpu_get_pic_interrupt: u8Interrupt=%d rc=%Rrc pc=%04x:%08llx ~flags=%08llx\n",
 
4182
             u8Interrupt, rc, env->segs[R_CS].selector, (uint64_t)env->eip, (uint64_t)env->eflags));
4157
4183
    if (RT_SUCCESS(rc))
4158
4184
    {
4159
4185
        if (VMCPU_FF_ISPENDING(env->pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
4166
4192
 
4167
4193
/* -+- local apic -+- */
4168
4194
 
 
4195
#if 0 /* CPUMSetGuestMsr does this now. */
4169
4196
void cpu_set_apic_base(CPUX86State *env, uint64_t val)
4170
4197
{
4171
4198
    int rc = PDMApicSetBase(env->pVM, val);
4172
4199
    LogFlow(("cpu_set_apic_base: val=%#llx rc=%Rrc\n", val, rc)); NOREF(rc);
4173
4200
}
 
4201
#endif
4174
4202
 
4175
4203
uint64_t cpu_get_apic_base(CPUX86State *env)
4176
4204
{
4204
4232
    return 0;
4205
4233
}
4206
4234
 
4207
 
 
4208
 
uint64_t cpu_apic_rdmsr(CPUX86State *env, uint32_t reg)
4209
 
{
4210
 
    uint64_t value;
4211
 
    int rc = PDMApicReadMSR(env->pVM, 0/* cpu */, reg, &value);
4212
 
    if (RT_SUCCESS(rc))
4213
 
    {
4214
 
        LogFlow(("cpu_apic_rdms returns %#x\n", value));
4215
 
        return value;
4216
 
    }
4217
 
    /** @todo: exception ? */
4218
 
    LogFlow(("cpu_apic_rdms returns 0 (rc=%Rrc)\n", rc));
4219
 
    return value;
4220
 
}
4221
 
 
4222
 
void     cpu_apic_wrmsr(CPUX86State *env, uint32_t reg, uint64_t value)
4223
 
{
4224
 
    int rc = PDMApicWriteMSR(env->pVM, 0 /* cpu */, reg, value);
4225
 
    /** @todo: exception if error ? */
4226
 
    LogFlow(("cpu_apic_wrmsr: rc=%Rrc\n", rc)); NOREF(rc);
4227
 
}
4228
 
 
4229
 
uint64_t cpu_rdmsr(CPUX86State *env, uint32_t msr)
4230
 
{
4231
 
    Assert(env->pVCpu);
4232
 
    return CPUMGetGuestMsr(env->pVCpu, msr);
4233
 
}
4234
 
 
4235
 
void cpu_wrmsr(CPUX86State *env, uint32_t msr, uint64_t val)
4236
 
{
4237
 
    Assert(env->pVCpu);
4238
 
    CPUMSetGuestMsr(env->pVCpu, msr, val);
 
4235
/**
 
4236
 * Read an MSR.
 
4237
 *
 
4238
 * @retval 0 success.
 
4239
 * @retval -1 failure, raise \#GP(0).
 
4240
 * @param   env     The cpu state.
 
4241
 * @param   idMsr   The MSR to read.
 
4242
 * @param   puValue Where to return the value.
 
4243
 */
 
4244
int cpu_rdmsr(CPUX86State *env, uint32_t idMsr, uint64_t *puValue)
 
4245
{
 
4246
    Assert(env->pVCpu);
 
4247
    return CPUMQueryGuestMsr(env->pVCpu, idMsr, puValue) == VINF_SUCCESS ? 0 : -1;
 
4248
}
 
4249
 
 
4250
/**
 
4251
 * Write to an MSR.
 
4252
 *
 
4253
 * @retval 0 success.
 
4254
 * @retval -1 failure, raise \#GP(0).
 
4255
 * @param   env     The cpu state.
 
4256
 * @param   idMsr   The MSR to read.
 
4257
 * @param   puValue Where to return the value.
 
4258
 */
 
4259
int cpu_wrmsr(CPUX86State *env, uint32_t idMsr, uint64_t uValue)
 
4260
{
 
4261
    Assert(env->pVCpu);
 
4262
    return CPUMSetGuestMsr(env->pVCpu, idMsr, uValue) == VINF_SUCCESS ? 0 : -1;
4239
4263
}
4240
4264
 
4241
4265
/* -+- I/O Ports -+- */
4474
4498
 * Aborts the VM.
4475
4499
 *
4476
4500
 * @param   rc      VBox error code.
4477
 
 * @param   pszTip  Hint about why/when this happend.
 
4501
 * @param   pszTip  Hint about why/when this happened.
4478
4502
 */
4479
4503
void remAbort(int rc, const char *pszTip)
4480
4504
{