mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-04-27 11:22:17 +00:00
vUART: change S5 vUART resource
This patch is to change the vUART resource occupied by S5 function between Service VM and guest VM to avoid the standard UART port conflict when legacy UART passthrough to guest VM. Tracked-On: #8622 Signed-off-by: YuanXin-Intel <xin.yuan@intel.com> Reviewed-by: Junjie Mao <junjie.mao@intel.com> Reviewed-by: Jian Jun Chen <jian.jun.chen@intel.com>
This commit is contained in:
parent
87dffcbc92
commit
e4429d632b
@ -59,7 +59,7 @@ SYSRES_IO(NMISC_PORT, 1);
|
||||
|
||||
static struct pci_vdev *lpc_bridge;
|
||||
|
||||
#define LPC_UART_NUM 4
|
||||
#define LPC_UART_NUM 5
|
||||
static struct lpc_uart_vdev {
|
||||
struct uart_vdev *uart;
|
||||
const char *opts;
|
||||
@ -67,19 +67,23 @@ static struct lpc_uart_vdev {
|
||||
int irq;
|
||||
int enabled; /* enabled/configured by user */
|
||||
} lpc_uart_vdev[LPC_UART_NUM];
|
||||
#define LPC_S5_UART_NAME "COM5"
|
||||
|
||||
static const char *lpc_uart_names[LPC_UART_NUM] = { "COM1", "COM2", "COM3", "COM4" };
|
||||
static const char *lpc_uart_names[LPC_UART_NUM] = { "COM1", "COM2", "COM3", "COM4", LPC_S5_UART_NAME};
|
||||
|
||||
/*
|
||||
* LPC device configuration is in the following form:
|
||||
* <lpc_device_name>[,<options>]
|
||||
* For e.g. "com1,stdio"
|
||||
* For S5 e.g. "com5,/dev/pts/0,0x9000,5"
|
||||
*/
|
||||
int
|
||||
lpc_device_parse(const char *opts)
|
||||
{
|
||||
int unit, error;
|
||||
char *str, *cpy, *lpcdev;
|
||||
char *lpcopt, *lpcport, *endptr;
|
||||
int s5_port = 0, s5_irq = 0;
|
||||
|
||||
error = -1;
|
||||
str = cpy = strdup(opts);
|
||||
@ -88,7 +92,25 @@ lpc_device_parse(const char *opts)
|
||||
for (unit = 0; unit < LPC_UART_NUM; unit++) {
|
||||
if (strcasecmp(lpcdev, lpc_uart_names[unit]) == 0) {
|
||||
lpc_uart_vdev[unit].enabled = 1;
|
||||
lpc_uart_vdev[unit].opts = str;
|
||||
if(strcasecmp(lpcdev,LPC_S5_UART_NAME) == 0){
|
||||
lpcopt = strsep(&str,",");
|
||||
if(lpcopt != NULL){
|
||||
lpc_uart_vdev[unit].opts = lpcopt;
|
||||
}
|
||||
lpcport = strsep(&str, ",");
|
||||
if(lpcport != NULL){
|
||||
if(dm_strtoul(lpcport, &endptr, 0, (long unsigned int*)&s5_port))
|
||||
goto done;
|
||||
if(dm_strtoul(str, &endptr, 0, (long unsigned int*)&s5_irq))
|
||||
goto done;
|
||||
}
|
||||
if((s5_port != 0) && (s5_irq != 0)){
|
||||
uart_legacy_reinit_res(unit, s5_port, s5_irq);
|
||||
}
|
||||
}
|
||||
else{
|
||||
lpc_uart_vdev[unit].opts = str;
|
||||
}
|
||||
error = 0;
|
||||
goto done;
|
||||
}
|
||||
|
@ -56,6 +56,8 @@
|
||||
#define COM3_IRQ 6
|
||||
#define COM4_BASE 0x2E8
|
||||
#define COM4_IRQ 7
|
||||
#define COM5_BASE 0x9000 /*for S5 connection*/
|
||||
#define COM5_IRQ 10
|
||||
|
||||
#define DEFAULT_RCLK 1843200
|
||||
#define DEFAULT_BAUD 9600
|
||||
@ -89,6 +91,7 @@ static struct {
|
||||
{ COM2_BASE, COM2_IRQ, false},
|
||||
{ COM3_BASE, COM3_IRQ, false},
|
||||
{ COM4_BASE, COM4_IRQ, false},
|
||||
{ COM5_BASE, COM5_IRQ, false},
|
||||
};
|
||||
|
||||
#define UART_NLDEVS (ARRAY_SIZE(uart_lres))
|
||||
@ -624,6 +627,18 @@ uart_legacy_alloc(int which, int *baseaddr, int *irq)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
uart_legacy_reinit_res(int which, int baseaddr, int irq)
|
||||
{
|
||||
if (which < 0 || which >= UART_NLDEVS || uart_lres[which].inuse)
|
||||
return -1;
|
||||
|
||||
uart_lres[which].baseaddr = baseaddr;
|
||||
uart_lres[which].irq = irq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
uart_legacy_dealloc(int which)
|
||||
{
|
||||
|
@ -36,6 +36,7 @@ struct uart_vdev;
|
||||
|
||||
typedef void (*uart_intr_func_t)(void *arg);
|
||||
int uart_legacy_alloc(int unit, int *ioaddr, int *irq);
|
||||
int uart_legacy_reinit_res(int which, int baseaddr, int irq);
|
||||
void uart_legacy_dealloc(int which);
|
||||
uint8_t uart_read(struct uart_vdev *uart, int offset);
|
||||
void uart_write(struct uart_vdev *uart, int offset, uint8_t value);
|
||||
|
@ -74,6 +74,9 @@ def alloc_vuart_connection_irqs(board_etree, scenario_etree, allocation_etree):
|
||||
remove_irq(irq_list, 3)
|
||||
if 4 in irq_list:
|
||||
remove_irq(irq_list, 4)
|
||||
else:
|
||||
if 14 in irq_list:
|
||||
remove_irq(irq_list, 14)
|
||||
vuart_id = 1
|
||||
legacy_vuart_irq = "0"
|
||||
vmname = get_node("./name/text()", vm_node)
|
||||
@ -97,7 +100,7 @@ def alloc_vuart_connection_irqs(board_etree, scenario_etree, allocation_etree):
|
||||
vuart_id = vuart_id + 1
|
||||
# Allocate irq for S5 vuart, we have to use the irq of COM2
|
||||
if load_order != "SERVICE_VM":
|
||||
legacy_vuart_irq = alloc_standard_irq("0x2F8")
|
||||
legacy_vuart_irq = alloc_irq(irq_list)
|
||||
create_vuart_irq_node(allocation_etree, get_node("./@id", vm_node), load_order, str(vuart_id), legacy_vuart_irq)
|
||||
vuart_id = vuart_id + 1
|
||||
|
||||
|
@ -8,9 +8,11 @@
|
||||
import sys
|
||||
import acrn_config_utilities, lib.error
|
||||
from acrn_config_utilities import get_node
|
||||
from collections import defaultdict
|
||||
|
||||
# The COM1 was used for console vUART, so we alloc io_port frome COM2~COM4
|
||||
service_port_list = list(range(0x9000, 0x9100, 8))
|
||||
val = lambda:list(range(0x9000, 0x9100, 8))
|
||||
vm_port_list = defaultdict(val)
|
||||
|
||||
def create_s5_vuart_connection(allocation_etree, service_vm_name, service_vm_port, user_vm_name, user_vm_port):
|
||||
vuart_connections_node = get_node(f"/acrn-config/hv/vuart_connections", allocation_etree)
|
||||
@ -49,23 +51,25 @@ def get_console_vuart_port(scenario_etree, vm_name):
|
||||
|
||||
def alloc_free_port(scenario_etree, load_order, vm_name):
|
||||
port_list = scenario_etree.xpath(f"//endpoint[vm_name = '{vm_name}']/io_port/text()")
|
||||
if load_order == "SERVICE_VM":
|
||||
vm_id = int(get_node(f"//vm[load_order = 'SERVICE_VM']/@id", scenario_etree))
|
||||
else:
|
||||
vm_id = int(get_node(f"//vm[name = '{vm_name}']/@id", scenario_etree))
|
||||
console_port = get_console_vuart_port(scenario_etree, vm_name)
|
||||
if console_port is not None:
|
||||
port_list.append(console_port.replace("U", ""))
|
||||
|
||||
tmp_list = []
|
||||
for port in port_list:
|
||||
tmp_list.append(int(port, 16))
|
||||
|
||||
if load_order == "SERVICE_VM":
|
||||
tmp_list = []
|
||||
for port in port_list:
|
||||
tmp_list.append(int(port, 16))
|
||||
|
||||
global service_port_list
|
||||
service_port_list = list(set(service_port_list) - set(tmp_list))
|
||||
service_port_list.sort()
|
||||
port = hex(service_port_list[0])
|
||||
service_port_list.remove(service_port_list[0])
|
||||
return str(port).upper()
|
||||
else:
|
||||
return "0x2F8"
|
||||
global vm_port_list
|
||||
vm_port_list[vm_id] = list(set(vm_port_list[vm_id]) - set(tmp_list))
|
||||
vm_port_list[vm_id].sort()
|
||||
port = hex(vm_port_list[vm_id][0])
|
||||
vm_port_list[vm_id].remove(vm_port_list[vm_id][0])
|
||||
return str(port).upper()
|
||||
|
||||
def alloc_vuart_connection_info(board_etree, scenario_etree, allocation_etree):
|
||||
user_vm_list = scenario_etree.xpath(f"//vm[load_order != 'SERVICE_VM']")
|
||||
|
Loading…
Reference in New Issue
Block a user