diff --git a/devicemodel/hw/pci/lpc.c b/devicemodel/hw/pci/lpc.c index 4bc5292c4..95d74c17d 100644 --- a/devicemodel/hw/pci/lpc.c +++ b/devicemodel/hw/pci/lpc.c @@ -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: * [,] * 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; } diff --git a/devicemodel/hw/uart_core.c b/devicemodel/hw/uart_core.c index e119beaa1..d001b9800 100644 --- a/devicemodel/hw/uart_core.c +++ b/devicemodel/hw/uart_core.c @@ -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) { diff --git a/devicemodel/include/uart_core.h b/devicemodel/include/uart_core.h index ef262118b..73901ebac 100644 --- a/devicemodel/include/uart_core.h +++ b/devicemodel/include/uart_core.h @@ -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); diff --git a/misc/config_tools/static_allocators/intx.py b/misc/config_tools/static_allocators/intx.py index 7fd15d7c5..c49e0e260 100644 --- a/misc/config_tools/static_allocators/intx.py +++ b/misc/config_tools/static_allocators/intx.py @@ -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 diff --git a/misc/config_tools/static_allocators/s5_vuart.py b/misc/config_tools/static_allocators/s5_vuart.py index bc4d5dfb0..a6bfbf976 100644 --- a/misc/config_tools/static_allocators/s5_vuart.py +++ b/misc/config_tools/static_allocators/s5_vuart.py @@ -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']")