1.. _vuart_virtualization: 2 3vUART Virtualization 4#################### 5 6Architecture 7************ 8 9A vUART is a virtual 16550 UART implemented in the hypervisor. It can work as a 10console or a communication port. The vUART is mapped to the 11traditional COM port address. A UART driver in the kernel can auto detect the 12port base and IRQ. 13 14.. figure:: images/uart-virt-hld-1.png 15 :align: center 16 :name: uart-arch-pic 17 18 UART Virtualization Architecture 19 20Each vUART has two FIFOs: 8192 bytes TX FIFO and 256 bytes RX FIFO. 21We only provide 4 ports for use. 22 23- COM1 (port base: 0x3F8, irq: 4) 24 25- COM2 (port base: 0x2F8, irq: 3) 26 27- COM3 (port base: 0x3E8, irq: 6) 28 29- COM4 (port base: 0x2E8, irq: 7) 30 31A VM can enable one console vUART and several communication vUARTs. 32 33Console vUART 34************* 35 36A vUART can be used as a console port, and it can be activated by 37a ``vm_console <vm_id>`` command in the hypervisor console. 38:numref:`console-uart-arch` shows only one physical UART, but four console 39vUARTs (green color blocks). A hypervisor console is implemented above the 40physical UART, and it works in polling mode. The hypervisor console has a 41timer. The timer handler sends input from the physical UART to the 42vUART or the hypervisor shell process. The timer handler also gets data from 43the vUART's TX FIFO and sends it to the physical UART. The data in the vUART's 44FIFOs is overwritten if it is not taken out in time. 45 46.. figure:: images/uart-virt-hld-2.png 47 :align: center 48 :name: console-uart-arch 49 50 Console vUART Architecture 51 52Communication vUART 53******************* 54 55The communication vUART is used to transfer data between two VMs in low 56speed. For the kernel driver, it is a general UART that can be detected and 57probed by 8250 serial driver. But in the hypervisor, it has a special process. 58 59From :numref:`communication-uart-arch`, the vUART in two VMs is 60connected according to the configuration in the hypervisor. When a user 61writes a byte to the communication UART in VM0: 62 63Operations in VM0 64 65- VM0 UART driver puts the data to THR. 66 67- VM traps to hypervisor, and the vUART PIO handler is called. 68 69- Puts the data to its target vUART's RX FIFO. 70 71- Injects a Data Ready interrupt to VM1. 72 73- If the target vUART's FIFO is not full, injects a THRE interrupt to VM0. 74 75- Returns. 76 77Operations in VM1 78 79- Receives an interrupt, dispatches to UART driver. 80 81- Reads LSR register, finds a Data Ready interrupt. 82 83- Reads data from RX FIFO. 84 85- If RX FIFO is not full, injects THRE interrupt to VM0. 86 87.. figure:: images/uart-virt-hld-3.png 88 :align: center 89 :name: communication-uart-arch 90 91 Communication vUART Architecture 92 93Usage 94***** 95 96- For console vUART 97 98 To enable the console port for a VM, change the ``port_base`` and ``irq`` 99 fields in 100 ``configs/scenarios/<scenario name>/vm_configurations.c`` under the 101 hypervisor build directory using the combinations listed below. If the IRQ 102 number has been used in your 103 system ( ``cat /proc/interrupt``), you can choose other IRQ number. Set 104 the ``.irq =0``, the vUART will work in polling mode. 105 106 - COM1_BASE (0x3F8) + COM1_IRQ(4) 107 108 - COM2_BASE (0x2F8) + COM2_IRQ(3) 109 110 - COM3_BASE (0x3E8) + COM3_IRQ(6) 111 112 - COM4_BASE (0x2E8) + COM4_IRQ(7) 113 114 Example:: 115 116 .vuart[0] = { 117 .type = VUART_LEGACY_PIO, 118 .addr.port_base = COM1_BASE, 119 .irq = COM1_IRQ, 120 } 121 122 The kernel bootargs ``console=ttySx`` should be the same with 123 vuart[0]; otherwise, the kernel console log cannot be captured by the 124 hypervisor. Then, after bringing up the system, you can switch the console 125 to the target VM by: 126 127 .. code-block:: console 128 129 ACRN:\>vm_console 0 130 ----- Entering VM 0 Shell ----- 131 132- For communication vUART 133 134 To enable the communication port, configure vuart[1] in 135 the two VMs that need to communicate. The port_base and IRQ should 136 not repeat with the vuart[0] in the same VM. t_vuart.vm_id is the 137 target VM's vm_id, start from 0 (0 means VM0). t_vuart.vuart_id is the 138 target vUART index in the target VM, start from 1 (1 means vuart[1]). 139 140 Example:: 141 142 /* VM0 */ 143 ... 144 /* VM1 */ 145 .vuart[1] = { 146 .type = VUART_LEGACY_PIO, 147 .addr.port_base = COM2_BASE, 148 .irq = COM2_IRQ, 149 .t_vuart.vm_id = 2U, 150 .t_vuart.vuart_id = 1U, 151 }, 152 ... 153 /* VM2 */ 154 .vuart[1] = { 155 .type = VUART_LEGACY_PIO, 156 .addr.port_base = COM2_BASE, 157 .irq = COM2_IRQ, 158 .t_vuart.vm_id = 1U, 159 .t_vuart.vuart_id = 1U, 160 }, 161 162.. note:: The Device Model also has a virtual UART and uses 0x3F8 163 and 0x2F8 as port base. If you add ``-s <slot>, lpc`` in the launch 164 script, the Device Model will create COM0 and COM1 for the post-launched VM. 165 It will also add the port information to the ACPI table. This configuration 166 is useful for Windows and VxWorks as they probe the driver according to the 167 ACPI table. 168 169 If you enable the Device Model UART and the hypervisor vUART at the 170 same port address, access to the port address will be responded to by the 171 hypervisor vUART directly, and will not pass to the Device Model. 172