Changeset 11277 in vbox for trunk/src/VBox
- Timestamp:
- Aug 8, 2008 8:15:59 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 34370
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Serial/DevSerial.cpp
r11269 r11277 1 /* $Id$ */ 1 2 /** @file 2 * 3 * VBox serial device: 4 * Serial communication port driver 3 * DevSerial - 16450 UART emulation. 5 4 */ 6 5 … … 47 46 * 48 47 */ 49 50 48 51 49 /******************************************************************************* … … 60 58 #include <iprt/critsect.h> 61 59 62 #include " Builtins.h"60 #include "../Builtins.h" 63 61 64 62 #undef VBOX_SERIAL_PCI /* The PCI variant has lots of problems: wrong IRQ line and wrong IO base assigned. */ 65 63 66 64 #ifdef VBOX_SERIAL_PCI 67 # include <VBox/pci.h>65 # include <VBox/pci.h> 68 66 #endif /* VBOX_SERIAL_PCI */ 69 67 68 69 /******************************************************************************* 70 * Defined Constants And Macros * 71 *******************************************************************************/ 70 72 #define SERIAL_SAVED_STATE_VERSION 3 71 73 … … 115 117 #define UART_LSR_DR 0x01 /* Receiver data ready */ 116 118 119 120 /******************************************************************************* 121 * Structures and Typedefs * 122 *******************************************************************************/ 117 123 struct SerialState 118 124 { … … 120 126 PDMCRITSECT CritSect; 121 127 122 /** Pointer to the device instance . */123 R3PTRTYPE(PPDMDEVINS) pDevInsHC;124 /** Pointer to the device instance . */125 RCPTRTYPE(PPDMDEVINS) pDevInsGC;126 #if HC_ARCH_BITS == 64 127 RTRCPTR Alignment0;128 #endif 128 /** Pointer to the device instance - R3 Ptr. */ 129 PPDMDEVINSR3 pDevInsR3; 130 /** Pointer to the device instance - R0 Ptr. */ 131 PPDMDEVINSR0 pDevInsR0; 132 /** Pointer to the device instance - RC Ptr. */ 133 PPDMDEVINSRC pDevInsRC; 134 RTRCPTR Alignment0; /**< Alignment. */ 129 135 /** The base interface. */ 130 136 PDMIBASE IBase; … … 175 181 176 182 183 /******************************************************************************* 184 * Internal Functions * 185 *******************************************************************************/ 177 186 __BEGIN_DECLS 178 187 PDMBOTHCBDECL(int) serialIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); … … 181 190 182 191 #ifdef IN_RING3 192 183 193 static void serial_update_irq(SerialState *s) 184 194 { … … 194 204 if (s->iir != UART_IIR_NO_INT) { 195 205 Log(("serial_update_irq %d 1\n", s->irq)); 196 # ifdef VBOX_SERIAL_PCI197 PDMDevHlpPCISetIrqNoWait( CTXSUFF(s->pDevIns), 0, 1);198 # else /* !VBOX_SERIAL_PCI */199 PDMDevHlpISASetIrqNoWait( CTXSUFF(s->pDevIns), s->irq, 1);200 # endif /* !VBOX_SERIAL_PCI */206 # ifdef VBOX_SERIAL_PCI 207 PDMDevHlpPCISetIrqNoWait(s->CTX_SUFF(pDevIns), 0, 1); 208 # else /* !VBOX_SERIAL_PCI */ 209 PDMDevHlpISASetIrqNoWait(s->CTX_SUFF(pDevIns), s->irq, 1); 210 # endif /* !VBOX_SERIAL_PCI */ 201 211 } else { 202 212 Log(("serial_update_irq %d 0\n", s->irq)); 203 # ifdef VBOX_SERIAL_PCI204 PDMDevHlpPCISetIrqNoWait( CTXSUFF(s->pDevIns), 0, 0);205 # else /* !VBOX_SERIAL_PCI */206 PDMDevHlpISASetIrqNoWait( CTXSUFF(s->pDevIns), s->irq, 0);207 # endif /* !VBOX_SERIAL_PCI */213 # ifdef VBOX_SERIAL_PCI 214 PDMDevHlpPCISetIrqNoWait(s->CTX_SUFF(pDevIns), 0, 0); 215 # else /* !VBOX_SERIAL_PCI */ 216 PDMDevHlpISASetIrqNoWait(s->CTX_SUFF(pDevIns), s->irq, 0); 217 # endif /* !VBOX_SERIAL_PCI */ 208 218 } 209 219 } … … 233 243 s->pDrvChar->pfnSetParameters(s->pDrvChar, speed, parity, data_bits, stop_bits); 234 244 } 235 #endif 245 246 #endif /* IN_RING3 */ 236 247 237 248 static int serial_ioport_write(void *opaque, uint32_t addr, uint32_t val) … … 398 409 399 410 #ifdef IN_RING3 411 400 412 static DECLCALLBACK(int) serialNotifyRead(PPDMICHARPORT pInterface, const void *pvBuf, size_t *pcbRead) 401 413 { … … 496 508 { 497 509 Log2(("%s: port %#06x val %#04x\n", __FUNCTION__, Port, u32)); 498 rc = serial_ioport_write 510 rc = serial_ioport_write(pThis, Port, u32); 499 511 PDMCritSectLeave(&pThis->CritSect); 500 512 } … … 528 540 if (rc == VINF_SUCCESS) 529 541 { 530 *pu32 = serial_ioport_read 542 *pu32 = serial_ioport_read(pThis, Port, &rc); 531 543 Log2(("%s: port %#06x val %#04x\n", __FUNCTION__, Port, *pu32)); 532 544 PDMCritSectLeave(&pThis->CritSect); … … 540 552 541 553 #ifdef IN_RING3 554 542 555 /** 543 556 * Saves a state of the serial port device. … … 610 623 if (u32 != ~0U) 611 624 { 612 Assert MsgFailed(("u32=%#x expected ~0\n", u32));625 AssertLogRelMsgFailed(("u32=%#x expected ~0\n", u32)); 613 626 return VERR_SSM_DATA_UNIT_FORMAT_CHANGED; 614 627 } … … 621 634 AssertRC(rc); 622 635 } 623 pThis->pDevInsHC = pDevIns; 624 pThis->pDevInsGC = PDMDEVINS_2_GCPTR(pDevIns); 636 637 /* this isn't strictly necessary but cannot hurt... */ 638 pThis->pDevInsR3 = pDevIns; 639 pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns); 640 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 625 641 return VINF_SUCCESS; 626 642 } … … 633 649 { 634 650 SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *); 635 pThis->pDevIns GC = PDMDEVINS_2_GCPTR(pDevIns);651 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 636 652 } 637 653 … … 723 739 Assert(iInstance < 4); 724 740 725 pThis->pDevInsHC = pDevIns;726 pThis->pDevInsGC = PDMDEVINS_2_GCPTR(pDevIns);727 728 741 /* 729 * Validate configuration. 742 * Initialize the instance data. 743 * (Do this early or the destructor might choke on something!) 730 744 */ 731 if (!CFGMR3AreValuesValid(pCfgHandle, "IRQ\0IOBase\0")) 732 { 733 AssertMsgFailed(("serialConstruct Invalid configuration values\n")); 734 return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES; 735 } 736 737 rc = CFGMR3QueryBool(pCfgHandle, "GCEnabled", &pThis->fGCEnabled); 738 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 739 pThis->fGCEnabled = true; 740 else if (RT_FAILURE(rc)) 741 return PDMDEV_SET_ERROR(pDevIns, rc, 742 N_("Configuration error: Failed to get the \"GCEnabled\" value")); 743 744 rc = CFGMR3QueryBool(pCfgHandle, "R0Enabled", &pThis->fR0Enabled); 745 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 746 pThis->fR0Enabled = true; 747 else if (RT_FAILURE(rc)) 748 return PDMDEV_SET_ERROR(pDevIns, rc, 749 N_("Configuration error: Failed to get the \"R0Enabled\" value")); 745 pThis->pDevInsR3 = pDevIns; 746 pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns); 747 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 748 749 pThis->lsr = UART_LSR_TEMT | UART_LSR_THRE; 750 pThis->iir = UART_IIR_NO_INT; 751 pThis->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS; 750 752 751 753 /* IBase */ … … 756 758 pThis->ICharPort.pfnNotifyStatusLinesChanged = serialNotifyStatusLinesChanged; 757 759 758 rc = RTSemEventCreate(&pThis->ReceiveSem);759 AssertRC(rc);760 761 /*762 * Initialize critical section.763 * This must of course be done before attaching drivers or anything else which can call us back..764 */765 char szName[24];766 RTStrPrintf(szName, sizeof(szName), "Serial#%d", iInstance);767 rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, szName);768 if (RT_FAILURE(rc))769 return rc;770 771 rc = CFGMR3QueryU8 (pCfgHandle, "IRQ", &irq_lvl);772 if (rc == VERR_CFGM_VALUE_NOT_FOUND)773 {774 /* Provide sensible defaults. */775 if (iInstance == 0)776 irq_lvl = 4;777 else if (iInstance == 1)778 irq_lvl = 3;779 }780 else if (RT_FAILURE(rc))781 return PDMDEV_SET_ERROR(pDevIns, rc,782 N_("Configuration error: Failed to get the \"IRQ\" value"));783 784 rc = CFGMR3QueryU16 (pCfgHandle, "IOBase", &io_base);785 if (rc == VERR_CFGM_VALUE_NOT_FOUND)786 {787 if (iInstance == 0)788 io_base = 0x3f8;789 else if (iInstance == 1)790 io_base = 0x2f8;791 }792 else if (RT_FAILURE(rc))793 return PDMDEV_SET_ERROR(pDevIns, rc,794 N_("Configuration error: Failed to get the \"IOBase\" value"));795 796 Log(("serialConstruct instance %d iobase=%04x irq=%d\n", iInstance, io_base, irq_lvl));797 798 pThis->irq = irq_lvl;799 pThis->lsr = UART_LSR_TEMT | UART_LSR_THRE;800 pThis->iir = UART_IIR_NO_INT;801 pThis->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;802 760 #ifdef VBOX_SERIAL_PCI 803 pThis->base = -1;761 /* the PCI device */ 804 762 pThis->dev.config[0x00] = 0xee; /* Vendor: ??? */ 805 763 pThis->dev.config[0x01] = 0x80; … … 813 771 pThis->dev.config[0x3c] = irq_lvl; /* preconfigure IRQ number (0 = autoconfig)*/ 814 772 pThis->dev.config[0x3d] = 1; /* interrupt pin 0 */ 773 #endif /* VBOX_SERIAL_PCI */ 774 775 /* 776 * Validate and read the configuration. 777 */ 778 if (!CFGMR3AreValuesValid(pCfgHandle, "IRQ\0" "IOBase\0" "GCEnabled\0" "R0Enabled\0")) 779 { 780 AssertMsgFailed(("serialConstruct Invalid configuration values\n")); 781 return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES; 782 } 783 784 rc = CFGMR3QueryBoolDef(pCfgHandle, "GCEnabled", &pThis->fGCEnabled, true); 785 if (RT_FAILURE(rc)) 786 return PDMDEV_SET_ERROR(pDevIns, rc, 787 N_("Configuration error: Failed to get the \"GCEnabled\" value")); 788 789 rc = CFGMR3QueryBoolDef(pCfgHandle, "R0Enabled", &pThis->fR0Enabled, true); 790 if (RT_FAILURE(rc)) 791 return PDMDEV_SET_ERROR(pDevIns, rc, 792 N_("Configuration error: Failed to get the \"R0Enabled\" value")); 793 794 rc = CFGMR3QueryU8(pCfgHandle, "IRQ", &irq_lvl); 795 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 796 { 797 /* Provide sensible defaults. */ 798 if (iInstance == 0) 799 irq_lvl = 4; 800 else if (iInstance == 1) 801 irq_lvl = 3; 802 else 803 AssertReleaseFailed(); /* irq_lvl is undefined. */ 804 } 805 else if (RT_FAILURE(rc)) 806 return PDMDEV_SET_ERROR(pDevIns, rc, 807 N_("Configuration error: Failed to get the \"IRQ\" value")); 808 809 rc = CFGMR3QueryU16(pCfgHandle, "IOBase", &io_base); 810 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 811 { 812 if (iInstance == 0) 813 io_base = 0x3f8; 814 else if (iInstance == 1) 815 io_base = 0x2f8; 816 else 817 AssertReleaseFailed(); /* io_base is undefined */ 818 } 819 else if (RT_FAILURE(rc)) 820 return PDMDEV_SET_ERROR(pDevIns, rc, 821 N_("Configuration error: Failed to get the \"IOBase\" value")); 822 823 Log(("DevSerial: instance %d iobase=%04x irq=%d\n", iInstance, io_base, irq_lvl)); 824 825 pThis->irq = irq_lvl; 826 #ifdef VBOX_SERIAL_PCI 827 pThis->base = -1; 828 #else 829 pThis->base = io_base; 830 #endif 831 832 /* 833 * Initialize critical section and the semaphore. 834 * This must of course be done before attaching drivers or anything else which can call us back.. 835 */ 836 char szName[24]; 837 RTStrPrintf(szName, sizeof(szName), "Serial#%d", iInstance); 838 rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, szName); 839 if (RT_FAILURE(rc)) 840 return rc; 841 842 rc = RTSemEventCreate(&pThis->ReceiveSem); 843 AssertRC(rc); 844 845 #ifdef VBOX_SERIAL_PCI 846 /* 847 * Register the PCI Device and region. 848 */ 815 849 rc = PDMDevHlpPCIRegister(pDevIns, &pThis->dev); 816 850 if (RT_FAILURE(rc)) 817 851 return rc; 818 /*819 * Register the PCI I/O ports.820 */821 852 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, 8, PCI_ADDRESS_SPACE_IO, serialIOPortRegionMap); 822 853 if (RT_FAILURE(rc)) 823 854 return rc; 855 824 856 #else /* !VBOX_SERIAL_PCI */ 857 /* 858 * Register the I/O ports. 859 */ 825 860 pThis->base = io_base; 826 861 rc = PDMDevHlpIOPortRegister(pDevIns, io_base, 8, 0, 827 862 serialIOPortWrite, serialIOPortRead, 828 863 NULL, NULL, "SERIAL"); 829 if (RT_FAILURE 864 if (RT_FAILURE(rc)) 830 865 return rc; 831 866 … … 837 872 rc = PDMDevHlpIOPortRegisterR0(pDevIns, io_base, 8, 0, "serialIOPortWrite", 838 873 "serialIOPortRead", NULL, NULL, "Serial"); 839 840 874 #endif /* !VBOX_SERIAL_PCI */ 841 875 842 /* Attach the char driver and get the interfaces. For now no run-time 843 * changes are supported. */ 844 rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Serial Char"); 845 if (RT_SUCCESS(rc)) 846 { 847 pThis->pDrvChar = (PDMICHAR *)pThis->pDrvBase->pfnQueryInterface(pThis->pDrvBase, PDMINTERFACE_CHAR); 848 if (!pThis->pDrvChar) 849 { 850 AssertMsgFailed(("Configuration error: instance %d has no char interface!\n", iInstance)); 851 return VERR_PDM_MISSING_INTERFACE; 852 } 853 /** @todo provide read notification interface!!!! */ 854 } 855 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 856 { 857 pThis->pDrvBase = NULL; 858 pThis->pDrvChar = NULL; 859 LogRel(("Serial%d: no unit\n", iInstance)); 860 } 861 else 862 { 863 AssertMsgFailed(("Serial%d: Failed to attach to char driver. rc=%Vrc\n", iInstance, rc)); 864 /* Don't call VMSetError here as we assume that the driver already set an appropriate error */ 865 return rc; 866 } 867 868 rc = PDMDevHlpSSMRegister ( 876 /* 877 * Saved state. 878 */ 879 rc = PDMDevHlpSSMRegister( 869 880 pDevIns, /* pDevIns */ 870 881 pDevIns->pDevReg->szDeviceName, /* pszName */ … … 882 893 return rc; 883 894 895 /* 896 * Attach the char driver and get the interfaces. 897 * For now no run-time changes are supported. 898 */ 899 rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Serial Char"); 900 if (RT_SUCCESS(rc)) 901 { 902 pThis->pDrvChar = (PDMICHAR *)pThis->pDrvBase->pfnQueryInterface(pThis->pDrvBase, PDMINTERFACE_CHAR); 903 if (!pThis->pDrvChar) 904 { 905 AssertLogRelMsgFailed(("Configuration error: instance %d has no char interface!\n", iInstance)); 906 return VERR_PDM_MISSING_INTERFACE; 907 } 908 /** @todo provide read notification interface!!!! */ 909 } 910 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 911 { 912 pThis->pDrvBase = NULL; 913 pThis->pDrvChar = NULL; 914 LogRel(("Serial%d: no unit\n", iInstance)); 915 } 916 else 917 { 918 AssertLogRelMsgFailed(("Serial%d: Failed to attach to char driver. rc=%Vrc\n", iInstance, rc)); 919 /* Don't call VMSetError here as we assume that the driver already set an appropriate error */ 920 return rc; 921 } 922 884 923 return VINF_SUCCESS; 885 924 } 925 886 926 887 927 /** -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeGC.cpp
r11270 r11277 901 901 GEN_CHECK_OFF(SerialState, fGCEnabled); 902 902 GEN_CHECK_OFF(SerialState, fR0Enabled); 903 GEN_CHECK_OFF(SerialState, pDevInsGC); 904 GEN_CHECK_OFF(SerialState, pDevInsHC); 903 GEN_CHECK_OFF(SerialState, pDevInsR3); 904 GEN_CHECK_OFF(SerialState, pDevInsR0); 905 GEN_CHECK_OFF(SerialState, pDevInsRC); 905 906 GEN_CHECK_OFF(SerialState, IBase); 906 907 GEN_CHECK_OFF(SerialState, ICharPort);
Note:
See TracChangeset
for help on using the changeset viewer.