Index: trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
===================================================================
--- trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 73767)
+++ trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 73768)
@@ -608,4 +608,5 @@
                      "                                             file <file>|\n"
                      "                                             <devicename>]\n"
+                     "                            [--uarttype<1-N> 16450|16550A|16750\n"
 #if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
                      "                            [--lpt<1-N> off|<I/O base> <IRQ>]\n"
Index: trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
===================================================================
--- trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp	(revision 73767)
+++ trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp	(revision 73768)
@@ -1493,4 +1493,5 @@
                 Bstr path;
                 BOOL fServer;
+                UartType_T UartType;
                 uart->COMGETTER(IRQ)(&ulIRQ);
                 uart->COMGETTER(IOBase)(&ulIOBase);
@@ -1498,4 +1499,5 @@
                 uart->COMGETTER(Server)(&fServer);
                 uart->COMGETTER(HostMode)(&HostMode);
+                uart->COMGETTER(UartType)(&UartType);
 
                 if (details == VMINFO_MACHINEREADABLE)
@@ -1510,5 +1512,5 @@
                             RTPrintf("uartmode%d=\"disconnected\"\n", currentUART + 1);
                         else
-                            RTPrintf(", disconnected\n");
+                            RTPrintf(", disconnected");
                         break;
                     case PortMode_RawFile:
@@ -1525,5 +1527,5 @@
                                      fServer ? "tcpserver" : "tcpclient", path.raw());
                         else
-                            RTPrintf(", attached to tcp (%s) '%ls'\n",
+                            RTPrintf(", attached to tcp (%s) '%ls'",
                                      fServer ? "server" : "client", path.raw());
                         break;
@@ -1533,5 +1535,5 @@
                                      fServer ? "server" : "client", path.raw());
                         else
-                            RTPrintf(", attached to pipe (%s) '%ls'\n",
+                            RTPrintf(", attached to pipe (%s) '%ls'",
                                      fServer ? "server" : "client", path.raw());
                         break;
@@ -1541,5 +1543,27 @@
                                      path.raw());
                         else
-                            RTPrintf(", attached to device '%ls'\n", path.raw());
+                            RTPrintf(", attached to device '%ls'", path.raw());
+                        break;
+                }
+                switch (UartType)
+                {
+                    default:
+                    case UartType_U16450:
+                        if (details == VMINFO_MACHINEREADABLE)
+                            RTPrintf("uarttype%d=\"16450\"\n", currentUART + 1);
+                        else
+                            RTPrintf(", 16450\n");
+                        break;
+                    case UartType_U16550A:
+                        if (details == VMINFO_MACHINEREADABLE)
+                            RTPrintf("uarttype%d=\"16550A\"\n", currentUART + 1);
+                        else
+                            RTPrintf(", 16550A\n");
+                        break;
+                    case UartType_U16750:
+                        if (details == VMINFO_MACHINEREADABLE)
+                            RTPrintf("uarttype%d=\"16750\"\n", currentUART + 1);
+                        else
+                            RTPrintf(", 16750\n");
                         break;
                 }
Index: trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp
===================================================================
--- trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp	(revision 73767)
+++ trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp	(revision 73768)
@@ -147,4 +147,5 @@
     MODIFYVM_HIDKBD,
     MODIFYVM_UARTMODE,
+    MODIFYVM_UARTTYPE,
     MODIFYVM_UART,
 #if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
@@ -334,4 +335,5 @@
     { "--keyboard",                 MODIFYVM_HIDKBD,                    RTGETOPT_REQ_STRING },
     { "--uartmode",                 MODIFYVM_UARTMODE,                  RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
+    { "--uarttype",                 MODIFYVM_UARTTYPE,                  RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
     { "--uart",                     MODIFYVM_UART,                      RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
 #if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
@@ -2157,4 +2159,30 @@
             }
 
+            case MODIFYVM_UARTTYPE:
+            {
+                ComPtr<ISerialPort> uart;
+
+                CHECK_ERROR_BREAK(sessionMachine, GetSerialPort(GetOptState.uIndex - 1, uart.asOutParam()));
+                ASSERT(uart);
+
+                if (!RTStrICmp(ValueUnion.psz, "16450"))
+                {
+                    CHECK_ERROR(uart, COMSETTER(UartType)(UartType_U16450));
+                }
+                else if (!RTStrICmp(ValueUnion.psz, "16550A"))
+                {
+                    CHECK_ERROR(uart, COMSETTER(UartType)(UartType_U16550A));
+                }
+                else if (!RTStrICmp(ValueUnion.psz, "16750"))
+                {
+                    CHECK_ERROR(uart, COMSETTER(UartType)(UartType_U16750));
+                }
+                else
+                    return errorSyntax(USAGE_MODIFYVM,
+                                       "Invalid argument to '%s'",
+                                       GetOptState.pDef->pszLong);
+                break;
+            }
+
             case MODIFYVM_UART:
             {
Index: trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 73767)
+++ trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 73768)
@@ -593,5 +593,5 @@
       <desc>Settings version "1.17", written by VirtualBox 6.0.x.</desc>
       <!--
-          Machine changes: nested hardware virtualization.
+          Machine changes: nested hardware virtualization, UART type selection.
       -->
     </const>
@@ -18388,9 +18388,34 @@
   </enum>
 
+  <enum
+    name="UartType"
+    uuid="c8899d39-0b90-4265-9d02-1e38bd4d1b39"
+    >
+    <desc>
+      The UART type represents the emulated UART chip for the serial port device.
+    </desc>
+
+    <const name="U16450"            value="0">
+      <desc>The most basic emulated UART which doesn't support FIFO operation.</desc>
+    </const>
+    <const name="U16550A"           value="1">
+      <desc>
+        The successor of the 16450 UART introducing a 16 byte FIFO to reduce
+        operational overhead.
+      </desc>
+    </const>
+    <const name="U16750"            value="2">
+      <desc>
+        This UART developed by Texas Instruments introduced a 64 byte FIFO
+        and hardware flow control.
+      </desc>
+    </const>
+  </enum>
+
   <interface
     name="ISerialPort" extends="$unknown"
     uuid="cb0a4a29-43a3-9040-0c25-34845db7b042"
     wsmap="managed"
-    reservedAttributes="2"
+    reservedAttributes="1"
     >
 
@@ -18470,4 +18495,8 @@
         value is an error. Otherwise, the value of this property is ignored.
       </desc>
+    </attribute>
+
+    <attribute name="uartType" type="UartType">
+      <desc>Selects the emulated UART implementation.</desc>
     </attribute>
 
Index: trunk/src/VBox/Main/include/SerialPortImpl.h
===================================================================
--- trunk/src/VBox/Main/include/SerialPortImpl.h	(revision 73767)
+++ trunk/src/VBox/Main/include/SerialPortImpl.h	(revision 73768)
@@ -79,4 +79,6 @@
     HRESULT getPath(com::Utf8Str &aPath);
     HRESULT setPath(const com::Utf8Str &aPath);
+    HRESULT getUartType(UartType_T *aUartType);
+    HRESULT setUartType(UartType_T aUartType);
 
     struct Data;
Index: trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 73767)
+++ trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 73768)
@@ -2706,4 +2706,16 @@
             hrc = serialPort->COMGETTER(Server)(&fServer);                                  H();
             hrc = serialPort->COMGETTER(Path)(bstr.asOutParam());                           H();
+            UartType_T eUartType;
+            const char *pszUartType;
+            hrc = serialPort->COMGETTER(UartType)(&eUartType);                              H();
+            switch (eUartType)
+            {
+                case UartType_U16450: pszUartType = "16450"; break;
+                case UartType_U16750: pszUartType = "16750"; break;
+                default: AssertFailed(); RT_FALL_THRU();
+                case UartType_U16550A: pszUartType = "16550A"; break;
+            }
+            InsertConfigString(pCfg, "UartType", pszUartType);
+
             PortMode_T eHostMode;
             hrc = serialPort->COMGETTER(HostMode)(&eHostMode);                              H();
Index: trunk/src/VBox/Main/src-server/SerialPortImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/SerialPortImpl.cpp	(revision 73767)
+++ trunk/src/VBox/Main/src-server/SerialPortImpl.cpp	(revision 73768)
@@ -476,4 +476,40 @@
         m->bd.backup();
         m->bd->fServer = RT_BOOL(aServer);
+
+        m->fModified = true;
+        // leave the lock before informing callbacks
+        alock.release();
+
+        AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
+        m->pMachine->i_setModified(Machine::IsModified_SerialPorts);
+        mlock.release();
+
+        m->pMachine->i_onSerialPortChange(this);
+    }
+
+    return S_OK;
+}
+
+HRESULT SerialPort::getUartType(UartType_T *aUartType)
+{
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    *aUartType = m->bd->uartType;
+
+    return S_OK;
+}
+
+HRESULT SerialPort::setUartType(UartType_T aUartType)
+{
+    /* the machine needs to be mutable */
+    AutoMutableOrSavedOrRunningStateDependency adep(m->pMachine);
+    if (FAILED(adep.rc())) return adep.rc();
+
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    if (m->bd->uartType != aUartType)
+    {
+        m->bd.backup();
+        m->bd->uartType = aUartType;
 
         m->fModified = true;
Index: trunk/src/VBox/Main/xml/Settings.cpp
===================================================================
--- trunk/src/VBox/Main/xml/Settings.cpp	(revision 73767)
+++ trunk/src/VBox/Main/xml/Settings.cpp	(revision 73768)
@@ -2495,5 +2495,6 @@
     ulIRQ(4),
     portMode(PortMode_Disconnected),
-    fServer(false)
+    fServer(false),
+    uartType(UartType_U16550A)
 {
 }
@@ -2513,5 +2514,6 @@
             && portMode          == s.portMode
             && strPath           == s.strPath
-            && fServer           == s.fServer);
+            && fServer           == s.fServer
+            && uartType          == s.uartType);
 }
 
@@ -3637,4 +3639,17 @@
         pelmPort->getAttributeValue("server", port.fServer);
 
+        Utf8Str strUartType;
+        if (pelmPort->getAttributeValue("uartType", strUartType))
+        {
+            if (strUartType == "16450")
+                port.uartType = UartType_U16450;
+            else if (strUartType == "16550A")
+                port.uartType = UartType_U16550A;
+            else if (strUartType == "16750")
+                port.uartType = UartType_U16750;
+            else
+                throw ConfigFileError(this, pelmPort, N_("Invalid value '%s' in UART/Port/@uartType attribute"), strUartType.c_str());
+        }
+
         ll.push_back(port);
     }
@@ -6011,4 +6026,19 @@
             }
             pelmPort->setAttribute("hostMode", pcszHostMode);
+
+            if (   m->sv >= SettingsVersion_v1_17
+                && port.uartType != UartType_U16550A)
+            {
+                const char *pcszUartType;
+
+                switch (port.uartType)
+                {
+                    case UartType_U16450: pcszUartType = "16450"; break;
+                    case UartType_U16550A: pcszUartType = "16550A"; break;
+                    case UartType_U16750: pcszUartType = "16750"; break;
+                    default: pcszUartType = "16550A"; break;
+                }
+                pelmPort->setAttribute("uartType", pcszUartType);
+            }
         }
     }
@@ -6982,4 +7012,19 @@
             return;
         }
+
+        /*
+         * Check if any serial port uses a non 16550A serial port.
+         */
+        for (SerialPortsList::const_iterator it = hardwareMachine.llSerialPorts.begin();
+             it != hardwareMachine.llSerialPorts.end();
+             ++it)
+        {
+            const SerialPort &port = *it;
+            if (port.uartType != UartType_U16550A)
+            {
+                m->sv = SettingsVersion_v1_17;
+                return;
+            }
+        }
     }
 
