VirtualBox

Changeset 44626 in vbox for trunk


Ignore:
Timestamp:
Feb 11, 2013 10:52:19 AM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
83713
Message:

DevAPIC.cpp,++: Changed the APIC MMIO registrations to let IOM handle the weird access work. Some cleanups elsewhere.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/iom.h

    r44573 r44626  
    119119/** All write accesses are DWORD (32-bit) sized and aligned, attempts at other
    120120 * accesses are ignored.
    121  * @remarks E1000 */
     121 * @remarks E1000, APIC */
    122122#define IOMMMIO_FLAGS_WRITE_ONLY_DWORD                  UINT32_C(0x00000050)
    123123/** All write accesses are DWORD (32-bit) or QWORD (64-bit) sized and aligned,
  • trunk/src/VBox/Devices/PC/DevACPI.cpp

    r44514 r44626  
    17201720    R(PM1a_EVT_OFFSET,   1, acpiR3PM1aStsWrite,      acpiR3Pm1aStsRead,     "ACPI PM1a Status");
    17211721    R(PM1a_CTL_OFFSET,   1, acpiR3PM1aCtlWrite,      acpiR3Pm1aCtlRead,     "ACPI PM1a Control");
    1722     R(PM_TMR_OFFSET,     1, NULL,                  acpiPMTmrRead,       "ACPI PM Timer");
     1722    R(PM_TMR_OFFSET,     1, NULL,                    acpiPMTmrRead,         "ACPI PM Timer");
    17231723    R(GPE0_OFFSET + L,   L, acpiR3Gpe0EnWrite,       acpiR3Gpe0EnRead,      "ACPI GPE0 Enable");
    17241724    R(GPE0_OFFSET,       L, acpiR3Gpe0StsWrite,      acpiR3Gpe0StsRead,     "ACPI GPE0 Status");
  • trunk/src/VBox/Devices/PC/DevAPIC.cpp

    r44515 r44626  
    18121812    APICState *pApic = apicGetStateByCurEmt(pDev);
    18131813
    1814     Log(("CPU%d: apicMMIORead at %llx\n", pApic->phys_id,  (uint64_t)GCPhysAddr));
     1814    Log(("CPU%d: apicMMIORead at %RGp\n", pApic->phys_id, GCPhysAddr));
     1815    Assert(cb == 4);
    18151816
    18161817    /** @todo add LAPIC range validity checks (different LAPICs can
     
    18181819
    18191820    STAM_COUNTER_INC(&CTXSUFF(pDev->StatMMIORead));
    1820     switch (cb)
    1821     {
    1822         case 1:
    1823             /** @todo this is not how recent APIC behave!  We will fix
    1824              *        this via the IOM. */
    1825             *(uint8_t *)pv = 0;
    1826             break;
    1827 
    1828         case 2:
    1829             /** @todo this is not how recent APIC behave! */
    1830             *(uint16_t *)pv = 0;
    1831             break;
    1832 
    1833         case 4:
    1834         {
    18351821#if 0 /* Note! experimental */
    18361822#ifndef IN_RING3
    1837             uint32_t index = (GCPhysAddr >> 4) & 0xff;
    1838 
    1839             if (    index == 0x08 /* TPR */
    1840                 &&  ++pApic->cTPRPatchAttempts < APIC_MAX_PATCH_ATTEMPTS)
    1841             {
    1842 #ifdef IN_RC
    1843                 pDevIns->pDevHlpGC->pfnPATMSetMMIOPatchInfo(pDevIns, GCPhysAddr, &pApic->tpr);
    1844 #else
    1845                 RTGCPTR pDevInsGC = PDMINS2DATA_GCPTR(pDevIns);
    1846                 pDevIns->pHlpR0->pfnPATMSetMMIOPatchInfo(pDevIns, GCPhysAddr, pDevIns + RT_OFFSETOF(APICState, tpr));
    1847 #endif
    1848                 return VINF_PATM_HC_MMIO_PATCH_READ;
    1849             }
     1823    uint32_t index = (GCPhysAddr >> 4) & 0xff;
     1824
     1825    if (    index == 0x08 /* TPR */
     1826        &&  ++pApic->cTPRPatchAttempts < APIC_MAX_PATCH_ATTEMPTS)
     1827    {
     1828# ifdef IN_RC
     1829        pDevIns->pDevHlpGC->pfnPATMSetMMIOPatchInfo(pDevIns, GCPhysAddr, &pApic->tpr);
     1830# else
     1831        RTGCPTR pDevInsGC = PDMINS2DATA_GCPTR(pDevIns);
     1832        pDevIns->pHlpR0->pfnPATMSetMMIOPatchInfo(pDevIns, GCPhysAddr, pDevIns + RT_OFFSETOF(APICState, tpr));
     1833# endif
     1834        return VINF_PATM_HC_MMIO_PATCH_READ;
     1835    }
    18501836#endif
    18511837#endif /* experimental */
    18521838
    1853             /* It does its own locking. */
    1854             uint64_t u64Value = 0;
    1855             int rc = apicReadRegister(pDev, pApic, (GCPhysAddr >> 4) & 0xff, &u64Value,
    1856                                       VINF_IOM_R3_MMIO_READ, false /*fMsr*/);
    1857             *(uint32_t *)pv = (uint32_t)u64Value;
    1858             return rc;
    1859         }
    1860 
    1861         default:
    1862             AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
    1863             return VERR_INTERNAL_ERROR;
    1864     }
    1865     return VINF_SUCCESS;
     1839    /* Note! apicReadRegister does its own locking. */
     1840    uint64_t u64Value = 0;
     1841    int rc = apicReadRegister(pDev, pApic, (GCPhysAddr >> 4) & 0xff, &u64Value, VINF_IOM_R3_MMIO_READ, false /*fMsr*/);
     1842    *(uint32_t *)pv = (uint32_t)u64Value;
     1843    return rc;
    18661844}
    18671845
     
    18711849    APICState *pApic = apicGetStateByCurEmt(pDev);
    18721850
    1873     Log(("CPU%d: apicMMIOWrite at %llx\n", pApic->phys_id, (uint64_t)GCPhysAddr));
     1851    Log(("CPU%d: apicMMIOWrite at %RGp\n", pApic->phys_id, GCPhysAddr));
     1852    Assert(cb == 4);
    18741853
    18751854    /** @todo: add LAPIC range validity checks (multiple LAPICs can theoretically have
     
    18771856
    18781857    STAM_COUNTER_INC(&CTXSUFF(pDev->StatMMIOWrite));
    1879     switch (cb)
    1880     {
    1881         case 1:
    1882         case 2:
    1883             /* ignore */
    1884             break;
    1885 
    1886         case 4:
    1887             /* It does its own locking. */
    1888             return apicWriteRegister(pDev, pApic, (GCPhysAddr >> 4) & 0xff, *(uint32_t const *)pv,
    1889                                      VINF_IOM_R3_MMIO_WRITE, false /*fMsr*/);
    1890 
    1891         default:
    1892             AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
    1893             return VERR_INTERNAL_ERROR;
    1894     }
    1895     return VINF_SUCCESS;
     1858    /* Note! It does its own locking. */
     1859    return apicWriteRegister(pDev, pApic, (GCPhysAddr >> 4) & 0xff, *(uint32_t const *)pv,
     1860                             VINF_IOM_R3_MMIO_WRITE, false /*fMsr*/);
    18961861}
    18971862
     
    23812346    uint32_t ApicBase = pDev->paLapicsR3[0].apicbase & ~0xfff;
    23822347    rc = PDMDevHlpMMIORegister(pDevIns, ApicBase, 0x1000, pDev,
    2383                                IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
     2348                               IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_ONLY_DWORD,
    23842349                               apicMMIOWrite, apicMMIORead, "APIC Memory");
    23852350    if (RT_FAILURE(rc))
  • trunk/src/VBox/ExtPacks/BusMouseSample/BusMouse.cpp

    r44514 r44626  
    124124typedef struct MouState
    125125{
    126     /* 8255A state */
     126    /** @name 8255A state
     127     * @{ */
    127128    uint8_t         port_a;
    128129    uint8_t         port_b;
     
    138139    /** Timer period in milliseconds. */
    139140    uint32_t        cTimerPeriodMs;
    140     /* mouse state */
     141    /** @} */
     142
     143    /** @name mouse state
     144     * @{ */
    141145    int32_t         disable_counter;
    142146    uint8_t         mouse_enabled;
     
    145149    uint8_t         mouse_buttons;
    146150    uint8_t         mouse_buttons_reported;
     151    /** @}  */
    147152
    148153    /** Pointer to the device instance - RC. */
     
    348353}
    349354
    350 static int bms_write_port(MouState *pThis, uint32_t addr, uint32_t val)
     355static int bms_write_port(MouState *pThis, uint32_t offPort, uint32_t uValue)
    351356{
    352357    int rc = VINF_SUCCESS;
    353358
    354     LogRel3(("%s: write port %d: 0x%02x\n", __PRETTY_FUNCTION__, addr, val));
    355 
    356     switch(addr) {
    357     case BMS_PORT_SIG:
    358         /* Update port B. */
    359         pThis->port_b = val;
    360         break;
    361     case BMS_PORT_DATA:
    362         /* Do nothing, port A is not writable. */
    363         break;
    364     case BMS_PORT_INIT:
    365         pThis->ctrl_port = val;
    366         break;
    367     case BMS_PORT_CTRL:
    368         /* Update the high nibble of port C. */
    369         pThis->port_c = (val & 0xF0) | (pThis->port_c & 0x0F);
    370         bms_update_ctrl(pThis);
    371         break;
    372     default:
    373         AssertMsgFailed(("invalid port %#x\n", addr));
    374         break;
     359    LogRel3(("%s: write port %d: 0x%02x\n", __PRETTY_FUNCTION__, offPort, uValue));
     360
     361    switch (offPort)
     362    {
     363        case BMS_PORT_SIG:
     364            /* Update port B. */
     365            pThis->port_b = uValue;
     366            break;
     367        case BMS_PORT_DATA:
     368            /* Do nothing, port A is not writable. */
     369            break;
     370        case BMS_PORT_INIT:
     371            pThis->ctrl_port = uValue;
     372            break;
     373        case BMS_PORT_CTRL:
     374            /* Update the high nibble of port C. */
     375            pThis->port_c = (uValue & 0xF0) | (pThis->port_c & 0x0F);
     376            bms_update_ctrl(pThis);
     377            break;
     378        default:
     379            AssertMsgFailed(("invalid port %#x\n", offPort));
     380            break;
    375381    }
    376382    return rc;
    377383}
    378384
    379 static uint32_t bms_read_port(MouState *pThis, uint32_t addr)
    380 {
    381     uint32_t val;
    382 
    383     switch(addr) {
    384     case BMS_PORT_DATA:
    385         /* Read port A. */
    386         val = pThis->port_a;
    387         break;
    388     case BMS_PORT_SIG:
    389         /* Read port B. */
    390         val = pThis->port_b;
    391         break;
    392     case BMS_PORT_CTRL:
    393         /* Read port C. */
    394         val = pThis->port_c;
    395         /* Some Microsoft driver code reads the control port 10,000 times when
    396          * determining the IRQ level. This can occur faster than the IRQ line
    397          * transitions and the detection fails. To work around this, we force
    398          * the IRQ bit to toggle every once in a while.
    399          */
    400         if (pThis->irq_toggle_counter)
    401             pThis->irq_toggle_counter--;
    402         else
    403         {
    404             pThis->irq_toggle_counter = 1000;
    405             val ^= BMS_IRQ_BIT(pThis->irq);
    406         }
    407         break;
    408     case BMS_PORT_INIT:
    409         /* Read the 8255A control port. */
    410         val = pThis->ctrl_port;
    411         break;
    412     default:
    413         AssertMsgFailed(("invalid port %#x\n", addr));
    414         break;
    415     }
    416     LogRel3(("%s: read port %d: 0x%02x\n", __PRETTY_FUNCTION__, addr, val));
    417     return val;
     385static uint32_t bms_read_port(MouState *pThis, uint32_t offPort)
     386{
     387    uint32_t uValue;
     388
     389    switch (offPort)
     390    {
     391        case BMS_PORT_DATA:
     392            /* Read port A. */
     393            uValue = pThis->port_a;
     394            break;
     395        case BMS_PORT_SIG:
     396            /* Read port B. */
     397            uValue = pThis->port_b;
     398            break;
     399        case BMS_PORT_CTRL:
     400            /* Read port C. */
     401            uValue = pThis->port_c;
     402            /* Some Microsoft driver code reads the control port 10,000 times when
     403             * determining the IRQ level. This can occur faster than the IRQ line
     404             * transitions and the detection fails. To work around this, we force
     405             * the IRQ bit to toggle every once in a while.
     406             */
     407            if (pThis->irq_toggle_counter)
     408                pThis->irq_toggle_counter--;
     409            else
     410            {
     411                pThis->irq_toggle_counter = 1000;
     412                uValue ^= BMS_IRQ_BIT(pThis->irq);
     413            }
     414            break;
     415        case BMS_PORT_INIT:
     416            /* Read the 8255A control port. */
     417            uValue = pThis->ctrl_port;
     418            break;
     419        default:
     420            AssertMsgFailed(("invalid port %#x\n", offPort));
     421            break;
     422    }
     423    LogRel3(("%s: read port %d: 0x%02x\n", __PRETTY_FUNCTION__, offPort, uValue));
     424    return uValue;
    418425}
    419426
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette