VirtualBox

Changeset 73259 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Jul 20, 2018 10:14:05 AM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
123866
Message:

Devices/Serial: Saved state handling for the UART core and the legacy serial device (no saved states for the OXPCIe958 device yet)

Location:
trunk/src/VBox/Devices/Serial
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Serial/DevSerialNew.cpp

    r73243 r73259  
    145145
    146146
     147/* -=-=-=-=-=-=-=-=- Saved State -=-=-=-=-=-=-=-=- */
     148
     149/**
     150 * @callback_method_impl{FNSSMDEVLIVEEXEC}
     151 */
     152static DECLCALLBACK(int) serialR3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
     153{
     154    RT_NOREF(uPass);
     155    PDEVSERIAL pThis = PDMINS_2_DATA(pDevIns, PDEVSERIAL);
     156    SSMR3PutU8(pSSM, pThis->uIrq);
     157    SSMR3PutIOPort(pSSM, pThis->PortBase);
     158    SSMR3PutU32(pSSM, pThis->UartCore.enmType);
     159
     160    return VINF_SSM_DONT_CALL_AGAIN;
     161}
     162
     163
     164/**
     165 * @callback_method_impl{FNSSMDEVSAVEEXEC}
     166 */
     167static DECLCALLBACK(int) serialR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     168{
     169    PDEVSERIAL pThis = PDMINS_2_DATA(pDevIns, PDEVSERIAL);
     170
     171    SSMR3PutU8(    pSSM, pThis->uIrq);
     172    SSMR3PutIOPort(pSSM, pThis->PortBase);
     173    SSMR3PutU32(   pSSM, pThis->UartCore.enmType);
     174
     175    uartR3SaveExec(&pThis->UartCore, pSSM);
     176    return SSMR3PutU32(pSSM, UINT32_MAX); /* sanity/terminator */
     177}
     178
     179
     180/**
     181 * @callback_method_impl{FNSSMDEVLOADEXEC}
     182 */
     183static DECLCALLBACK(int) serialR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     184{
     185    PDEVSERIAL pThis = PDMINS_2_DATA(pDevIns, PDEVSERIAL);
     186    uint8_t    uIrq;
     187    RTIOPORT   PortBase;
     188    UARTTYPE   enmType;
     189
     190    AssertMsgReturn(uVersion >= UART_SAVED_STATE_VERSION_16450, ("%d\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
     191
     192    if (uPass != SSM_PASS_FINAL)
     193    {
     194        SSMR3GetU8(pSSM, &uIrq);
     195        SSMR3GetIOPort(pSSM, &PortBase);
     196        int rc = SSMR3GetU32(pSSM, (uint32_t *)&enmType);
     197        AssertRCReturn(rc, rc);
     198    }
     199    else
     200    {
     201        int rc = VINF_SUCCESS;
     202
     203        if (uVersion > UART_SAVED_STATE_VERSION_LEGACY_CODE)
     204        {
     205            SSMR3GetU8(    pSSM, &uIrq);
     206            SSMR3GetIOPort(pSSM, &PortBase);
     207            SSMR3GetU32(   pSSM, (uint32_t *)&enmType);
     208            rc = uartR3LoadExec(&pThis->UartCore, pSSM, uVersion, uPass, NULL, NULL);
     209        }
     210        else
     211            rc = uartR3LoadExec(&pThis->UartCore, pSSM, uVersion, uPass, &uIrq, &PortBase);
     212        if (RT_SUCCESS(rc))
     213        {
     214            /* The marker. */
     215            uint32_t u32;
     216            rc = SSMR3GetU32(pSSM, &u32);
     217            if (RT_FAILURE(rc))
     218                return rc;
     219            AssertMsgReturn(u32 == UINT32_MAX, ("%#x\n", u32), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
     220        }
     221    }
     222
     223    /*
     224     * Check the config.
     225     */
     226    if (    pThis->uIrq     != uIrq
     227        ||  pThis->PortBase != PortBase
     228        ||  pThis->UartCore.enmType != enmType)
     229        return SSMR3SetCfgError(pSSM, RT_SRC_POS,
     230                                N_("Config mismatch - saved IRQ=%#x PortBase=%#x Type=%d; configured IRQ=%#x PortBase=%#x Type=%d"),
     231                                uIrq, PortBase, enmType, pThis->uIrq, pThis->PortBase, pThis->UartCore.enmType);
     232
     233    return VINF_SUCCESS;
     234}
     235
     236
     237/**
     238 * @callback_method_impl{FNSSMDEVLOADDONE}
     239 */
     240static DECLCALLBACK(int) serialR3LoadDone(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     241{
     242    PDEVSERIAL  pThis = PDMINS_2_DATA(pDevIns, PDEVSERIAL);
     243    return uartR3LoadDone(&pThis->UartCore, pSSM);
     244}
     245
     246
    147247/* -=-=-=-=-=-=-=-=- PDMDEVREG -=-=-=-=-=-=-=-=- */
    148248
     
    347447    }
    348448
    349 #if 0 /** @todo Later */
    350449    /*
    351450     * Saved state.
    352451     */
    353     rc = PDMDevHlpSSMRegister3(pDevIns, SERIAL_SAVED_STATE_VERSION, sizeof (*pThis),
    354                                serialR3LiveExec, serialR3SaveExec, serialR3LoadExec);
     452    rc = PDMDevHlpSSMRegisterEx(pDevIns, UART_SAVED_STATE_VERSION, sizeof(*pThis), NULL,
     453                                NULL, serialR3LiveExec, NULL,
     454                                NULL, serialR3SaveExec, NULL,
     455                                NULL, serialR3LoadExec, serialR3LoadDone);
    355456    if (RT_FAILURE(rc))
    356457        return rc;
    357 #endif
    358 
    359458
    360459    /* Init the UART core structure. */
  • trunk/src/VBox/Devices/Serial/UartCore.cpp

    r73243 r73259  
    12851285    RT_NOREF(pDevIns, pTimer);
    12861286    PUARTCORE pThis = (PUARTCORE)pvUser;
    1287     Assert(PDMCritSectIsOwner(&pThis->CritSect));
     1287    PDMCritSectEnter(&pThis->CritSect, VERR_IGNORED);
    12881288    if (pThis->FifoRecv.cbUsed)
    12891289    {
     
    12911291        uartIrqUpdate(pThis);
    12921292    }
     1293    PDMCritSectLeave(&pThis->CritSect);
    12931294}
    12941295
     
    14281429    PDMIBASE_RETURN_INTERFACE(pszIID, PDMISERIALPORT, &pThis->ISerialPort);
    14291430    return NULL;
     1431}
     1432
     1433
     1434DECLHIDDEN(int) uartR3SaveExec(PUARTCORE pThis, PSSMHANDLE pSSM)
     1435{
     1436    SSMR3PutU16(pSSM,  pThis->uRegDivisor);
     1437    SSMR3PutU8(pSSM,   pThis->uRegRbr);
     1438    SSMR3PutU8(pSSM,   pThis->uRegThr);
     1439    SSMR3PutU8(pSSM,   pThis->uRegIer);
     1440    SSMR3PutU8(pSSM,   pThis->uRegIir);
     1441    SSMR3PutU8(pSSM,   pThis->uRegFcr);
     1442    SSMR3PutU8(pSSM,   pThis->uRegLcr);
     1443    SSMR3PutU8(pSSM,   pThis->uRegMcr);
     1444    SSMR3PutU8(pSSM,   pThis->uRegLsr);
     1445    SSMR3PutU8(pSSM,   pThis->uRegMsr);
     1446    SSMR3PutU8(pSSM,   pThis->uRegScr);
     1447    SSMR3PutBool(pSSM, pThis->fIrqCtiPending);
     1448    SSMR3PutU8(pSSM,   pThis->FifoXmit.cbMax);
     1449    SSMR3PutU8(pSSM,   pThis->FifoXmit.cbItl);
     1450    SSMR3PutU8(pSSM,   pThis->FifoRecv.cbMax);
     1451    SSMR3PutU8(pSSM,   pThis->FifoRecv.cbItl);
     1452
     1453    return TMR3TimerSave(pThis->pTimerRcvFifoTimeoutR3, pSSM);
     1454}
     1455
     1456
     1457DECLHIDDEN(int) uartR3LoadExec(PUARTCORE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass,
     1458                               uint8_t *puIrq, RTIOPORT *pPortBase)
     1459{
     1460    int rc = VINF_SUCCESS;
     1461
     1462    if (uVersion > UART_SAVED_STATE_VERSION_LEGACY_CODE)
     1463    {
     1464        SSMR3GetU16(pSSM,  &pThis->uRegDivisor);
     1465        SSMR3GetU8(pSSM,   &pThis->uRegRbr);
     1466        SSMR3GetU8(pSSM,   &pThis->uRegThr);
     1467        SSMR3GetU8(pSSM,   &pThis->uRegIer);
     1468        SSMR3GetU8(pSSM,   &pThis->uRegIir);
     1469        SSMR3GetU8(pSSM,   &pThis->uRegFcr);
     1470        SSMR3GetU8(pSSM,   &pThis->uRegLcr);
     1471        SSMR3GetU8(pSSM,   &pThis->uRegMcr);
     1472        SSMR3GetU8(pSSM,   &pThis->uRegLsr);
     1473        SSMR3GetU8(pSSM,   &pThis->uRegMsr);
     1474        SSMR3GetU8(pSSM,   &pThis->uRegScr);
     1475        SSMR3GetBool(pSSM, &pThis->fIrqCtiPending);
     1476        SSMR3GetU8(pSSM,   &pThis->FifoXmit.cbMax);
     1477        SSMR3GetU8(pSSM,   &pThis->FifoXmit.cbItl);
     1478        SSMR3GetU8(pSSM,   &pThis->FifoRecv.cbMax);
     1479        SSMR3GetU8(pSSM,   &pThis->FifoRecv.cbItl);
     1480
     1481        TMR3TimerLoad(pThis->pTimerRcvFifoTimeoutR3, pSSM);
     1482    }
     1483    else
     1484    {
     1485        if (uVersion == UART_SAVED_STATE_VERSION_16450)
     1486        {
     1487            pThis->enmType = UARTTYPE_16450;
     1488            LogRel(("Serial#%d: falling back to 16450 mode from load state\n", pThis->pDevInsR3->iInstance));
     1489        }
     1490
     1491        int      uIrq;
     1492        uint32_t PortBase;
     1493
     1494        SSMR3GetU16(pSSM, &pThis->uRegDivisor);
     1495        SSMR3GetU8(pSSM, &pThis->uRegRbr);
     1496        SSMR3GetU8(pSSM, &pThis->uRegIer);
     1497        SSMR3GetU8(pSSM, &pThis->uRegLcr);
     1498        SSMR3GetU8(pSSM, &pThis->uRegMcr);
     1499        SSMR3GetU8(pSSM, &pThis->uRegLsr);
     1500        SSMR3GetU8(pSSM, &pThis->uRegMsr);
     1501        SSMR3GetU8(pSSM, &pThis->uRegScr);
     1502        if (uVersion > UART_SAVED_STATE_VERSION_16450)
     1503            SSMR3GetU8(pSSM, &pThis->uRegFcr);
     1504        SSMR3Skip(pSSM, sizeof(int32_t));
     1505        SSMR3GetS32(pSSM, &uIrq);
     1506        SSMR3Skip(pSSM, sizeof(int32_t));
     1507        SSMR3GetU32(pSSM, &PortBase);
     1508        rc = SSMR3Skip(pSSM, sizeof(int32_t));
     1509
     1510        if (   RT_SUCCESS(rc)
     1511            && uVersion > UART_SAVED_STATE_VERSION_MISSING_BITS)
     1512        {
     1513            SSMR3GetU8(pSSM, &pThis->uRegThr);
     1514            SSMR3Skip(pSSM, sizeof(uint8_t)); /* The old transmit shift register, not used anymore. */
     1515            SSMR3GetU8(pSSM, &pThis->uRegIir);
     1516
     1517            int iTimeoutPending = 0;
     1518            SSMR3GetS32(pSSM, &iTimeoutPending);
     1519            pThis->fIrqCtiPending = RT_BOOL(iTimeoutPending);
     1520
     1521            TMR3TimerLoad(pThis->pTimerRcvFifoTimeoutR3, pSSM);
     1522            TMR3TimerSkip(pSSM, NULL);
     1523            SSMR3GetU8(pSSM, &pThis->FifoRecv.cbItl);
     1524            rc = SSMR3GetU8(pSSM, &pThis->FifoRecv.cbItl);
     1525        }
     1526
     1527        if (RT_SUCCESS(rc))
     1528        {
     1529            AssertPtr(puIrq);
     1530            AssertPtr(pPortBase);
     1531            *puIrq     = (uint8_t)uIrq;
     1532            *pPortBase = (RTIOPORT)PortBase;
     1533        }
     1534    }
     1535
     1536    return rc;
     1537}
     1538
     1539
     1540DECLHIDDEN(int) uartR3LoadDone(PUARTCORE pThis, PSSMHANDLE pSSM)
     1541{
     1542    RT_NOREF(pSSM);
     1543
     1544    uartR3ParamsUpdate(pThis);
     1545    uartIrqUpdate(pThis);
     1546
     1547    if (pThis->pDrvSerial)
     1548    {
     1549        /* Set the modem lines to reflect the current state. */
     1550        int rc = pThis->pDrvSerial->pfnChgModemLines(pThis->pDrvSerial,
     1551                                                     RT_BOOL(pThis->uRegMcr & UART_REG_MCR_RTS),
     1552                                                     RT_BOOL(pThis->uRegMcr & UART_REG_MCR_DTR));
     1553        if (RT_FAILURE(rc))
     1554            LogRel(("Serial#%d: Failed to set modem lines with %Rrc during saved state load\n",
     1555                    pThis->pDevInsR3->iInstance, rc));
     1556
     1557        uint32_t fStsLines = 0;
     1558        rc = pThis->pDrvSerial->pfnQueryStsLines(pThis->pDrvSerial, &fStsLines);
     1559        if (RT_SUCCESS(rc))
     1560            uartR3StsLinesUpdate(pThis, fStsLines);
     1561        else
     1562            LogRel(("Serial#%d: Failed to query status line status with %Rrc during reset\n",
     1563                    pThis->pDevInsR3->iInstance, rc));
     1564    }
     1565
     1566    return VINF_SUCCESS;
    14301567}
    14311568
  • trunk/src/VBox/Devices/Serial/UartCore.h

    r73243 r73259  
    2323#include <VBox/vmm/pdmdev.h>
    2424#include <VBox/vmm/pdmserialifs.h>
     25#include <VBox/vmm/ssm.h>
    2526#include <iprt/assert.h>
    2627
     
    3031*   Defined Constants And Macros                                                                                                 *
    3132*********************************************************************************************************************************/
     33
     34/** The current serial code saved state version. */
     35#define UART_SAVED_STATE_VERSION              6
     36/** Saved state version of the legacy code which got replaced after 5.2. */
     37#define UART_SAVED_STATE_VERSION_LEGACY_CODE  5
     38/** Includes some missing bits from the previous saved state. */
     39#define UART_SAVED_STATE_VERSION_MISSING_BITS 4
     40/** Saved state version when only the 16450 variant was implemented. */
     41#define UART_SAVED_STATE_VERSION_16450        3
    3242
    3343/** Maximum size of a FIFO. */
     
    278288DECLHIDDEN(void) uartR3Relocate(PUARTCORE pThis, RTGCINTPTR offDelta);
    279289
     290/**
     291 * Saves the UART state to the given SSM handle.
     292 *
     293 * @returns VBox status code.
     294 * @param   pThis               The UART core instance.
     295 * @param   pSSM                The SSM handle to save to.
     296 */
     297DECLHIDDEN(int) uartR3SaveExec(PUARTCORE pThis, PSSMHANDLE pSSM);
     298
     299/**
     300 * Loads the UART state from the given SSM handle.
     301 *
     302 * @returns VBox status code.
     303 * @param   pThis               The UART core instance.
     304 * @param   pSSM                The SSM handle to load from.
     305 * @param   uVersion            Saved state version.
     306 * @param   uPass               The SSM pass the call is done in.
     307 * @param   puIrq               Where to store the IRQ value for legacy
     308 *                              saved states - optional.
     309 * @param   pPortBase           Where to store the I/O port base for legacy
     310 *                              saved states - optional.
     311 */
     312DECLHIDDEN(int) uartR3LoadExec(PUARTCORE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass,
     313                               uint8_t *puIrq, RTIOPORT *pPortBase);
     314
     315/**
     316 * Called when loading the state completed, updates the parameters of any driver underneath.
     317 *
     318 * @returns VBox status code.
     319 * @param   pThis               The UART core instance.
     320 * @param   pSSM                The SSM handle.
     321 */
     322DECLHIDDEN(int) uartR3LoadDone(PUARTCORE pThis, PSSMHANDLE pSSM);
     323
    280324# endif
    281325
Note: See TracChangeset for help on using the changeset viewer.

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