VirtualBox

Changeset 14830 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 30, 2008 9:03:02 AM (16 years ago)
Author:
vboxsync
Message:

DevPCI: field trivial I/O port accesses in R0/RC. (speeds up OS/2 boot as it does 3.6M register reads)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevPCI.cpp

    r14474 r14830  
    219219PDMBOTHCBDECL(void) pciSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel);
    220220PDMBOTHCBDECL(void) pcibridgeSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel);
     221PDMBOTHCBDECL(int)  pciIOPortAddressWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
     222PDMBOTHCBDECL(int)  pciIOPortAddressRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
     223PDMBOTHCBDECL(int)  pciIOPortDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
     224PDMBOTHCBDECL(int)  pciIOPortDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
    221225
    222226#ifdef IN_RING3
     
    239243#define PCI_MAX_LAT         0x3f    /* 8 bits */
    240244
     245
    241246#ifdef IN_RING3
    242 
    243 static void pci_addr_writel(PPCIGLOBALS pGlobals, uint32_t addr, uint32_t val)
    244 {
    245     pGlobals->uConfigReg = val;
    246 }
    247 
    248 static uint32_t pci_addr_readl(PPCIGLOBALS pGlobals, uint32_t addr)
    249 {
    250     return pGlobals->uConfigReg;
    251 }
    252247
    253248static void pci_update_mappings(PCIDevice *d)
     
    474469}
    475470
    476 static void pci_data_write(PPCIGLOBALS pGlobals, uint32_t addr, uint32_t val, int len)
    477 {
    478     PCIDevice *pci_dev;
     471#endif /* IN_RING3 */
     472
     473static int pci_data_write(PPCIGLOBALS pGlobals, uint32_t addr, uint32_t val, int len)
     474{
    479475    uint8_t iBus, iDevice;
    480476    uint32_t config_addr;
     
    483479
    484480    if (!(pGlobals->uConfigReg & (1 << 31))) {
    485         return;
     481        return VINF_SUCCESS;
    486482    }
    487483    if ((pGlobals->uConfigReg & 0x3) != 0) {
    488         return;
     484        return VINF_SUCCESS;
    489485    }
    490486    iBus = (pGlobals->uConfigReg >> 16) & 0xff;
     
    493489    if (iBus != 0)
    494490    {
    495         PPCIDEVICE pBridgeDevice = pciFindBridge(&pGlobals->PciBus, iBus);
    496         if (pBridgeDevice)
    497         {
    498             AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigWrite);
    499             pBridgeDevice->Int.s.pfnBridgeConfigWrite(pBridgeDevice->pDevIns, iBus, iDevice, config_addr, val, len);
     491        if (pGlobals->PciBus.cBridges)
     492        {
     493#ifdef IN_RING3 /** @todo do lookup in R0/RC too! */
     494            PPCIDEVICE pBridgeDevice = pciFindBridge(&pGlobals->PciBus, iBus);
     495            if (pBridgeDevice)
     496            {
     497                AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigWrite);
     498                pBridgeDevice->Int.s.pfnBridgeConfigWrite(pBridgeDevice->pDevIns, iBus, iDevice, config_addr, val, len);
     499            }
     500#else
     501            return VINF_IOM_HC_IOPORT_WRITE;
     502#endif
    500503        }
    501504    }
    502505    else
    503506    {
    504         pci_dev = pGlobals->PciBus.devices[iDevice];
    505         if (!pci_dev)
    506             return;
    507         Log(("pci_config_write: %s: addr=%02x val=%08x len=%d\n", pci_dev->name, config_addr, val, len));
    508         pci_dev->Int.s.pfnConfigWrite(pci_dev, config_addr, val, len);
    509     }
    510 }
    511 
    512 static uint32_t pci_data_read(PPCIGLOBALS pGlobals, uint32_t addr, int len)
     507        R3PTRTYPE(PCIDevice *) pci_dev = pGlobals->PciBus.devices[iDevice];
     508        if (pci_dev)
     509        {
     510#ifdef IN_RING3
     511            Log(("pci_config_write: %s: addr=%02x val=%08x len=%d\n", pci_dev->name, config_addr, val, len));
     512            pci_dev->Int.s.pfnConfigWrite(pci_dev, config_addr, val, len);
     513#else
     514            return VINF_IOM_HC_IOPORT_WRITE;
     515#endif
     516        }
     517    }
     518    return VINF_SUCCESS;
     519}
     520
     521static int pci_data_read(PPCIGLOBALS pGlobals, uint32_t addr, int len, uint32_t *pu32)
    513522{
    514523    uint8_t iBus, iDevice;
    515524    uint32_t config_addr;
    516     uint32_t val = 0xffffffff;
     525
     526    *pu32 = 0xffffffff;
    517527
    518528    if (!(pGlobals->uConfigReg & (1 << 31)))
    519         goto the_end;
     529        return VINF_SUCCESS;
    520530    if ((pGlobals->uConfigReg & 0x3) != 0)
    521         goto the_end;
     531        return VINF_SUCCESS;
    522532    iBus = (pGlobals->uConfigReg >> 16) & 0xff;
    523533    iDevice = (pGlobals->uConfigReg >> 8) & 0xff;
     
    525535    if (iBus != 0)
    526536    {
    527         PPCIDEVICE pBridgeDevice = pciFindBridge(&pGlobals->PciBus, iBus);
    528         if (pBridgeDevice)
    529         {
    530             AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigRead);
    531             val = pBridgeDevice->Int.s.pfnBridgeConfigRead(pBridgeDevice->pDevIns, iBus, iDevice, config_addr, len);
     537        if (pGlobals->PciBus.cBridges)
     538        {
     539#ifdef IN_RING3 /** @todo do lookup in R0/RC too! */
     540            PPCIDEVICE pBridgeDevice = pciFindBridge(&pGlobals->PciBus, iBus);
     541            if (pBridgeDevice)
     542            {
     543                AssertPtr(pBridgeDevice->Int.s.pfnBridgeConfigRead);
     544                *pu32 = pBridgeDevice->Int.s.pfnBridgeConfigRead(pBridgeDevice->pDevIns, iBus, iDevice, config_addr, len);
     545            }
     546#else
     547            return VINF_IOM_HC_IOPORT_READ;
     548#endif
    532549        }
    533550    }
    534551    else
    535552    {
    536         PCIDevice *pci_dev;
    537 
    538         pci_dev = pGlobals->PciBus.devices[iDevice];
    539         if (!pci_dev) {
    540             goto the_end;
    541         }
    542         val = pci_dev->Int.s.pfnConfigRead(pci_dev, config_addr, len);
    543         Log(("pci_config_read: %s: addr=%02x val=%08x len=%d\n", pci_dev->name, config_addr, val, len));
    544     }
    545 
    546  the_end:
    547     return val;
    548 }
    549 
    550 #endif /* IN_RING3 */
     553        R3PTRTYPE(PCIDevice *) pci_dev = pGlobals->PciBus.devices[iDevice];
     554        if (pci_dev)
     555        {
     556#ifdef IN_RING3
     557            *pu32 = pci_dev->Int.s.pfnConfigRead(pci_dev, config_addr, len);
     558            Log(("pci_config_read: %s: addr=%02x val=%08x len=%d\n", pci_dev->name, config_addr, *pu32, len));
     559#else
     560            return VINF_IOM_HC_IOPORT_READ;
     561#endif
     562        }
     563    }
     564
     565    return VINF_SUCCESS;
     566}
     567
    551568
    552569
     
    814831    pGlobals->uConfigReg = 0x80000000 | (uBus << 16) |
    815832        (uDevFn << 8) | addr;
    816     return pci_data_read(pGlobals, 0, 4);
     833    uint32_t u32Val;
     834    int rc = pci_data_read(pGlobals, 0, 4, &u32Val);
     835    AssertRC(rc);
     836    return u32Val;
    817837}
    818838
     
    821841    pGlobals->uConfigReg = 0x80000000 | (uBus << 16) |
    822842        (uDevFn << 8) | (addr & ~3);
    823     return pci_data_read(pGlobals, addr & 3, 2);
     843    uint32_t u32Val;
     844    int rc = pci_data_read(pGlobals, addr & 3, 2, &u32Val);
     845    AssertRC(rc);
     846    return u32Val;
    824847}
    825848
     
    828851    pGlobals->uConfigReg = 0x80000000 | (uBus << 16) |
    829852        (uDevFn << 8) | (addr & ~3);
    830     return pci_data_read(pGlobals, addr & 3, 1);
     853    uint32_t u32Val;
     854    int rc = pci_data_read(pGlobals, addr & 3, 1, &u32Val);
     855    AssertRC(rc);
     856    return u32Val;
    831857}
    832858
     
    10711097}
    10721098
     1099#endif /* IN_RING3 */
     1100
    10731101/* -=-=-=-=-=- wrappers -=-=-=-=-=- */
    10741102
     
    10841112 * @param   cb          The value size in bytes.
    10851113 */
    1086 static DECLCALLBACK(int) pciIOPortAddressWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
     1114PDMBOTHCBDECL(int) pciIOPortAddressWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
    10871115{
    10881116    Log(("pciIOPortAddressWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
     
    10901118    if (cb == 4)
    10911119    {
     1120        PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
    10921121        PCI_LOCK(pDevIns, VINF_IOM_HC_IOPORT_WRITE);
    1093         pci_addr_writel(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), Port, u32);
     1122        pThis->uConfigReg = u32;
    10941123        PCI_UNLOCK(pDevIns);
    10951124    }
     
    10981127    return VINF_SUCCESS;
    10991128}
     1129
    11001130
    11011131/**
     
    11101140 * @param   cb          Number of bytes read.
    11111141 */
    1112 static DECLCALLBACK(int) pciIOPortAddressRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
     1142PDMBOTHCBDECL(int) pciIOPortAddressRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
    11131143{
    11141144    NOREF(pvUser);
    11151145    if (cb == 4)
    11161146    {
     1147        PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
    11171148        PCI_LOCK(pDevIns, VINF_IOM_HC_IOPORT_READ);
    1118         *pu32 = pci_addr_readl(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), Port);
     1149        *pu32 = pThis->uConfigReg;
    11191150        PCI_UNLOCK(pDevIns);
    11201151        Log(("pciIOPortAddressRead: Port=%#x cb=%d -> %#x\n", Port, cb, *pu32));
     
    11391170 * @param   cb          The value size in bytes.
    11401171 */
    1141 static DECLCALLBACK(int) pciIOPortDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
     1172PDMBOTHCBDECL(int) pciIOPortDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
    11421173{
    11431174    Log(("pciIOPortDataWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
    11441175    NOREF(pvUser);
     1176    int rc = VINF_SUCCESS;
    11451177    if (!(Port % cb))
    11461178    {
    11471179        PCI_LOCK(pDevIns, VINF_IOM_HC_IOPORT_WRITE);
    1148         pci_data_write(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), Port, u32, cb);
     1180        rc = pci_data_write(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), Port, u32, cb);
    11491181        PCI_UNLOCK(pDevIns);
    11501182    }
    11511183    else
    11521184        AssertMsgFailed(("Write to port %#x u32=%#x cb=%d\n", Port, u32, cb));
    1153     return VINF_SUCCESS;
     1185    return rc;
    11541186}
    11551187
     
    11661198 * @param   cb          Number of bytes read.
    11671199 */
    1168 static DECLCALLBACK(int) pciIOPortDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
     1200PDMBOTHCBDECL(int) pciIOPortDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
    11691201{
    11701202    NOREF(pvUser);
     
    11721204    {
    11731205        PCI_LOCK(pDevIns, VINF_IOM_HC_IOPORT_READ);
    1174         *pu32 = pci_data_read(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), Port, cb);
     1206        int rc = pci_data_read(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), Port, cb, pu32);
    11751207        PCI_UNLOCK(pDevIns);
    1176         Log(("pciIOPortDataRead: Port=%#x cb=%#x -> %#x\n", Port, cb, *pu32));
    1177         return VINF_SUCCESS;
     1208        Log(("pciIOPortDataRead: Port=%#x cb=%#x -> %#x (%Rrc)\n", Port, cb, *pu32, rc));
     1209        return rc;
    11781210    }
    11791211    AssertMsgFailed(("Read from port %#x cb=%d\n", Port, cb));
     
    11811213}
    11821214
     1215#ifdef IN_RING3
    11831216
    11841217/**
     
    18261859    if (RT_FAILURE(rc))
    18271860        return rc;
     1861    if (fGCEnabled)
     1862    {
     1863        rc = PDMDevHlpIOPortRegisterGC(pDevIns, 0x0cf8, 1, NIL_RTGCPTR, "pciIOPortAddressWrite", "pciIOPortAddressRead", NULL, NULL, "i440FX (PCI)");
     1864        if (RT_FAILURE(rc))
     1865            return rc;
     1866        rc = PDMDevHlpIOPortRegisterGC(pDevIns, 0x0cfc, 4, NIL_RTGCPTR, "pciIOPortDataWrite", "pciIOPortDataRead", NULL, NULL, "i440FX (PCI)");
     1867        if (RT_FAILURE(rc))
     1868            return rc;
     1869    }
     1870    if (fR0Enabled)
     1871    {
     1872        rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x0cf8, 1, NIL_RTR0PTR, "pciIOPortAddressWrite", "pciIOPortAddressRead", NULL, NULL, "i440FX (PCI)");
     1873        if (RT_FAILURE(rc))
     1874            return rc;
     1875        rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x0cfc, 4, NIL_RTR0PTR, "pciIOPortDataWrite", "pciIOPortDataRead", NULL, NULL, "i440FX (PCI)");
     1876        if (RT_FAILURE(rc))
     1877            return rc;
     1878    }
     1879
    18281880    rc = PDMDevHlpSSMRegister(pDevIns, "pci", iInstance, VBOX_PCI_SAVED_STATE_VERSION, sizeof(*pBus),
    18291881                              NULL, pciSaveExec, NULL, NULL, pciLoadExec, NULL);
Note: See TracChangeset for help on using the changeset viewer.

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