VirtualBox

Changeset 11270 in vbox for trunk/src/VBox/Devices/Parallel


Ignore:
Timestamp:
Aug 8, 2008 4:56:16 PM (16 years ago)
Author:
vboxsync
Message:

#1865: DevParallel. Also fixed some serious GC/R0 alignment bugs and adding the thing to the testcase.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Parallel/DevParallel.cpp

    r11269 r11270  
    11/* $Id$ */
    22/** @file
    3  * VirtualBox Parallel Device Emulation.
     3 * DevParallel - Parallel (Port) Device Emulation.
    44 *
    55 * Contributed by: Alexander Eichner
     6 * Based on DevSerial.cpp
    67 */
    78
     
    2122 * additional information or have any questions.
    2223 */
    23 
    24 /* based on DevSerial.cpp */
    2524
    2625/*******************************************************************************
     
    3534#include <iprt/critsect.h>
    3635
    37 #include "Builtins.h"
     36#include "../Builtins.h"
    3837
    3938#define PARALLEL_SAVED_STATE_VERSION 1
     
    9291    PDMCRITSECT                         CritSect;
    9392
    94     /** Pointer to the device instance. */
    95     R3R0PTRTYPE(PPDMDEVINS)             pDevInsHC;
    96     /** Pointer to the device instance. */
    97     RCPTRTYPE(PPDMDEVINS)               pDevInsGC;
    98 #if HC_ARCH_BITS == 64 && GC_ARCH_BITS != 64
    99     RTGCPTR                             Alignment0;
    100 #endif
     93    /** Pointer to the device instance - R3 Ptr */
     94    PPDMDEVINSR3                        pDevInsR3;
     95    /** Pointer to the device instance - R0 Ptr */
     96    PPDMDEVINSR0                        pDevInsR0;
     97    /** Pointer to the device instance - RC Ptr */
     98    PPDMDEVINSRC                        pDevInsRC;
     99    RTRCPTR                             Alignment0; /**< Alignment. */
    101100    /** The base interface. */
    102     R3PTRTYPE(PDMIBASE)                 IBase;
     101    PDMIBASE                            IBase;
    103102    /** The host device port interface. */
    104     R3PTRTYPE(PDMIHOSTPARALLELPORT)     IHostParallelPort;
     103    PDMIHOSTPARALLELPORT                IHostParallelPort;
    105104    /** Pointer to the attached base driver. */
    106105    R3PTRTYPE(PPDMIBASE)                pDrvBase;
    107106    /** Pointer to the attached host device. */
    108107    R3PTRTYPE(PPDMIHOSTPARALLELCONNECTOR) pDrvHostParallelConnector;
     108    /** Unused event semaphore... */
     109    RTSEMEVENT                          ReceiveSem;
    109110
    110111    uint8_t                             reg_data;
     
    119120    /** The ECP FIFO implementation*/
    120121    uint8_t                             ecp_fifo[LPT_ECP_FIFO_DEPTH];
     122    uint8_t                             abAlignemnt[2];
    121123    int                                 act_fifo_pos_write;
    122124    int                                 act_fifo_pos_read;
     
    127129    bool                                fGCEnabled;
    128130    bool                                fR0Enabled;
    129     bool                                afAlignment[6];
    130 
    131     RTSEMEVENT                          ReceiveSem;
     131    bool                                afAlignment[1];
     132
    132133    uint32_t                            base;
    133134
     
    156157    {
    157158        Log(("parallel_update_irq %d 1\n", s->irq));
    158         PDMDevHlpISASetIrqNoWait(CTXSUFF(s->pDevIns), s->irq, 1);
     159        PDMDevHlpISASetIrqNoWait(s->CTX_SUFF(pDevIns), s->irq, 1);
    159160    }
    160161}
     
    163164{
    164165    Log(("parallel_update_irq %d 0\n", s->irq));
    165     PDMDevHlpISASetIrqNoWait(CTXSUFF(s->pDevIns), s->irq, 0);
     166    PDMDevHlpISASetIrqNoWait(s->CTX_SUFF(pDevIns), s->irq, 0);
    166167}
    167168#endif
     
    427428{
    428429    ParallelState *pThis = PDMINS_2_DATA(pDevIns, ParallelState *);
    429     int          rc = VINF_SUCCESS;
     430    int            rc = VINF_SUCCESS;
    430431
    431432    if (cb == 1)
     
    460461{
    461462    ParallelState *pThis = PDMINS_2_DATA(pDevIns, ParallelState *);
    462     int          rc = VINF_SUCCESS;
     463    int            rc = VINF_SUCCESS;
    463464
    464465    if (cb == 1)
     
    494495{
    495496    ParallelState *pThis = PDMINS_2_DATA(pDevIns, ParallelState *);
    496     int          rc = VINF_SUCCESS;
     497    int            rc = VINF_SUCCESS;
    497498
    498499    if (cb == 1)
     
    527528{
    528529    ParallelState *pThis = PDMINS_2_DATA(pDevIns, ParallelState *);
    529     int          rc = VINF_SUCCESS;
     530    int            rc = VINF_SUCCESS;
    530531
    531532    if (cb == 1)
     
    586587    if (u32Version != PARALLEL_SAVED_STATE_VERSION)
    587588    {
    588         AssertMsgFailed(("u32Version=%d\n", u32Version));
     589        AssertLogRelMsgFailed(("u32Version=%d\n", u32Version));
    589590        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    590591    }
     
    602603    if (u32 != ~0U)
    603604    {
    604         AssertMsgFailed(("u32=%#x expected ~0\n", u32));
     605        AssertLogRelMsgFailed(("u32=%#x expected ~0\n", u32));
    605606        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    606607    }
    607608
    608     pThis->pDevInsHC = pDevIns;
    609     pThis->pDevInsGC = PDMDEVINS_2_GCPTR(pDevIns);
     609    /* not necessary... but it doesn't harm. */
     610    pThis->pDevInsR3 = pDevIns;
     611    pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
     612    pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
    610613    return VINF_SUCCESS;
    611614}
     
    618621{
    619622    ParallelState *pThis = PDMINS_2_DATA(pDevIns, ParallelState *);
    620     pThis->pDevInsGC    += offDelta;
     623    pThis->pDevInsRC += offDelta;
    621624}
    622625
     
    674677{
    675678    int            rc;
    676     ParallelState  *pThis = PDMINS_2_DATA(pDevIns, ParallelState*);
    677     uint16_t       io_base;
    678     uint8_t        irq_lvl;
     679    ParallelState *pThis = PDMINS_2_DATA(pDevIns, ParallelState*);
    679680
    680681    Assert(iInstance < 4);
    681682
    682     pThis->pDevInsHC = pDevIns;
    683     pThis->pDevInsGC = PDMDEVINS_2_GCPTR(pDevIns);
    684 
    685683    /*
    686      * Validate configuration.
     684     * Init the data so parallelDestruct doesn't choke.
    687685     */
    688     if (!CFGMR3AreValuesValid(pCfgHandle, "IRQ\0IOBase\0GCEnabled\0R0Enabled\0"))
     686    pThis->pDevInsR3 = pDevIns;
     687    pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
     688    pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
     689    pThis->ReceiveSem = NIL_RTSEMEVENT;
     690
     691    /* IBase */
     692    pThis->IBase.pfnQueryInterface = parallelQueryInterface;
     693
     694    /* IHostParallelPort */
     695    pThis->IHostParallelPort.pfnNotifyInterrupt = parallelNotifyInterrupt;
     696
     697    /* Init parallel state */
     698    pThis->reg_data = 0;
     699    pThis->reg_ecp_ecr = LPT_ECP_ECR_CHIPMODE_COMPAT | LPT_ECP_ECR_FIFO_EMPTY;
     700    pThis->act_fifo_pos_read = 0;
     701    pThis->act_fifo_pos_write = 0;
     702
     703    /*
     704     * Validate and read the configuration.
     705     */
     706    if (!CFGMR3AreValuesValid(pCfgHandle, "IRQ\0" "IOBase\0" "GCEnabled\0" "R0Enabled\0"))
    689707        return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
    690708                                N_("Configuration error: Unknown config key"));
    691709
    692     rc = CFGMR3QueryBool(pCfgHandle, "GCEnabled", &pThis->fGCEnabled);
    693     if (rc == VERR_CFGM_VALUE_NOT_FOUND)
    694         pThis->fGCEnabled = true;
    695     else if (RT_FAILURE(rc))
     710    rc = CFGMR3QueryBoolDef(pCfgHandle, "GCEnabled", &pThis->fGCEnabled, true);
     711    if (RT_FAILURE(rc))
    696712        return PDMDEV_SET_ERROR(pDevIns, rc,
    697713                                N_("Configuration error: Failed to get the \"GCEnabled\" value"));
    698714
    699     rc = CFGMR3QueryBool(pCfgHandle, "R0Enabled", &pThis->fR0Enabled);
    700     if (rc == VERR_CFGM_VALUE_NOT_FOUND)
    701         pThis->fR0Enabled = true;
    702     else if (RT_FAILURE(rc))
     715    rc = CFGMR3QueryBoolDef(pCfgHandle, "R0Enabled", &pThis->fR0Enabled, true);
     716    if (RT_FAILURE(rc))
    703717        return PDMDEV_SET_ERROR(pDevIns, rc,
    704718                                N_("Configuration error: Failed to get the \"R0Enabled\" value"));
    705719
    706     /* IBase */
    707     pThis->IBase.pfnQueryInterface = parallelQueryInterface;
    708 
    709     /* IHostParallelPort */
    710     pThis->IHostParallelPort.pfnNotifyInterrupt = parallelNotifyInterrupt;
    711 
    712     rc = RTSemEventCreate(&pThis->ReceiveSem);
    713     AssertRC(rc);
     720    uint8_t irq_lvl;
     721    rc = CFGMR3QueryU8Def(pCfgHandle, "IRQ", &irq_lvl, 7);
     722    if (RT_FAILURE(rc))
     723        return PDMDEV_SET_ERROR(pDevIns, rc,
     724                                N_("Configuration error: Failed to get the \"IRQ\" value"));
     725
     726    uint16_t io_base;
     727    rc = CFGMR3QueryU16Def(pCfgHandle, "IOBase", &io_base, 0x378);
     728    if (RT_FAILURE(rc))
     729        return PDMDEV_SET_ERROR(pDevIns, rc,
     730                                N_("Configuration error: Failed to get the \"IOBase\" value"));
     731
     732    Log(("parallelConstruct instance %d iobase=%04x irq=%d\n", iInstance, io_base, irq_lvl));
     733
     734    pThis->irq = irq_lvl;
     735    pThis->base = io_base;
    714736
    715737    /*
    716      * Initialize critical section.
     738     * Initialize critical section and event semaphore.
    717739     * This must of course be done before attaching drivers or anything else which can call us back..
    718740     */
     
    723745        return rc;
    724746
    725     rc = CFGMR3QueryU8(pCfgHandle, "IRQ", &irq_lvl);
    726     if (rc == VERR_CFGM_VALUE_NOT_FOUND)
    727         irq_lvl = 7;
    728     else if (RT_FAILURE(rc))
    729         return PDMDEV_SET_ERROR(pDevIns, rc,
    730                                 N_("Configuration error: Failed to get the \"IRQ\" value"));
    731 
    732     rc = CFGMR3QueryU16(pCfgHandle, "IOBase", &io_base);
    733     if (rc == VERR_CFGM_VALUE_NOT_FOUND)
    734         io_base = 0x378;
    735     else if (RT_FAILURE(rc))
    736         return PDMDEV_SET_ERROR(pDevIns, rc,
    737                                 N_("Configuration error: Failed to get the \"IOBase\" value"));
    738 
    739     Log(("parallelConstruct instance %d iobase=%04x irq=%d\n", iInstance, io_base, irq_lvl));
    740 
    741     pThis->irq = irq_lvl;
    742     pThis->base = io_base;
    743 
    744     /* Init parallel state */
    745     pThis->reg_data = 0;
    746     pThis->reg_ecp_ecr = LPT_ECP_ECR_CHIPMODE_COMPAT | LPT_ECP_ECR_FIFO_EMPTY;
    747     pThis->act_fifo_pos_read = 0;
    748     pThis->act_fifo_pos_write = 0;
    749 
     747    rc = RTSemEventCreate(&pThis->ReceiveSem);
     748    if (RT_FAILURE(rc))
     749        return rc;
     750
     751    /*
     752     * Register the I/O ports and saved state.
     753     */
    750754    rc = PDMDevHlpIOPortRegister(pDevIns, io_base, 8, 0,
    751755                                 parallelIOPortWrite, parallelIOPortRead,
     
    792796#endif
    793797    }
    794 
    795     /* Attach the parallel port driver and get the interfaces. For now no run-time
    796      * changes are supported. */
    797     rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Parallel Host");
    798     if (RT_SUCCESS(rc))
    799     {
    800         pThis->pDrvHostParallelConnector = (PDMIHOSTPARALLELCONNECTOR *)pThis->pDrvBase->pfnQueryInterface(pThis->pDrvBase,
    801                                                                                                            PDMINTERFACE_HOST_PARALLEL_CONNECTOR);
    802         if (!pThis->pDrvHostParallelConnector)
    803         {
    804             AssertMsgFailed(("Configuration error: instance %d has no host parallel interface!\n", iInstance));
    805             return VERR_PDM_MISSING_INTERFACE;
    806         }
    807         /** @todo provide read notification interface!!!! */
    808     }
    809     else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
    810     {
    811         pThis->pDrvBase = NULL;
    812         pThis->pDrvHostParallelConnector = NULL;
    813         LogRel(("Parallel%d: no unit\n", iInstance));
    814     }
    815     else
    816     {
    817         AssertMsgFailed(("Parallel%d: Failed to attach to host driver. rc=%Vrc\n", iInstance, rc));
    818         return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
    819                                    N_("Parallel device %d cannot attach to host driver"), iInstance);
    820     }
    821 
    822     /* Set compatibility mode */
    823     pThis->pDrvHostParallelConnector->pfnSetMode(pThis->pDrvHostParallelConnector, PDM_PARALLEL_PORT_MODE_COMPAT);
    824     /* Get status of control register */
    825     pThis->pDrvHostParallelConnector->pfnReadControl(pThis->pDrvHostParallelConnector, &pThis->reg_control);
    826798
    827799    rc = PDMDevHlpSSMRegister(
     
    840812    if (RT_FAILURE(rc))
    841813        return rc;
     814
     815
     816    /*
     817     * Attach the parallel port driver and get the interfaces.
     818     * For now no run-time changes are supported.
     819     */
     820    rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Parallel Host");
     821    if (RT_SUCCESS(rc))
     822    {
     823        pThis->pDrvHostParallelConnector = (PDMIHOSTPARALLELCONNECTOR *)pThis->pDrvBase->pfnQueryInterface(pThis->pDrvBase,
     824                                                                                                           PDMINTERFACE_HOST_PARALLEL_CONNECTOR);
     825        if (!pThis->pDrvHostParallelConnector)
     826        {
     827            AssertMsgFailed(("Configuration error: instance %d has no host parallel interface!\n", iInstance));
     828            return VERR_PDM_MISSING_INTERFACE;
     829        }
     830        /** @todo provide read notification interface!!!! */
     831    }
     832    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     833    {
     834        pThis->pDrvBase = NULL;
     835        pThis->pDrvHostParallelConnector = NULL;
     836        LogRel(("Parallel%d: no unit\n", iInstance));
     837    }
     838    else
     839    {
     840        AssertMsgFailed(("Parallel%d: Failed to attach to host driver. rc=%Vrc\n", iInstance, rc));
     841        return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     842                                   N_("Parallel device %d cannot attach to host driver"), iInstance);
     843    }
     844
     845    /* Set compatibility mode */
     846    pThis->pDrvHostParallelConnector->pfnSetMode(pThis->pDrvHostParallelConnector, PDM_PARALLEL_PORT_MODE_COMPAT);
     847    /* Get status of control register */
     848    pThis->pDrvHostParallelConnector->pfnReadControl(pThis->pDrvHostParallelConnector, &pThis->reg_control);
    842849
    843850    return VINF_SUCCESS;
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