VirtualBox

Changeset 26001 in vbox


Ignore:
Timestamp:
Jan 25, 2010 2:21:13 PM (15 years ago)
Author:
vboxsync
Message:

PDM,*: Redid the PDM structure versions. Check the instance and helper versions in every device and driver constructor.

Location:
trunk
Files:
55 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/pdmcommon.h

    r25891 r26001  
    4141 * @{
    4242 */
     43
     44/** Makes a PDM structure version out of an unique magic value and major &
     45 * minor version numbers.
     46 *
     47 * @returns 32-bit structure version number.
     48 *
     49 * @param   uMagic      16-bit magic value.  This must be unique.
     50 * @param   uMajor      12-bit major version number.  Structures with different
     51 *                      major numbers are not compatible.
     52 * @param   uMinor      4-bit minor version number.  When only the minor version
     53 *                      differs, the structures will be 100% backwards
     54 *                      compatible.
     55 */
     56#define PDM_VERSION_MAKE(uMagic, uMajor, uMinor) \
     57    ( ((uint32_t)(uMagic) << 16) | ((uint32_t)((uMajor) & 0xff) << 4) | ((uint32_t)((uMinor) & 0xf) << 0) )
     58
     59/** Checks if @a uVerMagic1 is compatible with @a uVerMagic2.
     60 *
     61 * @returns true / false.
     62 * @param   uVerMagic1  Typically the runtime version of the struct.  This must
     63 *                      have the same magic and major version as @a uVerMagic2
     64 *                      and the minor version must be greater or equal to that
     65 *                      of @a uVerMagic2.
     66 * @param   uVerMagic2  Typically the version the code was compiled against.
     67 *
     68 * @remarks The parameters will be referenced more than once.
     69 */
     70#define PDM_VERSION_ARE_COMPATIBLE(uVerMagic1, uVerMagic2) \
     71    (    (uVerMagic1) == (uVerMagic2) \
     72      || (   (uVerMagic1) >= (uVerMagic2) \
     73          && ((uVerMagic1) & UINT32_C(0xfffffff0)) == ((uVerMagic2) & UINT32_C(0xfffffff0)) ) \
     74    )
     75
    4376
    4477/** PDM Attach/Detach Callback Flags.
  • trunk/include/VBox/pdmdev.h

    r25995 r26001  
    44
    55/*
    6  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     6 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    305305
    306306/** Current DEVREG version number. */
    307 #define PDM_DEVREG_VERSION                      0xc0020000
     307#define PDM_DEVREG_VERSION                      PDM_VERSION_MAKE(0xffff, 1, 0)
    308308
    309309/** PDM Device Flags.
     
    519519
    520520/** Current PDMPCIBUSREG version number. */
    521 #define PDM_PCIBUSREG_VERSION   0xd0020000
     521#define PDM_PCIBUSREG_VERSION                   PDM_VERSION_MAKE(0xfffe, 1, 0)
    522522
    523523/**
     
    575575
    576576/** Current PDMPCIHLPR3 version number. */
    577 #define PDM_PCIHLPRC_VERSION  0xe1010000
     577#define PDM_PCIHLPRC_VERSION                    PDM_VERSION_MAKE(0xfffd, 1, 0)
    578578
    579579
     
    632632
    633633/** Current PDMPCIHLPR0 version number. */
    634 #define PDM_PCIHLPR0_VERSION  0xe1010000
     634#define PDM_PCIHLPR0_VERSION                    PDM_VERSION_MAKE(0xfffc, 1, 0)
    635635
    636636/**
     
    722722
    723723/** Current PDMPCIHLPR3 version number. */
    724 #define PDM_PCIHLPR3_VERSION  0xf1020000
     724#define PDM_PCIHLPR3_VERSION                    PDM_VERSION_MAKE(0xfffb, 1, 0)
    725725
    726726
     
    764764
    765765/** Current PDMPICREG version number. */
    766 #define PDM_PICREG_VERSION      0xe0020000
     766#define PDM_PICREG_VERSION                      PDM_VERSION_MAKE(0xfffa, 1, 0)
    767767
    768768/**
     
    815815
    816816/** Current PDMPICHLPRC version number. */
    817 #define PDM_PICHLPRC_VERSION  0xfc010000
     817#define PDM_PICHLPRC_VERSION                    PDM_VERSION_MAKE(0xfff9, 1, 0)
    818818
    819819
     
    867867
    868868/** Current PDMPICHLPR0 version number. */
    869 #define PDM_PICHLPR0_VERSION  0xfc010000
     869#define PDM_PICHLPR0_VERSION                    PDM_VERSION_MAKE(0xfff8, 1, 0)
    870870
    871871/**
     
    940940
    941941/** Current PDMPICHLPR3 version number. */
    942 #define PDM_PICHLPR3_VERSION  0xf0010000
     942#define PDM_PICHLPR3_VERSION                    PDM_VERSION_MAKE(0xfff7, 1, 0)
    943943
    944944
     
    11021102
    11031103/** Current PDMAPICREG version number. */
    1104 #define PDM_APICREG_VERSION     0x70010000
     1104#define PDM_APICREG_VERSION                     PDM_VERSION_MAKE(0xfff6, 1, 0)
    11051105
    11061106
     
    12091209
    12101210/** Current PDMAPICHLPRC version number. */
    1211 #define PDM_APICHLPRC_VERSION   0x60020000
     1211#define PDM_APICHLPRC_VERSION                   PDM_VERSION_MAKE(0xfff5, 1, 0)
    12121212
    12131213
     
    12791279
    12801280/** Current PDMAPICHLPR0 version number. */
    1281 #define PDM_APICHLPR0_VERSION   0x60020000
     1281#define PDM_APICHLPR0_VERSION                   PDM_VERSION_MAKE(0xfff4, 1, 0)
    12821282
    12831283/**
     
    13951395
    13961396/** Current PDMAPICHLP version number. */
    1397 #define PDM_APICHLPR3_VERSION  0xfd030000
     1397#define PDM_APICHLPR3_VERSION                   PDM_VERSION_MAKE(0xfff3, 1, 0)
    13981398
    13991399
     
    14251425
    14261426/** Current PDMAPICREG version number. */
    1427 #define PDM_IOAPICREG_VERSION     0x50010000
     1427#define PDM_IOAPICREG_VERSION                   PDM_VERSION_MAKE(0xfff2, 1, 0)
    14281428
    14291429
     
    14791479
    14801480/** Current PDMIOAPICHLPRC version number. */
    1481 #define PDM_IOAPICHLPRC_VERSION   0xfe010000
     1481#define PDM_IOAPICHLPRC_VERSION                 PDM_VERSION_MAKE(0xfff1, 1, 0)
    14821482
    14831483
     
    15331533
    15341534/** Current PDMIOAPICHLPR0 version number. */
    1535 #define PDM_IOAPICHLPR0_VERSION   0xfe010000
     1535#define PDM_IOAPICHLPR0_VERSION                 PDM_VERSION_MAKE(0xfff0, 1, 0)
    15361536
    15371537/**
     
    16081608
    16091609/** Current PDMIOAPICHLPR3 version number. */
    1610 #define PDM_IOAPICHLPR3_VERSION   0xff010000
     1610#define PDM_IOAPICHLPR3_VERSION                 PDM_VERSION_MAKE(0xffef, 1, 0)
    16111611
    16121612
     
    16611661
    16621662/** Current PDMHPETHLPRC version number. */
    1663 #define PDM_HPETHLPRC_VERSION  0xe1010000
     1663#define PDM_HPETHLPRC_VERSION                   PDM_VERSION_MAKE(0xffee, 1, 0)
    16641664
    16651665
     
    16991699
    17001700/** Current PDMHPETHLPR0 version number. */
    1701 #define PDM_HPETHLPR0_VERSION  0xe1010000
     1701#define PDM_HPETHLPR0_VERSION                   PDM_VERSION_MAKE(0xffed, 1, 0)
    17021702
    17031703/**
     
    17081708    /** Structure version. PDM_HPETHLP_VERSION defines the current version. */
    17091709    uint32_t                u32Version;
    1710 
    17111710
    17121711    /**
     
    17691768
    17701769/** Current PDMHPETHLPR3 version number. */
    1771 #define PDM_HPETHLPR3_VERSION  0x1e010000
     1770#define PDM_HPETHLPR3_VERSION                   PDM_VERSION_MAKE(0xffec, 1, 0)
     1771
    17721772
    17731773
     
    18591859
    18601860/** Current PDMDMACREG version number. */
    1861 #define PDM_DMACREG_VERSION     0xf5010000
     1861#define PDM_DMACREG_VERSION                     PDM_VERSION_MAKE(0xffeb, 1, 0)
    18621862
    18631863
     
    18791879
    18801880/** Current PDMDMACHLP version number. */
    1881 #define PDM_DMACHLP_VERSION  0xf6010000
     1881#define PDM_DMACHLP_VERSION                     PDM_VERSION_MAKE(0xffea, 1, 0)
    18821882
    18831883#endif /* IN_RING3 */
     
    19211921
    19221922/** Current PDMRTCREG version number. */
    1923 #define PDM_RTCREG_VERSION     0xfa010000
     1923#define PDM_RTCREG_VERSION                      PDM_VERSION_MAKE(0xffe9, 1, 0)
    19241924
    19251925
     
    19411941
    19421942/** Current PDMRTCHLP version number. */
    1943 #define PDM_RTCHLP_VERSION  0xf6010000
     1943#define PDM_RTCHLP_VERSION                      PDM_VERSION_MAKE(0xffe8, 1, 0)
    19441944
    19451945
     
    31183118
    31193119/** Current PDMDEVHLP version number. */
    3120 #define PDM_DEVHLP_VERSION  0xf20c0001
     3120#define PDM_DEVHLP_VERSION                      PDM_VERSION_MAKE(0xffe7, 1, 0)
    31213121
    31223122
     
    32643264
    32653265/** Current PDMDEVHLP version number. */
    3266 #define PDM_DEVHLPRC_VERSION  0xfb020000
     3266#define PDM_DEVHLPRC_VERSION                    PDM_VERSION_MAKE(0xffe6, 1, 0)
    32673267
    32683268
     
    34183418
    34193419/** Current PDMDEVHLP version number. */
    3420 #define PDM_DEVHLPR0_VERSION  0xfb030000
     3420#define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 1, 0)
    34213421
    34223422
     
    34753475
    34763476/** Current PDMDEVINS version number. */
    3477 #define PDM_DEVINS_VERSION  0xf3020000
     3477#define PDM_DEVINS_VERSION                      PDM_VERSION_MAKE(0xffe4, 1, 0)
    34783478
    34793479/** Converts a pointer to the PDMDEVINS::IBase to a pointer to PDMDEVINS. */
    34803480#define PDMIBASE_2_PDMDEV(pInterface) ( (PPDMDEVINS)((char *)(pInterface) - RT_OFFSETOF(PDMDEVINS, IBase)) )
    34813481
     3482/**
     3483 * Checks the structure versions of the device instance and device helpers,
     3484 * returning if they are incompatible.
     3485 *
     3486 * This is for use in the constructor.
     3487 *
     3488 * @param   pDevIns     The device instance pointer.
     3489 */
     3490#define PDMDEV_CHECK_VERSIONS_RETURN(pDevIns) \
     3491    do \
     3492    { \
     3493        PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
     3494        AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION), \
     3495                              ("DevIns=%#x  mine=%#x\n", (pDevIns)->u32Version, PDM_DEVINS_VERSION), \
     3496                              VERR_VERSION_MISMATCH); \
     3497        AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->pDevHlpR3->u32Version, PDM_DEVHLP_VERSION), \
     3498                              ("DevHlp=%#x  mine=%#x\n", (pDevIns)->pDevHlpR3->u32Version, PDM_DEVHLP_VERSION), \
     3499                              VERR_VERSION_MISMATCH); \
     3500    } while (0)
     3501
     3502/**
     3503 * Quietly checks the structure versions of the device instance and device
     3504 * helpers, returning if they are incompatible.
     3505 *
     3506 * This is for use in the destructor.
     3507 *
     3508 * @param   pDevIns     The device instance pointer.
     3509 */
     3510#define PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns) \
     3511    do \
     3512    { \
     3513        PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
     3514        if (RT_UNLIKELY(   !PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION) \
     3515                        || !PDM_VERSION_ARE_COMPATIBLE((pDevIns)->pDevHlpR3->u32Version, PDM_DEVHLP_VERSION) )) \
     3516            return VERR_VERSION_MISMATCH; \
     3517    } while (0)
    34823518
    34833519/** @def PDMDEV_ASSERT_EMT
     
    42494285
    42504286/** Current version of the PDMDEVREGCB structure.  */
    4251 #define PDM_DEVREG_CB_VERSION 0xf4010000
     4287#define PDM_DEVREG_CB_VERSION                   PDM_VERSION_MAKE(0xffe3, 1, 0)
    42524288
    42534289
  • trunk/include/VBox/pdmdrv.h

    r25966 r26001  
    279279
    280280/** Current DRVREG version number. */
    281 #define PDM_DRVREG_VERSION                      UINT32_C(0x80030000)
     281#define PDM_DRVREG_VERSION                      PDM_VERSION_MAKE(0xf0ff, 1, 0)
    282282
    283283/** PDM Driver Flags.
     
    397397
    398398/** Current DRVREG version number. */
    399 #define PDM_DRVINS_VERSION      UINT32_C(0xa0020000)
     399#define PDM_DRVINS_VERSION                      PDM_VERSION_MAKE(0xf0fe, 1, 0)
    400400
    401401/** Converts a pointer to the PDMDRVINS::IBase to a pointer to PDMDRVINS. */
    402402#define PDMIBASE_2_PDMDRV(pInterface) ( (PPDMDRVINS)((char *)(pInterface) - RT_OFFSETOF(PDMDRVINS, IBase)) )
     403
     404/**
     405 * Checks the structure versions of the drive instance and driver helpers,
     406 * returning if they are incompatible.
     407 *
     408 * Intended for the constructor.
     409 *
     410 * @param   pDrvIns     The drvice instance pointer.
     411 */
     412#define PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns) \
     413    do \
     414    { \
     415        PPDMDRVINS pDrvInsTypeCheck = (pDrvIns); NOREF(pDrvInsTypeCheck); \
     416        AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->u32Version, PDM_DRVINS_VERSION), \
     417                              ("DrvIns=%#x  mine=%#x\n", (pDrvIns)->u32Version, PDM_DRVINS_VERSION), \
     418                              VERR_VERSION_MISMATCH); \
     419        AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->pDrvHlpR3->u32Version, PDM_DRVHLPR3_VERSION), \
     420                              ("DrvHlp=%#x  mine=%#x\n", (pDrvIns)->pDrvHlpR3->u32Version, PDM_DRVHLPR3_VERSION), \
     421                              VERR_VERSION_MISMATCH); \
     422    } while (0)
     423
     424/**
     425 * Quietly checks the structure versions of the drive instance and driver
     426 * helpers, returning if they are incompatible.
     427 *
     428 * Intended for the destructor.
     429 *
     430 * @param   pDrvIns     The drvice instance pointer.
     431 */
     432#define PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns) \
     433    do \
     434    { \
     435        PPDMDRVINS pDrvInsTypeCheck = (pDrvIns); NOREF(pDrvInsTypeCheck); \
     436        if (RT_UNLIKELY(   !PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->u32Version, PDM_DRVINS_VERSION) \
     437                        || !PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->pDrvHlpR3->u32Version, PDM_DRVHLPR3_VERSION)) ) \
     438            return; \
     439    } while (0)
    403440
    404441
     
    446483
    447484/** Current PDMUSBHUBREG version number. */
    448 #define PDM_USBHUBREG_VERSION       UINT32_C(0xeb010000)
     485#define PDM_USBHUBREG_VERSION                   PDM_VERSION_MAKE(0xf0fd, 1, 0)
    449486
    450487
     
    469506
    470507/** Current PDMUSBHUBHLP version number. */
    471 #define PDM_USBHUBHLP_VERSION       UINT32_C(0xea010000)
     508#define PDM_USBHUBHLP_VERSION                   PDM_VERSION_MAKE(0xf0fc, 1, 0)
    472509
    473510
     
    478515typedef struct PDMDRVHLPR3
    479516{
    480     /** Structure version. PDM_DRVHLP_VERSION defines the current version. */
     517    /** Structure version. PDM_DRVHLPR3_VERSION defines the current version. */
    481518    uint32_t                    u32Version;
    482519
     
    860897} PDMDRVHLPR3;
    861898/** Current DRVHLP version number. */
    862 #define PDM_DRVHLPR3_VERSION    UINT32_C(0x90050000)
     899#define PDM_DRVHLPR3_VERSION                    PDM_VERSION_MAKE(0xf0fb, 1, 0)
    863900
    864901
     
    11891226
    11901227/** Current version of the PDMDRVREGCB structure.  */
    1191 #define PDM_DRVREG_CB_VERSION   UINT32_C(0xb0010000)
     1228#define PDM_DRVREG_CB_VERSION                   PDM_VERSION_MAKE(0xf0fa, 1, 0)
    11921229
    11931230
  • trunk/include/VBox/pdmsrv.h

    r21217 r26001  
    247247
    248248/** Current SRVHLP version number. */
    249 #define PDM_SRVHLP_VERSION  0xf9010000
     249#define PDM_SRVHLP_VERSION                      PDM_VERSION_MAKE(0xdfff, 1, 0)
    250250
    251251
     
    286286
    287287/** Current PDMSRVREG version number. */
    288 #define PDM_SRVINS_VERSION  0xf7010000
     288#define PDM_SRVINS_VERSION                      PDM_VERSION_MAKE(0xdffe, 1, 0)
    289289
    290290/** Converts a pointer to the PDMSRVINS::IBase to a pointer to PDMSRVINS. */
     
    317317
    318318/** Current version of the PDMSRVREGCB structure. */
    319 #define PDM_SRVREG_CB_VERSION 0xf8010000
     319#define PDM_SRVREG_CB_VERSION                   PDM_VERSION_MAKE(0xdffd, 1, 0)
    320320
    321321
  • trunk/include/VBox/pdmthread.h

    r25728 r26001  
    44
    55/*
    6  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     6 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    281281
    282282/** PDMTHREAD::u32Version value. */
    283 #define PDMTHREAD_VERSION   0xef010000
     283#define PDMTHREAD_VERSION                       PDM_VERSION_MAKE(0xefff, 1, 0)
    284284
    285285#ifdef IN_RING3
  • trunk/include/VBox/pdmusb.h

    r25728 r26001  
    44
    55/*
    6  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     6 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    368368
    369369/** Current USBREG version number. */
    370 #define PDM_USBREG_VERSION  0xed010000
     370#define PDM_USBREG_VERSION                      PDM_VERSION_MAKE(0xeeff, 1, 0)
    371371
    372372/** PDM USB Device Flags.
     
    607607
    608608/** Current USBHLP version number. */
    609 #define PDM_USBHLP_VERSION  0xec020001
     609#define PDM_USBHLP_VERSION                      PDM_VERSION_MAKE(0xeefe, 1, 0)
    610610
    611611#endif /* IN_RING3 */
     
    662662
    663663/** Current USBINS version number. */
    664 #define PDM_USBINS_VERSION  0xf3010000
     664#define PDM_USBINS_VERSION                      PDM_VERSION_MAKE(0xeefd, 1, 0)
    665665
    666666/** Converts a pointer to the PDMUSBINS::IBase to a pointer to PDMUSBINS. */
     
    793793
    794794/** Current version of the PDMUSBREGCB structure.  */
    795 #define PDM_USBREG_CB_VERSION 0xee010000
     795#define PDM_USBREG_CB_VERSION                   PDM_VERSION_MAKE(0xeefc, 1, 0)
    796796
    797797
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r25985 r26001  
    15761576
    15771577    Assert(iInstance == 0);
     1578    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    15781579
    15791580    /*
  • trunk/src/VBox/Devices/Audio/DevSB16.cpp

    r25985 r26001  
    17941794     */
    17951795    Assert(iInstance == 0);
     1796    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    17961797    if (!CFGMR3AreValuesValid(pCfgHandle,
    17971798                              "IRQ\0"
  • trunk/src/VBox/Devices/Audio/audio.c

    r25985 r26001  
    19621962{
    19631963    LogFlow(("drvAUDIODestruct:\n"));
     1964    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    19641965
    19651966    audio_atexit ();
     
    19781979
    19791980    LogFlow(("drvAUDIOConstruct:\n"));
     1981    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    19801982
    19811983    /*
  • trunk/src/VBox/Devices/Audio/audiosniffer.c

    r25985 r26001  
    128128    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIAUDIOSNIFFERPORT, &pThis->IPort);
    129129    return NULL;
     130}
     131
     132/**
     133 * Destruct a device instance.
     134 *
     135 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
     136 * resources can be freed correctly.
     137 *
     138 * @returns VBox status.
     139 * @param   pDevIns     The device instance data.
     140 */
     141static DECLCALLBACK(int) audioSnifferR3Destruct(PPDMDEVINS pDevIns)
     142{
     143    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
     144
     145    /* Zero the global pointer. */
     146    g_pData = NULL;
     147
     148    return VINF_SUCCESS;
    130149}
    131150
     
    145164static DECLCALLBACK(int) audioSnifferR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
    146165{
    147     int rc = VINF_SUCCESS;
    148 
     166    int                rc    = VINF_SUCCESS;
    149167    AUDIOSNIFFERSTATE *pThis = PDMINS_2_DATA(pDevIns, AUDIOSNIFFERSTATE *);
    150168
    151169    Assert(iInstance == 0);
     170    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    152171
    153172    /*
     
    208227
    209228    return rc;
    210 }
    211 
    212 /**
    213  * Destruct a device instance.
    214  *
    215  * Most VM resources are freed by the VM. This callback is provided so that any non-VM
    216  * resources can be freed correctly.
    217  *
    218  * @returns VBox status.
    219  * @param   pDevIns     The device instance data.
    220  */
    221 static DECLCALLBACK(int) audioSnifferR3Destruct(PPDMDEVINS pDevIns)
    222 {
    223     /* Zero the global pointer. */
    224     g_pData = NULL;
    225 
    226     return VINF_SUCCESS;
    227229}
    228230
  • trunk/src/VBox/Devices/Graphics/DevVGA.cpp

    r25985 r26001  
    58105810}
    58115811
     5812
     5813/**
     5814 * Destruct a device instance.
     5815 *
     5816 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
     5817 * resources can be freed correctly.
     5818 *
     5819 * @param   pDevIns     The device instance data.
     5820 */
     5821static DECLCALLBACK(int) vgaR3Destruct(PPDMDEVINS pDevIns)
     5822{
     5823    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
     5824
     5825#ifdef VBE_NEW_DYN_LIST
     5826    PVGASTATE   pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
     5827    LogFlow(("vgaR3Destruct:\n"));
     5828
     5829    /*
     5830     * Free MM heap pointers.
     5831     */
     5832    if (pThis->pu8VBEExtraData)
     5833    {
     5834        MMR3HeapFree(pThis->pu8VBEExtraData);
     5835        pThis->pu8VBEExtraData = NULL;
     5836    }
     5837#endif
     5838
     5839    PDMR3CritSectDelete(&pThis->lock);
     5840    return VINF_SUCCESS;
     5841}
     5842
     5843
    58125844/**
    58135845 * Construct a VGA device instance for a VM.
     
    58255857static DECLCALLBACK(int)   vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
    58265858{
     5859
    58275860    static bool s_fExpandDone = false;
    58285861    int         rc;
    5829     unsigned i;
    5830     PVGASTATE   pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
    5831     PVM         pVM = PDMDevHlpGetVM(pDevIns);
     5862    unsigned    i;
    58325863#ifdef VBE_NEW_DYN_LIST
    58335864    uint32_t    cCustomModes;
     
    58375868    unsigned    cb;
    58385869#endif
     5870    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
     5871    PVGASTATE   pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
     5872    PVM         pVM   = PDMDevHlpGetVM(pDevIns);
     5873
    58395874    Assert(iInstance == 0);
    58405875    Assert(pVM);
     
    65586593    pThis->uMaskLatchAccess = 0x3ff;
    65596594    return rc;
    6560 }
    6561 
    6562 
    6563 /**
    6564  * Destruct a device instance.
    6565  *
    6566  * Most VM resources are freed by the VM. This callback is provided so that any non-VM
    6567  * resources can be freed correctly.
    6568  *
    6569  * @param   pDevIns     The device instance data.
    6570  */
    6571 static DECLCALLBACK(int) vgaR3Destruct(PPDMDEVINS pDevIns)
    6572 {
    6573 #ifdef VBE_NEW_DYN_LIST
    6574     PVGASTATE   pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
    6575     LogFlow(("vgaR3Destruct:\n"));
    6576 
    6577     /*
    6578      * Free MM heap pointers.
    6579      */
    6580     if (pThis->pu8VBEExtraData)
    6581     {
    6582         MMR3HeapFree(pThis->pu8VBEExtraData);
    6583         pThis->pu8VBEExtraData = NULL;
    6584     }
    6585 #endif
    6586 
    6587     PDMR3CritSectDelete(&pThis->lock);
    6588     return VINF_SUCCESS;
    65896595}
    65906596
  • trunk/src/VBox/Devices/Input/DevPS2.cpp

    r25985 r26001  
    15721572{
    15731573    KBDState   *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
     1574    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
     1575
    15741576    PDMR3CritSectDelete(&pThis->CritSect);
    15751577
     
    15981600    bool        fR0Enabled;
    15991601    Assert(iInstance == 0);
     1602
     1603    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    16001604
    16011605    /*
  • trunk/src/VBox/Devices/Input/DrvKeyboardQueue.cpp

    r25985 r26001  
    238238    PDRVKBDQUEUE pDrv = PDMINS_2_DATA(pDrvIns, PDRVKBDQUEUE);
    239239    LogFlow(("drvKbdQueueConstruct: iInstance=%d\n", pDrvIns->iInstance));
     240    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    240241
    241242    /*
  • trunk/src/VBox/Devices/Input/DrvMouseQueue.cpp

    r25985 r26001  
    227227    PDRVMOUSEQUEUE pDrv = PDMINS_2_DATA(pDrvIns, PDRVMOUSEQUEUE);
    228228    LogFlow(("drvMouseQueueConstruct: iInstance=%d\n", pDrvIns->iInstance));
     229    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    229230
    230231    /*
  • trunk/src/VBox/Devices/Network/DevE1000.cpp

    r25986 r26001  
    47244724}
    47254725
     4726/* -=-=-=-=- PDMDEVREG -=-=-=-=- */
     4727
     4728#ifdef VBOX_DYNAMIC_NET_ATTACH
     4729
     4730/**
     4731 * Detach notification.
     4732 *
     4733 * One port on the network card has been disconnected from the network.
     4734 *
     4735 * @param   pDevIns     The device instance.
     4736 * @param   iLUN        The logical unit which is being detached.
     4737 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
     4738 */
     4739static DECLCALLBACK(void) e1kDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
     4740{
     4741    E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
     4742    Log(("%s e1kDetach:\n", INSTANCE(pState)));
     4743
     4744    AssertLogRelReturnVoid(iLUN == 0);
     4745
     4746    PDMCritSectEnter(&pState->cs, VERR_SEM_BUSY);
     4747
     4748    /** @todo: r=pritesh still need to check if i missed
     4749     * to clean something in this function
     4750     */
     4751
     4752    /*
     4753     * Zero some important members.
     4754     */
     4755    pState->pDrvBase = NULL;
     4756    pState->pDrv = NULL;
     4757
     4758    PDMCritSectLeave(&pState->cs);
     4759}
     4760
     4761
     4762/**
     4763 * Attach the Network attachment.
     4764 *
     4765 * One port on the network card has been connected to a network.
     4766 *
     4767 * @returns VBox status code.
     4768 * @param   pDevIns     The device instance.
     4769 * @param   iLUN        The logical unit which is being attached.
     4770 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
     4771 *
     4772 * @remarks This code path is not used during construction.
     4773 */
     4774static DECLCALLBACK(int) e1kAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
     4775{
     4776    E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
     4777    LogFlow(("%s e1kAttach:\n",  INSTANCE(pState)));
     4778
     4779    AssertLogRelReturn(iLUN == 0, VERR_PDM_NO_SUCH_LUN);
     4780
     4781    PDMCritSectEnter(&pState->cs, VERR_SEM_BUSY);
     4782
     4783    /*
     4784     * Attach the driver.
     4785     */
     4786    int rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->IBase, &pState->pDrvBase, "Network Port");
     4787    if (RT_SUCCESS(rc))
     4788    {
     4789        if (rc == VINF_NAT_DNS)
     4790        {
     4791#ifdef RT_OS_LINUX
     4792            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
     4793                                       N_("A Domain Name Server (DNS) for NAT networking could not be determined. Please check your /etc/resolv.conf for <tt>nameserver</tt> entries. Either add one manually (<i>man resolv.conf</i>) or ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
     4794#else
     4795            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
     4796                                       N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
     4797#endif
     4798        }
     4799        pState->pDrv = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKCONNECTOR);
     4800        AssertMsgStmt(pState->pDrv, ("Failed to obtain the PDMINETWORKCONNECTOR interface!\n"),
     4801                      rc = VERR_PDM_MISSING_INTERFACE_BELOW);
     4802    }
     4803    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     4804        Log(("%s No attached driver!\n", INSTANCE(pState)));
     4805
     4806
     4807    /*
     4808     * Temporary set the link down if it was up so that the guest
     4809     * will know that we have change the configuration of the
     4810     * network card
     4811     */
     4812    if ((STATUS & STATUS_LU) && RT_SUCCESS(rc))
     4813    {
     4814        STATUS &= ~STATUS_LU;
     4815        Phy::setLinkStatus(&pState->phy, false);
     4816        e1kRaiseInterrupt(pState, VERR_SEM_BUSY, ICR_LSC);
     4817        /* Restore the link back in 5 second. */
     4818        e1kArmTimer(pState, pState->pLUTimer, 5000000);
     4819    }
     4820
     4821    PDMCritSectLeave(&pState->cs);
     4822    return rc;
     4823
     4824}
     4825
     4826#endif /* VBOX_DYNAMIC_NET_ATTACH */
     4827
     4828/**
     4829 * @copydoc FNPDMDEVPOWEROFF
     4830 */
     4831static DECLCALLBACK(void) e1kPowerOff(PPDMDEVINS pDevIns)
     4832{
     4833    /* Poke thread waiting for buffer space. */
     4834    e1kWakeupReceive(pDevIns);
     4835}
     4836
     4837/**
     4838 * @copydoc FNPDMDEVSUSPEND
     4839 */
     4840static DECLCALLBACK(void) e1kSuspend(PPDMDEVINS pDevIns)
     4841{
     4842    /* Poke thread waiting for buffer space. */
     4843    e1kWakeupReceive(pDevIns);
     4844}
     4845
     4846/**
     4847 * Device relocation callback.
     4848 *
     4849 * When this callback is called the device instance data, and if the
     4850 * device have a GC component, is being relocated, or/and the selectors
     4851 * have been changed. The device must use the chance to perform the
     4852 * necessary pointer relocations and data updates.
     4853 *
     4854 * Before the GC code is executed the first time, this function will be
     4855 * called with a 0 delta so GC pointer calculations can be one in one place.
     4856 *
     4857 * @param   pDevIns     Pointer to the device instance.
     4858 * @param   offDelta    The relocation delta relative to the old location.
     4859 *
     4860 * @remark  A relocation CANNOT fail.
     4861 */
     4862static DECLCALLBACK(void) e1kRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
     4863{
     4864    E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
     4865    pState->pDevInsRC     = PDMDEVINS_2_RCPTR(pDevIns);
     4866    pState->pTxQueueRC    = PDMQueueRCPtr(pState->pTxQueueR3);
     4867    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
     4868#ifdef E1K_USE_RX_TIMERS
     4869    pState->pRIDTimerRC   = TMTimerRCPtr(pState->pRIDTimerR3);
     4870    pState->pRADTimerRC   = TMTimerRCPtr(pState->pRADTimerR3);
     4871#endif /* E1K_USE_RX_TIMERS */
     4872#ifdef E1K_USE_TX_TIMERS
     4873    pState->pTIDTimerRC   = TMTimerRCPtr(pState->pTIDTimerR3);
     4874# ifndef E1K_NO_TAD
     4875    pState->pTADTimerRC   = TMTimerRCPtr(pState->pTADTimerR3);
     4876# endif /* E1K_NO_TAD */
     4877#endif /* E1K_USE_TX_TIMERS */
     4878    pState->pIntTimerRC   = TMTimerRCPtr(pState->pIntTimerR3);
     4879}
     4880
     4881/**
     4882 * Destruct a device instance.
     4883 *
     4884 * We need to free non-VM resources only.
     4885 *
     4886 * @returns VBox status.
     4887 * @param   pDevIns     The device instance data.
     4888 * @thread  EMT
     4889 */
     4890static DECLCALLBACK(int) e1kDestruct(PPDMDEVINS pDevIns)
     4891{
     4892    E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
     4893    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
     4894
     4895    e1kDumpState(pState);
     4896    E1kLog(("%s Destroying instance\n", INSTANCE(pState)));
     4897    if (PDMCritSectIsInitialized(&pState->cs))
     4898    {
     4899        if (pState->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
     4900        {
     4901            RTSemEventSignal(pState->hEventMoreRxDescAvail);
     4902            RTSemEventDestroy(pState->hEventMoreRxDescAvail);
     4903            pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
     4904        }
     4905        if (pState->hTxSem != NIL_RTSEMEVENT)
     4906        {
     4907            RTSemEventDestroy(pState->hTxSem);
     4908            pState->hTxSem = NIL_RTSEMEVENT;
     4909        }
     4910#ifndef E1K_GLOBAL_MUTEX
     4911        PDMR3CritSectDelete(&pState->csRx);
     4912        //PDMR3CritSectDelete(&pState->csTx);
     4913#endif
     4914        PDMR3CritSectDelete(&pState->cs);
     4915    }
     4916    return VINF_SUCCESS;
     4917}
     4918
    47264919/**
    47274920 * Sets 8-bit register in PCI configuration space.
     
    48475040    E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
    48485041    int       rc;
     5042    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    48495043
    48505044    /* Init handles and log related stuff. */
     
    51295323
    51305324    return VINF_SUCCESS;
    5131 }
    5132 
    5133 /**
    5134  * Destruct a device instance.
    5135  *
    5136  * We need to free non-VM resources only.
    5137  *
    5138  * @returns VBox status.
    5139  * @param   pDevIns     The device instance data.
    5140  * @thread  EMT
    5141  */
    5142 static DECLCALLBACK(int) e1kDestruct(PPDMDEVINS pDevIns)
    5143 {
    5144     E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
    5145 
    5146     e1kDumpState(pState);
    5147     E1kLog(("%s Destroying instance\n", INSTANCE(pState)));
    5148     if (PDMCritSectIsInitialized(&pState->cs))
    5149     {
    5150         if (pState->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
    5151         {
    5152             RTSemEventSignal(pState->hEventMoreRxDescAvail);
    5153             RTSemEventDestroy(pState->hEventMoreRxDescAvail);
    5154             pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
    5155         }
    5156         if (pState->hTxSem != NIL_RTSEMEVENT)
    5157         {
    5158             RTSemEventDestroy(pState->hTxSem);
    5159             pState->hTxSem = NIL_RTSEMEVENT;
    5160         }
    5161 #ifndef E1K_GLOBAL_MUTEX
    5162         PDMR3CritSectDelete(&pState->csRx);
    5163         //PDMR3CritSectDelete(&pState->csTx);
    5164 #endif
    5165         PDMR3CritSectDelete(&pState->cs);
    5166     }
    5167     return VINF_SUCCESS;
    5168 }
    5169 
    5170 /**
    5171  * Device relocation callback.
    5172  *
    5173  * When this callback is called the device instance data, and if the
    5174  * device have a GC component, is being relocated, or/and the selectors
    5175  * have been changed. The device must use the chance to perform the
    5176  * necessary pointer relocations and data updates.
    5177  *
    5178  * Before the GC code is executed the first time, this function will be
    5179  * called with a 0 delta so GC pointer calculations can be one in one place.
    5180  *
    5181  * @param   pDevIns     Pointer to the device instance.
    5182  * @param   offDelta    The relocation delta relative to the old location.
    5183  *
    5184  * @remark  A relocation CANNOT fail.
    5185  */
    5186 static DECLCALLBACK(void) e1kRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
    5187 {
    5188     E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
    5189     pState->pDevInsRC     = PDMDEVINS_2_RCPTR(pDevIns);
    5190     pState->pTxQueueRC    = PDMQueueRCPtr(pState->pTxQueueR3);
    5191     pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
    5192 #ifdef E1K_USE_RX_TIMERS
    5193     pState->pRIDTimerRC   = TMTimerRCPtr(pState->pRIDTimerR3);
    5194     pState->pRADTimerRC   = TMTimerRCPtr(pState->pRADTimerR3);
    5195 #endif /* E1K_USE_RX_TIMERS */
    5196 #ifdef E1K_USE_TX_TIMERS
    5197     pState->pTIDTimerRC   = TMTimerRCPtr(pState->pTIDTimerR3);
    5198 # ifndef E1K_NO_TAD
    5199     pState->pTADTimerRC   = TMTimerRCPtr(pState->pTADTimerR3);
    5200 # endif /* E1K_NO_TAD */
    5201 #endif /* E1K_USE_TX_TIMERS */
    5202     pState->pIntTimerRC   = TMTimerRCPtr(pState->pIntTimerR3);
    5203 }
    5204 
    5205 /**
    5206  * @copydoc FNPDMDEVSUSPEND
    5207  */
    5208 static DECLCALLBACK(void) e1kSuspend(PPDMDEVINS pDevIns)
    5209 {
    5210     /* Poke thread waiting for buffer space. */
    5211     e1kWakeupReceive(pDevIns);
    5212 }
    5213 
    5214 
    5215 #ifdef VBOX_DYNAMIC_NET_ATTACH
    5216 /**
    5217  * Detach notification.
    5218  *
    5219  * One port on the network card has been disconnected from the network.
    5220  *
    5221  * @param   pDevIns     The device instance.
    5222  * @param   iLUN        The logical unit which is being detached.
    5223  * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    5224  */
    5225 static DECLCALLBACK(void) e1kDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
    5226 {
    5227     E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
    5228     Log(("%s e1kDetach:\n", INSTANCE(pState)));
    5229 
    5230     AssertLogRelReturnVoid(iLUN == 0);
    5231 
    5232     PDMCritSectEnter(&pState->cs, VERR_SEM_BUSY);
    5233 
    5234     /** @todo: r=pritesh still need to check if i missed
    5235      * to clean something in this function
    5236      */
    5237 
    5238     /*
    5239      * Zero some important members.
    5240      */
    5241     pState->pDrvBase = NULL;
    5242     pState->pDrv = NULL;
    5243 
    5244     PDMCritSectLeave(&pState->cs);
    5245 }
    5246 
    5247 
    5248 /**
    5249  * Attach the Network attachment.
    5250  *
    5251  * One port on the network card has been connected to a network.
    5252  *
    5253  * @returns VBox status code.
    5254  * @param   pDevIns     The device instance.
    5255  * @param   iLUN        The logical unit which is being attached.
    5256  * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    5257  *
    5258  * @remarks This code path is not used during construction.
    5259  */
    5260 static DECLCALLBACK(int) e1kAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
    5261 {
    5262     E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
    5263     LogFlow(("%s e1kAttach:\n",  INSTANCE(pState)));
    5264 
    5265     AssertLogRelReturn(iLUN == 0, VERR_PDM_NO_SUCH_LUN);
    5266 
    5267     PDMCritSectEnter(&pState->cs, VERR_SEM_BUSY);
    5268 
    5269     /*
    5270      * Attach the driver.
    5271      */
    5272     int rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->IBase, &pState->pDrvBase, "Network Port");
    5273     if (RT_SUCCESS(rc))
    5274     {
    5275         if (rc == VINF_NAT_DNS)
    5276         {
    5277 #ifdef RT_OS_LINUX
    5278             PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
    5279                                        N_("A Domain Name Server (DNS) for NAT networking could not be determined. Please check your /etc/resolv.conf for <tt>nameserver</tt> entries. Either add one manually (<i>man resolv.conf</i>) or ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
    5280 #else
    5281             PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
    5282                                        N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
    5283 #endif
    5284         }
    5285         pState->pDrv = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKCONNECTOR);
    5286         AssertMsgStmt(pState->pDrv, ("Failed to obtain the PDMINETWORKCONNECTOR interface!\n"),
    5287                       rc = VERR_PDM_MISSING_INTERFACE_BELOW);
    5288     }
    5289     else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
    5290         Log(("%s No attached driver!\n", INSTANCE(pState)));
    5291 
    5292 
    5293     /*
    5294      * Temporary set the link down if it was up so that the guest
    5295      * will know that we have change the configuration of the
    5296      * network card
    5297      */
    5298     if ((STATUS & STATUS_LU) && RT_SUCCESS(rc))
    5299     {
    5300         STATUS &= ~STATUS_LU;
    5301         Phy::setLinkStatus(&pState->phy, false);
    5302         e1kRaiseInterrupt(pState, VERR_SEM_BUSY, ICR_LSC);
    5303         /* Restore the link back in 5 second. */
    5304         e1kArmTimer(pState, pState->pLUTimer, 5000000);
    5305     }
    5306 
    5307     PDMCritSectLeave(&pState->cs);
    5308     return rc;
    5309 
    5310 }
    5311 #endif /* VBOX_DYNAMIC_NET_ATTACH */
    5312 
    5313 
    5314 /**
    5315  * @copydoc FNPDMDEVPOWEROFF
    5316  */
    5317 static DECLCALLBACK(void) e1kPowerOff(PPDMDEVINS pDevIns)
    5318 {
    5319     /* Poke thread waiting for buffer space. */
    5320     e1kWakeupReceive(pDevIns);
    53215325}
    53225326
  • trunk/src/VBox/Devices/Network/DevINIP.cpp

    r25986 r26001  
    389389}
    390390
     391/* -=-=-=-=- PDMIBASE -=-=-=-=- */
    391392
    392393/**
     
    400401    PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKPORT, &pThis->INetworkPort);
    401402    return NULL;
     403}
     404
     405/* -=-=-=-=- PDMDEVREG -=-=-=-=- */
     406
     407/**
     408 * Destruct a device instance.
     409 *
     410 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
     411 * resources can be freed correctly.
     412 *
     413 * @returns VBox status.
     414 * @param   pDevIns     The device instance data.
     415 */
     416static DECLCALLBACK(int) devINIPDestruct(PPDMDEVINS pDevIns)
     417{
     418    PDEVINTNETIP pThis = PDMINS_2_DATA(pDevIns, PDEVINTNETIP);
     419
     420    LogFlow(("%s: pDevIns=%p\n", __FUNCTION__, pDevIns));
     421    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
     422
     423    if (g_pDevINIPData != NULL)
     424    {
     425        netif_set_down(&pThis->IntNetIF);
     426        netif_remove(&pThis->IntNetIF);
     427        tcpip_terminate();
     428        lwip_sys_sem_wait(pThis->LWIPTcpInitSem);
     429        lwip_sys_sem_free(pThis->LWIPTcpInitSem);
     430    }
     431
     432    if (pThis->pszIP)
     433        MMR3HeapFree(pThis->pszIP);
     434    if (pThis->pszNetmask)
     435        MMR3HeapFree(pThis->pszNetmask);
     436    if (pThis->pszGateway)
     437        MMR3HeapFree(pThis->pszGateway);
     438
     439    LogFlow(("%s: success\n", __FUNCTION__));
     440    return VINF_SUCCESS;
    402441}
    403442
     
    426465
    427466    Assert(iInstance == 0);
     467    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    428468
    429469    /*
     
    631671
    632672/**
    633  * Destruct a device instance.
    634  *
    635  * Most VM resources are freed by the VM. This callback is provided so that any non-VM
    636  * resources can be freed correctly.
    637  *
    638  * @returns VBox status.
    639  * @param   pDevIns     The device instance data.
    640  */
    641 static DECLCALLBACK(int) devINIPDestruct(PPDMDEVINS pDevIns)
    642 {
    643     PDEVINTNETIP pThis = PDMINS_2_DATA(pDevIns, PDEVINTNETIP);
    644 
    645     LogFlow(("%s: pDevIns=%p\n", __FUNCTION__, pDevIns));
    646 
    647     if (g_pDevINIPData != NULL)
    648     {
    649         netif_set_down(&pThis->IntNetIF);
    650         netif_remove(&pThis->IntNetIF);
    651         tcpip_terminate();
    652         lwip_sys_sem_wait(pThis->LWIPTcpInitSem);
    653         lwip_sys_sem_free(pThis->LWIPTcpInitSem);
    654     }
    655 
    656     if (pThis->pszIP)
    657         MMR3HeapFree(pThis->pszIP);
    658     if (pThis->pszNetmask)
    659         MMR3HeapFree(pThis->pszNetmask);
    660     if (pThis->pszGateway)
    661         MMR3HeapFree(pThis->pszGateway);
    662 
    663     LogFlow(("%s: success\n", __FUNCTION__));
    664     return VINF_SUCCESS;
    665 }
    666 
    667 
    668 /**
    669673 * Query whether lwIP is initialized or not. Since there is only a single
    670674 * instance of this device ever for a VM, it can be a global function.
  • trunk/src/VBox/Devices/Network/DevPCNet.cpp

    r25986 r26001  
    49064906{
    49074907    PCNetState *pThis = PDMINS_2_DATA(pDevIns, PCNetState *);
     4908    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
    49084909
    49094910    if (PDMCritSectIsInitialized(&pThis->CritSect))
     
    49524953    Assert((iInstance >= 0) && (iInstance < 8));
    49534954
     4955    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    49544956    Assert(RT_ELEMENTS(pThis->aBCR) == BCR_MAX_RAP);
    49554957    Assert(RT_ELEMENTS(pThis->aMII) == MII_MAX_REG);
  • trunk/src/VBox/Devices/Network/DevVirtioNet.cpp

    r25986 r26001  
    14341434}
    14351435
    1436 /**
    1437  * Construct a device instance for a VM.
    1438  *
    1439  * @returns VBox status.
    1440  * @param   pDevIns     The device instance data.
    1441  *                      If the registration structure is needed, pDevIns->pDevReg points to it.
    1442  * @param   iInstance   Instance number. Use this to figure out which registers and such to use.
    1443  *                      The device number is also found in pDevIns->iInstance, but since it's
    1444  *                      likely to be freqently used PDM passes it as parameter.
    1445  * @param   pCfgHandle  Configuration node handle for the device. Use this to obtain the configuration
    1446  *                      of the device instance. It's also found in pDevIns->pCfgHandle, but like
    1447  *                      iInstance it's expected to be used a bit in this function.
    1448  * @thread  EMT
    1449  */
    1450 static DECLCALLBACK(int) vnetConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
    1451 {
    1452     VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
    1453     int        rc;
    1454 
    1455     /* Initialize PCI part first. */
    1456     pState->VPCI.IBase.pfnQueryInterface    = vnetQueryInterface;
    1457     rc = vpciConstruct(pDevIns, &pState->VPCI, iInstance,
    1458                        VNET_NAME_FMT, VNET_PCI_SUBSYSTEM_ID,
    1459                        VNET_PCI_CLASS, VNET_N_QUEUES);
    1460     pState->pRxQueue  = vpciAddQueue(&pState->VPCI, 256, vnetQueueReceive,  "RX ");
    1461     pState->pTxQueue  = vpciAddQueue(&pState->VPCI, 256, vnetQueueTransmit, "TX ");
    1462     pState->pCtlQueue = vpciAddQueue(&pState->VPCI, 16,  vnetQueueControl,  "CTL");
    1463 
    1464     Log(("%s Constructing new instance\n", INSTANCE(pState)));
    1465 
    1466     pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
    1467 
    1468     /*
    1469      * Validate configuration.
    1470      */
    1471     if (!CFGMR3AreValuesValid(pCfgHandle, "MAC\0" "CableConnected\0" "LineSpeed\0"))
    1472                     return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
    1473                                             N_("Invalid configuration for VirtioNet device"));
    1474 
    1475     /* Get config params */
    1476     rc = CFGMR3QueryBytes(pCfgHandle, "MAC", pState->macConfigured.au8,
    1477                           sizeof(pState->macConfigured));
    1478     if (RT_FAILURE(rc))
    1479         return PDMDEV_SET_ERROR(pDevIns, rc,
    1480                                 N_("Configuration error: Failed to get MAC address"));
    1481     rc = CFGMR3QueryBool(pCfgHandle, "CableConnected", &pState->fCableConnected);
    1482     if (RT_FAILURE(rc))
    1483         return PDMDEV_SET_ERROR(pDevIns, rc,
    1484                                 N_("Configuration error: Failed to get the value of 'CableConnected'"));
    1485 
    1486     /* Initialize PCI config space */
    1487     memcpy(pState->config.mac.au8, pState->macConfigured.au8, sizeof(pState->config.mac.au8));
    1488     pState->config.uStatus = 0;
    1489 
    1490     /* Initialize state structure */
    1491     pState->u32PktNo     = 1;
    1492 
    1493     /* Interfaces */
    1494     pState->INetworkPort.pfnWaitReceiveAvail = vnetWaitReceiveAvail;
    1495     pState->INetworkPort.pfnReceive          = vnetReceive;
    1496     pState->INetworkConfig.pfnGetMac         = vnetGetMac;
    1497     pState->INetworkConfig.pfnGetLinkState   = vnetGetLinkState;
    1498     pState->INetworkConfig.pfnSetLinkState   = vnetSetLinkState;
    1499 
    1500     pState->pTxBuf = (uint8_t *)RTMemAllocZ(VNET_MAX_FRAME_SIZE);
    1501     AssertMsgReturn(pState->pTxBuf,
    1502                     ("Cannot allocate TX buffer for virtio-net device\n"), VERR_NO_MEMORY);
    1503 
    1504     /* Initialize critical section. */
    1505     // char szTmp[sizeof(pState->VPCI.szInstance) + 2];
    1506     // RTStrPrintf(szTmp, sizeof(szTmp), "%sRX", pState->VPCI.szInstance);
    1507     // rc = PDMDevHlpCritSectInit(pDevIns, &pState->csRx, szTmp);
    1508     // if (RT_FAILURE(rc))
    1509     //     return rc;
    1510 
    1511     /* Map our ports to IO space. */
    1512     rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0,
    1513                                       VPCI_CONFIG + sizeof(VNetPCIConfig),
    1514                                       PCI_ADDRESS_SPACE_IO, vnetMap);
    1515     if (RT_FAILURE(rc))
    1516         return rc;
    1517 
    1518 
    1519     /* Register save/restore state handlers. */
    1520     rc = PDMDevHlpSSMRegisterEx(pDevIns, VIRTIO_SAVEDSTATE_VERSION, sizeof(VNETSTATE), NULL,
    1521                                 NULL,         vnetLiveExec, NULL,
    1522                                 vnetSavePrep, vnetSaveExec, NULL,
    1523                                 vnetLoadPrep, vnetLoadExec, vnetLoadDone);
    1524     if (RT_FAILURE(rc))
    1525         return rc;
    1526 
    1527     /* Create the RX notifier signaller. */
    1528     rc = PDMDevHlpPDMQueueCreate(pDevIns, sizeof(PDMQUEUEITEMCORE), 1, 0,
    1529                                  vnetCanRxQueueConsumer, true, "VNet-Rcv", &pState->pCanRxQueueR3);
    1530     if (RT_FAILURE(rc))
    1531         return rc;
    1532     pState->pCanRxQueueR0 = PDMQueueR0Ptr(pState->pCanRxQueueR3);
    1533     pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
    1534 
    1535     /* Create Link Up Timer */
    1536     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetLinkUpTimer, pState,
    1537                                 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
    1538                                 "VirtioNet Link Up Timer", &pState->pLinkUpTimer);
    1539     if (RT_FAILURE(rc))
    1540         return rc;
    1541 
    1542 #ifdef VNET_TX_DELAY
    1543     /* Create Transmit Delay Timer */
    1544     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetTxTimer, pState,
    1545                                 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
    1546                                 "VirtioNet TX Delay Timer", &pState->pTxTimerR3);
    1547     if (RT_FAILURE(rc))
    1548         return rc;
    1549     pState->pTxTimerR0 = TMTimerR0Ptr(pState->pTxTimerR3);
    1550     pState->pTxTimerRC = TMTimerRCPtr(pState->pTxTimerR3);
    1551 
    1552     pState->u32i = pState->u32AvgDiff = pState->u32MaxDiff = 0;
    1553     pState->u32MinDiff = ~0;
    1554 #endif /* VNET_TX_DELAY */
    1555 
    1556     rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->VPCI.IBase, &pState->pDrvBase, "Network Port");
    1557     if (RT_SUCCESS(rc))
    1558     {
    1559         if (rc == VINF_NAT_DNS)
    1560         {
    1561             PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
    1562                                        N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
    1563         }
    1564         pState->pDrv = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKCONNECTOR);
    1565         AssertMsgReturn(pState->pDrv, ("Failed to obtain the PDMINETWORKCONNECTOR interface!\n"),
    1566                         VERR_PDM_MISSING_INTERFACE_BELOW);
    1567     }
    1568     else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
    1569     {
    1570         Log(("%s This adapter is not attached to any network!\n", INSTANCE(pState)));
    1571     }
    1572     else
    1573         return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach the network LUN"));
    1574 
    1575     rc = RTSemEventCreate(&pState->hEventMoreRxDescAvail);
    1576     if (RT_FAILURE(rc))
    1577         return rc;
    1578 
    1579     vnetReset(pState);
    1580 
    1581     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveBytes,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,          "Amount of data received",            "/Devices/VNet%d/ReceiveBytes", iInstance);
    1582     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitBytes,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,          "Amount of data transmitted",         "/Devices/VNet%d/TransmitBytes", iInstance);
    1583 #if defined(VBOX_WITH_STATISTICS)
    1584     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceive,            STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive",                  "/Devices/VNet%d/Receive/Total", iInstance);
    1585     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveStore,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive storing",          "/Devices/VNet%d/Receive/Store", iInstance);
    1586     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflow,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling RX overflows",        "/Devices/VNet%d/RxOverflow", iInstance);
    1587     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflowWakeup,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of RX overflow wakeups",          "/Devices/VNet%d/RxOverflowWakeup", iInstance);
    1588     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmit,           STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling transmits in HC",          "/Devices/VNet%d/Transmit/Total", iInstance);
    1589     PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitSend,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling send transmit in HC",      "/Devices/VNet%d/Transmit/Send", iInstance);
    1590 #endif /* VBOX_WITH_STATISTICS */
    1591 
    1592     return VINF_SUCCESS;
    1593 }
    1594 
    1595 /**
    1596  * Destruct a device instance.
    1597  *
    1598  * We need to free non-VM resources only.
    1599  *
    1600  * @returns VBox status.
    1601  * @param   pDevIns     The device instance data.
    1602  * @thread  EMT
    1603  */
    1604 static DECLCALLBACK(int) vnetDestruct(PPDMDEVINS pDevIns)
    1605 {
    1606     VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
    1607 
    1608     LogRel(("TxTimer stats (avg/min/max): %7d usec %7d usec %7d usec\n",
    1609             pState->u32AvgDiff, pState->u32MinDiff, pState->u32MaxDiff));
    1610     Log(("%s Destroying instance\n", INSTANCE(pState)));
    1611     if (pState->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
    1612     {
    1613         RTSemEventSignal(pState->hEventMoreRxDescAvail);
    1614         RTSemEventDestroy(pState->hEventMoreRxDescAvail);
    1615         pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
    1616     }
    1617 
    1618     if (pState->pTxBuf)
    1619     {
    1620         RTMemFree(pState->pTxBuf);
    1621         pState->pTxBuf = NULL;
    1622     }
    1623     // if (PDMCritSectIsInitialized(&pState->csRx))
    1624     //     PDMR3CritSectDelete(&pState->csRx);
    1625 
    1626     return vpciDestruct(&pState->VPCI);
    1627 }
    1628 
    1629 /**
    1630  * Device relocation callback.
    1631  *
    1632  * When this callback is called the device instance data, and if the
    1633  * device have a GC component, is being relocated, or/and the selectors
    1634  * have been changed. The device must use the chance to perform the
    1635  * necessary pointer relocations and data updates.
    1636  *
    1637  * Before the GC code is executed the first time, this function will be
    1638  * called with a 0 delta so GC pointer calculations can be one in one place.
    1639  *
    1640  * @param   pDevIns     Pointer to the device instance.
    1641  * @param   offDelta    The relocation delta relative to the old location.
    1642  *
    1643  * @remark  A relocation CANNOT fail.
    1644  */
    1645 static DECLCALLBACK(void) vnetRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
    1646 {
    1647     VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
    1648     vpciRelocate(pDevIns, offDelta);
    1649     pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
    1650 #ifdef VNET_TX_DELAY
    1651     pState->pTxTimerRC    = TMTimerRCPtr(pState->pTxTimerR3);
    1652 #endif /* VNET_TX_DELAY */
    1653     // TBD
    1654 }
    1655 
    1656 /**
    1657  * @copydoc FNPDMDEVSUSPEND
    1658  */
    1659 static DECLCALLBACK(void) vnetSuspend(PPDMDEVINS pDevIns)
    1660 {
    1661     /* Poke thread waiting for buffer space. */
    1662     vnetWakeupReceive(pDevIns);
    1663 }
    1664 
     1436/* -=-=-=-=- PDMDEVREG -=-=-=-=- */
    16651437
    16661438#ifdef VBOX_DYNAMIC_NET_ATTACH
     1439
    16671440/**
    16681441 * Detach notification.
     
    17601533
    17611534}
     1535
    17621536#endif /* VBOX_DYNAMIC_NET_ATTACH */
    17631537
    1764 
    1765 /**
    1766  * @copydoc FNPDMDEVPOWEROFF
    1767  */
    1768 static DECLCALLBACK(void) vnetPowerOff(PPDMDEVINS pDevIns)
     1538/**
     1539 * @copydoc FNPDMDEVSUSPEND
     1540 */
     1541static DECLCALLBACK(void) vnetSuspend(PPDMDEVINS pDevIns)
    17691542{
    17701543    /* Poke thread waiting for buffer space. */
    17711544    vnetWakeupReceive(pDevIns);
     1545}
     1546
     1547/**
     1548 * @copydoc FNPDMDEVPOWEROFF
     1549 */
     1550static DECLCALLBACK(void) vnetPowerOff(PPDMDEVINS pDevIns)
     1551{
     1552    /* Poke thread waiting for buffer space. */
     1553    vnetWakeupReceive(pDevIns);
     1554}
     1555
     1556/**
     1557 * Device relocation callback.
     1558 *
     1559 * When this callback is called the device instance data, and if the
     1560 * device have a GC component, is being relocated, or/and the selectors
     1561 * have been changed. The device must use the chance to perform the
     1562 * necessary pointer relocations and data updates.
     1563 *
     1564 * Before the GC code is executed the first time, this function will be
     1565 * called with a 0 delta so GC pointer calculations can be one in one place.
     1566 *
     1567 * @param   pDevIns     Pointer to the device instance.
     1568 * @param   offDelta    The relocation delta relative to the old location.
     1569 *
     1570 * @remark  A relocation CANNOT fail.
     1571 */
     1572static DECLCALLBACK(void) vnetRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
     1573{
     1574    VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
     1575    vpciRelocate(pDevIns, offDelta);
     1576    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
     1577#ifdef VNET_TX_DELAY
     1578    pState->pTxTimerRC    = TMTimerRCPtr(pState->pTxTimerR3);
     1579#endif /* VNET_TX_DELAY */
     1580    // TBD
     1581}
     1582
     1583/**
     1584 * Destruct a device instance.
     1585 *
     1586 * We need to free non-VM resources only.
     1587 *
     1588 * @returns VBox status.
     1589 * @param   pDevIns     The device instance data.
     1590 * @thread  EMT
     1591 */
     1592static DECLCALLBACK(int) vnetDestruct(PPDMDEVINS pDevIns)
     1593{
     1594    VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
     1595    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
     1596
     1597    LogRel(("TxTimer stats (avg/min/max): %7d usec %7d usec %7d usec\n",
     1598            pState->u32AvgDiff, pState->u32MinDiff, pState->u32MaxDiff));
     1599    Log(("%s Destroying instance\n", INSTANCE(pState)));
     1600    if (pState->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
     1601    {
     1602        RTSemEventSignal(pState->hEventMoreRxDescAvail);
     1603        RTSemEventDestroy(pState->hEventMoreRxDescAvail);
     1604        pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
     1605    }
     1606
     1607    if (pState->pTxBuf)
     1608    {
     1609        RTMemFree(pState->pTxBuf);
     1610        pState->pTxBuf = NULL;
     1611    }
     1612    // if (PDMCritSectIsInitialized(&pState->csRx))
     1613    //     PDMR3CritSectDelete(&pState->csRx);
     1614
     1615    return vpciDestruct(&pState->VPCI);
     1616}
     1617
     1618/**
     1619 * Construct a device instance for a VM.
     1620 *
     1621 * @returns VBox status.
     1622 * @param   pDevIns     The device instance data.
     1623 *                      If the registration structure is needed, pDevIns->pDevReg points to it.
     1624 * @param   iInstance   Instance number. Use this to figure out which registers and such to use.
     1625 *                      The device number is also found in pDevIns->iInstance, but since it's
     1626 *                      likely to be freqently used PDM passes it as parameter.
     1627 * @param   pCfgHandle  Configuration node handle for the device. Use this to obtain the configuration
     1628 *                      of the device instance. It's also found in pDevIns->pCfgHandle, but like
     1629 *                      iInstance it's expected to be used a bit in this function.
     1630 * @thread  EMT
     1631 */
     1632static DECLCALLBACK(int) vnetConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
     1633{
     1634    VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
     1635    int        rc;
     1636    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
     1637
     1638    /* Initialize PCI part first. */
     1639    pState->VPCI.IBase.pfnQueryInterface    = vnetQueryInterface;
     1640    rc = vpciConstruct(pDevIns, &pState->VPCI, iInstance,
     1641                       VNET_NAME_FMT, VNET_PCI_SUBSYSTEM_ID,
     1642                       VNET_PCI_CLASS, VNET_N_QUEUES);
     1643    pState->pRxQueue  = vpciAddQueue(&pState->VPCI, 256, vnetQueueReceive,  "RX ");
     1644    pState->pTxQueue  = vpciAddQueue(&pState->VPCI, 256, vnetQueueTransmit, "TX ");
     1645    pState->pCtlQueue = vpciAddQueue(&pState->VPCI, 16,  vnetQueueControl,  "CTL");
     1646
     1647    Log(("%s Constructing new instance\n", INSTANCE(pState)));
     1648
     1649    pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
     1650
     1651    /*
     1652     * Validate configuration.
     1653     */
     1654    if (!CFGMR3AreValuesValid(pCfgHandle, "MAC\0" "CableConnected\0" "LineSpeed\0"))
     1655                    return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
     1656                                            N_("Invalid configuration for VirtioNet device"));
     1657
     1658    /* Get config params */
     1659    rc = CFGMR3QueryBytes(pCfgHandle, "MAC", pState->macConfigured.au8,
     1660                          sizeof(pState->macConfigured));
     1661    if (RT_FAILURE(rc))
     1662        return PDMDEV_SET_ERROR(pDevIns, rc,
     1663                                N_("Configuration error: Failed to get MAC address"));
     1664    rc = CFGMR3QueryBool(pCfgHandle, "CableConnected", &pState->fCableConnected);
     1665    if (RT_FAILURE(rc))
     1666        return PDMDEV_SET_ERROR(pDevIns, rc,
     1667                                N_("Configuration error: Failed to get the value of 'CableConnected'"));
     1668
     1669    /* Initialize PCI config space */
     1670    memcpy(pState->config.mac.au8, pState->macConfigured.au8, sizeof(pState->config.mac.au8));
     1671    pState->config.uStatus = 0;
     1672
     1673    /* Initialize state structure */
     1674    pState->u32PktNo     = 1;
     1675
     1676    /* Interfaces */
     1677    pState->INetworkPort.pfnWaitReceiveAvail = vnetWaitReceiveAvail;
     1678    pState->INetworkPort.pfnReceive          = vnetReceive;
     1679    pState->INetworkConfig.pfnGetMac         = vnetGetMac;
     1680    pState->INetworkConfig.pfnGetLinkState   = vnetGetLinkState;
     1681    pState->INetworkConfig.pfnSetLinkState   = vnetSetLinkState;
     1682
     1683    pState->pTxBuf = (uint8_t *)RTMemAllocZ(VNET_MAX_FRAME_SIZE);
     1684    AssertMsgReturn(pState->pTxBuf,
     1685                    ("Cannot allocate TX buffer for virtio-net device\n"), VERR_NO_MEMORY);
     1686
     1687    /* Initialize critical section. */
     1688    // char szTmp[sizeof(pState->VPCI.szInstance) + 2];
     1689    // RTStrPrintf(szTmp, sizeof(szTmp), "%sRX", pState->VPCI.szInstance);
     1690    // rc = PDMDevHlpCritSectInit(pDevIns, &pState->csRx, szTmp);
     1691    // if (RT_FAILURE(rc))
     1692    //     return rc;
     1693
     1694    /* Map our ports to IO space. */
     1695    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0,
     1696                                      VPCI_CONFIG + sizeof(VNetPCIConfig),
     1697                                      PCI_ADDRESS_SPACE_IO, vnetMap);
     1698    if (RT_FAILURE(rc))
     1699        return rc;
     1700
     1701
     1702    /* Register save/restore state handlers. */
     1703    rc = PDMDevHlpSSMRegisterEx(pDevIns, VIRTIO_SAVEDSTATE_VERSION, sizeof(VNETSTATE), NULL,
     1704                                NULL,         vnetLiveExec, NULL,
     1705                                vnetSavePrep, vnetSaveExec, NULL,
     1706                                vnetLoadPrep, vnetLoadExec, vnetLoadDone);
     1707    if (RT_FAILURE(rc))
     1708        return rc;
     1709
     1710    /* Create the RX notifier signaller. */
     1711    rc = PDMDevHlpPDMQueueCreate(pDevIns, sizeof(PDMQUEUEITEMCORE), 1, 0,
     1712                                 vnetCanRxQueueConsumer, true, "VNet-Rcv", &pState->pCanRxQueueR3);
     1713    if (RT_FAILURE(rc))
     1714        return rc;
     1715    pState->pCanRxQueueR0 = PDMQueueR0Ptr(pState->pCanRxQueueR3);
     1716    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
     1717
     1718    /* Create Link Up Timer */
     1719    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetLinkUpTimer, pState,
     1720                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
     1721                                "VirtioNet Link Up Timer", &pState->pLinkUpTimer);
     1722    if (RT_FAILURE(rc))
     1723        return rc;
     1724
     1725#ifdef VNET_TX_DELAY
     1726    /* Create Transmit Delay Timer */
     1727    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetTxTimer, pState,
     1728                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
     1729                                "VirtioNet TX Delay Timer", &pState->pTxTimerR3);
     1730    if (RT_FAILURE(rc))
     1731        return rc;
     1732    pState->pTxTimerR0 = TMTimerR0Ptr(pState->pTxTimerR3);
     1733    pState->pTxTimerRC = TMTimerRCPtr(pState->pTxTimerR3);
     1734
     1735    pState->u32i = pState->u32AvgDiff = pState->u32MaxDiff = 0;
     1736    pState->u32MinDiff = ~0;
     1737#endif /* VNET_TX_DELAY */
     1738
     1739    rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->VPCI.IBase, &pState->pDrvBase, "Network Port");
     1740    if (RT_SUCCESS(rc))
     1741    {
     1742        if (rc == VINF_NAT_DNS)
     1743        {
     1744            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
     1745                                       N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
     1746        }
     1747        pState->pDrv = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKCONNECTOR);
     1748        AssertMsgReturn(pState->pDrv, ("Failed to obtain the PDMINETWORKCONNECTOR interface!\n"),
     1749                        VERR_PDM_MISSING_INTERFACE_BELOW);
     1750    }
     1751    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     1752    {
     1753        Log(("%s This adapter is not attached to any network!\n", INSTANCE(pState)));
     1754    }
     1755    else
     1756        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach the network LUN"));
     1757
     1758    rc = RTSemEventCreate(&pState->hEventMoreRxDescAvail);
     1759    if (RT_FAILURE(rc))
     1760        return rc;
     1761
     1762    vnetReset(pState);
     1763
     1764    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveBytes,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,          "Amount of data received",            "/Devices/VNet%d/ReceiveBytes", iInstance);
     1765    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitBytes,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,          "Amount of data transmitted",         "/Devices/VNet%d/TransmitBytes", iInstance);
     1766#if defined(VBOX_WITH_STATISTICS)
     1767    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceive,            STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive",                  "/Devices/VNet%d/Receive/Total", iInstance);
     1768    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveStore,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive storing",          "/Devices/VNet%d/Receive/Store", iInstance);
     1769    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflow,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling RX overflows",        "/Devices/VNet%d/RxOverflow", iInstance);
     1770    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflowWakeup,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of RX overflow wakeups",          "/Devices/VNet%d/RxOverflowWakeup", iInstance);
     1771    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmit,           STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling transmits in HC",          "/Devices/VNet%d/Transmit/Total", iInstance);
     1772    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitSend,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling send transmit in HC",      "/Devices/VNet%d/Transmit/Send", iInstance);
     1773#endif /* VBOX_WITH_STATISTICS */
     1774
     1775    return VINF_SUCCESS;
    17721776}
    17731777
  • trunk/src/VBox/Devices/Network/DrvIntNet.cpp

    r25993 r26001  
    711711    LogFlow(("drvR3IntNetDestruct\n"));
    712712    PDRVINTNET pThis = PDMINS_2_DATA(pDrvIns, PDRVINTNET);
     713    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    713714
    714715    /*
     
    778779    PDRVINTNET pThis = PDMINS_2_DATA(pDrvIns, PDRVINTNET);
    779780    bool f;
     781    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    780782
    781783    /*
  • trunk/src/VBox/Devices/Network/DrvNAT.cpp

    r25985 r26001  
    947947{
    948948    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
    949 
    950949    LogFlow(("drvNATDestruct:\n"));
     950    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    951951
    952952    slirp_term(pThis->pNATState);
     
    969969{
    970970    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
    971 
    972971    LogFlow(("drvNATConstruct:\n"));
     972    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    973973
    974974    /*
  • trunk/src/VBox/Devices/Network/DrvNetSniffer.cpp

    r25985 r26001  
    332332{
    333333    PDRVNETSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSNIFFER);
     334    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    334335
    335336    if (RTCritSectIsInitialized(&pThis->Lock))
     
    353354    PDRVNETSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSNIFFER);
    354355    LogFlow(("drvNetSnifferConstruct:\n"));
     356    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    355357
    356358    /*
  • trunk/src/VBox/Devices/Network/DrvTAP.cpp

    r25985 r26001  
    775775#endif  /* RT_OS_SOLARIS */
    776776
     777/* -=-=-=-=- PDMIBASE -=-=-=-=- */
    777778
    778779/**
     
    789790}
    790791
     792/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
    791793
    792794/**
     
    802804    LogFlow(("drvTAPDestruct\n"));
    803805    PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
     806    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    804807
    805808    /*
     
    879882{
    880883    PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
     884    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    881885
    882886    /*
  • trunk/src/VBox/Devices/PC/DevACPI.cpp

    r25987 r26001  
    22662266    ACPIState *s   = PDMINS_2_DATA(pDevIns, ACPIState *);
    22672267    PCIDevice *dev = &s->dev;
     2268    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    22682269
    22692270    /* Validate and read the configuration. */
     
    23992400    s->uPmIoPortBase = PM_PORT_BASE;
    24002401
    2401     /* 
    2402      * FDC and SMC try to use the same non-shareable interrupt (6), 
     2402    /*
     2403     * FDC and SMC try to use the same non-shareable interrupt (6),
    24032404     * enable only one device.
    24042405     */
  • trunk/src/VBox/Devices/PC/DevPcBios.cpp

    r25974 r26001  
    797797    PDEVPCBIOS  pThis = PDMINS_2_DATA(pDevIns, PDEVPCBIOS);
    798798    LogFlow(("pcbiosDestruct:\n"));
     799    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
    799800
    800801    /*
     
    887888
    888889    Assert(iInstance == 0);
     890    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    889891
    890892    /*
  • trunk/src/VBox/Devices/PC/DrvACPI.cpp

    r25985 r26001  
    712712{
    713713    LogFlow(("drvACPIDestruct\n"));
     714    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    714715}
    715716
     
    722723{
    723724    PDRVACPI pThis = PDMINS_2_DATA(pDrvIns, PDRVACPI);
     725    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    724726
    725727    /*
  • trunk/src/VBox/Devices/PC/DrvAcpiCpu.cpp

    r25985 r26001  
    5555{
    5656    LogFlow(("drvACPICpuDestruct\n"));
     57    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    5758}
    5859
     
    6465static DECLCALLBACK(int) drvACPICpuConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
    6566{
     67    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
     68
    6669    /*
    6770     * Init the static parts.
  • trunk/src/VBox/Devices/Parallel/DevParallel.cpp

    r25985 r26001  
    673673{
    674674    ParallelState *pThis = PDMINS_2_DATA(pDevIns, ParallelState *);
     675    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
    675676
    676677    PDMR3CritSectDelete(&pThis->CritSect);
     
    702703
    703704    Assert(iInstance < 4);
     705    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    704706
    705707    /*
  • trunk/src/VBox/Devices/Parallel/DrvHostParallel.cpp

    r25985 r26001  
    249249
    250250/**
    251  * Construct a host parallel driver instance.
    252  *
    253  * @copydoc FNPDMDRVCONSTRUCT
    254  */
    255 static DECLCALLBACK(int) drvHostParallelConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
     251 * Destruct a host parallel driver instance.
     252 *
     253 * Most VM resources are freed by the VM. This callback is provided so that
     254 * any non-VM resources can be freed correctly.
     255 *
     256 * @param   pDrvIns     The driver instance data.
     257 */
     258static DECLCALLBACK(void) drvHostParallelDestruct(PPDMDRVINS pDrvIns)
    256259{
    257260    PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
    258261    LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
     262    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     263
     264    ioctl(pThis->FileDevice, PPRELEASE);
     265
     266    if (pThis->WakeupPipeW != NIL_RTFILE)
     267    {
     268        int rc = RTFileClose(pThis->WakeupPipeW);
     269        AssertRC(rc);
     270        pThis->WakeupPipeW = NIL_RTFILE;
     271    }
     272    if (pThis->WakeupPipeR != NIL_RTFILE)
     273    {
     274        int rc = RTFileClose(pThis->WakeupPipeR);
     275        AssertRC(rc);
     276        pThis->WakeupPipeR = NIL_RTFILE;
     277    }
     278    if (pThis->FileDevice != NIL_RTFILE)
     279    {
     280        int rc = RTFileClose(pThis->FileDevice);
     281        AssertRC(rc);
     282        pThis->FileDevice = NIL_RTFILE;
     283    }
     284}
     285
     286/**
     287 * Construct a host parallel driver instance.
     288 *
     289 * @copydoc FNPDMDRVCONSTRUCT
     290 */
     291static DECLCALLBACK(int) drvHostParallelConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
     292{
     293    PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
     294    LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
     295    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    259296
    260297    /*
     
    348385
    349386    return VINF_SUCCESS;
    350 }
    351 
    352 
    353 /**
    354  * Destruct a host parallel driver instance.
    355  *
    356  * Most VM resources are freed by the VM. This callback is provided so that
    357  * any non-VM resources can be freed correctly.
    358  *
    359  * @param   pDrvIns     The driver instance data.
    360  */
    361 static DECLCALLBACK(void) drvHostParallelDestruct(PPDMDRVINS pDrvIns)
    362 {
    363     PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
    364 
    365     LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
    366 
    367     ioctl(pThis->FileDevice, PPRELEASE);
    368 
    369     if (pThis->WakeupPipeW != NIL_RTFILE)
    370     {
    371         int rc = RTFileClose(pThis->WakeupPipeW);
    372         AssertRC(rc);
    373         pThis->WakeupPipeW = NIL_RTFILE;
    374     }
    375     if (pThis->WakeupPipeR != NIL_RTFILE)
    376     {
    377         int rc = RTFileClose(pThis->WakeupPipeR);
    378         AssertRC(rc);
    379         pThis->WakeupPipeR = NIL_RTFILE;
    380     }
    381     if (pThis->FileDevice != NIL_RTFILE)
    382     {
    383         int rc = RTFileClose(pThis->FileDevice);
    384         AssertRC(rc);
    385         pThis->FileDevice = NIL_RTFILE;
    386     }
    387387}
    388388
  • trunk/src/VBox/Devices/Serial/DevSerial.cpp

    r25985 r26001  
    755755{
    756756    SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *);
     757    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
    757758
    758759    RTSemEventDestroy(pThis->ReceiveSem);
     
    787788
    788789    Assert(iInstance < 4);
     790    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    789791
    790792    /*
  • trunk/src/VBox/Devices/Serial/DrvChar.cpp

    r25985 r26001  
    299299
    300300/**
    301  * Construct a char driver instance.
    302  *
    303  * @copydoc FNPDMDRVCONSTRUCT
    304  */
    305 static DECLCALLBACK(int) drvCharConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
     301 * Destruct a char driver instance.
     302 *
     303 * Most VM resources are freed by the VM. This callback is provided so that
     304 * any non-VM resources can be freed correctly.
     305 *
     306 * @param   pDrvIns     The driver instance data.
     307 */
     308static DECLCALLBACK(void) drvCharDestruct(PPDMDRVINS pDrvIns)
    306309{
    307310    PDRVCHAR pThis = PDMINS_2_DATA(pDrvIns, PDRVCHAR);
    308311    LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
     312    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     313
     314    pThis->fShutdown = true;
     315    if (pThis->ReceiveThread)
     316    {
     317        RTThreadWait(pThis->ReceiveThread, 1000, NULL);
     318        if (pThis->ReceiveThread != NIL_RTTHREAD)
     319            LogRel(("Char%d: receive thread did not terminate\n", pDrvIns->iInstance));
     320    }
     321
     322    /* Empty the send queue */
     323    pThis->iSendQueueTail = pThis->iSendQueueHead = 0;
     324
     325    RTSemEventSignal(pThis->SendSem);
     326    RTSemEventDestroy(pThis->SendSem);
     327    pThis->SendSem = NIL_RTSEMEVENT;
     328
     329    if (pThis->SendThread)
     330    {
     331        RTThreadWait(pThis->SendThread, 1000, NULL);
     332        if (pThis->SendThread != NIL_RTTHREAD)
     333            LogRel(("Char%d: send thread did not terminate\n", pDrvIns->iInstance));
     334    }
     335}
     336
     337
     338/**
     339 * Construct a char driver instance.
     340 *
     341 * @copydoc FNPDMDRVCONSTRUCT
     342 */
     343static DECLCALLBACK(int) drvCharConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
     344{
     345    PDRVCHAR pThis = PDMINS_2_DATA(pDrvIns, PDRVCHAR);
     346    LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
     347    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    309348
    310349    /*
     
    363402}
    364403
    365 
    366 /**
    367  * Destruct a char driver instance.
    368  *
    369  * Most VM resources are freed by the VM. This callback is provided so that
    370  * any non-VM resources can be freed correctly.
    371  *
    372  * @param   pDrvIns     The driver instance data.
    373  */
    374 static DECLCALLBACK(void) drvCharDestruct(PPDMDRVINS pDrvIns)
    375 {
    376     PDRVCHAR     pThis = PDMINS_2_DATA(pDrvIns, PDRVCHAR);
    377 
    378     LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
    379 
    380     pThis->fShutdown = true;
    381     if (pThis->ReceiveThread)
    382     {
    383         RTThreadWait(pThis->ReceiveThread, 1000, NULL);
    384         if (pThis->ReceiveThread != NIL_RTTHREAD)
    385             LogRel(("Char%d: receive thread did not terminate\n", pDrvIns->iInstance));
    386     }
    387 
    388     /* Empty the send queue */
    389     pThis->iSendQueueTail = pThis->iSendQueueHead = 0;
    390 
    391     RTSemEventSignal(pThis->SendSem);
    392     RTSemEventDestroy(pThis->SendSem);
    393     pThis->SendSem = NIL_RTSEMEVENT;
    394 
    395     if (pThis->SendThread)
    396     {
    397         RTThreadWait(pThis->SendThread, 1000, NULL);
    398         if (pThis->SendThread != NIL_RTTHREAD)
    399             LogRel(("Char%d: send thread did not terminate\n", pDrvIns->iInstance));
    400     }
    401 }
    402404
    403405/**
  • trunk/src/VBox/Devices/Serial/DrvHostSerial.cpp

    r25985 r26001  
    12031203
    12041204/**
     1205 * Destruct a char driver instance.
     1206 *
     1207 * Most VM resources are freed by the VM. This callback is provided so that
     1208 * any non-VM resources can be freed correctly.
     1209 *
     1210 * @param   pDrvIns     The driver instance data.
     1211 */
     1212static DECLCALLBACK(void) drvHostSerialDestruct(PPDMDRVINS pDrvIns)
     1213{
     1214    PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
     1215    LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
     1216    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     1217
     1218    /* Empty the send queue */
     1219    pThis->iSendQueueTail = pThis->iSendQueueHead = 0;
     1220
     1221    RTSemEventDestroy(pThis->SendSem);
     1222    pThis->SendSem = NIL_RTSEMEVENT;
     1223
     1224#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
     1225
     1226    if (pThis->WakeupPipeW != NIL_RTFILE)
     1227    {
     1228        int rc = RTFileClose(pThis->WakeupPipeW);
     1229        AssertRC(rc);
     1230        pThis->WakeupPipeW = NIL_RTFILE;
     1231    }
     1232    if (pThis->WakeupPipeR != NIL_RTFILE)
     1233    {
     1234        int rc = RTFileClose(pThis->WakeupPipeR);
     1235        AssertRC(rc);
     1236        pThis->WakeupPipeR = NIL_RTFILE;
     1237    }
     1238# if defined(RT_OS_DARWIN)
     1239    if (pThis->DeviceFileR != NIL_RTFILE)
     1240    {
     1241        if (pThis->DeviceFileR != pThis->DeviceFile)
     1242        {
     1243            int rc = RTFileClose(pThis->DeviceFileR);
     1244            AssertRC(rc);
     1245        }
     1246        pThis->DeviceFileR = NIL_RTFILE;
     1247    }
     1248# endif
     1249    if (pThis->DeviceFile != NIL_RTFILE)
     1250    {
     1251        int rc = RTFileClose(pThis->DeviceFile);
     1252        AssertRC(rc);
     1253        pThis->DeviceFile = NIL_RTFILE;
     1254    }
     1255
     1256#elif defined(RT_OS_WINDOWS)
     1257
     1258    CloseHandle(pThis->hEventRecv);
     1259    CloseHandle(pThis->hEventSend);
     1260    CancelIo(pThis->hDeviceFile);
     1261    CloseHandle(pThis->hDeviceFile);
     1262
     1263#endif
     1264}
     1265
     1266/**
    12051267 * Construct a char driver instance.
    12061268 *
     
    12111273    PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
    12121274    LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
     1275    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    12131276
    12141277    /*
     
    13871450
    13881451    return VINF_SUCCESS;
    1389 }
    1390 
    1391 
    1392 /**
    1393  * Destruct a char driver instance.
    1394  *
    1395  * Most VM resources are freed by the VM. This callback is provided so that
    1396  * any non-VM resources can be freed correctly.
    1397  *
    1398  * @param   pDrvIns     The driver instance data.
    1399  */
    1400 static DECLCALLBACK(void) drvHostSerialDestruct(PPDMDRVINS pDrvIns)
    1401 {
    1402     PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
    1403 
    1404     LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
    1405 
    1406     /* Empty the send queue */
    1407     pThis->iSendQueueTail = pThis->iSendQueueHead = 0;
    1408 
    1409     RTSemEventDestroy(pThis->SendSem);
    1410     pThis->SendSem = NIL_RTSEMEVENT;
    1411 
    1412 #if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
    1413 
    1414     if (pThis->WakeupPipeW != NIL_RTFILE)
    1415     {
    1416         int rc = RTFileClose(pThis->WakeupPipeW);
    1417         AssertRC(rc);
    1418         pThis->WakeupPipeW = NIL_RTFILE;
    1419     }
    1420     if (pThis->WakeupPipeR != NIL_RTFILE)
    1421     {
    1422         int rc = RTFileClose(pThis->WakeupPipeR);
    1423         AssertRC(rc);
    1424         pThis->WakeupPipeR = NIL_RTFILE;
    1425     }
    1426 # if defined(RT_OS_DARWIN)
    1427     if (pThis->DeviceFileR != NIL_RTFILE)
    1428     {
    1429         if (pThis->DeviceFileR != pThis->DeviceFile)
    1430         {
    1431             int rc = RTFileClose(pThis->DeviceFileR);
    1432             AssertRC(rc);
    1433         }
    1434         pThis->DeviceFileR = NIL_RTFILE;
    1435     }
    1436 # endif
    1437     if (pThis->DeviceFile != NIL_RTFILE)
    1438     {
    1439         int rc = RTFileClose(pThis->DeviceFile);
    1440         AssertRC(rc);
    1441         pThis->DeviceFile = NIL_RTFILE;
    1442     }
    1443 
    1444 #elif defined(RT_OS_WINDOWS)
    1445 
    1446     CloseHandle(pThis->hEventRecv);
    1447     CloseHandle(pThis->hEventSend);
    1448     CancelIo(pThis->hDeviceFile);
    1449     CloseHandle(pThis->hDeviceFile);
    1450 
    1451 #endif
    14521452}
    14531453
  • trunk/src/VBox/Devices/Serial/DrvNamedPipe.cpp

    r25985 r26001  
    383383}
    384384
     385/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
     386
     387/**
     388 * Power off a named pipe stream driver instance.
     389 *
     390 * This does most of the destruction work, to avoid ordering dependencies.
     391 *
     392 * @param   pDrvIns     The driver instance data.
     393 */
     394static DECLCALLBACK(void) drvNamedPipePowerOff(PPDMDRVINS pDrvIns)
     395{
     396    PDRVNAMEDPIPE pThis = PDMINS_2_DATA(pDrvIns, PDRVNAMEDPIPE);
     397    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
     398
     399    pThis->fShutdown = true;
     400
     401#ifdef RT_OS_WINDOWS
     402    if (pThis->NamedPipe != INVALID_HANDLE_VALUE)
     403    {
     404        if (pThis->fIsServer)
     405        {
     406            FlushFileBuffers(pThis->NamedPipe);
     407            DisconnectNamedPipe(pThis->NamedPipe);
     408        }
     409
     410        CloseHandle(pThis->NamedPipe);
     411        pThis->NamedPipe = INVALID_HANDLE_VALUE;
     412        CloseHandle(pThis->OverlappedRead.hEvent);
     413        CloseHandle(pThis->OverlappedWrite.hEvent);
     414    }
     415    if (pThis->fIsServer)
     416    {
     417        /* Wake up listen thread */
     418        RTSemEventSignal(pThis->ListenSem);
     419        RTSemEventDestroy(pThis->ListenSem);
     420    }
     421#else /* !RT_OS_WINDOWS */
     422    if (pThis->fIsServer)
     423    {
     424        if (pThis->LocalSocketServer != NIL_RTSOCKET)
     425            close(pThis->LocalSocketServer);
     426        if (pThis->pszLocation)
     427            RTFileDelete(pThis->pszLocation);
     428    }
     429    else
     430    {
     431        if (pThis->LocalSocket != NIL_RTSOCKET)
     432            close(pThis->LocalSocket);
     433    }
     434#endif /* !RT_OS_WINDOWS */
     435}
     436
     437
     438/**
     439 * Destruct a named pipe stream driver instance.
     440 *
     441 * Most VM resources are freed by the VM. This callback is provided so that
     442 * any non-VM resources can be freed correctly.
     443 *
     444 * @param   pDrvIns     The driver instance data.
     445 */
     446static DECLCALLBACK(void) drvNamedPipeDestruct(PPDMDRVINS pDrvIns)
     447{
     448    PDRVNAMEDPIPE pThis = PDMINS_2_DATA(pDrvIns, PDRVNAMEDPIPE);
     449    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
     450    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     451
     452    if (pThis->ListenThread)
     453    {   RTThreadWait(pThis->ListenThread, 250, NULL);
     454        if (pThis->ListenThread != NIL_RTTHREAD)
     455            LogRel(("NamedPipe%d: listen thread did not terminate\n", pDrvIns->iInstance));
     456    }
     457
     458    if (pThis->pszLocation)
     459        MMR3HeapFree(pThis->pszLocation);
     460}
     461
    385462
    386463/**
     
    394471    char *pszLocation = NULL;
    395472    PDRVNAMEDPIPE pThis = PDMINS_2_DATA(pDrvIns, PDRVNAMEDPIPE);
     473    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    396474
    397475    /*
     
    421499    {
    422500        rc = VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
    423         goto out;
     501        goto l_out;
    424502    }
    425503
     
    428506    {
    429507        AssertMsgFailed(("Configuration error: query \"Location\" resulted in %Rrc.\n", rc));
    430         goto out;
     508        goto l_out;
    431509    }
    432510    pThis->pszLocation = pszLocation;
     
    437515    {
    438516        AssertMsgFailed(("Configuration error: query \"IsServer\" resulted in %Rrc.\n", rc));
    439         goto out;
     517        goto l_out;
    440518    }
    441519    pThis->fIsServer = fIsServer;
     
    509587#endif /* !RT_OS_WINDOWS */
    510588
    511 out:
     589l_out:
    512590    if (RT_FAILURE(rc))
    513591    {
     
    520598    LogRel(("NamedPipe: location %s, %s\n", pszLocation, fIsServer ? "server" : "client"));
    521599    return VINF_SUCCESS;
    522 }
    523 
    524 
    525 /**
    526  * Destruct a named pipe stream driver instance.
    527  *
    528  * Most VM resources are freed by the VM. This callback is provided so that
    529  * any non-VM resources can be freed correctly.
    530  *
    531  * @param   pDrvIns     The driver instance data.
    532  */
    533 static DECLCALLBACK(void) drvNamedPipeDestruct(PPDMDRVINS pDrvIns)
    534 {
    535     PDRVNAMEDPIPE pThis = PDMINS_2_DATA(pDrvIns, PDRVNAMEDPIPE);
    536     LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
    537 
    538     if (pThis->ListenThread)
    539     {
    540         RTThreadWait(pThis->ListenThread, 250, NULL);
    541         if (pThis->ListenThread != NIL_RTTHREAD)
    542             LogRel(("NamedPipe%d: listen thread did not terminate\n", pDrvIns->iInstance));
    543     }
    544 
    545     if (pThis->pszLocation)
    546         MMR3HeapFree(pThis->pszLocation);
    547 }
    548 
    549 
    550 /**
    551  * Power off a named pipe stream driver instance.
    552  *
    553  * This does most of the destruction work, to avoid ordering dependencies.
    554  *
    555  * @param   pDrvIns     The driver instance data.
    556  */
    557 static DECLCALLBACK(void) drvNamedPipePowerOff(PPDMDRVINS pDrvIns)
    558 {
    559     PDRVNAMEDPIPE pThis = PDMINS_2_DATA(pDrvIns, PDRVNAMEDPIPE);
    560     LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
    561 
    562     pThis->fShutdown = true;
    563 
    564 #ifdef RT_OS_WINDOWS
    565     if (pThis->NamedPipe != INVALID_HANDLE_VALUE)
    566     {
    567         if (pThis->fIsServer)
    568         {
    569             FlushFileBuffers(pThis->NamedPipe);
    570             DisconnectNamedPipe(pThis->NamedPipe);
    571         }
    572 
    573         CloseHandle(pThis->NamedPipe);
    574         pThis->NamedPipe = INVALID_HANDLE_VALUE;
    575         CloseHandle(pThis->OverlappedRead.hEvent);
    576         CloseHandle(pThis->OverlappedWrite.hEvent);
    577     }
    578     if (pThis->fIsServer)
    579     {
    580         /* Wake up listen thread */
    581         RTSemEventSignal(pThis->ListenSem);
    582         RTSemEventDestroy(pThis->ListenSem);
    583     }
    584 #else /* !RT_OS_WINDOWS */
    585     if (pThis->fIsServer)
    586     {
    587         if (pThis->LocalSocketServer != NIL_RTSOCKET)
    588             close(pThis->LocalSocketServer);
    589         if (pThis->pszLocation)
    590             RTFileDelete(pThis->pszLocation);
    591     }
    592     else
    593     {
    594         if (pThis->LocalSocket != NIL_RTSOCKET)
    595             close(pThis->LocalSocket);
    596     }
    597 #endif /* !RT_OS_WINDOWS */
    598600}
    599601
  • trunk/src/VBox/Devices/Serial/DrvRawFile.cpp

    r25985 r26001  
    6969
    7070
     71/* -=-=-=-=- PDMISTREAM -=-=-=-=- */
    7172
    7273/** @copydoc PDMISTREAM::pfnWrite */
     
    9495}
    9596
     97/* -=-=-=-=- PDMIBASE -=-=-=-=- */
    9698
    9799/**
     
    108110}
    109111
     112/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
     113
     114
     115/**
     116 * Power off a raw output stream driver instance.
     117 *
     118 * This does most of the destruction work, to avoid ordering dependencies.
     119 *
     120 * @param   pDrvIns     The driver instance data.
     121 */
     122static DECLCALLBACK(void) drvRawFilePowerOff(PPDMDRVINS pDrvIns)
     123{
     124    PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
     125    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
     126
     127    if (pThis->OutputFile != NIL_RTFILE)
     128    {
     129        RTFileClose(pThis->OutputFile);
     130        pThis->OutputFile = NIL_RTFILE;
     131    }
     132}
     133
     134
     135/**
     136 * Destruct a raw output stream driver instance.
     137 *
     138 * Most VM resources are freed by the VM. This callback is provided so that
     139 * any non-VM resources can be freed correctly.
     140 *
     141 * @param   pDrvIns     The driver instance data.
     142 */
     143static DECLCALLBACK(void) drvRawFileDestruct(PPDMDRVINS pDrvIns)
     144{
     145    PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
     146    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
     147    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     148
     149    if (pThis->pszLocation)
     150        MMR3HeapFree(pThis->pszLocation);
     151
     152    if (pThis->OutputFile != NIL_RTFILE)
     153    {
     154        RTFileClose(pThis->OutputFile);
     155        pThis->OutputFile = NIL_RTFILE;
     156    }
     157}
     158
    110159
    111160/**
     
    117166{
    118167    PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
     168    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    119169
    120170    /*
     
    152202    LogRel(("RawFile#%u: location %s\n", pDrvIns->iInstance, pThis->pszLocation));
    153203    return VINF_SUCCESS;
    154 }
    155 
    156 
    157 /**
    158  * Destruct a raw output stream driver instance.
    159  *
    160  * Most VM resources are freed by the VM. This callback is provided so that
    161  * any non-VM resources can be freed correctly.
    162  *
    163  * @param   pDrvIns     The driver instance data.
    164  */
    165 static DECLCALLBACK(void) drvRawFileDestruct(PPDMDRVINS pDrvIns)
    166 {
    167     PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
    168     LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
    169 
    170     if (pThis->pszLocation)
    171         MMR3HeapFree(pThis->pszLocation);
    172 
    173     if (pThis->OutputFile != NIL_RTFILE)
    174     {
    175         RTFileClose(pThis->OutputFile);
    176         pThis->OutputFile = NIL_RTFILE;
    177     }
    178 }
    179 
    180 
    181 /**
    182  * Power off a raw output stream driver instance.
    183  *
    184  * This does most of the destruction work, to avoid ordering dependencies.
    185  *
    186  * @param   pDrvIns     The driver instance data.
    187  */
    188 static DECLCALLBACK(void) drvRawFilePowerOff(PPDMDRVINS pDrvIns)
    189 {
    190     PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
    191     LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
    192 
    193     if (pThis->OutputFile != NIL_RTFILE)
    194     {
    195         RTFileClose(pThis->OutputFile);
    196         pThis->OutputFile = NIL_RTFILE;
    197     }
    198204}
    199205
  • trunk/src/VBox/Devices/Storage/DevAHCI.cpp

    r25985 r26001  
    60596059static DECLCALLBACK(int) ahciR3Destruct(PPDMDEVINS pDevIns)
    60606060{
    6061     PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
    6062     int rc = VINF_SUCCESS;
    6063     unsigned iActPort = 0;
     6061    PAHCI       pAhci    = PDMINS_2_DATA(pDevIns, PAHCI);
     6062    int         rc       = VINF_SUCCESS;
     6063    unsigned    iActPort = 0;
     6064    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
    60646065
    60656066    /*
     
    64796480    bool       fR0Enabled = false;
    64806481    uint32_t   cbTotalBufferSize = 0;
     6482    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    64816483
    64826484    /*
  • trunk/src/VBox/Devices/Storage/DevATA.cpp

    r25999 r26001  
    11581158      count--;
    11591159    }
    1160            
     1160
    11611161    return (uint8_t)-(int32_t)sum;
    11621162}
     
    13141314    p[93] = RT_H2LE_U16((1 | 1 << 1) << ((s->iLUN & 1) == 0 ? 0 : 8) | 1 << 13 | 1 << 14);
    13151315    /* According to ATAPI-5 spec:
    1316      * 
    1317      * The use of this word is optional. 
    1318      * If bits 7:0 of this word contain the signature A5h, bits 15:8 
     1316     *
     1317     * The use of this word is optional.
     1318     * If bits 7:0 of this word contain the signature A5h, bits 15:8
    13191319     * contain the data
    1320      * structure checksum. 
    1321      * The data structure checksum is the twos complement of the sum of 
    1322      * all bytes in words 0 through 254 and the byte consisting of 
    1323      * bits 7:0 in word 255. 
    1324      * Each byte shall be added with unsigned arithmetic, 
    1325      * and overflow shall be ignored. 
     1320     * structure checksum.
     1321     * The data structure checksum is the twos complement of the sum of
     1322     * all bytes in words 0 through 254 and the byte consisting of
     1323     * bits 7:0 in word 255.
     1324     * Each byte shall be added with unsigned arithmetic,
     1325     * and overflow shall be ignored.
    13261326     * The sum of all 512 bytes is zero when the checksum is correct.
    13271327     */
     
    55825582
    55835583    Log(("ataR3Destruct\n"));
     5584    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
    55845585
    55855586    /*
     
    65266527
    65276528    Assert(iInstance == 0);
     6529    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    65286530
    65296531    /*
  • trunk/src/VBox/Devices/Storage/DevBusLogic.cpp

    r25985 r26001  
    25082508static DECLCALLBACK(int) buslogicDestruct(PPDMDEVINS pDevIns)
    25092509{
    2510     int rc = VINF_SUCCESS;
    25112510    PBUSLOGIC  pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
    2512 
    2513     rc = RTCacheDestroy(pThis->pTaskCache);
     2511    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
     2512
     2513    int rc = RTCacheDestroy(pThis->pTaskCache);
    25142514    AssertMsgRC(rc, ("Destroying task cache failed rc=%Rrc\n", rc));
    25152515
     
    25342534    PBUSLOGIC  pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
    25352535    int        rc = VINF_SUCCESS;
     2536    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    25362537
    25372538    /*
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp

    r25985 r26001  
    43544354{
    43554355    PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);
    4356     int rc = VINF_SUCCESS;
     4356    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
    43574357
    43584358    PDMR3CritSectDelete(&pThis->ReplyFreeQueueCritSect);
     
    43634363
    43644364    /* Destroy task cache. */
     4365    int rc = VINF_SUCCESS;
    43654366    if (pThis->pTaskCache)
    43664367        rc = RTCacheDestroy(pThis->pTaskCache);
     
    43804381    char *pszCtrlType = NULL;
    43814382    PVM pVM = PDMDevHlpGetVM(pDevIns);
     4383    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    43824384
    43834385    /*
  • trunk/src/VBox/Devices/Storage/DrvBlock.cpp

    r25985 r26001  
    701701    PDRVBLOCK pThis = PDMINS_2_DATA(pDrvIns, PDRVBLOCK);
    702702    LogFlow(("drvblockConstruct: iInstance=%d\n", pDrvIns->iInstance));
     703    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    703704
    704705    /*
  • trunk/src/VBox/Devices/Storage/DrvMediaISO.cpp

    r25985 r26001  
    6969
    7070
    71 /*******************************************************************************
    72 *   Internal Functions                                                         *
    73 *******************************************************************************/
    74 static DECLCALLBACK(int) drvMediaISORead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead);
    75 static DECLCALLBACK(int) drvMediaISOWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite);
    76 static DECLCALLBACK(int) drvMediaISOFlush(PPDMIMEDIA pInterface);
    77 static DECLCALLBACK(bool) drvMediaISOIsReadOnly(PPDMIMEDIA pInterface);
    78 static DECLCALLBACK(uint64_t) drvMediaISOGetSize(PPDMIMEDIA pInterface);
    79 static DECLCALLBACK(int) drvMediaISOGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid);
    80 static DECLCALLBACK(int) drvMediaISOBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry);
    81 static DECLCALLBACK(int) drvMediaISOBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry);
    82 static DECLCALLBACK(int) drvMediaISOBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry);
    83 static DECLCALLBACK(int) drvMediaISOBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry);
    84 
    85 static DECLCALLBACK(void *) drvMediaISOQueryInterface(PPDMIBASE pInterface, const char *pszIID);
    86 
    87 
     71/* -=-=-=-=- PDMIMEDIA -=-=-=-=- */
     72
     73/** @copydoc PDMIMEDIA::pfnGetSize */
     74static DECLCALLBACK(uint64_t) drvMediaISOGetSize(PPDMIMEDIA pInterface)
     75{
     76    PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
     77    LogFlow(("drvMediaISOGetSize: '%s'\n", pThis->pszFilename));
     78
     79    uint64_t cbFile;
     80    int rc = RTFileGetSize(pThis->File, &cbFile);
     81    if (RT_SUCCESS(rc))
     82    {
     83        LogFlow(("drvMediaISOGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
     84        return cbFile;
     85    }
     86
     87    AssertMsgFailed(("Error querying ISO file size, rc=%Rrc. (%s)\n", rc, pThis->pszFilename));
     88    return 0;
     89}
     90
     91
     92/** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
     93static DECLCALLBACK(int) drvMediaISOBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
     94{
     95    return VERR_NOT_IMPLEMENTED;
     96}
     97
     98
     99/** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
     100static DECLCALLBACK(int) drvMediaISOBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
     101{
     102    return VERR_NOT_IMPLEMENTED;
     103}
     104
     105
     106/** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
     107static DECLCALLBACK(int) drvMediaISOBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
     108{
     109    return VERR_NOT_IMPLEMENTED;
     110}
     111
     112
     113/** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
     114static DECLCALLBACK(int) drvMediaISOBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
     115{
     116    return VERR_NOT_IMPLEMENTED;
     117}
     118
     119
     120/**
     121 * Read bits.
     122 *
     123 * @see PDMIMEDIA::pfnRead for details.
     124 */
     125static DECLCALLBACK(int) drvMediaISORead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
     126{
     127    PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
     128    LogFlow(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
     129
     130    Assert(pThis->File);
     131    Assert(pvBuf);
     132
     133    /*
     134     * Seek to the position and read.
     135     */
     136    int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
     137    if (RT_SUCCESS(rc))
     138    {
     139        rc = RTFileRead(pThis->File, pvBuf, cbRead, NULL);
     140        if (RT_SUCCESS(rc))
     141        {
     142            Log2(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
     143                  "%16.*Rhxd\n",
     144                  off, pvBuf, cbRead, pThis->pszFilename,
     145                  cbRead, pvBuf));
     146        }
     147        else
     148            AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
     149                             pThis->File, pvBuf, cbRead, rc, off, pThis->pszFilename));
     150    }
     151    else
     152        AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
     153    LogFlow(("drvMediaISORead: returns %Rrc\n", rc));
     154    return rc;
     155}
     156
     157
     158/** @copydoc PDMIMEDIA::pfnWrite */
     159static DECLCALLBACK(int) drvMediaISOWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
     160{
     161    AssertMsgFailed(("Attempt to write to an ISO file!\n"));
     162    return VERR_NOT_IMPLEMENTED;
     163}
     164
     165
     166/** @copydoc PDMIMEDIA::pfnFlush */
     167static DECLCALLBACK(int) drvMediaISOFlush(PPDMIMEDIA pInterface)
     168{
     169    /* No buffered data that still needs to be written. */
     170    return VINF_SUCCESS;
     171}
     172
     173
     174/** @copydoc PDMIMEDIA::pfnGetUuid */
     175static DECLCALLBACK(int) drvMediaISOGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
     176{
     177    LogFlow(("drvMediaISOGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
     178    return VERR_NOT_IMPLEMENTED;
     179}
     180
     181
     182/** @copydoc PDMIMEDIA::pfnIsReadOnly */
     183static DECLCALLBACK(bool) drvMediaISOIsReadOnly(PPDMIMEDIA pInterface)
     184{
     185    return true;
     186}
     187
     188/* -=-=-=-=- PDMIBASE -=-=-=-=- */
     189
     190/**
     191 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
     192 */
     193static DECLCALLBACK(void *) drvMediaISOQueryInterface(PPDMIBASE pInterface, const char *pszIID)
     194{
     195    PPDMDRVINS pDrvIns = PDMIBASE_2_DRVINS(pInterface);
     196    PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
     197    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
     198    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
     199    return NULL;
     200}
     201
     202/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
     203
     204/**
     205 * Destruct a driver instance.
     206 *
     207 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
     208 * resources can be freed correctly.
     209 *
     210 * @param   pDrvIns     The driver instance data.
     211 */
     212static DECLCALLBACK(void) drvMediaISODestruct(PPDMDRVINS pDrvIns)
     213{
     214    PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
     215    LogFlow(("drvMediaISODestruct: '%s'\n", pThis->pszFilename));
     216    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     217
     218    if (pThis->File != NIL_RTFILE)
     219    {
     220        RTFileClose(pThis->File);
     221        pThis->File = NIL_RTFILE;
     222    }
     223    if (pThis->pszFilename)
     224        MMR3HeapFree(pThis->pszFilename);
     225}
    88226
    89227
     
    96234{
    97235    PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
     236    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    98237
    99238    /*
     
    144283
    145284    return rc;
    146 }
    147 
    148 
    149 /**
    150  * Destruct a driver instance.
    151  *
    152  * Most VM resources are freed by the VM. This callback is provided so that any non-VM
    153  * resources can be freed correctly.
    154  *
    155  * @param   pDrvIns     The driver instance data.
    156  */
    157 static DECLCALLBACK(void) drvMediaISODestruct(PPDMDRVINS pDrvIns)
    158 {
    159     PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
    160     LogFlow(("drvMediaISODestruct: '%s'\n", pThis->pszFilename));
    161 
    162     if (pThis->File != NIL_RTFILE)
    163     {
    164         RTFileClose(pThis->File);
    165         pThis->File = NIL_RTFILE;
    166     }
    167     if (pThis->pszFilename)
    168         MMR3HeapFree(pThis->pszFilename);
    169 }
    170 
    171 
    172 /** @copydoc PDMIMEDIA::pfnGetSize */
    173 static DECLCALLBACK(uint64_t) drvMediaISOGetSize(PPDMIMEDIA pInterface)
    174 {
    175     PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
    176     LogFlow(("drvMediaISOGetSize: '%s'\n", pThis->pszFilename));
    177 
    178     uint64_t cbFile;
    179     int rc = RTFileGetSize(pThis->File, &cbFile);
    180     if (RT_SUCCESS(rc))
    181     {
    182         LogFlow(("drvMediaISOGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
    183         return cbFile;
    184     }
    185 
    186     AssertMsgFailed(("Error querying ISO file size, rc=%Rrc. (%s)\n", rc, pThis->pszFilename));
    187     return 0;
    188 }
    189 
    190 
    191 /** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
    192 static DECLCALLBACK(int) drvMediaISOBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
    193 {
    194     return VERR_NOT_IMPLEMENTED;
    195 }
    196 
    197 
    198 /** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
    199 static DECLCALLBACK(int) drvMediaISOBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
    200 {
    201     return VERR_NOT_IMPLEMENTED;
    202 }
    203 
    204 
    205 /** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
    206 static DECLCALLBACK(int) drvMediaISOBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
    207 {
    208     return VERR_NOT_IMPLEMENTED;
    209 }
    210 
    211 
    212 /** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
    213 static DECLCALLBACK(int) drvMediaISOBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
    214 {
    215     return VERR_NOT_IMPLEMENTED;
    216 }
    217 
    218 
    219 /**
    220  * Read bits.
    221  *
    222  * @see PDMIMEDIA::pfnRead for details.
    223  */
    224 static DECLCALLBACK(int) drvMediaISORead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
    225 {
    226     PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
    227     LogFlow(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
    228 
    229     Assert(pThis->File);
    230     Assert(pvBuf);
    231 
    232     /*
    233      * Seek to the position and read.
    234      */
    235     int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
    236     if (RT_SUCCESS(rc))
    237     {
    238         rc = RTFileRead(pThis->File, pvBuf, cbRead, NULL);
    239         if (RT_SUCCESS(rc))
    240         {
    241             Log2(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
    242                   "%16.*Rhxd\n",
    243                   off, pvBuf, cbRead, pThis->pszFilename,
    244                   cbRead, pvBuf));
    245         }
    246         else
    247             AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
    248                              pThis->File, pvBuf, cbRead, rc, off, pThis->pszFilename));
    249     }
    250     else
    251         AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
    252     LogFlow(("drvMediaISORead: returns %Rrc\n", rc));
    253     return rc;
    254 }
    255 
    256 
    257 /** @copydoc PDMIMEDIA::pfnWrite */
    258 static DECLCALLBACK(int) drvMediaISOWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
    259 {
    260     AssertMsgFailed(("Attempt to write to an ISO file!\n"));
    261     return VERR_NOT_IMPLEMENTED;
    262 }
    263 
    264 
    265 /** @copydoc PDMIMEDIA::pfnFlush */
    266 static DECLCALLBACK(int) drvMediaISOFlush(PPDMIMEDIA pInterface)
    267 {
    268     /* No buffered data that still needs to be written. */
    269     return VINF_SUCCESS;
    270 }
    271 
    272 
    273 /** @copydoc PDMIMEDIA::pfnGetUuid */
    274 static DECLCALLBACK(int) drvMediaISOGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
    275 {
    276     LogFlow(("drvMediaISOGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
    277     return VERR_NOT_IMPLEMENTED;
    278 }
    279 
    280 
    281 /** @copydoc PDMIMEDIA::pfnIsReadOnly */
    282 static DECLCALLBACK(bool) drvMediaISOIsReadOnly(PPDMIMEDIA pInterface)
    283 {
    284     return true;
    285 }
    286 
    287 
    288 /**
    289  * @interface_method_impl{PDMIBASE,pfnQueryInterface}
    290  */
    291 static DECLCALLBACK(void *) drvMediaISOQueryInterface(PPDMIBASE pInterface, const char *pszIID)
    292 {
    293     PPDMDRVINS pDrvIns = PDMIBASE_2_DRVINS(pInterface);
    294     PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
    295     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
    296     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
    297     return NULL;
    298285}
    299286
  • trunk/src/VBox/Devices/Storage/DrvRawImage.cpp

    r25985 r26001  
    7272
    7373
    74 /*******************************************************************************
    75 *   Internal Functions                                                         *
    76 *******************************************************************************/
    77 static DECLCALLBACK(int) drvRawImageRead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead);
    78 static DECLCALLBACK(int) drvRawImageWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite);
    79 static DECLCALLBACK(int) drvRawImageFlush(PPDMIMEDIA pInterface);
    80 static DECLCALLBACK(bool) drvRawImageIsReadOnly(PPDMIMEDIA pInterface);
    81 static DECLCALLBACK(uint64_t) drvRawImageGetSize(PPDMIMEDIA pInterface);
    82 static DECLCALLBACK(int) drvRawImageGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid);
    83 static DECLCALLBACK(int) drvRawImageBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry);
    84 static DECLCALLBACK(int) drvRawImageBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry);
    85 static DECLCALLBACK(int) drvRawImageBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry);
    86 static DECLCALLBACK(int) drvRawImageBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry);
    87 
    88 static DECLCALLBACK(void *) drvRawImageQueryInterface(PPDMIBASE pInterface, const char *pszIID);
    89 
    90 
     74/* -=-=-=-=- PDMIMEDIA -=-=-=-=- */
     75
     76/** @copydoc PDMIMEDIA::pfnGetSize */
     77static DECLCALLBACK(uint64_t) drvRawImageGetSize(PPDMIMEDIA pInterface)
     78{
     79    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
     80    LogFlow(("drvRawImageGetSize: '%s'\n", pThis->pszFilename));
     81
     82    uint64_t cbFile;
     83    int rc = RTFileGetSize(pThis->File, &cbFile);
     84    if (RT_SUCCESS(rc))
     85    {
     86        LogFlow(("drvRawImageGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
     87        return cbFile;
     88    }
     89
     90    AssertMsgFailed(("Error querying Raw image file size, rc=%Rrc. (%s)\n", rc, pThis->pszFilename));
     91    return 0;
     92}
     93
     94
     95/** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
     96static DECLCALLBACK(int) drvRawImageBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
     97{
     98    return VERR_NOT_IMPLEMENTED;
     99}
     100
     101
     102/** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
     103static DECLCALLBACK(int) drvRawImageBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
     104{
     105    return VERR_NOT_IMPLEMENTED;
     106}
     107
     108
     109/** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
     110static DECLCALLBACK(int) drvRawImageBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
     111{
     112    return VERR_NOT_IMPLEMENTED;
     113}
     114
     115
     116/** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
     117static DECLCALLBACK(int) drvRawImageBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
     118{
     119    return VERR_NOT_IMPLEMENTED;
     120}
     121
     122
     123/**
     124 * Read bits.
     125 *
     126 * @see PDMIMEDIA::pfnRead for details.
     127 */
     128static DECLCALLBACK(int) drvRawImageRead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
     129{
     130    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
     131    LogFlow(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
     132
     133    Assert(pThis->File);
     134    Assert(pvBuf);
     135
     136    /*
     137     * Seek to the position and read.
     138     */
     139    int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
     140    if (RT_SUCCESS(rc))
     141    {
     142        rc = RTFileRead(pThis->File, pvBuf, cbRead, NULL);
     143        if (RT_SUCCESS(rc))
     144        {
     145            Log2(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
     146                  "%16.*Rhxd\n",
     147                  off, pvBuf, cbRead, pThis->pszFilename,
     148                  cbRead, pvBuf));
     149        }
     150        else
     151            AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
     152                             pThis->File, pvBuf, cbRead, rc, off, pThis->pszFilename));
     153    }
     154    else
     155        AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
     156    LogFlow(("drvRawImageRead: returns %Rrc\n", rc));
     157    return rc;
     158}
     159
     160
     161/** @copydoc PDMIMEDIA::pfnWrite */
     162static DECLCALLBACK(int) drvRawImageWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
     163{
     164    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
     165    LogFlow(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n", off, pvBuf, cbWrite, pThis->pszFilename));
     166
     167    Assert(pThis->File);
     168    Assert(pvBuf);
     169
     170    /*
     171     * Seek to the position and write.
     172     */
     173    int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
     174    if (RT_SUCCESS(rc))
     175    {
     176        rc = RTFileWrite(pThis->File, pvBuf, cbWrite, NULL);
     177        if (RT_SUCCESS(rc))
     178        {
     179            Log2(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n"
     180                  "%16.*Rhxd\n",
     181                  off, pvBuf, cbWrite, pThis->pszFilename,
     182                  cbWrite, pvBuf));
     183        }
     184        else
     185            AssertMsgFailed(("RTFileWrite(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
     186                             pThis->File, pvBuf, cbWrite, rc, off, pThis->pszFilename));
     187    }
     188    else
     189        AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
     190    LogFlow(("drvRawImageWrite: returns %Rrc\n", rc));
     191    return rc;
     192}
     193
     194
     195/** @copydoc PDMIMEDIA::pfnFlush */
     196static DECLCALLBACK(int) drvRawImageFlush(PPDMIMEDIA pInterface)
     197{
     198    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
     199    LogFlow(("drvRawImageFlush: (%s)\n", pThis->pszFilename));
     200
     201    Assert(pThis->File != NIL_RTFILE);
     202    int rc = RTFileFlush(pThis->File);
     203    LogFlow(("drvRawImageFlush: returns %Rrc\n", rc));
     204    return rc;
     205}
     206
     207
     208/** @copydoc PDMIMEDIA::pfnGetUuid */
     209static DECLCALLBACK(int) drvRawImageGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
     210{
     211    LogFlow(("drvRawImageGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
     212    return VERR_NOT_IMPLEMENTED;
     213}
     214
     215
     216/** @copydoc PDMIMEDIA::pfnIsReadOnly */
     217static DECLCALLBACK(bool) drvRawImageIsReadOnly(PPDMIMEDIA pInterface)
     218{
     219    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
     220    return pThis->fReadOnly;
     221}
     222
     223
     224/* -=-=-=-=- PDMIBASE -=-=-=-=- */
     225
     226/**
     227 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
     228 */
     229static DECLCALLBACK(void *) drvRawImageQueryInterface(PPDMIBASE pInterface, const char *pszIID)
     230{
     231    PPDMDRVINS      pDrvIns = PDMIBASE_2_DRVINS(pInterface);
     232    PDRVRAWIMAGE    pThis   = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
     233
     234    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
     235    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
     236    return NULL;
     237}
     238
     239/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
     240
     241/**
     242 * Destruct a driver instance.
     243 *
     244 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
     245 * resources can be freed correctly.
     246 *
     247 * @param   pDrvIns     The driver instance data.
     248 */
     249static DECLCALLBACK(void) drvRawImageDestruct(PPDMDRVINS pDrvIns)
     250{
     251    PDRVRAWIMAGE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
     252    LogFlow(("drvRawImageDestruct: '%s'\n", pThis->pszFilename));
     253    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     254
     255    if (pThis->File != NIL_RTFILE)
     256    {
     257        RTFileClose(pThis->File);
     258        pThis->File = NIL_RTFILE;
     259    }
     260    if (pThis->pszFilename)
     261        MMR3HeapFree(pThis->pszFilename);
     262}
    91263
    92264
     
    99271{
    100272    PDRVRAWIMAGE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
     273    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    101274
    102275    /*
     
    162335
    163336    return rc;
    164 }
    165 
    166 
    167 /**
    168  * Destruct a driver instance.
    169  *
    170  * Most VM resources are freed by the VM. This callback is provided so that any non-VM
    171  * resources can be freed correctly.
    172  *
    173  * @param   pDrvIns     The driver instance data.
    174  */
    175 static DECLCALLBACK(void) drvRawImageDestruct(PPDMDRVINS pDrvIns)
    176 {
    177     PDRVRAWIMAGE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
    178     LogFlow(("drvRawImageDestruct: '%s'\n", pThis->pszFilename));
    179 
    180     if (pThis->File != NIL_RTFILE)
    181     {
    182         RTFileClose(pThis->File);
    183         pThis->File = NIL_RTFILE;
    184     }
    185     if (pThis->pszFilename)
    186         MMR3HeapFree(pThis->pszFilename);
    187 }
    188 
    189 
    190 /** @copydoc PDMIMEDIA::pfnGetSize */
    191 static DECLCALLBACK(uint64_t) drvRawImageGetSize(PPDMIMEDIA pInterface)
    192 {
    193     PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
    194     LogFlow(("drvRawImageGetSize: '%s'\n", pThis->pszFilename));
    195 
    196     uint64_t cbFile;
    197     int rc = RTFileGetSize(pThis->File, &cbFile);
    198     if (RT_SUCCESS(rc))
    199     {
    200         LogFlow(("drvRawImageGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
    201         return cbFile;
    202     }
    203 
    204     AssertMsgFailed(("Error querying Raw image file size, rc=%Rrc. (%s)\n", rc, pThis->pszFilename));
    205     return 0;
    206 }
    207 
    208 
    209 /** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
    210 static DECLCALLBACK(int) drvRawImageBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
    211 {
    212     return VERR_NOT_IMPLEMENTED;
    213 }
    214 
    215 
    216 /** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
    217 static DECLCALLBACK(int) drvRawImageBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
    218 {
    219     return VERR_NOT_IMPLEMENTED;
    220 }
    221 
    222 
    223 /** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
    224 static DECLCALLBACK(int) drvRawImageBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
    225 {
    226     return VERR_NOT_IMPLEMENTED;
    227 }
    228 
    229 
    230 /** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
    231 static DECLCALLBACK(int) drvRawImageBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
    232 {
    233     return VERR_NOT_IMPLEMENTED;
    234 }
    235 
    236 
    237 /**
    238  * Read bits.
    239  *
    240  * @see PDMIMEDIA::pfnRead for details.
    241  */
    242 static DECLCALLBACK(int) drvRawImageRead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
    243 {
    244     PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
    245     LogFlow(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
    246 
    247     Assert(pThis->File);
    248     Assert(pvBuf);
    249 
    250     /*
    251      * Seek to the position and read.
    252      */
    253     int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
    254     if (RT_SUCCESS(rc))
    255     {
    256         rc = RTFileRead(pThis->File, pvBuf, cbRead, NULL);
    257         if (RT_SUCCESS(rc))
    258         {
    259             Log2(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
    260                   "%16.*Rhxd\n",
    261                   off, pvBuf, cbRead, pThis->pszFilename,
    262                   cbRead, pvBuf));
    263         }
    264         else
    265             AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
    266                              pThis->File, pvBuf, cbRead, rc, off, pThis->pszFilename));
    267     }
    268     else
    269         AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
    270     LogFlow(("drvRawImageRead: returns %Rrc\n", rc));
    271     return rc;
    272 }
    273 
    274 
    275 /** @copydoc PDMIMEDIA::pfnWrite */
    276 static DECLCALLBACK(int) drvRawImageWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
    277 {
    278     PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
    279     LogFlow(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n", off, pvBuf, cbWrite, pThis->pszFilename));
    280 
    281     Assert(pThis->File);
    282     Assert(pvBuf);
    283 
    284     /*
    285      * Seek to the position and write.
    286      */
    287     int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
    288     if (RT_SUCCESS(rc))
    289     {
    290         rc = RTFileWrite(pThis->File, pvBuf, cbWrite, NULL);
    291         if (RT_SUCCESS(rc))
    292         {
    293             Log2(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n"
    294                   "%16.*Rhxd\n",
    295                   off, pvBuf, cbWrite, pThis->pszFilename,
    296                   cbWrite, pvBuf));
    297         }
    298         else
    299             AssertMsgFailed(("RTFileWrite(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
    300                              pThis->File, pvBuf, cbWrite, rc, off, pThis->pszFilename));
    301     }
    302     else
    303         AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
    304     LogFlow(("drvRawImageWrite: returns %Rrc\n", rc));
    305     return rc;
    306 }
    307 
    308 
    309 /** @copydoc PDMIMEDIA::pfnFlush */
    310 static DECLCALLBACK(int) drvRawImageFlush(PPDMIMEDIA pInterface)
    311 {
    312     PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
    313     LogFlow(("drvRawImageFlush: (%s)\n", pThis->pszFilename));
    314 
    315     Assert(pThis->File != NIL_RTFILE);
    316     int rc = RTFileFlush(pThis->File);
    317     LogFlow(("drvRawImageFlush: returns %Rrc\n", rc));
    318     return rc;
    319 }
    320 
    321 
    322 /** @copydoc PDMIMEDIA::pfnGetUuid */
    323 static DECLCALLBACK(int) drvRawImageGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
    324 {
    325     LogFlow(("drvRawImageGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
    326     return VERR_NOT_IMPLEMENTED;
    327 }
    328 
    329 
    330 /** @copydoc PDMIMEDIA::pfnIsReadOnly */
    331 static DECLCALLBACK(bool) drvRawImageIsReadOnly(PPDMIMEDIA pInterface)
    332 {
    333     PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
    334     return pThis->fReadOnly;
    335 }
    336 
    337 
    338 /**
    339  * @interface_method_impl{PDMIBASE,pfnQueryInterface}
    340  */
    341 static DECLCALLBACK(void *) drvRawImageQueryInterface(PPDMIBASE pInterface, const char *pszIID)
    342 {
    343     PPDMDRVINS      pDrvIns = PDMIBASE_2_DRVINS(pInterface);
    344     PDRVRAWIMAGE    pThis   = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
    345 
    346     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
    347     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
    348     return NULL;
    349337}
    350338
  • trunk/src/VBox/Devices/Storage/DrvSCSI.cpp

    r25985 r26001  
    914914static DECLCALLBACK(void) drvscsiDestruct(PPDMDRVINS pDrvIns)
    915915{
    916     int rc;
    917916    PDRVSCSI pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSI);
     917    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    918918
    919919    if (pThis->pQueueRequests)
     
    922922            LogRel(("drvscsiDestruct#%u: previous dummy request is still pending\n", pDrvIns->iInstance));
    923923
    924         rc = RTReqDestroyQueue(pThis->pQueueRequests);
     924        int rc = RTReqDestroyQueue(pThis->pQueueRequests);
    925925        AssertMsgRC(rc, ("Failed to destroy queue rc=%Rrc\n", rc));
    926926    }
    927 
    928927}
    929928
     
    936935{
    937936    PDRVSCSI pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSI);
    938 
    939937    LogFlowFunc(("pDrvIns=%#p pCfgHandle=%#p\n", pDrvIns, pCfgHandle));
     938    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    940939
    941940    /*
  • trunk/src/VBox/Devices/Storage/DrvSCSIHost.cpp

    r25985 r26001  
    394394}
    395395
    396 /* -=-=-=-=- IBase -=-=-=-=- */
     396/* -=-=-=-=- PDMIBASE -=-=-=-=- */
    397397
    398398/**
     
    409409}
    410410
     411/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
     412
    411413/**
    412414 * Destruct a driver instance.
     
    419421static DECLCALLBACK(void) drvscsihostDestruct(PPDMDRVINS pDrvIns)
    420422{
    421     int rc;
    422423    PDRVSCSIHOST pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSIHOST);
     424    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    423425
    424426    if (pThis->DeviceFile != NIL_RTFILE)
     
    430432    if (pThis->pQueueRequests)
    431433    {
    432         rc = RTReqDestroyQueue(pThis->pQueueRequests);
     434        int rc = RTReqDestroyQueue(pThis->pQueueRequests);
    433435        AssertMsgRC(rc, ("Failed to destroy queue rc=%Rrc\n", rc));
    434436    }
     
    444446{
    445447    PDRVSCSIHOST pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSIHOST);
    446 
    447448    LogFlowFunc(("pDrvIns=%#p pCfgHandle=%#p\n", pDrvIns, pCfgHandle));
     449    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    448450
    449451    /*
  • trunk/src/VBox/Devices/Storage/DrvVD.cpp

    r25985 r26001  
    951951    PVBOXDISK pThis = PDMINS_2_DATA(pDrvIns, PVBOXDISK);
    952952    LogFlow(("%s:\n", __FUNCTION__));
     953    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    953954
    954955    if (VALID_PTR(pThis->pDisk))
     
    976977    bool fReadOnly;         /**< True if the media is read-only. */
    977978    bool fHonorZeroWrites;  /**< True if zero blocks should be written. */
     979    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    978980
    979981    /*
  • trunk/src/VBox/Devices/Storage/fdc.c

    r25985 r26001  
    27642764
    27652765    Assert(iInstance == 0);
     2766    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    27662767
    27672768    /*
  • trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r25985 r26001  
    24042404}
    24052405
     2406/* -=-=-=-=- PDMDEVREG -=-=-=-=- */
     2407
    24062408/**
    24072409 * (Re-)initializes the MMIO2 data.
     
    24152417    pThis->pVMMDevRAMR3->u32Version = VMMDEV_MEMORY_VERSION;
    24162418}
     2419
     2420/**
     2421 * Reset notification.
     2422 *
     2423 * @returns VBox status.
     2424 * @param   pDrvIns     The driver instance data.
     2425 */
     2426static DECLCALLBACK(void) vmmdevReset(PPDMDEVINS pDevIns)
     2427{
     2428    VMMDevState *pThis = PDMINS_2_DATA(pDevIns, VMMDevState*);
     2429
     2430    /*
     2431     * Reset the mouse integration feature bits
     2432     */
     2433    if (pThis->mouseCapabilities & VMMDEV_MOUSE_GUEST_MASK)
     2434    {
     2435        pThis->mouseCapabilities &= ~VMMDEV_MOUSE_GUEST_MASK;
     2436        /* notify the connector */
     2437        Log(("vmmdevReset: capabilities changed (%x), informing connector\n", pThis->mouseCapabilities));
     2438        pThis->pDrv->pfnUpdateMouseCapabilities(pThis->pDrv, pThis->mouseCapabilities);
     2439    }
     2440    pThis->fHostCursorRequested = false;
     2441
     2442    pThis->hypervisorSize = 0;
     2443
     2444    pThis->u32HostEventFlags = 0;
     2445
     2446    /* re-initialize the VMMDev memory */
     2447    if (pThis->pVMMDevRAMR3)
     2448        vmmdevInitRam(pThis);
     2449
     2450    /* credentials have to go away (by default) */
     2451    if (!pThis->fKeepCredentials)
     2452    {
     2453        memset(pThis->credentialsLogon.szUserName, '\0', VMMDEV_CREDENTIALS_STRLEN);
     2454        memset(pThis->credentialsLogon.szPassword, '\0', VMMDEV_CREDENTIALS_STRLEN);
     2455        memset(pThis->credentialsLogon.szDomain, '\0', VMMDEV_CREDENTIALS_STRLEN);
     2456    }
     2457    memset(pThis->credentialsJudge.szUserName, '\0', VMMDEV_CREDENTIALS_STRLEN);
     2458    memset(pThis->credentialsJudge.szPassword, '\0', VMMDEV_CREDENTIALS_STRLEN);
     2459    memset(pThis->credentialsJudge.szDomain, '\0', VMMDEV_CREDENTIALS_STRLEN);
     2460
     2461    /* Reset means that additions will report again. */
     2462    const bool fVersionChanged = pThis->fu32AdditionsOk
     2463                              || pThis->guestInfo.additionsVersion
     2464                              || pThis->guestInfo.osType != VBOXOSTYPE_Unknown;
     2465    if (fVersionChanged)
     2466        Log(("vmmdevReset: fu32AdditionsOk=%d additionsVersion=%x osType=%#x\n",
     2467             pThis->fu32AdditionsOk, pThis->guestInfo.additionsVersion, pThis->guestInfo.osType));
     2468    pThis->fu32AdditionsOk = false;
     2469    memset (&pThis->guestInfo, 0, sizeof (pThis->guestInfo));
     2470
     2471    /* clear pending display change request. */
     2472    memset (&pThis->lastReadDisplayChangeRequest, 0, sizeof (pThis->lastReadDisplayChangeRequest));
     2473    pThis->fGuestSentChangeEventAck = false;
     2474
     2475    /* disable seamless mode */
     2476    pThis->fLastSeamlessEnabled = false;
     2477
     2478    /* disabled memory ballooning */
     2479    pThis->u32LastMemoryBalloonSize = 0;
     2480
     2481    /* disabled statistics updating */
     2482    pThis->u32LastStatIntervalSize = 0;
     2483
     2484    /* Clear the "HGCM event enabled" flag so the event can be automatically reenabled.  */
     2485    pThis->u32HGCMEnabled = 0;
     2486
     2487    /*
     2488     * Clear the event variables.
     2489     *
     2490     *   Note: The pThis->u32HostEventFlags is not cleared.
     2491     *         It is designed that way so host events do not
     2492     *         depend on guest resets.
     2493     */
     2494    pThis->u32GuestFilterMask    = 0;
     2495    pThis->u32NewGuestFilterMask = 0;
     2496    pThis->fNewGuestFilterMask   = 0;
     2497
     2498    /* This is the default, as Windows and OS/2 guests take this for granted. (Actually, neither does...) */
     2499    /** @todo change this when we next bump the interface version */
     2500    const bool fCapsChanged = pThis->guestCaps != VMMDEV_GUEST_SUPPORTS_GRAPHICS;
     2501    if (fCapsChanged)
     2502        Log(("vmmdevReset: fCapsChanged=%#x -> %#x\n", pThis->guestCaps, VMMDEV_GUEST_SUPPORTS_GRAPHICS));
     2503    pThis->guestCaps = VMMDEV_GUEST_SUPPORTS_GRAPHICS; /** @todo r=bird: why? I cannot see this being done at construction?*/
     2504
     2505    /*
     2506     * Call the update functions as required.
     2507     */
     2508    if (fVersionChanged)
     2509        pThis->pDrv->pfnUpdateGuestVersion(pThis->pDrv, &pThis->guestInfo);
     2510    if (fCapsChanged)
     2511        pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, pThis->guestCaps);
     2512}
     2513
    24172514
    24182515/**
     
    24352532
    24362533    Assert(iInstance == 0);
     2534    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    24372535
    24382536    /*
     
    26372735
    26382736    return rc;
    2639 }
    2640 
    2641 /**
    2642  * Reset notification.
    2643  *
    2644  * @returns VBox status.
    2645  * @param   pDrvIns     The driver instance data.
    2646  */
    2647 static DECLCALLBACK(void) vmmdevReset(PPDMDEVINS pDevIns)
    2648 {
    2649     VMMDevState *pThis = PDMINS_2_DATA(pDevIns, VMMDevState*);
    2650 
    2651     /*
    2652      * Reset the mouse integration feature bits
    2653      */
    2654     if (pThis->mouseCapabilities & VMMDEV_MOUSE_GUEST_MASK)
    2655     {
    2656         pThis->mouseCapabilities &= ~VMMDEV_MOUSE_GUEST_MASK;
    2657         /* notify the connector */
    2658         Log(("vmmdevReset: capabilities changed (%x), informing connector\n", pThis->mouseCapabilities));
    2659         pThis->pDrv->pfnUpdateMouseCapabilities(pThis->pDrv, pThis->mouseCapabilities);
    2660     }
    2661     pThis->fHostCursorRequested = false;
    2662 
    2663     pThis->hypervisorSize = 0;
    2664 
    2665     pThis->u32HostEventFlags = 0;
    2666 
    2667     /* re-initialize the VMMDev memory */
    2668     if (pThis->pVMMDevRAMR3)
    2669         vmmdevInitRam(pThis);
    2670 
    2671     /* credentials have to go away (by default) */
    2672     if (!pThis->fKeepCredentials)
    2673     {
    2674         memset(pThis->credentialsLogon.szUserName, '\0', VMMDEV_CREDENTIALS_STRLEN);
    2675         memset(pThis->credentialsLogon.szPassword, '\0', VMMDEV_CREDENTIALS_STRLEN);
    2676         memset(pThis->credentialsLogon.szDomain, '\0', VMMDEV_CREDENTIALS_STRLEN);
    2677     }
    2678     memset(pThis->credentialsJudge.szUserName, '\0', VMMDEV_CREDENTIALS_STRLEN);
    2679     memset(pThis->credentialsJudge.szPassword, '\0', VMMDEV_CREDENTIALS_STRLEN);
    2680     memset(pThis->credentialsJudge.szDomain, '\0', VMMDEV_CREDENTIALS_STRLEN);
    2681 
    2682     /* Reset means that additions will report again. */
    2683     const bool fVersionChanged = pThis->fu32AdditionsOk
    2684                               || pThis->guestInfo.additionsVersion
    2685                               || pThis->guestInfo.osType != VBOXOSTYPE_Unknown;
    2686     if (fVersionChanged)
    2687         Log(("vmmdevReset: fu32AdditionsOk=%d additionsVersion=%x osType=%#x\n",
    2688              pThis->fu32AdditionsOk, pThis->guestInfo.additionsVersion, pThis->guestInfo.osType));
    2689     pThis->fu32AdditionsOk = false;
    2690     memset (&pThis->guestInfo, 0, sizeof (pThis->guestInfo));
    2691 
    2692     /* clear pending display change request. */
    2693     memset (&pThis->lastReadDisplayChangeRequest, 0, sizeof (pThis->lastReadDisplayChangeRequest));
    2694     pThis->fGuestSentChangeEventAck = false;
    2695 
    2696     /* disable seamless mode */
    2697     pThis->fLastSeamlessEnabled = false;
    2698 
    2699     /* disabled memory ballooning */
    2700     pThis->u32LastMemoryBalloonSize = 0;
    2701 
    2702     /* disabled statistics updating */
    2703     pThis->u32LastStatIntervalSize = 0;
    2704 
    2705     /* Clear the "HGCM event enabled" flag so the event can be automatically reenabled.  */
    2706     pThis->u32HGCMEnabled = 0;
    2707 
    2708     /*
    2709      * Clear the event variables.
    2710      *
    2711      *   Note: The pThis->u32HostEventFlags is not cleared.
    2712      *         It is designed that way so host events do not
    2713      *         depend on guest resets.
    2714      */
    2715     pThis->u32GuestFilterMask    = 0;
    2716     pThis->u32NewGuestFilterMask = 0;
    2717     pThis->fNewGuestFilterMask   = 0;
    2718 
    2719     /* This is the default, as Windows and OS/2 guests take this for granted. (Actually, neither does...) */
    2720     /** @todo change this when we next bump the interface version */
    2721     const bool fCapsChanged = pThis->guestCaps != VMMDEV_GUEST_SUPPORTS_GRAPHICS;
    2722     if (fCapsChanged)
    2723         Log(("vmmdevReset: fCapsChanged=%#x -> %#x\n", pThis->guestCaps, VMMDEV_GUEST_SUPPORTS_GRAPHICS));
    2724     pThis->guestCaps = VMMDEV_GUEST_SUPPORTS_GRAPHICS; /** @todo r=bird: why? I cannot see this being done at construction?*/
    2725 
    2726     /*
    2727      * Call the update functions as required.
    2728      */
    2729     if (fVersionChanged)
    2730         pThis->pDrv->pfnUpdateGuestVersion(pThis->pDrv, &pThis->guestInfo);
    2731     if (fCapsChanged)
    2732         pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, pThis->guestCaps);
    27332737}
    27342738
  • trunk/src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp

    r25971 r26001  
    11711171    PDRVMAINDISPLAY pData = PDMINS_2_DATA(pDrvIns, PDRVMAINDISPLAY);
    11721172    LogFlow(("VMDisplay::drvConstruct: iInstance=%d\n", pDrvIns->iInstance));
    1173 
     1173    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    11741174
    11751175    /*
  • trunk/src/VBox/Main/AudioSnifferInterface.cpp

    r25985 r26001  
    140140    PDRVAUDIOSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOSNIFFER);
    141141    LogFlow(("AudioSniffer::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
     142    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     143
    142144    if (pThis->pAudioSniffer)
    143145    {
     
    157159
    158160    LogFlow(("AudioSniffer::drvConstruct: iInstance=%d\n", pDrvIns->iInstance));
     161    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    159162
    160163    /*
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r25985 r26001  
    81468146    PDRVMAINSTATUS pData = PDMINS_2_DATA(pDrvIns, PDRVMAINSTATUS);
    81478147    LogFlowFunc(("iInstance=%d\n", pDrvIns->iInstance));
     8148    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     8149
    81488150    if (pData->papLeds)
    81498151    {
     
    81648166    PDRVMAINSTATUS pData = PDMINS_2_DATA(pDrvIns, PDRVMAINSTATUS);
    81658167    LogFlowFunc(("iInstance=%d\n", pDrvIns->iInstance));
     8168    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    81668169
    81678170    /*
  • trunk/src/VBox/Main/DisplayImpl.cpp

    r25985 r26001  
    33853385    PDRVMAINDISPLAY pData = PDMINS_2_DATA(pDrvIns, PDRVMAINDISPLAY);
    33863386    LogFlowFunc (("iInstance=%d\n", pDrvIns->iInstance));
     3387    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
     3388
    33873389    if (pData->pDisplay)
    33883390    {
     
    34083410    PDRVMAINDISPLAY pData = PDMINS_2_DATA(pDrvIns, PDRVMAINDISPLAY);
    34093411    LogFlowFunc (("iInstance=%d\n", pDrvIns->iInstance));
     3412    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    34103413
    34113414    /*
  • trunk/src/VBox/Main/KeyboardImpl.cpp

    r25985 r26001  
    242242    PDRVMAINKEYBOARD pData = PDMINS_2_DATA(pDrvIns, PDRVMAINKEYBOARD);
    243243    LogFlow(("Keyboard::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
     244    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     245
    244246    if (pData->pKeyboard)
    245247    {
     
    267269    PDRVMAINKEYBOARD pData = PDMINS_2_DATA (pDrvIns, PDRVMAINKEYBOARD);
    268270    LogFlow(("Keyboard::drvConstruct: iInstance=%d\n", pDrvIns->iInstance));
     271    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    269272
    270273    /*
  • trunk/src/VBox/Main/MouseImpl.cpp

    r25985 r26001  
    377377    PDRVMAINMOUSE pData = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
    378378    LogFlow(("Mouse::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
     379    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     380
    379381    if (pData->pMouse)
    380382    {
     
    394396    PDRVMAINMOUSE pData = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
    395397    LogFlow(("drvMainMouse_Construct: iInstance=%d\n", pDrvIns->iInstance));
     398    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    396399
    397400    /*
  • trunk/src/VBox/VMM/PDMDevHlp.cpp

    r25995 r26001  
    19551955    return VINF_SUCCESS;
    19561956}
     1957
     1958
    19571959/** @copydoc PDMDEVHLPR3::pfnHPETRegister */
    19581960static DECLCALLBACK(int) pdmR3DevHlp_HPETRegister(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3)
     
    19841986    return VINF_SUCCESS;
    19851987}
     1988
    19861989
    19871990/** @copydoc PDMDEVHLPR3::pfnDMACRegister */
     
    29282931}
    29292932
     2933
    29302934/** @copydoc PDMDEVHLPR3::pfnHPETRegister */
    29312935static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_HPETRegister(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3)
     
    29372941    return VERR_ACCESS_DENIED;
    29382942}
     2943
    29392944
    29402945/** @copydoc PDMDEVHLPR3::pfnDMACRegister */
     
    33863391
    33873392/** @} */
     3393
  • trunk/src/VBox/VMM/PDMDevMiscHlp.cpp

    r25995 r26001  
    55
    66/*
    7  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3939
    4040
    41 /** @name HC PIC Helpers
     41/** @name Ring-3 PIC Helpers
    4242 * @{
    4343 */
     
    365365
    366366
    367 /** @name HC I/O APIC Helpers
     367/** @name Ring-3 I/O APIC Helpers
    368368 * @{
    369369 */
     
    450450
    451451
    452 /** @name HC PCI Bus Helpers
     452/** @name Ring-3 PCI Bus Helpers
    453453 * @{
    454454 */
     
    530530}
    531531
    532 
    533 /** @copydoc PDMHPETHLPR3::pfnSetLegacyMode */
    534 static DECLCALLBACK(int) pdmR3HpetHlp_SetLegacyMode(PPDMDEVINS pDevIns, bool fActivate)
    535 {
    536     PDMDEV_ASSERT_DEVINS(pDevIns);
    537     LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: fActivate=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fActivate));
    538     return 0;
    539 }
    540 
    541 /** @copydoc PDMHPETHLPR3::pfnLock */
    542 static DECLCALLBACK(int) pdmR3HpetHlp_Lock(PPDMDEVINS pDevIns, int rc)
    543 {
    544     PDMDEV_ASSERT_DEVINS(pDevIns);
    545     LogFlow(("pdmR3HpetHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
    546     return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
    547 }
    548 
    549 
    550 /** @copydoc PDMHPETHLPR3::pfnUnlock */
    551 static DECLCALLBACK(void) pdmR3HpetHlp_Unlock(PPDMDEVINS pDevIns)
    552 {
    553     PDMDEV_ASSERT_DEVINS(pDevIns);
    554     LogFlow(("pdmR3HpetHlp_Unlock: caller='%s'/%d:\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
    555     pdmUnlock(pDevIns->Internal.s.pVMR3);
    556 }
    557 
    558 /** @copydoc PDMHPETHLPR3::pfnGetRCHelpers */
    559 static DECLCALLBACK(PCPDMHPETHLPRC) pdmR3HpetHlp_GetRCHelpers(PPDMDEVINS pDevIns)
    560 {
    561     PDMDEV_ASSERT_DEVINS(pDevIns);
    562     VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    563     RTRCPTR pRCHelpers = 0;
    564     int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCHpetHlp", &pRCHelpers);
    565     AssertReleaseRC(rc);
    566     AssertRelease(pRCHelpers);
    567     LogFlow(("pdmR3HpetHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
    568              pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));
    569     return pRCHelpers;
    570 }
    571 
    572 /** @copydoc PDMHPETHLPR3::pfnGetR0Helpers */
    573 static DECLCALLBACK(PCPDMHPETHLPR0) pdmR3HpetHlp_GetR0Helpers(PPDMDEVINS pDevIns)
    574 {
    575     PDMDEV_ASSERT_DEVINS(pDevIns);
    576     VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    577     PCPDMHPETHLPR0 pR0Helpers = 0;
    578     int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0HpetHlp", &pR0Helpers);
    579     AssertReleaseRC(rc);
    580     AssertRelease(pR0Helpers);
    581     LogFlow(("pdmR3HpetHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
    582              pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));
    583     return pR0Helpers;
    584 }
    585532
    586533/**
     
    602549/** @} */
    603550
     551
     552
     553
     554/** @name Ring-3 HPET Helpers
     555 * {@
     556 */
     557
     558/** @copydoc PDMHPETHLPR3::pfnSetLegacyMode */
     559static DECLCALLBACK(int) pdmR3HpetHlp_SetLegacyMode(PPDMDEVINS pDevIns, bool fActivate)
     560{
     561    PDMDEV_ASSERT_DEVINS(pDevIns);
     562    LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: fActivate=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fActivate));
     563    return 0;
     564}
     565
     566
     567/** @copydoc PDMHPETHLPR3::pfnLock */
     568static DECLCALLBACK(int) pdmR3HpetHlp_Lock(PPDMDEVINS pDevIns, int rc)
     569{
     570    PDMDEV_ASSERT_DEVINS(pDevIns);
     571    LogFlow(("pdmR3HpetHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
     572    return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
     573}
     574
     575
     576/** @copydoc PDMHPETHLPR3::pfnUnlock */
     577static DECLCALLBACK(void) pdmR3HpetHlp_Unlock(PPDMDEVINS pDevIns)
     578{
     579    PDMDEV_ASSERT_DEVINS(pDevIns);
     580    LogFlow(("pdmR3HpetHlp_Unlock: caller='%s'/%d:\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
     581    pdmUnlock(pDevIns->Internal.s.pVMR3);
     582}
     583
     584
     585/** @copydoc PDMHPETHLPR3::pfnGetRCHelpers */
     586static DECLCALLBACK(PCPDMHPETHLPRC) pdmR3HpetHlp_GetRCHelpers(PPDMDEVINS pDevIns)
     587{
     588    PDMDEV_ASSERT_DEVINS(pDevIns);
     589    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
     590    RTRCPTR pRCHelpers = 0;
     591    int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCHpetHlp", &pRCHelpers);
     592    AssertReleaseRC(rc);
     593    AssertRelease(pRCHelpers);
     594    LogFlow(("pdmR3HpetHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
     595             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));
     596    return pRCHelpers;
     597}
     598
     599
     600/** @copydoc PDMHPETHLPR3::pfnGetR0Helpers */
     601static DECLCALLBACK(PCPDMHPETHLPR0) pdmR3HpetHlp_GetR0Helpers(PPDMDEVINS pDevIns)
     602{
     603    PDMDEV_ASSERT_DEVINS(pDevIns);
     604    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
     605    PCPDMHPETHLPR0 pR0Helpers = 0;
     606    int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0HpetHlp", &pR0Helpers);
     607    AssertReleaseRC(rc);
     608    AssertRelease(pR0Helpers);
     609    LogFlow(("pdmR3HpetHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
     610             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));
     611    return pR0Helpers;
     612}
     613
     614
    604615/**
    605616 * HPET Device Helpers.
     
    608619{
    609620    PDM_HPETHLPR3_VERSION,
    610     pdmR3HpetHlp_SetLegacyMode,   
     621    pdmR3HpetHlp_SetLegacyMode,
    611622    pdmR3HpetHlp_Lock,
    612623    pdmR3HpetHlp_Unlock,
  • trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp

    r25995 r26001  
    11/* $Id$ */
    22/** @file
    3  * PDM - Pluggable Device and Driver Manager, GC Device parts.
     3 * PDM - Pluggable Device and Driver Manager, RC Device parts.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    5656*   Internal Functions                                                         *
    5757*******************************************************************************/
    58 /** @name GC Device Helpers
     58static void pdmRCIsaSetIrq(PVM pVM, int iIrq, int iLevel);
     59static void pdmRCIoApicSetIrq(PVM pVM, int iIrq, int iLevel);
     60
     61
     62
     63
     64/** @name Raw-Mode Context Device Helpers
    5965 * @{
    6066 */
    61 static DECLCALLBACK(void) pdmGCDevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
    62 static DECLCALLBACK(void) pdmGCDevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
    63 static DECLCALLBACK(int)  pdmGCDevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
    64 static DECLCALLBACK(int)  pdmGCDevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
    65 static DECLCALLBACK(bool) pdmGCDevHlp_A20IsEnabled(PPDMDEVINS pDevIns);
    66 static DECLCALLBACK(int)  pdmGCDevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
    67 static DECLCALLBACK(int)  pdmGCDevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va);
    68 static DECLCALLBACK(int)  pdmGCDevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...);
    69 static DECLCALLBACK(int)  pdmGCDevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va);
    70 static DECLCALLBACK(int)  pdmGCDevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData);
    71 static DECLCALLBACK(PVM)  pdmGCDevHlp_GetVM(PPDMDEVINS pDevIns);
    72 static DECLCALLBACK(PVMCPU)  pdmGCDevHlp_GetVMCPU(PPDMDEVINS pDevIns);
    73 /** @} */
    74 
    75 
    76 /** @name PIC GC Helpers
    77  * @{
    78  */
    79 static DECLCALLBACK(void) pdmRCPicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
    80 static DECLCALLBACK(void) pdmRCPicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
    81 static DECLCALLBACK(int)  pdmRCPicHlp_Lock(PPDMDEVINS pDevIns, int rc);
    82 static DECLCALLBACK(void) pdmRCPicHlp_Unlock(PPDMDEVINS pDevIns);
    83 /** @} */
    84 
    85 
    86 /** @name APIC RC Helpers
    87  * @{
    88  */
    89 static DECLCALLBACK(void) pdmRCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
    90 static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
    91 static DECLCALLBACK(void) pdmRCApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion);
    92 static DECLCALLBACK(int) pdmRCApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
    93 static DECLCALLBACK(void) pdmRCApicHlp_Unlock(PPDMDEVINS pDevIns);
    94 static DECLCALLBACK(VMCPUID) pdmRCApicHlp_GetCpuId(PPDMDEVINS pDevIns);
    95 /** @} */
    96 
    97 
    98 /** @name I/O APIC RC Helpers
    99  * @{
    100  */
    101 static DECLCALLBACK(int) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
    102                                                         uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode);
    103 static DECLCALLBACK(int) pdmRCIoApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
    104 static DECLCALLBACK(void) pdmRCIoApicHlp_Unlock(PPDMDEVINS pDevIns);
    105 /** @} */
    106 
    107 
    108 /** @name PCI Bus RC Helpers
    109  * @{
    110  */
    111 static DECLCALLBACK(void) pdmRCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
    112 static DECLCALLBACK(void) pdmRCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
    113 static DECLCALLBACK(int) pdmRCPciHlp_Lock(PPDMDEVINS pDevIns, int rc);
    114 static DECLCALLBACK(void) pdmRCPciHlp_Unlock(PPDMDEVINS pDevIns);
    115 /** @} */
    116 
    117 
    118 /** @name HPET RC Helpers
    119  * @{
    120  */
    121 static DECLCALLBACK(int) pdmRCHpetHlp_Lock(PPDMDEVINS pDevIns, int rc);
    122 static DECLCALLBACK(void) pdmRCHpetHlp_Unlock(PPDMDEVINS pDevIns);
    123 /** @} */
    124 
    125 
    126 static void pdmGCIsaSetIrq(PVM pVM, int iIrq, int iLevel);
    127 static void pdmGCIoApicSetIrq(PVM pVM, int iIrq, int iLevel);
    128 
    129 
    130 
    131 /**
    132  * The Guest Context Device Helper Callbacks.
     67
     68/** @copydoc PDMDEVHLPRC::pfnPCISetIrq */
     69static DECLCALLBACK(void) pdmGCDevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
     70{
     71    PDMDEV_ASSERT_DEVINS(pDevIns);
     72    LogFlow(("pdmGCDevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
     73
     74    PVM         pVM     = pDevIns->Internal.s.pVMRC;
     75    PPCIDEVICE  pPciDev = pDevIns->Internal.s.pPciDeviceRC;
     76    PPDMPCIBUS  pPciBus = pDevIns->Internal.s.pPciBusRC;
     77    if (    pPciDev
     78        &&  pPciBus
     79        &&  pPciBus->pDevInsRC)
     80    {
     81        pdmLock(pVM);
     82        pPciBus->pfnSetIrqRC(pPciBus->pDevInsRC, pPciDev, iIrq, iLevel);
     83        pdmUnlock(pVM);
     84    }
     85    else
     86    {
     87        /* queue for ring-3 execution. */
     88        PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueRC);
     89        if (pTask)
     90        {
     91            pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
     92            pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
     93            pTask->u.SetIRQ.iIrq = iIrq;
     94            pTask->u.SetIRQ.iLevel = iLevel;
     95
     96            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0);
     97        }
     98        else
     99            AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
     100    }
     101
     102    LogFlow(("pdmGCDevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
     103}
     104
     105
     106/** @copydoc PDMDEVHLPRC::pfnPCISetIrq */
     107static DECLCALLBACK(void) pdmGCDevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
     108{
     109    PDMDEV_ASSERT_DEVINS(pDevIns);
     110    LogFlow(("pdmGCDevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
     111
     112    pdmRCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
     113
     114    LogFlow(("pdmGCDevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
     115}
     116
     117
     118/** @copydoc PDMDEVHLPRC::pfnPhysRead */
     119static DECLCALLBACK(int) pdmGCDevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
     120{
     121    PDMDEV_ASSERT_DEVINS(pDevIns);
     122    LogFlow(("pdmGCDevHlp_PhysRead: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
     123             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
     124
     125    int rc = PGMPhysRead(pDevIns->Internal.s.pVMRC, GCPhys, pvBuf, cbRead);
     126    AssertRC(rc); /** @todo track down the users for this bugger. */
     127
     128    Log(("pdmGCDevHlp_PhysRead: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
     129    return rc;
     130}
     131
     132
     133/** @copydoc PDMDEVHLPRC::pfnPhysWrite */
     134static DECLCALLBACK(int) pdmGCDevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
     135{
     136    PDMDEV_ASSERT_DEVINS(pDevIns);
     137    LogFlow(("pdmGCDevHlp_PhysWrite: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
     138             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
     139
     140    int rc = PGMPhysWrite(pDevIns->Internal.s.pVMRC, GCPhys, pvBuf, cbWrite);
     141    AssertRC(rc); /** @todo track down the users for this bugger. */
     142
     143    Log(("pdmGCDevHlp_PhysWrite: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
     144    return rc;
     145}
     146
     147
     148/** @copydoc PDMDEVHLPRC::pfnA20IsEnabled */
     149static DECLCALLBACK(bool) pdmGCDevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
     150{
     151    PDMDEV_ASSERT_DEVINS(pDevIns);
     152    LogFlow(("pdmGCDevHlp_A20IsEnabled: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
     153
     154    bool fEnabled = PGMPhysIsA20Enabled(VMMGetCpu0(pDevIns->Internal.s.pVMRC));
     155
     156    Log(("pdmGCDevHlp_A20IsEnabled: caller=%p/%d: returns %RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
     157    return fEnabled;
     158}
     159
     160
     161/** @copydoc PDMDEVHLPRC::pfnVMSetError */
     162static DECLCALLBACK(int) pdmGCDevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
     163{
     164    PDMDEV_ASSERT_DEVINS(pDevIns);
     165    va_list args;
     166    va_start(args, pszFormat);
     167    int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMRC, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
     168    va_end(args);
     169    return rc;
     170}
     171
     172
     173/** @copydoc PDMDEVHLPRC::pfnVMSetErrorV */
     174static DECLCALLBACK(int) pdmGCDevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
     175{
     176    PDMDEV_ASSERT_DEVINS(pDevIns);
     177    int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMRC, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
     178    return rc;
     179}
     180
     181
     182/** @copydoc PDMDEVHLPRC::pfnVMSetRuntimeError */
     183static DECLCALLBACK(int) pdmGCDevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
     184{
     185    PDMDEV_ASSERT_DEVINS(pDevIns);
     186    va_list va;
     187    va_start(va, pszFormat);
     188    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMRC, fFlags, pszErrorId, pszFormat, va);
     189    va_end(va);
     190    return rc;
     191}
     192
     193
     194/** @copydoc PDMDEVHLPRC::pfnVMSetErrorV */
     195static DECLCALLBACK(int) pdmGCDevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
     196{
     197    PDMDEV_ASSERT_DEVINS(pDevIns);
     198    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMRC, fFlags, pszErrorId, pszFormat, va);
     199    return rc;
     200}
     201
     202
     203/** @copydoc PDMDEVHLPRC::pfnPATMSetMMIOPatchInfo */
     204static DECLCALLBACK(int) pdmGCDevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData)
     205{
     206    PDMDEV_ASSERT_DEVINS(pDevIns);
     207    LogFlow(("pdmGCDevHlp_PATMSetMMIOPatchInfo: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
     208
     209    return PATMSetMMIOPatchInfo(pDevIns->Internal.s.pVMRC, GCPhys, (RTRCPTR)pCachedData);
     210}
     211
     212
     213/** @copydoc PDMDEVHLPRC::pfnGetVM */
     214static DECLCALLBACK(PVM)  pdmGCDevHlp_GetVM(PPDMDEVINS pDevIns)
     215{
     216    PDMDEV_ASSERT_DEVINS(pDevIns);
     217    LogFlow(("pdmGCDevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
     218    return pDevIns->Internal.s.pVMRC;
     219}
     220
     221
     222/** @copydoc PDMDEVHLPRC::pfnGetVMCPU */
     223static DECLCALLBACK(PVMCPU) pdmGCDevHlp_GetVMCPU(PPDMDEVINS pDevIns)
     224{
     225    PDMDEV_ASSERT_DEVINS(pDevIns);
     226    LogFlow(("pdmGCDevHlp_GetVMCPU: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
     227    return VMMGetCpu(pDevIns->Internal.s.pVMRC);
     228}
     229
     230
     231/**
     232 * The Raw-Mode Context Device Helper Callbacks.
    133233 */
    134234extern DECLEXPORT(const PDMDEVHLPRC) g_pdmRCDevHlp =
     
    150250};
    151251
     252/** @} */
     253
     254
     255
     256
     257/** @name PIC RC Helpers
     258 * @{
     259 */
     260
     261/** @copydoc PDMPICHLPGC::pfnSetInterruptFF */
     262static DECLCALLBACK(void) pdmRCPicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
     263{
     264    PDMDEV_ASSERT_DEVINS(pDevIns);
     265    PVM pVM = pDevIns->Internal.s.pVMRC;
     266
     267    if (pVM->pdm.s.Apic.pfnLocalInterruptRC)
     268    {
     269        LogFlow(("pdmRCPicHlp_SetInterruptFF: caller='%p'/%d: Setting local interrupt on LAPIC\n",
     270                 pDevIns, pDevIns->iInstance));
     271        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
     272        pVM->pdm.s.Apic.pfnLocalInterruptRC(pVM->pdm.s.Apic.pDevInsRC, 0, 1);
     273        return;
     274    }
     275
     276    PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
     277
     278    LogFlow(("pdmRCPicHlp_SetInterruptFF: caller=%p/%d: VMMCPU_FF_INTERRUPT_PIC %d -> 1\n",
     279             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
     280
     281    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
     282}
     283
     284
     285/** @copydoc PDMPICHLPGC::pfnClearInterruptFF */
     286static DECLCALLBACK(void) pdmRCPicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
     287{
     288    PDMDEV_ASSERT_DEVINS(pDevIns);
     289    PVM pVM = pDevIns->Internal.s.CTX_SUFF(pVM);
     290
     291    if (pVM->pdm.s.Apic.pfnLocalInterruptRC)
     292    {
     293        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
     294        LogFlow(("pdmRCPicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
     295                 pDevIns, pDevIns->iInstance));
     296        /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
     297        pVM->pdm.s.Apic.pfnLocalInterruptRC(pVM->pdm.s.Apic.pDevInsRC, 0, 0);
     298        return;
     299    }
     300
     301    PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
     302
     303    LogFlow(("pdmRCPicHlp_ClearInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
     304             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
     305
     306    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
     307}
     308
     309
     310/** @copydoc PDMPICHLPGC::pfnLock */
     311static DECLCALLBACK(int) pdmRCPicHlp_Lock(PPDMDEVINS pDevIns, int rc)
     312{
     313    PDMDEV_ASSERT_DEVINS(pDevIns);
     314    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
     315}
     316
     317
     318/** @copydoc PDMPICHLPGC::pfnUnlock */
     319static DECLCALLBACK(void) pdmRCPicHlp_Unlock(PPDMDEVINS pDevIns)
     320{
     321    PDMDEV_ASSERT_DEVINS(pDevIns);
     322    pdmUnlock(pDevIns->Internal.s.pVMRC);
     323}
     324
     325
    152326/**
    153327 * The Raw-Mode Context PIC Helper Callbacks.
     
    162336    PDM_PICHLPRC_VERSION
    163337};
     338
     339/** @} */
     340
     341
     342
     343
     344/** @name APIC RC Helpers
     345 * @{
     346 */
     347
     348/** @copydoc PDMAPICHLPRC::pfnSetInterruptFF */
     349static DECLCALLBACK(void) pdmRCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
     350{
     351    PDMDEV_ASSERT_DEVINS(pDevIns);
     352    PVM pVM = pDevIns->Internal.s.pVMRC;
     353    PVMCPU pVCpu = &pVM->aCpus[idCpu];
     354
     355    AssertReturnVoid(idCpu < pVM->cCpus);
     356
     357    LogFlow(("pdmRCApicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 1\n",
     358             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
     359    switch (enmType)
     360    {
     361        case PDMAPICIRQ_HARDWARE:
     362            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
     363            break;
     364        case PDMAPICIRQ_NMI:
     365            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
     366            break;
     367        case PDMAPICIRQ_SMI:
     368            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
     369            break;
     370        case PDMAPICIRQ_EXTINT:
     371            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
     372            break;
     373        default:
     374            AssertMsgFailed(("enmType=%d\n", enmType));
     375            break;
     376    }
     377}
     378
     379
     380/** @copydoc PDMAPICHLPRC::pfnClearInterruptFF */
     381static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
     382{
     383    PDMDEV_ASSERT_DEVINS(pDevIns);
     384    PVM pVM = pDevIns->Internal.s.pVMRC;
     385    PVMCPU pVCpu = &pVM->aCpus[idCpu];
     386
     387    AssertReturnVoid(idCpu < pVM->cCpus);
     388
     389    LogFlow(("pdmRCApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
     390             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
     391
     392    /* Note: NMI/SMI can't be cleared. */
     393    switch (enmType)
     394    {
     395        case PDMAPICIRQ_HARDWARE:
     396            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
     397            break;
     398        case PDMAPICIRQ_EXTINT:
     399            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
     400            break;
     401        default:
     402            AssertMsgFailed(("enmType=%d\n", enmType));
     403            break;
     404    }
     405}
     406
     407
     408/** @copydoc PDMAPICHLPRC::pfnChangeFeature */
     409static DECLCALLBACK(void) pdmRCApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion)
     410{
     411    PDMDEV_ASSERT_DEVINS(pDevIns);
     412    LogFlow(("pdmRCApicHlp_ChangeFeature: caller=%p/%d: version=%d\n", pDevIns, pDevIns->iInstance, (int)enmVersion));
     413    switch (enmVersion)
     414    {
     415        case PDMAPICVERSION_NONE:
     416            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_APIC);
     417            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_X2APIC);
     418            break;
     419        case PDMAPICVERSION_APIC:
     420            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_APIC);
     421            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_X2APIC);
     422            break;
     423        case PDMAPICVERSION_X2APIC:
     424            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_X2APIC);
     425            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_APIC);
     426            break;
     427        default:
     428            AssertMsgFailed(("Unknown APIC version: %d\n", (int)enmVersion));
     429    }
     430}
     431
     432
     433/** @copydoc PDMAPICHLPRC::pfnLock */
     434static DECLCALLBACK(int) pdmRCApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
     435{
     436    PDMDEV_ASSERT_DEVINS(pDevIns);
     437    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
     438}
     439
     440
     441/** @copydoc PDMAPICHLPRC::pfnUnlock */
     442static DECLCALLBACK(void) pdmRCApicHlp_Unlock(PPDMDEVINS pDevIns)
     443{
     444    PDMDEV_ASSERT_DEVINS(pDevIns);
     445    pdmUnlock(pDevIns->Internal.s.pVMRC);
     446}
     447
     448
     449/** @copydoc PDMAPICHLPRC::pfnGetCpuId */
     450static DECLCALLBACK(VMCPUID) pdmRCApicHlp_GetCpuId(PPDMDEVINS pDevIns)
     451{
     452    PDMDEV_ASSERT_DEVINS(pDevIns);
     453    return VMMGetCpuId(pDevIns->Internal.s.pVMRC);
     454}
    164455
    165456
     
    179470};
    180471
     472/** @} */
     473
     474
     475
     476
     477/** @name I/O APIC RC Helpers
     478 * @{
     479 */
     480
     481/** @copydoc PDMIOAPICHLPRC::pfnApicBusDeliver */
     482static DECLCALLBACK(int) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
     483                                                       uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
     484{
     485    PDMDEV_ASSERT_DEVINS(pDevIns);
     486    PVM pVM = pDevIns->Internal.s.pVMRC;
     487    LogFlow(("pdmRCIoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
     488             pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
     489    if (pVM->pdm.s.Apic.pfnBusDeliverRC)
     490        return pVM->pdm.s.Apic.pfnBusDeliverRC(pVM->pdm.s.Apic.pDevInsRC, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
     491    return VINF_SUCCESS;
     492}
     493
     494
     495/** @copydoc PDMIOAPICHLPRC::pfnLock */
     496static DECLCALLBACK(int) pdmRCIoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
     497{
     498    PDMDEV_ASSERT_DEVINS(pDevIns);
     499    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
     500}
     501
     502
     503/** @copydoc PDMIOAPICHLPRC::pfnUnlock */
     504static DECLCALLBACK(void) pdmRCIoApicHlp_Unlock(PPDMDEVINS pDevIns)
     505{
     506    PDMDEV_ASSERT_DEVINS(pDevIns);
     507    pdmUnlock(pDevIns->Internal.s.pVMRC);
     508}
     509
    181510
    182511/**
     
    191520    PDM_IOAPICHLPRC_VERSION
    192521};
     522
     523/** @} */
     524
     525
     526
     527
     528/** @name PCI Bus RC Helpers
     529 * @{
     530 */
     531
     532/** @copydoc PDMPCIHLPRC::pfnIsaSetIrq */
     533static DECLCALLBACK(void) pdmRCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
     534{
     535    PDMDEV_ASSERT_DEVINS(pDevIns);
     536    Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
     537    pdmRCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
     538}
     539
     540
     541/** @copydoc PDMPCIHLPRC::pfnIoApicSetIrq */
     542static DECLCALLBACK(void) pdmRCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
     543{
     544    PDMDEV_ASSERT_DEVINS(pDevIns);
     545    Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
     546    pdmRCIoApicSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
     547}
     548
     549
     550/** @copydoc PDMPCIHLPRC::pfnLock */
     551static DECLCALLBACK(int) pdmRCPciHlp_Lock(PPDMDEVINS pDevIns, int rc)
     552{
     553    PDMDEV_ASSERT_DEVINS(pDevIns);
     554    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
     555}
     556
     557
     558/** @copydoc PDMPCIHLPRC::pfnUnlock */
     559static DECLCALLBACK(void) pdmRCPciHlp_Unlock(PPDMDEVINS pDevIns)
     560{
     561    PDMDEV_ASSERT_DEVINS(pDevIns);
     562    pdmUnlock(pDevIns->Internal.s.pVMRC);
     563}
    193564
    194565
     
    206577};
    207578
     579/** @} */
     580
     581
     582
     583
     584/** @name HPET RC Helpers
     585 * @{
     586 */
     587
     588/** @copydoc PDMHPETHLPRC::pfnLock */
     589static DECLCALLBACK(int) pdmRCHpetHlp_Lock(PPDMDEVINS pDevIns, int rc)
     590{
     591    PDMDEV_ASSERT_DEVINS(pDevIns);
     592    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
     593}
     594
     595
     596/** @copydoc PDMHPETHLPRC::pfnUnlock */
     597static DECLCALLBACK(void) pdmRCHpetHlp_Unlock(PPDMDEVINS pDevIns)
     598{
     599    PDMDEV_ASSERT_DEVINS(pDevIns);
     600    pdmUnlock(pDevIns->Internal.s.pVMRC);
     601}
     602
     603
    208604/**
    209605 * The Raw-Mode Context HPET Helper Callbacks.
     
    217613};
    218614
    219 
    220 /** @copydoc PDMDEVHLPRC::pfnPCISetIrq */
    221 static DECLCALLBACK(void) pdmGCDevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    222 {
    223     PDMDEV_ASSERT_DEVINS(pDevIns);
    224     LogFlow(("pdmGCDevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
    225 
    226     PVM         pVM     = pDevIns->Internal.s.pVMRC;
    227     PPCIDEVICE  pPciDev = pDevIns->Internal.s.pPciDeviceRC;
    228     PPDMPCIBUS  pPciBus = pDevIns->Internal.s.pPciBusRC;
    229     if (    pPciDev
    230         &&  pPciBus
    231         &&  pPciBus->pDevInsRC)
    232     {
    233         pdmLock(pVM);
    234         pPciBus->pfnSetIrqRC(pPciBus->pDevInsRC, pPciDev, iIrq, iLevel);
    235         pdmUnlock(pVM);
    236     }
    237     else
    238     {
    239         /* queue for ring-3 execution. */
    240         PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueRC);
    241         if (pTask)
    242         {
    243             pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
    244             pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
    245             pTask->u.SetIRQ.iIrq = iIrq;
    246             pTask->u.SetIRQ.iLevel = iLevel;
    247 
    248             PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0);
    249         }
    250         else
    251             AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
    252     }
    253 
    254     LogFlow(("pdmGCDevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
    255 }
    256 
    257 
    258 /** @copydoc PDMDEVHLPRC::pfnPCISetIrq */
    259 static DECLCALLBACK(void) pdmGCDevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    260 {
    261     PDMDEV_ASSERT_DEVINS(pDevIns);
    262     LogFlow(("pdmGCDevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
    263 
    264     pdmGCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
    265 
    266     LogFlow(("pdmGCDevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
    267 }
    268 
    269 
    270 /** @copydoc PDMDEVHLPRC::pfnPhysRead */
    271 static DECLCALLBACK(int) pdmGCDevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
    272 {
    273     PDMDEV_ASSERT_DEVINS(pDevIns);
    274     LogFlow(("pdmGCDevHlp_PhysRead: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
    275              pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
    276 
    277     int rc = PGMPhysRead(pDevIns->Internal.s.pVMRC, GCPhys, pvBuf, cbRead);
    278     AssertRC(rc); /** @todo track down the users for this bugger. */
    279 
    280     Log(("pdmGCDevHlp_PhysRead: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
    281     return rc;
    282 }
    283 
    284 
    285 /** @copydoc PDMDEVHLPRC::pfnPhysWrite */
    286 static DECLCALLBACK(int) pdmGCDevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
    287 {
    288     PDMDEV_ASSERT_DEVINS(pDevIns);
    289     LogFlow(("pdmGCDevHlp_PhysWrite: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
    290              pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
    291 
    292     int rc = PGMPhysWrite(pDevIns->Internal.s.pVMRC, GCPhys, pvBuf, cbWrite);
    293     AssertRC(rc); /** @todo track down the users for this bugger. */
    294 
    295     Log(("pdmGCDevHlp_PhysWrite: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
    296     return rc;
    297 }
    298 
    299 
    300 /** @copydoc PDMDEVHLPRC::pfnA20IsEnabled */
    301 static DECLCALLBACK(bool) pdmGCDevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
    302 {
    303     PDMDEV_ASSERT_DEVINS(pDevIns);
    304     LogFlow(("pdmGCDevHlp_A20IsEnabled: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
    305 
    306     bool fEnabled = PGMPhysIsA20Enabled(VMMGetCpu0(pDevIns->Internal.s.pVMRC));
    307 
    308     Log(("pdmGCDevHlp_A20IsEnabled: caller=%p/%d: returns %RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
    309     return fEnabled;
    310 }
    311 
    312 
    313 /** @copydoc PDMDEVHLPRC::pfnVMSetError */
    314 static DECLCALLBACK(int) pdmGCDevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
    315 {
    316     PDMDEV_ASSERT_DEVINS(pDevIns);
    317     va_list args;
    318     va_start(args, pszFormat);
    319     int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMRC, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
    320     va_end(args);
    321     return rc;
    322 }
    323 
    324 
    325 /** @copydoc PDMDEVHLPRC::pfnVMSetErrorV */
    326 static DECLCALLBACK(int) pdmGCDevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
    327 {
    328     PDMDEV_ASSERT_DEVINS(pDevIns);
    329     int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMRC, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
    330     return rc;
    331 }
    332 
    333 
    334 /** @copydoc PDMDEVHLPRC::pfnVMSetRuntimeError */
    335 static DECLCALLBACK(int) pdmGCDevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
    336 {
    337     PDMDEV_ASSERT_DEVINS(pDevIns);
    338     va_list va;
    339     va_start(va, pszFormat);
    340     int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMRC, fFlags, pszErrorId, pszFormat, va);
    341     va_end(va);
    342     return rc;
    343 }
    344 
    345 
    346 /** @copydoc PDMDEVHLPRC::pfnVMSetErrorV */
    347 static DECLCALLBACK(int) pdmGCDevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
    348 {
    349     PDMDEV_ASSERT_DEVINS(pDevIns);
    350     int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMRC, fFlags, pszErrorId, pszFormat, va);
    351     return rc;
    352 }
    353 
    354 
    355 /** @copydoc PDMDEVHLPRC::pfnPATMSetMMIOPatchInfo */
    356 static DECLCALLBACK(int) pdmGCDevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData)
    357 {
    358     PDMDEV_ASSERT_DEVINS(pDevIns);
    359     LogFlow(("pdmGCDevHlp_PATMSetMMIOPatchInfo: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
    360 
    361     return PATMSetMMIOPatchInfo(pDevIns->Internal.s.pVMRC, GCPhys, (RTRCPTR)pCachedData);
    362 }
    363 
    364 
    365 /** @copydoc PDMDEVHLPRC::pfnGetVM */
    366 static DECLCALLBACK(PVM)  pdmGCDevHlp_GetVM(PPDMDEVINS pDevIns)
    367 {
    368     PDMDEV_ASSERT_DEVINS(pDevIns);
    369     LogFlow(("pdmGCDevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
    370     return pDevIns->Internal.s.pVMRC;
    371 }
    372 
    373 
    374 /** @copydoc PDMDEVHLPRC::pfnGetVMCPU */
    375 static DECLCALLBACK(PVMCPU) pdmGCDevHlp_GetVMCPU(PPDMDEVINS pDevIns)
    376 {
    377     PDMDEV_ASSERT_DEVINS(pDevIns);
    378     LogFlow(("pdmGCDevHlp_GetVMCPU: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
    379     return VMMGetCpu(pDevIns->Internal.s.pVMRC);
    380 }
    381 
    382 
    383 
    384 
    385 /** @copydoc PDMPICHLPGC::pfnSetInterruptFF */
    386 static DECLCALLBACK(void) pdmRCPicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
    387 {
    388     PDMDEV_ASSERT_DEVINS(pDevIns);
    389     PVM pVM = pDevIns->Internal.s.pVMRC;
    390 
    391     if (pVM->pdm.s.Apic.pfnLocalInterruptRC)
    392     {
    393         LogFlow(("pdmRCPicHlp_SetInterruptFF: caller='%p'/%d: Setting local interrupt on LAPIC\n",
    394                  pDevIns, pDevIns->iInstance));
    395         /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
    396         pVM->pdm.s.Apic.pfnLocalInterruptRC(pVM->pdm.s.Apic.pDevInsRC, 0, 1);
    397         return;
    398     }
    399 
    400     PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
    401 
    402     LogFlow(("pdmRCPicHlp_SetInterruptFF: caller=%p/%d: VMMCPU_FF_INTERRUPT_PIC %d -> 1\n",
    403              pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
    404 
    405     VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    406 }
    407 
    408 
    409 /** @copydoc PDMPICHLPGC::pfnClearInterruptFF */
    410 static DECLCALLBACK(void) pdmRCPicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
    411 {
    412     PDMDEV_ASSERT_DEVINS(pDevIns);
    413     PVM pVM = pDevIns->Internal.s.CTX_SUFF(pVM);
    414 
    415     if (pVM->pdm.s.Apic.pfnLocalInterruptRC)
    416     {
    417         /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
    418         LogFlow(("pdmRCPicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
    419                  pDevIns, pDevIns->iInstance));
    420         /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
    421         pVM->pdm.s.Apic.pfnLocalInterruptRC(pVM->pdm.s.Apic.pDevInsRC, 0, 0);
    422         return;
    423     }
    424 
    425     PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
    426 
    427     LogFlow(("pdmRCPicHlp_ClearInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
    428              pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
    429 
    430     VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    431 }
    432 
    433 
    434 /** @copydoc PDMPICHLPGC::pfnLock */
    435 static DECLCALLBACK(int) pdmRCPicHlp_Lock(PPDMDEVINS pDevIns, int rc)
    436 {
    437     PDMDEV_ASSERT_DEVINS(pDevIns);
    438     return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
    439 }
    440 
    441 
    442 /** @copydoc PDMPICHLPGC::pfnUnlock */
    443 static DECLCALLBACK(void) pdmRCPicHlp_Unlock(PPDMDEVINS pDevIns)
    444 {
    445     PDMDEV_ASSERT_DEVINS(pDevIns);
    446     pdmUnlock(pDevIns->Internal.s.pVMRC);
    447 }
    448 
    449 
    450 
    451 
    452 /** @copydoc PDMAPICHLPRC::pfnSetInterruptFF */
    453 static DECLCALLBACK(void) pdmRCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
    454 {
    455     PDMDEV_ASSERT_DEVINS(pDevIns);
    456     PVM pVM = pDevIns->Internal.s.pVMRC;
    457     PVMCPU pVCpu = &pVM->aCpus[idCpu];
    458 
    459     AssertReturnVoid(idCpu < pVM->cCpus);
    460 
    461     LogFlow(("pdmRCApicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 1\n",
    462              pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
    463     switch (enmType)
    464     {
    465         case PDMAPICIRQ_HARDWARE:
    466             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
    467             break;
    468         case PDMAPICIRQ_NMI:
    469             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
    470             break;
    471         case PDMAPICIRQ_SMI:
    472             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
    473             break;
    474         case PDMAPICIRQ_EXTINT:
    475             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    476             break;
    477         default:
    478             AssertMsgFailed(("enmType=%d\n", enmType));
    479             break;
    480     }
    481 }
    482 
    483 
    484 /** @copydoc PDMAPICHLPRC::pfnClearInterruptFF */
    485 static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
    486 {
    487     PDMDEV_ASSERT_DEVINS(pDevIns);
    488     PVM pVM = pDevIns->Internal.s.pVMRC;
    489     PVMCPU pVCpu = &pVM->aCpus[idCpu];
    490 
    491     AssertReturnVoid(idCpu < pVM->cCpus);
    492 
    493     LogFlow(("pdmRCApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
    494              pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
    495 
    496     /* Note: NMI/SMI can't be cleared. */
    497     switch (enmType)
    498     {
    499         case PDMAPICIRQ_HARDWARE:
    500             VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
    501             break;
    502         case PDMAPICIRQ_EXTINT:
    503             VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    504             break;
    505         default:
    506             AssertMsgFailed(("enmType=%d\n", enmType));
    507             break;
    508     }
    509 }
    510 
    511 
    512 /** @copydoc PDMAPICHLPRC::pfnChangeFeature */
    513 static DECLCALLBACK(void) pdmRCApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion)
    514 {
    515     PDMDEV_ASSERT_DEVINS(pDevIns);
    516     LogFlow(("pdmRCApicHlp_ChangeFeature: caller=%p/%d: version=%d\n", pDevIns, pDevIns->iInstance, (int)enmVersion));
    517     switch (enmVersion)
    518     {
    519         case PDMAPICVERSION_NONE:
    520             CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_APIC);
    521             CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_X2APIC);
    522             break;
    523         case PDMAPICVERSION_APIC:
    524             CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_APIC);
    525             CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_X2APIC);
    526             break;
    527         case PDMAPICVERSION_X2APIC:
    528             CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_X2APIC);
    529             CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_APIC);
    530             break;
    531         default:
    532             AssertMsgFailed(("Unknown APIC version: %d\n", (int)enmVersion));
    533     }
    534 }
    535 
    536 
    537 /** @copydoc PDMAPICHLPRC::pfnLock */
    538 static DECLCALLBACK(int) pdmRCApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
    539 {
    540     PDMDEV_ASSERT_DEVINS(pDevIns);
    541     return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
    542 }
    543 
    544 
    545 /** @copydoc PDMAPICHLPRC::pfnUnlock */
    546 static DECLCALLBACK(void) pdmRCApicHlp_Unlock(PPDMDEVINS pDevIns)
    547 {
    548     PDMDEV_ASSERT_DEVINS(pDevIns);
    549     pdmUnlock(pDevIns->Internal.s.pVMRC);
    550 }
    551 
    552 
    553 /** @copydoc PDMAPICHLPRC::pfnGetCpuId */
    554 static DECLCALLBACK(VMCPUID) pdmRCApicHlp_GetCpuId(PPDMDEVINS pDevIns)
    555 {
    556     PDMDEV_ASSERT_DEVINS(pDevIns);
    557     return VMMGetCpuId(pDevIns->Internal.s.pVMRC);
    558 }
    559 
    560 
    561 
    562 
    563 /** @copydoc PDMIOAPICHLPRC::pfnApicBusDeliver */
    564 static DECLCALLBACK(int) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
    565                                                         uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
    566 {
    567     PDMDEV_ASSERT_DEVINS(pDevIns);
    568     PVM pVM = pDevIns->Internal.s.pVMRC;
    569     LogFlow(("pdmRCIoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
    570              pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
    571     if (pVM->pdm.s.Apic.pfnBusDeliverRC)
    572         return pVM->pdm.s.Apic.pfnBusDeliverRC(pVM->pdm.s.Apic.pDevInsRC, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
    573     return VINF_SUCCESS;
    574 }
    575 
    576 
    577 /** @copydoc PDMIOAPICHLPRC::pfnLock */
    578 static DECLCALLBACK(int) pdmRCIoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
    579 {
    580     PDMDEV_ASSERT_DEVINS(pDevIns);
    581     return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
    582 }
    583 
    584 
    585 /** @copydoc PDMIOAPICHLPRC::pfnUnlock */
    586 static DECLCALLBACK(void) pdmRCIoApicHlp_Unlock(PPDMDEVINS pDevIns)
    587 {
    588     PDMDEV_ASSERT_DEVINS(pDevIns);
    589     pdmUnlock(pDevIns->Internal.s.pVMRC);
    590 }
    591 
    592 
    593 
    594 
    595 /** @copydoc PDMPCIHLPRC::pfnIsaSetIrq */
    596 static DECLCALLBACK(void) pdmRCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    597 {
    598     PDMDEV_ASSERT_DEVINS(pDevIns);
    599     Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
    600     pdmGCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
    601 }
    602 
    603 
    604 /** @copydoc PDMPCIHLPRC::pfnIoApicSetIrq */
    605 static DECLCALLBACK(void) pdmRCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    606 {
    607     PDMDEV_ASSERT_DEVINS(pDevIns);
    608     Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
    609     pdmGCIoApicSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
    610 }
    611 
    612 
    613 /** @copydoc PDMPCIHLPRC::pfnLock */
    614 static DECLCALLBACK(int) pdmRCPciHlp_Lock(PPDMDEVINS pDevIns, int rc)
    615 {
    616     PDMDEV_ASSERT_DEVINS(pDevIns);
    617     return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
    618 }
    619 
    620 
    621 /** @copydoc PDMPCIHLPRC::pfnUnlock */
    622 static DECLCALLBACK(void) pdmRCPciHlp_Unlock(PPDMDEVINS pDevIns)
    623 {
    624     PDMDEV_ASSERT_DEVINS(pDevIns);
    625     pdmUnlock(pDevIns->Internal.s.pVMRC);
    626 }
     615/** @} */
    627616
    628617
     
    636625 * @param   iLevel  The new level.
    637626 */
    638 static void pdmGCIsaSetIrq(PVM pVM, int iIrq, int iLevel)
     627static void pdmRCIsaSetIrq(PVM pVM, int iIrq, int iLevel)
    639628{
    640629    if (    (   pVM->pdm.s.IoApic.pDevInsRC
     
    676665 * @param   iLevel  The new level.
    677666 */
    678 static void pdmGCIoApicSetIrq(PVM pVM, int iIrq, int iLevel)
     667static void pdmRCIoApicSetIrq(PVM pVM, int iIrq, int iLevel)
    679668{
    680669    if (pVM->pdm.s.IoApic.pDevInsRC)
     
    702691}
    703692
    704 
    705 /** @copydoc PDMHPETHLPRC::pfnLock */
    706 static DECLCALLBACK(int) pdmRCHpetHlp_Lock(PPDMDEVINS pDevIns, int rc)
    707 {
    708     PDMDEV_ASSERT_DEVINS(pDevIns);
    709     return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
    710 }
    711 
    712 
    713 /** @copydoc PDMHPETHLPRC::pfnUnlock */
    714 static DECLCALLBACK(void) pdmRCHpetHlp_Unlock(PPDMDEVINS pDevIns)
    715 {
    716     PDMDEV_ASSERT_DEVINS(pDevIns);
    717     pdmUnlock(pDevIns->Internal.s.pVMRC);
    718 }
  • trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp

    r25995 r26001  
    55
    66/*
    7  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    5858*   Internal Functions                                                         *
    5959*******************************************************************************/
    60 /** @name GC Device Helpers
    61  * @{
    62  */
    63 static DECLCALLBACK(void) pdmR0DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
    64 static DECLCALLBACK(void) pdmR0DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
    65 static DECLCALLBACK(int)  pdmR0DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
    66 static DECLCALLBACK(int)  pdmR0DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
    67 static DECLCALLBACK(bool) pdmR0DevHlp_A20IsEnabled(PPDMDEVINS pDevIns);
    68 static DECLCALLBACK(int)  pdmR0DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
    69 static DECLCALLBACK(int)  pdmR0DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va);
    70 static DECLCALLBACK(int)  pdmR0DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...);
    71 static DECLCALLBACK(int)  pdmR0DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va);
    72 static DECLCALLBACK(int)  pdmR0DevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData);
    73 static DECLCALLBACK(PVM)  pdmR0DevHlp_GetVM(PPDMDEVINS pDevIns);
    74 static DECLCALLBACK(bool) pdmR0DevHlp_CanEmulateIoBlock(PPDMDEVINS pDevIns);
    75 static DECLCALLBACK(PVMCPU) pdmR0DevHlp_GetVMCPU(PPDMDEVINS pDevIns);
    76 /** @} */
    77 
    78 
    79 /** @name PIC GC Helpers
    80  * @{
    81  */
    82 static DECLCALLBACK(void) pdmR0PicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
    83 static DECLCALLBACK(void) pdmR0PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
    84 static DECLCALLBACK(int)  pdmR0PicHlp_Lock(PPDMDEVINS pDevIns, int rc);
    85 static DECLCALLBACK(void) pdmR0PicHlp_Unlock(PPDMDEVINS pDevIns);
    86 /** @} */
    87 
    88 
    89 /** @name APIC GC Helpers
    90  * @{
    91  */
    92 static DECLCALLBACK(void) pdmR0ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
    93 static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
    94 static DECLCALLBACK(void) pdmR0ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion);
    95 static DECLCALLBACK(int)  pdmR0ApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
    96 static DECLCALLBACK(void) pdmR0ApicHlp_Unlock(PPDMDEVINS pDevIns);
    97 static DECLCALLBACK(VMCPUID) pdmR0ApicHlp_GetCpuId(PPDMDEVINS pDevIns);
    98 /** @} */
    99 
    100 
    101 /** @name I/O APIC GC Helpers
    102  * @{
    103  */
    104 static DECLCALLBACK(int) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
    105                                                         uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode);
    106 static DECLCALLBACK(int) pdmR0IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
    107 static DECLCALLBACK(void) pdmR0IoApicHlp_Unlock(PPDMDEVINS pDevIns);
    108 /** @} */
    109 
    110 
    111 /** @name PCI Bus GC Helpers
    112  * @{
    113  */
    114 static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
    115 static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
    116 static DECLCALLBACK(int) pdmR0PciHlp_Lock(PPDMDEVINS pDevIns, int rc);
    117 static DECLCALLBACK(void) pdmR0PciHlp_Unlock(PPDMDEVINS pDevIns);
    118 /** @} */
    119 
    120 /** @name HPET GC Helpers
    121  * @{
    122  */
    123 static DECLCALLBACK(int) pdmR0HpetHlp_Lock(PPDMDEVINS pDevIns, int rc);
    124 static DECLCALLBACK(void) pdmR0HpetHlp_Unlock(PPDMDEVINS pDevIns);
    125 /** @} */
    126 
    127 
    12860static void pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel);
    12961static void pdmR0IoApicSetIrq(PVM pVM, int iIrq, int iLevel);
     
    13163
    13264
     65
     66/** @name Ring-0 Device Helpers
     67 * @{
     68 */
     69
     70/** @copydoc PDMDEVHLPR0::pfnPCISetIrq */
     71static DECLCALLBACK(void) pdmR0DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
     72{
     73    PDMDEV_ASSERT_DEVINS(pDevIns);
     74    LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
     75
     76    PVM          pVM     = pDevIns->Internal.s.pVMR0;
     77    PPCIDEVICE   pPciDev = pDevIns->Internal.s.pPciDeviceR0;
     78    PPDMPCIBUS   pPciBus = pDevIns->Internal.s.pPciBusR0;
     79    if (    pPciDev
     80        &&  pPciBus
     81        &&  pPciBus->pDevInsR0)
     82    {
     83        pdmLock(pVM);
     84        pPciBus->pfnSetIrqR0(pPciBus->pDevInsR0, pPciDev, iIrq, iLevel);
     85        pdmUnlock(pVM);
     86    }
     87    else
     88    {
     89        /* queue for ring-3 execution. */
     90        PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0);
     91        if (pTask)
     92        {
     93            pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
     94            pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
     95            pTask->u.SetIRQ.iIrq = iIrq;
     96            pTask->u.SetIRQ.iLevel = iLevel;
     97
     98            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
     99        }
     100        else
     101            AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
     102    }
     103
     104    LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
     105}
     106
     107
     108/** @copydoc PDMDEVHLPR0::pfnPCISetIrq */
     109static DECLCALLBACK(void) pdmR0DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
     110{
     111    PDMDEV_ASSERT_DEVINS(pDevIns);
     112    LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
     113
     114    pdmR0IsaSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
     115
     116    LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
     117}
     118
     119
     120/** @copydoc PDMDEVHLPR0::pfnPhysRead */
     121static DECLCALLBACK(int) pdmR0DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
     122{
     123    PDMDEV_ASSERT_DEVINS(pDevIns);
     124    LogFlow(("pdmR0DevHlp_PhysRead: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
     125             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
     126
     127    int rc = PGMPhysRead(pDevIns->Internal.s.pVMR0, GCPhys, pvBuf, cbRead);
     128    AssertRC(rc); /** @todo track down the users for this bugger. */
     129
     130    Log(("pdmR0DevHlp_PhysRead: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
     131    return rc;
     132}
     133
     134
     135/** @copydoc PDMDEVHLPR0::pfnPhysWrite */
     136static DECLCALLBACK(int) pdmR0DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
     137{
     138    PDMDEV_ASSERT_DEVINS(pDevIns);
     139    LogFlow(("pdmR0DevHlp_PhysWrite: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
     140             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
     141
     142    int rc = PGMPhysWrite(pDevIns->Internal.s.pVMR0, GCPhys, pvBuf, cbWrite);
     143    AssertRC(rc); /** @todo track down the users for this bugger. */
     144
     145    Log(("pdmR0DevHlp_PhysWrite: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
     146    return rc;
     147}
     148
     149
     150/** @copydoc PDMDEVHLPR0::pfnA20IsEnabled */
     151static DECLCALLBACK(bool) pdmR0DevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
     152{
     153    PDMDEV_ASSERT_DEVINS(pDevIns);
     154    LogFlow(("pdmR0DevHlp_A20IsEnabled: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
     155
     156    bool fEnabled = PGMPhysIsA20Enabled(VMMGetCpu(pDevIns->Internal.s.pVMR0));
     157
     158    Log(("pdmR0DevHlp_A20IsEnabled: caller=%p/%d: returns %RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
     159    return fEnabled;
     160}
     161
     162
     163/** @copydoc PDMDEVHLPR0::pfnVMSetError */
     164static DECLCALLBACK(int) pdmR0DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
     165{
     166    PDMDEV_ASSERT_DEVINS(pDevIns);
     167    va_list args;
     168    va_start(args, pszFormat);
     169    int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR0, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
     170    va_end(args);
     171    return rc;
     172}
     173
     174
     175/** @copydoc PDMDEVHLPR0::pfnVMSetErrorV */
     176static DECLCALLBACK(int) pdmR0DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
     177{
     178    PDMDEV_ASSERT_DEVINS(pDevIns);
     179    int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR0, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
     180    return rc;
     181}
     182
     183
     184/** @copydoc PDMDEVHLPR0::pfnVMSetRuntimeError */
     185static DECLCALLBACK(int) pdmR0DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
     186{
     187    PDMDEV_ASSERT_DEVINS(pDevIns);
     188    va_list va;
     189    va_start(va, pszFormat);
     190    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR0, fFlags, pszErrorId, pszFormat, va);
     191    va_end(va);
     192    return rc;
     193}
     194
     195
     196/** @copydoc PDMDEVHLPR0::pfnVMSetRuntimeErrorV */
     197static DECLCALLBACK(int) pdmR0DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
     198{
     199    PDMDEV_ASSERT_DEVINS(pDevIns);
     200    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR0, fFlags, pszErrorId, pszFormat, va);
     201    return rc;
     202}
     203
     204
     205/** @copydoc PDMDEVHLPR0::pdmR0DevHlp_PATMSetMMIOPatchInfo*/
     206static DECLCALLBACK(int) pdmR0DevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData)
     207{
     208    PDMDEV_ASSERT_DEVINS(pDevIns);
     209    LogFlow(("pdmR0DevHlp_PATMSetMMIOPatchInfo: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
     210
     211    AssertFailed();
     212
     213/*    return PATMSetMMIOPatchInfo(pDevIns->Internal.s.pVMR0, GCPhys, pCachedData); */
     214    return VINF_SUCCESS;
     215}
     216
     217
     218/** @copydoc PDMDEVHLPR0::pfnGetVM */
     219static DECLCALLBACK(PVM)  pdmR0DevHlp_GetVM(PPDMDEVINS pDevIns)
     220{
     221    PDMDEV_ASSERT_DEVINS(pDevIns);
     222    LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
     223    return pDevIns->Internal.s.pVMR0;
     224}
     225
     226
     227/** @copydoc PDMDEVHLPR0::pfnCanEmulateIoBlock */
     228static DECLCALLBACK(bool) pdmR0DevHlp_CanEmulateIoBlock(PPDMDEVINS pDevIns)
     229{
     230    PDMDEV_ASSERT_DEVINS(pDevIns);
     231    LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
     232    return HWACCMCanEmulateIoBlock(VMMGetCpu(pDevIns->Internal.s.pVMR0));
     233}
     234
     235
     236/** @copydoc PDMDEVHLPR0::pfnGetVMCPU */
     237static DECLCALLBACK(PVMCPU) pdmR0DevHlp_GetVMCPU(PPDMDEVINS pDevIns)
     238{
     239    PDMDEV_ASSERT_DEVINS(pDevIns);
     240    LogFlow(("pdmR0DevHlp_GetVMCPU: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
     241    return VMMGetCpu(pDevIns->Internal.s.pVMR0);
     242}
     243
     244
    133245/**
    134  * The Guest Context Device Helper Callbacks.
     246 * The Ring-0 Device Helper Callbacks.
    135247 */
    136248extern DECLEXPORT(const PDMDEVHLPR0) g_pdmR0DevHlp =
     
    153265};
    154266
     267/** @} */
     268
     269
     270
     271
     272/** @name PIC Ring-0 Helpers
     273 * @{
     274 */
     275
     276/** @copydoc PDMPICHLPR0::pfnSetInterruptFF */
     277static DECLCALLBACK(void) pdmR0PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
     278{
     279    PDMDEV_ASSERT_DEVINS(pDevIns);
     280    PVM    pVM   = pDevIns->Internal.s.pVMR0;
     281
     282    if (pVM->pdm.s.Apic.pfnLocalInterruptR0)
     283    {
     284        LogFlow(("pdmR0PicHlp_SetInterruptFF: caller='%p'/%d: Setting local interrupt on LAPIC\n",
     285                 pDevIns, pDevIns->iInstance));
     286        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
     287        pVM->pdm.s.Apic.pfnLocalInterruptR0(pVM->pdm.s.Apic.pDevInsR0, 0, 1);
     288        return;
     289    }
     290
     291    PVMCPU pVCpu = &pVM->aCpus[0];      /* for PIC we always deliver to CPU 0, MP use APIC */
     292
     293    LogFlow(("pdmR0PicHlp_SetInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 1\n",
     294             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
     295
     296    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
     297}
     298
     299
     300/** @copydoc PDMPICHLPR0::pfnClearInterruptFF */
     301static DECLCALLBACK(void) pdmR0PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
     302{
     303    PDMDEV_ASSERT_DEVINS(pDevIns);
     304    PVM    pVM   = pDevIns->Internal.s.pVMR0;
     305
     306    if (pVM->pdm.s.Apic.pfnLocalInterruptR0)
     307    {
     308        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
     309        LogFlow(("pdmR0PicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
     310                 pDevIns, pDevIns->iInstance));
     311        /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
     312        pVM->pdm.s.Apic.pfnLocalInterruptR0(pVM->pdm.s.Apic.pDevInsR0, 0, 0);
     313        return;
     314    }
     315
     316    PVMCPU pVCpu = &pVM->aCpus[0];      /* for PIC we always deliver to CPU 0, MP use APIC */
     317
     318    LogFlow(("pdmR0PicHlp_ClearInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
     319             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
     320
     321    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
     322}
     323
     324
     325/** @copydoc PDMPICHLPR0::pfnLock */
     326static DECLCALLBACK(int) pdmR0PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
     327{
     328    PDMDEV_ASSERT_DEVINS(pDevIns);
     329    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
     330}
     331
     332
     333/** @copydoc PDMPICHLPR0::pfnUnlock */
     334static DECLCALLBACK(void) pdmR0PicHlp_Unlock(PPDMDEVINS pDevIns)
     335{
     336    PDMDEV_ASSERT_DEVINS(pDevIns);
     337    pdmUnlock(pDevIns->Internal.s.pVMR0);
     338}
     339
     340
    155341/**
    156  * The Guest Context PIC Helper Callbacks.
     342 * The Ring-0 PIC Helper Callbacks.
    157343 */
    158344extern DECLEXPORT(const PDMPICHLPR0) g_pdmR0PicHlp =
     
    166352};
    167353
     354/** @} */
     355
     356
     357
     358
     359/** @name APIC Ring-0 Helpers
     360 * @{
     361 */
     362
     363/** @copydoc PDMAPICHLPR0::pfnSetInterruptFF */
     364static DECLCALLBACK(void) pdmR0ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
     365{
     366    PDMDEV_ASSERT_DEVINS(pDevIns);
     367    PVM    pVM   = pDevIns->Internal.s.pVMR0;
     368    PVMCPU pVCpu = &pVM->aCpus[idCpu];
     369
     370    AssertReturnVoid(idCpu < pVM->cCpus);
     371
     372    LogFlow(("pdmR0ApicHlp_SetInterruptFF: CPU%d=caller=%p/%d: VM_FF_INTERRUPT %d -> 1 (CPU%d)\n",
     373             VMMGetCpuId(pVM), pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC), idCpu));
     374
     375    switch (enmType)
     376    {
     377        case PDMAPICIRQ_HARDWARE:
     378            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
     379            break;
     380        case PDMAPICIRQ_NMI:
     381            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
     382            break;
     383        case PDMAPICIRQ_SMI:
     384            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
     385            break;
     386        case PDMAPICIRQ_EXTINT:
     387            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
     388            break;
     389        default:
     390            AssertMsgFailed(("enmType=%d\n", enmType));
     391            break;
     392    }
     393
     394    /* We need to wait up the target CPU. */
     395    if (VMMGetCpuId(pVM) != idCpu)
     396    {
     397        switch (VMCPU_GET_STATE(pVCpu))
     398        {
     399            case VMCPUSTATE_STARTED_EXEC:
     400                GVMMR0SchedPokeEx(pVM, pVCpu->idCpu, false /* don't take the used lock */);
     401                break;
     402
     403            case VMCPUSTATE_STARTED_HALTED:
     404                GVMMR0SchedWakeUpEx(pVM, pVCpu->idCpu, false /* don't take the used lock */);
     405                break;
     406
     407            default:
     408                break; /* nothing to do in other states. */
     409        }
     410    }
     411}
     412
     413
     414/** @copydoc PDMAPICHLPR0::pfnClearInterruptFF */
     415static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
     416{
     417    PDMDEV_ASSERT_DEVINS(pDevIns);
     418    PVM    pVM   = pDevIns->Internal.s.pVMR0;
     419    PVMCPU pVCpu = &pVM->aCpus[idCpu];
     420
     421    AssertReturnVoid(idCpu < pVM->cCpus);
     422
     423    LogFlow(("pdmR0ApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
     424             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
     425
     426    /* Note: NMI/SMI can't be cleared. */
     427    switch (enmType)
     428    {
     429        case PDMAPICIRQ_HARDWARE:
     430            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
     431            break;
     432        case PDMAPICIRQ_EXTINT:
     433            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
     434            break;
     435        default:
     436            AssertMsgFailed(("enmType=%d\n", enmType));
     437            break;
     438    }
     439}
     440
     441
     442/** @copydoc PDMAPICHLPR0::pfnChangeFeature */
     443static DECLCALLBACK(void) pdmR0ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion)
     444{
     445    PDMDEV_ASSERT_DEVINS(pDevIns);
     446    LogFlow(("pdmR0ApicHlp_ChangeFeature: caller=%p/%d: version=%d\n", pDevIns, pDevIns->iInstance, (int)enmVersion));
     447    switch (enmVersion)
     448    {
     449        case PDMAPICVERSION_NONE:
     450            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_APIC);
     451            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_X2APIC);
     452            break;
     453        case PDMAPICVERSION_APIC:
     454            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_APIC);
     455            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_X2APIC);
     456            break;
     457        case PDMAPICVERSION_X2APIC:
     458            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_X2APIC);
     459            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_APIC);
     460            break;
     461        default:
     462            AssertMsgFailed(("Unknown APIC version: %d\n", (int)enmVersion));
     463    }
     464}
     465
     466
     467/** @copydoc PDMAPICHLPR0::pfnLock */
     468static DECLCALLBACK(int) pdmR0ApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
     469{
     470    PDMDEV_ASSERT_DEVINS(pDevIns);
     471    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
     472}
     473
     474
     475/** @copydoc PDMAPICHLPR0::pfnUnlock */
     476static DECLCALLBACK(void) pdmR0ApicHlp_Unlock(PPDMDEVINS pDevIns)
     477{
     478    PDMDEV_ASSERT_DEVINS(pDevIns);
     479    pdmUnlock(pDevIns->Internal.s.pVMR0);
     480}
     481
     482
     483/** @copydoc PDMAPICHLPR0::pfnGetCpuId */
     484static DECLCALLBACK(VMCPUID) pdmR0ApicHlp_GetCpuId(PPDMDEVINS pDevIns)
     485{
     486    PDMDEV_ASSERT_DEVINS(pDevIns);
     487    return VMMGetCpuId(pDevIns->Internal.s.pVMR0);
     488}
     489
    168490
    169491/**
    170  * The Guest Context APIC Helper Callbacks.
     492 * The Ring-0 APIC Helper Callbacks.
    171493 */
    172494extern DECLEXPORT(const PDMAPICHLPR0) g_pdmR0ApicHlp =
     
    182504};
    183505
     506/** @} */
     507
     508
     509
     510
     511/** @name I/O APIC Ring-0 Helpers
     512 * @{
     513 */
     514
     515/** @copydoc PDMIOAPICHLPR0::pfnApicBusDeliver */
     516static DECLCALLBACK(int) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
     517                                                       uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
     518{
     519    PDMDEV_ASSERT_DEVINS(pDevIns);
     520    PVM pVM = pDevIns->Internal.s.pVMR0;
     521    LogFlow(("pdmR0IoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
     522             pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
     523    Assert(pVM->pdm.s.Apic.pDevInsR0);
     524    if (pVM->pdm.s.Apic.pfnBusDeliverR0)
     525        return pVM->pdm.s.Apic.pfnBusDeliverR0(pVM->pdm.s.Apic.pDevInsR0, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
     526    return VINF_SUCCESS;
     527}
     528
     529
     530/** @copydoc PDMIOAPICHLPR0::pfnLock */
     531static DECLCALLBACK(int) pdmR0IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
     532{
     533    PDMDEV_ASSERT_DEVINS(pDevIns);
     534    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
     535}
     536
     537
     538/** @copydoc PDMIOAPICHLPR0::pfnUnlock */
     539static DECLCALLBACK(void) pdmR0IoApicHlp_Unlock(PPDMDEVINS pDevIns)
     540{
     541    PDMDEV_ASSERT_DEVINS(pDevIns);
     542    pdmUnlock(pDevIns->Internal.s.pVMR0);
     543}
     544
    184545
    185546/**
    186  * The Guest Context I/O APIC Helper Callbacks.
     547 * The Ring-0 I/O APIC Helper Callbacks.
    187548 */
    188549extern DECLEXPORT(const PDMIOAPICHLPR0) g_pdmR0IoApicHlp =
     
    195556};
    196557
     558/** @} */
     559
     560
     561
     562
     563/** @name PCI Bus Ring-0 Helpers
     564 * @{
     565 */
     566
     567/** @copydoc PDMPCIHLPR0::pfnIsaSetIrq */
     568static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
     569{
     570    PDMDEV_ASSERT_DEVINS(pDevIns);
     571    Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
     572    pdmR0IsaSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
     573}
     574
     575
     576/** @copydoc PDMPCIHLPR0::pfnIoApicSetIrq */
     577static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
     578{
     579    PDMDEV_ASSERT_DEVINS(pDevIns);
     580    Log4(("pdmR0PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
     581    pdmR0IoApicSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
     582}
     583
     584
     585/** @copydoc PDMPCIHLPR0::pfnLock */
     586static DECLCALLBACK(int) pdmR0PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
     587{
     588    PDMDEV_ASSERT_DEVINS(pDevIns);
     589    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
     590}
     591
     592
     593/** @copydoc PDMPCIHLPR0::pfnUnlock */
     594static DECLCALLBACK(void) pdmR0PciHlp_Unlock(PPDMDEVINS pDevIns)
     595{
     596    PDMDEV_ASSERT_DEVINS(pDevIns);
     597    pdmUnlock(pDevIns->Internal.s.pVMR0);
     598}
     599
    197600
    198601/**
    199  * The Guest Context PCI Bus Helper Callbacks.
     602 * The Ring-0 PCI Bus Helper Callbacks.
    200603 */
    201604extern DECLEXPORT(const PDMPCIHLPR0) g_pdmR0PciHlp =
     
    209612};
    210613
     614/** @} */
     615
     616
     617
     618
     619/** @name HPET Ring-0 Helpers
     620 * @{
     621 */
     622
     623/** @copydoc PDMHPETHLPR0::pfnLock */
     624static DECLCALLBACK(int) pdmR0HpetHlp_Lock(PPDMDEVINS pDevIns, int rc)
     625{
     626    PDMDEV_ASSERT_DEVINS(pDevIns);
     627    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
     628}
     629
     630
     631/** @copydoc PDMHPETHLPR0::pfnUnlock */
     632static DECLCALLBACK(void) pdmR0HpetHlp_Unlock(PPDMDEVINS pDevIns)
     633{
     634    PDMDEV_ASSERT_DEVINS(pDevIns);
     635    pdmUnlock(pDevIns->Internal.s.pVMR0);
     636}
     637
     638
    211639/**
    212  * The Guest Context HPET Helper Callbacks.
     640 * The Ring-0 HPET Helper Callbacks.
    213641 */
    214642extern DECLEXPORT(const PDMHPETHLPR0) g_pdmR0HpetHlp =
     
    220648};
    221649
    222 
    223 /** @copydoc PDMDEVHLPR0::pfnPCISetIrq */
    224 static DECLCALLBACK(void) pdmR0DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    225 {
    226     PDMDEV_ASSERT_DEVINS(pDevIns);
    227     LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
    228 
    229     PVM          pVM     = pDevIns->Internal.s.pVMR0;
    230     PPCIDEVICE   pPciDev = pDevIns->Internal.s.pPciDeviceR0;
    231     PPDMPCIBUS   pPciBus = pDevIns->Internal.s.pPciBusR0;
    232     if (    pPciDev
    233         &&  pPciBus
    234         &&  pPciBus->pDevInsR0)
    235     {
    236         pdmLock(pVM);
    237         pPciBus->pfnSetIrqR0(pPciBus->pDevInsR0, pPciDev, iIrq, iLevel);
    238         pdmUnlock(pVM);
    239     }
    240     else
    241     {
    242         /* queue for ring-3 execution. */
    243         PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0);
    244         if (pTask)
    245         {
    246             pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
    247             pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
    248             pTask->u.SetIRQ.iIrq = iIrq;
    249             pTask->u.SetIRQ.iLevel = iLevel;
    250 
    251             PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
    252         }
    253         else
    254             AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
    255     }
    256 
    257     LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
    258 }
    259 
    260 
    261 /** @copydoc PDMDEVHLPR0::pfnPCISetIrq */
    262 static DECLCALLBACK(void) pdmR0DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    263 {
    264     PDMDEV_ASSERT_DEVINS(pDevIns);
    265     LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
    266 
    267     pdmR0IsaSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
    268 
    269     LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
    270 }
    271 
    272 
    273 /** @copydoc PDMDEVHLPR0::pfnPhysRead */
    274 static DECLCALLBACK(int) pdmR0DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
    275 {
    276     PDMDEV_ASSERT_DEVINS(pDevIns);
    277     LogFlow(("pdmR0DevHlp_PhysRead: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
    278              pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
    279 
    280     int rc = PGMPhysRead(pDevIns->Internal.s.pVMR0, GCPhys, pvBuf, cbRead);
    281     AssertRC(rc); /** @todo track down the users for this bugger. */
    282 
    283     Log(("pdmR0DevHlp_PhysRead: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
    284     return rc;
    285 }
    286 
    287 
    288 /** @copydoc PDMDEVHLPR0::pfnPhysWrite */
    289 static DECLCALLBACK(int) pdmR0DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
    290 {
    291     PDMDEV_ASSERT_DEVINS(pDevIns);
    292     LogFlow(("pdmR0DevHlp_PhysWrite: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
    293              pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
    294 
    295     int rc = PGMPhysWrite(pDevIns->Internal.s.pVMR0, GCPhys, pvBuf, cbWrite);
    296     AssertRC(rc); /** @todo track down the users for this bugger. */
    297 
    298     Log(("pdmR0DevHlp_PhysWrite: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
    299     return rc;
    300 }
    301 
    302 
    303 /** @copydoc PDMDEVHLPR0::pfnA20IsEnabled */
    304 static DECLCALLBACK(bool) pdmR0DevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
    305 {
    306     PDMDEV_ASSERT_DEVINS(pDevIns);
    307     LogFlow(("pdmR0DevHlp_A20IsEnabled: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
    308 
    309     bool fEnabled = PGMPhysIsA20Enabled(VMMGetCpu(pDevIns->Internal.s.pVMR0));
    310 
    311     Log(("pdmR0DevHlp_A20IsEnabled: caller=%p/%d: returns %RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
    312     return fEnabled;
    313 }
    314 
    315 
    316 /** @copydoc PDMDEVHLPR0::pfnVMSetError */
    317 static DECLCALLBACK(int) pdmR0DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
    318 {
    319     PDMDEV_ASSERT_DEVINS(pDevIns);
    320     va_list args;
    321     va_start(args, pszFormat);
    322     int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR0, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
    323     va_end(args);
    324     return rc;
    325 }
    326 
    327 
    328 /** @copydoc PDMDEVHLPR0::pfnVMSetErrorV */
    329 static DECLCALLBACK(int) pdmR0DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
    330 {
    331     PDMDEV_ASSERT_DEVINS(pDevIns);
    332     int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR0, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
    333     return rc;
    334 }
    335 
    336 
    337 /** @copydoc PDMDEVHLPR0::pfnVMSetRuntimeError */
    338 static DECLCALLBACK(int) pdmR0DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
    339 {
    340     PDMDEV_ASSERT_DEVINS(pDevIns);
    341     va_list va;
    342     va_start(va, pszFormat);
    343     int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR0, fFlags, pszErrorId, pszFormat, va);
    344     va_end(va);
    345     return rc;
    346 }
    347 
    348 
    349 /** @copydoc PDMDEVHLPR0::pfnVMSetRuntimeErrorV */
    350 static DECLCALLBACK(int) pdmR0DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
    351 {
    352     PDMDEV_ASSERT_DEVINS(pDevIns);
    353     int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR0, fFlags, pszErrorId, pszFormat, va);
    354     return rc;
    355 }
    356 
    357 
    358 /** @copydoc PDMDEVHLPR0::pdmR0DevHlp_PATMSetMMIOPatchInfo*/
    359 static DECLCALLBACK(int) pdmR0DevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData)
    360 {
    361     PDMDEV_ASSERT_DEVINS(pDevIns);
    362     LogFlow(("pdmR0DevHlp_PATMSetMMIOPatchInfo: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
    363 
    364     AssertFailed();
    365 
    366 /*    return PATMSetMMIOPatchInfo(pDevIns->Internal.s.pVMR0, GCPhys, pCachedData); */
    367     return VINF_SUCCESS;
    368 }
    369 
    370 
    371 /** @copydoc PDMDEVHLPR0::pfnGetVM */
    372 static DECLCALLBACK(PVM)  pdmR0DevHlp_GetVM(PPDMDEVINS pDevIns)
    373 {
    374     PDMDEV_ASSERT_DEVINS(pDevIns);
    375     LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
    376     return pDevIns->Internal.s.pVMR0;
    377 }
    378 
    379 
    380 /** @copydoc PDMDEVHLPR0::pfnCanEmulateIoBlock */
    381 static DECLCALLBACK(bool) pdmR0DevHlp_CanEmulateIoBlock(PPDMDEVINS pDevIns)
    382 {
    383     PDMDEV_ASSERT_DEVINS(pDevIns);
    384     LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
    385     return HWACCMCanEmulateIoBlock(VMMGetCpu(pDevIns->Internal.s.pVMR0));
    386 }
    387 
    388 
    389 /** @copydoc PDMDEVHLPR0::pfnGetVMCPU */
    390 static DECLCALLBACK(PVMCPU) pdmR0DevHlp_GetVMCPU(PPDMDEVINS pDevIns)
    391 {
    392     PDMDEV_ASSERT_DEVINS(pDevIns);
    393     LogFlow(("pdmR0DevHlp_GetVMCPU: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
    394     return VMMGetCpu(pDevIns->Internal.s.pVMR0);
    395 }
    396 
    397 
    398 
    399 
    400 /** @copydoc PDMPICHLPR0::pfnSetInterruptFF */
    401 static DECLCALLBACK(void) pdmR0PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
    402 {
    403     PDMDEV_ASSERT_DEVINS(pDevIns);
    404     PVM    pVM   = pDevIns->Internal.s.pVMR0;
    405 
    406     if (pVM->pdm.s.Apic.pfnLocalInterruptR0)
    407     {
    408         LogFlow(("pdmR0PicHlp_SetInterruptFF: caller='%p'/%d: Setting local interrupt on LAPIC\n",
    409                  pDevIns, pDevIns->iInstance));
    410         /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
    411         pVM->pdm.s.Apic.pfnLocalInterruptR0(pVM->pdm.s.Apic.pDevInsR0, 0, 1);
    412         return;
    413     }
    414 
    415     PVMCPU pVCpu = &pVM->aCpus[0];      /* for PIC we always deliver to CPU 0, MP use APIC */
    416 
    417     LogFlow(("pdmR0PicHlp_SetInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 1\n",
    418              pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
    419 
    420     VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    421 }
    422 
    423 
    424 /** @copydoc PDMPICHLPR0::pfnClearInterruptFF */
    425 static DECLCALLBACK(void) pdmR0PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
    426 {
    427     PDMDEV_ASSERT_DEVINS(pDevIns);
    428     PVM    pVM   = pDevIns->Internal.s.pVMR0;
    429 
    430     if (pVM->pdm.s.Apic.pfnLocalInterruptR0)
    431     {
    432         /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
    433         LogFlow(("pdmR0PicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
    434                  pDevIns, pDevIns->iInstance));
    435         /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
    436         pVM->pdm.s.Apic.pfnLocalInterruptR0(pVM->pdm.s.Apic.pDevInsR0, 0, 0);
    437         return;
    438     }
    439 
    440     PVMCPU pVCpu = &pVM->aCpus[0];      /* for PIC we always deliver to CPU 0, MP use APIC */
    441 
    442     LogFlow(("pdmR0PicHlp_ClearInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
    443              pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
    444 
    445     VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    446 }
    447 
    448 
    449 /** @copydoc PDMPICHLPR0::pfnLock */
    450 static DECLCALLBACK(int) pdmR0PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
    451 {
    452     PDMDEV_ASSERT_DEVINS(pDevIns);
    453     return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
    454 }
    455 
    456 
    457 /** @copydoc PDMPICHLPR0::pfnUnlock */
    458 static DECLCALLBACK(void) pdmR0PicHlp_Unlock(PPDMDEVINS pDevIns)
    459 {
    460     PDMDEV_ASSERT_DEVINS(pDevIns);
    461     pdmUnlock(pDevIns->Internal.s.pVMR0);
    462 }
    463 
    464 
    465 
    466 /** @copydoc PDMAPICHLPR0::pfnSetInterruptFF */
    467 static DECLCALLBACK(void) pdmR0ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
    468 {
    469     PDMDEV_ASSERT_DEVINS(pDevIns);
    470     PVM    pVM   = pDevIns->Internal.s.pVMR0;
    471     PVMCPU pVCpu = &pVM->aCpus[idCpu];
    472 
    473     AssertReturnVoid(idCpu < pVM->cCpus);
    474 
    475     LogFlow(("pdmR0ApicHlp_SetInterruptFF: CPU%d=caller=%p/%d: VM_FF_INTERRUPT %d -> 1 (CPU%d)\n",
    476              VMMGetCpuId(pVM), pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC), idCpu));
    477 
    478     switch (enmType)
    479     {
    480         case PDMAPICIRQ_HARDWARE:
    481             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
    482             break;
    483         case PDMAPICIRQ_NMI:
    484             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
    485             break;
    486         case PDMAPICIRQ_SMI:
    487             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
    488             break;
    489         case PDMAPICIRQ_EXTINT:
    490             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    491             break;
    492         default:
    493             AssertMsgFailed(("enmType=%d\n", enmType));
    494             break;
    495     }
    496 
    497     /* We need to wait up the target CPU. */
    498     if (VMMGetCpuId(pVM) != idCpu)
    499     {
    500         switch (VMCPU_GET_STATE(pVCpu))
    501         {
    502             case VMCPUSTATE_STARTED_EXEC:
    503                 GVMMR0SchedPokeEx(pVM, pVCpu->idCpu, false /* don't take the used lock */);
    504                 break;
    505 
    506             case VMCPUSTATE_STARTED_HALTED:
    507                 GVMMR0SchedWakeUpEx(pVM, pVCpu->idCpu, false /* don't take the used lock */);
    508                 break;
    509 
    510             default:
    511                 break; /* nothing to do in other states. */
    512         }
    513     }
    514 }
    515 
    516 
    517 /** @copydoc PDMAPICHLPR0::pfnClearInterruptFF */
    518 static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
    519 {
    520     PDMDEV_ASSERT_DEVINS(pDevIns);
    521     PVM    pVM   = pDevIns->Internal.s.pVMR0;
    522     PVMCPU pVCpu = &pVM->aCpus[idCpu];
    523 
    524     AssertReturnVoid(idCpu < pVM->cCpus);
    525 
    526     LogFlow(("pdmR0ApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
    527              pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
    528 
    529     /* Note: NMI/SMI can't be cleared. */
    530     switch (enmType)
    531     {
    532         case PDMAPICIRQ_HARDWARE:
    533             VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
    534             break;
    535         case PDMAPICIRQ_EXTINT:
    536             VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
    537             break;
    538         default:
    539             AssertMsgFailed(("enmType=%d\n", enmType));
    540             break;
    541     }
    542 }
    543 
    544 
    545 /** @copydoc PDMAPICHLPR0::pfnChangeFeature */
    546 static DECLCALLBACK(void) pdmR0ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion)
    547 {
    548     PDMDEV_ASSERT_DEVINS(pDevIns);
    549     LogFlow(("pdmR0ApicHlp_ChangeFeature: caller=%p/%d: version=%d\n", pDevIns, pDevIns->iInstance, (int)enmVersion));
    550     switch (enmVersion)
    551     {
    552         case PDMAPICVERSION_NONE:
    553             CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_APIC);
    554             CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_X2APIC);
    555             break;
    556         case PDMAPICVERSION_APIC:
    557             CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_APIC);
    558             CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_X2APIC);
    559             break;
    560         case PDMAPICVERSION_X2APIC:
    561             CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_X2APIC);
    562             CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_APIC);
    563             break;
    564         default:
    565             AssertMsgFailed(("Unknown APIC version: %d\n", (int)enmVersion));
    566     }
    567 }
    568 
    569 
    570 /** @copydoc PDMAPICHLPR0::pfnLock */
    571 static DECLCALLBACK(int) pdmR0ApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
    572 {
    573     PDMDEV_ASSERT_DEVINS(pDevIns);
    574     return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
    575 }
    576 
    577 
    578 /** @copydoc PDMAPICHLPR0::pfnUnlock */
    579 static DECLCALLBACK(void) pdmR0ApicHlp_Unlock(PPDMDEVINS pDevIns)
    580 {
    581     PDMDEV_ASSERT_DEVINS(pDevIns);
    582     pdmUnlock(pDevIns->Internal.s.pVMR0);
    583 }
    584 
    585 
    586 /** @copydoc PDMAPICHLPR0::pfnGetCpuId */
    587 static DECLCALLBACK(VMCPUID) pdmR0ApicHlp_GetCpuId(PPDMDEVINS pDevIns)
    588 {
    589     PDMDEV_ASSERT_DEVINS(pDevIns);
    590     return VMMGetCpuId(pDevIns->Internal.s.pVMR0);
    591 }
    592 
    593 
    594 
    595 
    596 
    597 /** @copydoc PDMIOAPICHLPR0::pfnApicBusDeliver */
    598 static DECLCALLBACK(int) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
    599                                                         uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
    600 {
    601     PDMDEV_ASSERT_DEVINS(pDevIns);
    602     PVM pVM = pDevIns->Internal.s.pVMR0;
    603     LogFlow(("pdmR0IoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
    604              pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
    605     Assert(pVM->pdm.s.Apic.pDevInsR0);
    606     if (pVM->pdm.s.Apic.pfnBusDeliverR0)
    607         return pVM->pdm.s.Apic.pfnBusDeliverR0(pVM->pdm.s.Apic.pDevInsR0, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
    608     return VINF_SUCCESS;
    609 }
    610 
    611 
    612 /** @copydoc PDMIOAPICHLPR0::pfnLock */
    613 static DECLCALLBACK(int) pdmR0IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
    614 {
    615     PDMDEV_ASSERT_DEVINS(pDevIns);
    616     return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
    617 }
    618 
    619 
    620 /** @copydoc PDMIOAPICHLPR0::pfnUnlock */
    621 static DECLCALLBACK(void) pdmR0IoApicHlp_Unlock(PPDMDEVINS pDevIns)
    622 {
    623     PDMDEV_ASSERT_DEVINS(pDevIns);
    624     pdmUnlock(pDevIns->Internal.s.pVMR0);
    625 }
    626 
    627 
    628 
    629 
    630 
    631 /** @copydoc PDMPCIHLPR0::pfnIsaSetIrq */
    632 static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    633 {
    634     PDMDEV_ASSERT_DEVINS(pDevIns);
    635     Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
    636     pdmR0IsaSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
    637 }
    638 
    639 
    640 /** @copydoc PDMPCIHLPR0::pfnIoApicSetIrq */
    641 static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
    642 {
    643     PDMDEV_ASSERT_DEVINS(pDevIns);
    644     Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
    645     pdmR0IoApicSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
    646 }
    647 
    648 
    649 /** @copydoc PDMPCIHLPR0::pfnLock */
    650 static DECLCALLBACK(int) pdmR0PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
    651 {
    652     PDMDEV_ASSERT_DEVINS(pDevIns);
    653     return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
    654 }
    655 
    656 
    657 /** @copydoc PDMPCIHLPR0::pfnUnlock */
    658 static DECLCALLBACK(void) pdmR0PciHlp_Unlock(PPDMDEVINS pDevIns)
    659 {
    660     PDMDEV_ASSERT_DEVINS(pDevIns);
    661     pdmUnlock(pDevIns->Internal.s.pVMR0);
    662 }
    663 
     650/** @} */
    664651
    665652
     
    738725}
    739726
    740 /** @copydoc PDMHPETHLPR0::pfnLock */
    741 static DECLCALLBACK(int) pdmR0HpetHlp_Lock(PPDMDEVINS pDevIns, int rc)
    742 {
    743     PDMDEV_ASSERT_DEVINS(pDevIns);
    744     return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
    745 }
    746 
    747 
    748 /** @copydoc PDMHPETHLPR0::pfnUnlock */
    749 static DECLCALLBACK(void) pdmR0HpetHlp_Unlock(PPDMDEVINS pDevIns)
    750 {
    751     PDMDEV_ASSERT_DEVINS(pDevIns);
    752     pdmUnlock(pDevIns->Internal.s.pVMR0);
    753 }
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