71
71
*******************************************************************************/
72
72
#define SERIAL_SAVED_STATE_VERSION 3
74
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
76
#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
77
#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
78
#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
79
#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
81
#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
82
#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
84
#define UART_IIR_MSI 0x00 /* Modem status interrupt */
85
#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
86
#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
87
#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
74
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
76
#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
77
#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
78
#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
79
#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
81
#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
82
#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
84
#define UART_IIR_MSI 0x00 /* Modem status interrupt */
85
#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
86
#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
87
#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
90
90
* These are the definitions for the Modem Control Register
92
#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
93
#define UART_MCR_OUT2 0x08 /* Out2 complement */
94
#define UART_MCR_OUT1 0x04 /* Out1 complement */
95
#define UART_MCR_RTS 0x02 /* RTS complement */
96
#define UART_MCR_DTR 0x01 /* DTR complement */
92
#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
93
#define UART_MCR_OUT2 0x08 /* Out2 complement */
94
#define UART_MCR_OUT1 0x04 /* Out1 complement */
95
#define UART_MCR_RTS 0x02 /* RTS complement */
96
#define UART_MCR_DTR 0x01 /* DTR complement */
99
99
* These are the definitions for the Modem Status Register
101
#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
102
#define UART_MSR_RI 0x40 /* Ring Indicator */
103
#define UART_MSR_DSR 0x20 /* Data Set Ready */
104
#define UART_MSR_CTS 0x10 /* Clear to Send */
105
#define UART_MSR_DDCD 0x08 /* Delta DCD */
106
#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
107
#define UART_MSR_DDSR 0x02 /* Delta DSR */
108
#define UART_MSR_DCTS 0x01 /* Delta CTS */
109
#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
101
#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
102
#define UART_MSR_RI 0x40 /* Ring Indicator */
103
#define UART_MSR_DSR 0x20 /* Data Set Ready */
104
#define UART_MSR_CTS 0x10 /* Clear to Send */
105
#define UART_MSR_DDCD 0x08 /* Delta DCD */
106
#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
107
#define UART_MSR_DDSR 0x02 /* Delta DSR */
108
#define UART_MSR_DCTS 0x01 /* Delta CTS */
109
#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
111
#define UART_LSR_TEMT 0x40 /* Transmitter empty */
112
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
113
#define UART_LSR_BI 0x10 /* Break interrupt indicator */
114
#define UART_LSR_FE 0x08 /* Frame error indicator */
115
#define UART_LSR_PE 0x04 /* Parity error indicator */
116
#define UART_LSR_OE 0x02 /* Overrun error indicator */
117
#define UART_LSR_DR 0x01 /* Receiver data ready */
111
#define UART_LSR_TEMT 0x40 /* Transmitter empty */
112
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
113
#define UART_LSR_BI 0x10 /* Break interrupt indicator */
114
#define UART_LSR_FE 0x08 /* Frame error indicator */
115
#define UART_LSR_PE 0x04 /* Parity error indicator */
116
#define UART_LSR_OE 0x02 /* Overrun error indicator */
117
#define UART_LSR_DR 0x01 /* Receiver data ready */
120
120
/*******************************************************************************
567
* Saves a state of the serial port device.
569
* @returns VBox status code.
570
* @param pDevIns The device instance.
571
* @param pSSMHandle The handle to save the state to.
591
* @copydoc FNSSMDEVLIVEEXEC
593
static DECLCALLBACK(int) serialLiveExec(PPDMDEVINS pDevIns,
597
SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *);
598
SSMR3PutS32(pSSM, pThis->irq);
599
SSMR3PutU32(pSSM, pThis->base);
600
return VINF_SSM_DONT_CALL_AGAIN;
604
* @copydoc FNSSMDEVSAVEEXEC
573
606
static DECLCALLBACK(int) serialSaveExec(PPDMDEVINS pDevIns,
574
PSSMHANDLE pSSMHandle)
576
609
SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *);
578
SSMR3PutU16(pSSMHandle, pThis->divider);
579
SSMR3PutU8(pSSMHandle, pThis->rbr);
580
SSMR3PutU8(pSSMHandle, pThis->ier);
581
SSMR3PutU8(pSSMHandle, pThis->lcr);
582
SSMR3PutU8(pSSMHandle, pThis->mcr);
583
SSMR3PutU8(pSSMHandle, pThis->lsr);
584
SSMR3PutU8(pSSMHandle, pThis->msr);
585
SSMR3PutU8(pSSMHandle, pThis->scr);
586
SSMR3PutS32(pSSMHandle, pThis->thr_ipending);
587
SSMR3PutS32(pSSMHandle, pThis->irq);
588
SSMR3PutS32(pSSMHandle, pThis->last_break_enable);
589
SSMR3PutU32(pSSMHandle, pThis->base);
590
SSMR3PutBool(pSSMHandle, pThis->msr_changed);
591
return SSMR3PutU32(pSSMHandle, ~0); /* sanity/terminator */
611
SSMR3PutU16(pSSM, pThis->divider);
612
SSMR3PutU8(pSSM, pThis->rbr);
613
SSMR3PutU8(pSSM, pThis->ier);
614
SSMR3PutU8(pSSM, pThis->lcr);
615
SSMR3PutU8(pSSM, pThis->mcr);
616
SSMR3PutU8(pSSM, pThis->lsr);
617
SSMR3PutU8(pSSM, pThis->msr);
618
SSMR3PutU8(pSSM, pThis->scr);
619
SSMR3PutS32(pSSM, pThis->thr_ipending);
620
SSMR3PutS32(pSSM, pThis->irq);
621
SSMR3PutS32(pSSM, pThis->last_break_enable);
622
SSMR3PutU32(pSSM, pThis->base);
623
SSMR3PutBool(pSSM, pThis->msr_changed);
624
return SSMR3PutU32(pSSM, ~0); /* sanity/terminator */
595
* Loads a saved serial port device state.
597
* @returns VBox status code.
598
* @param pDevIns The device instance.
599
* @param pSSMHandle The handle to the saved state.
600
* @param u32Version The data unit version number.
628
* @copydoc FNSSMDEVLOADEXEC
602
630
static DECLCALLBACK(int) serialLoadExec(PPDMDEVINS pDevIns,
603
PSSMHANDLE pSSMHandle,
608
635
SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *);
610
if (u32Version != SERIAL_SAVED_STATE_VERSION)
612
AssertMsgFailed(("u32Version=%d\n", u32Version));
613
return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
616
SSMR3GetU16(pSSMHandle, &pThis->divider);
617
SSMR3GetU8(pSSMHandle, &pThis->rbr);
618
SSMR3GetU8(pSSMHandle, &pThis->ier);
619
SSMR3GetU8(pSSMHandle, &pThis->lcr);
620
SSMR3GetU8(pSSMHandle, &pThis->mcr);
621
SSMR3GetU8(pSSMHandle, &pThis->lsr);
622
SSMR3GetU8(pSSMHandle, &pThis->msr);
623
SSMR3GetU8(pSSMHandle, &pThis->scr);
624
SSMR3GetS32(pSSMHandle, &pThis->thr_ipending);
625
SSMR3GetS32(pSSMHandle, &pThis->irq);
626
SSMR3GetS32(pSSMHandle, &pThis->last_break_enable);
627
SSMR3GetU32(pSSMHandle, &pThis->base);
628
SSMR3GetBool(pSSMHandle, &pThis->msr_changed);
630
rc = SSMR3GetU32(pSSMHandle, &u32);
636
AssertLogRelMsgFailed(("u32=%#x expected ~0\n", u32));
637
return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
639
/* Be careful with pointers in the structure; they are not preserved
640
* in the saved state. */
642
if (pThis->lsr & UART_LSR_DR)
644
int rc = RTSemEventSignal(pThis->ReceiveSem);
648
/* this isn't strictly necessary but cannot hurt... */
649
pThis->pDevInsR3 = pDevIns;
650
pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
651
pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
637
AssertMsgReturn(uVersion == SERIAL_SAVED_STATE_VERSION, ("%d\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
639
if (uPass == SSM_PASS_FINAL)
641
SSMR3GetU16(pSSM, &pThis->divider);
642
SSMR3GetU8(pSSM, &pThis->rbr);
643
SSMR3GetU8(pSSM, &pThis->ier);
644
SSMR3GetU8(pSSM, &pThis->lcr);
645
SSMR3GetU8(pSSM, &pThis->mcr);
646
SSMR3GetU8(pSSM, &pThis->lsr);
647
SSMR3GetU8(pSSM, &pThis->msr);
648
SSMR3GetU8(pSSM, &pThis->scr);
649
SSMR3GetS32(pSSM, &pThis->thr_ipending);
653
SSMR3GetS32(pSSM, &iIrq);
655
if (uPass == SSM_PASS_FINAL)
656
SSMR3GetS32(pSSM, &pThis->last_break_enable);
659
int rc = SSMR3GetU32(pSSM, &IOBase);
660
AssertRCReturn(rc, rc);
662
if ( pThis->irq != iIrq
663
|| pThis->base != IOBase)
664
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - saved irq=%#x iobase=%#x; configured irq=%#x iobase=%#x"),
665
iIrq, IOBase, pThis->irq, pThis->base);
667
if (uPass == SSM_PASS_FINAL)
669
SSMR3GetBool(pSSM, &pThis->msr_changed);
672
rc = SSMR3GetU32(pSSM, &u32);
675
AssertMsgReturn(u32 == ~0U, ("%#x\n", u32), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
677
if (pThis->lsr & UART_LSR_DR)
679
rc = RTSemEventSignal(pThis->ReceiveSem);
683
/* this isn't strictly necessary but cannot hurt... */
684
pThis->pDevInsR3 = pDevIns;
685
pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
686
pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
652
689
return VINF_SUCCESS;
883
921
if (pThis->fGCEnabled)
884
923
rc = PDMDevHlpIOPortRegisterGC(pDevIns, io_base, 8, 0, "serialIOPortWrite",
885
924
"serialIOPortRead", NULL, NULL, "Serial");
887
930
if (pThis->fR0Enabled)
888
932
rc = PDMDevHlpIOPortRegisterR0(pDevIns, io_base, 8, 0, "serialIOPortWrite",
889
933
"serialIOPortRead", NULL, NULL, "Serial");
890
937
#endif /* !VBOX_SERIAL_PCI */
895
rc = PDMDevHlpSSMRegister(
896
pDevIns, /* pDevIns */
897
pDevIns->pDevReg->szDeviceName, /* pszName */
898
iInstance, /* u32Instance */
899
SERIAL_SAVED_STATE_VERSION, /* u32Version */
900
sizeof (*pThis), /* cbGuess */
901
NULL, /* pfnSavePrep */
902
serialSaveExec, /* pfnSaveExec */
903
NULL, /* pfnSaveDone */
904
NULL, /* pfnLoadPrep */
905
serialLoadExec, /* pfnLoadExec */
906
NULL /* pfnLoadDone */
942
rc = PDMDevHlpSSMRegister3(pDevIns, SERIAL_SAVED_STATE_VERSION, sizeof (*pThis),
943
serialLiveExec, serialSaveExec, serialLoadExec);
908
944
if (RT_FAILURE(rc))