diff --git a/hypervisor/arch/x86/Kconfig b/hypervisor/arch/x86/Kconfig index 396659636..e5d41373c 100644 --- a/hypervisor/arch/x86/Kconfig +++ b/hypervisor/arch/x86/Kconfig @@ -134,11 +134,12 @@ config SERIAL_MMIO endchoice config SERIAL_PCI_BDF - string "BDF of serial PCI device" + hex "BDF of serial PCI device" depends on SERIAL_PCI - default "0:18.2" + default 0x00c2 help - BDF: bus, device and function of the serial PCI device; for an example, + BDF: bus, device and function of the serial PCI device. The BDF is packed + into a 16bit WORD with format (B:8, D:5, F:3). For an example, PCI device ttyS2: 0:18.2. config SERIAL_PIO_BASE diff --git a/hypervisor/debug/dbg_cmd.c b/hypervisor/debug/dbg_cmd.c index b8a5ffc8a..ff2e463b5 100644 --- a/hypervisor/debug/dbg_cmd.c +++ b/hypervisor/debug/dbg_cmd.c @@ -28,6 +28,7 @@ static struct uart_cmd { bool handle_dbg_cmd(const char *cmd, int32_t len) { uint32_t i; + uint64_t data; for (i = 0; i < ARRAY_SIZE(cmd_list); i++) { int32_t tmp = strnlen_s(cmd_list[i].str, MAX_CMD_LEN); @@ -44,18 +45,16 @@ bool handle_dbg_cmd(const char *cmd, int32_t len) /* set uart disabled*/ uart16550_set_property(false, type, 0UL); } else if (type == PIO) { - uint64_t addr = strtoul_hex(cmd + tmp); + data = strtoul_hex(cmd + tmp); - if (addr > MAX_PORT) { - addr = DEFAULT_UART_PORT; + if (data > MAX_PORT) { + data = DEFAULT_UART_PORT; } - uart16550_set_property(true, type, addr); - } else if (type == PCI) { - uart16550_set_property(true, type, (uint64_t)(cmd+tmp)); + uart16550_set_property(true, type, data); } else { - uint64_t addr = strtoul_hex(cmd + tmp); - uart16550_set_property(true, type, addr); + data = strtoul_hex(cmd + tmp); + uart16550_set_property(true, type, data); } } diff --git a/hypervisor/debug/uart16550.c b/hypervisor/debug/uart16550.c index d80343952..500518d07 100644 --- a/hypervisor/debug/uart16550.c +++ b/hypervisor/debug/uart16550.c @@ -20,6 +20,7 @@ struct console_uart { enum serial_dev_type type; union { uint16_t port_address; + union pci_bdf bdf; void *mmio_base_vaddr; }; @@ -36,14 +37,13 @@ static struct console_uart uart = { .port_address = CONFIG_SERIAL_PIO_BASE, .reg_width = 1, }; -static char pci_bdf_info[MAX_BDF_LEN + 1U]; #elif defined(CONFIG_SERIAL_PCI_BDF) static struct console_uart uart = { .enabled = true, .type = PCI, + .bdf.value = CONFIG_SERIAL_PCI_BDF, .reg_width = 4, }; -static char pci_bdf_info[MAX_BDF_LEN + 1U] = CONFIG_SERIAL_PCI_BDF; #elif defined(CONFIG_SERIAL_MMIO_BASE) static struct console_uart uart = { .enabled = true, @@ -51,38 +51,9 @@ static struct console_uart uart = { .mmio_base_vaddr = (void *)CONFIG_SERIAL_MMIO_BASE, .reg_width = 1, }; -static char pci_bdf_info[MAX_BDF_LEN + 1U]; #endif typedef uint32_t uart_reg_t; -static union pci_bdf serial_pci_bdf; - - -/* PCI BDF must follow format: bus:dev.func, for example 0:18.2 */ -static uint16_t get_pci_bdf_value(char *bdf) -{ - char *pos; - char *start = bdf; - char dst[3][4]; - uint64_t value= 0UL; - - pos = strchr(start, ':'); - if (pos != NULL) { - strncpy_s(dst[0], 3, start, pos -start); - start = pos + 1; - - pos = strchr(start, '.'); - if (pos != NULL) { - strncpy_s(dst[1], 3, start, pos -start); - start = pos + 1; - - strncpy_s(dst[2], 2, start, 1); - value= (strtoul_hex(dst[0]) << 8) | (strtoul_hex(dst[1]) << 3) | strtoul_hex(dst[2]); - } - } - - return (uint16_t)value; -} /** * @pre uart->enabled == true @@ -162,9 +133,8 @@ void uart16550_init(bool early_boot) /* if configure serial PCI BDF, get its base MMIO address */ if (uart.type == PCI) { - serial_pci_bdf.value = get_pci_bdf_value(pci_bdf_info); uart.mmio_base_vaddr = - hpa2hva_early(pci_pdev_read_cfg(serial_pci_bdf, pci_bar_offset(0), 4U) & PCIM_BAR_MEM_BASE); + hpa2hva_early(pci_pdev_read_cfg(uart.bdf, pci_bar_offset(0), 4U) & PCIM_BAR_MEM_BASE); } spinlock_init(&uart.rx_lock); spinlock_init(&uart.tx_lock); @@ -245,19 +215,18 @@ size_t uart16550_puts(const char *buf, uint32_t len) return len; } -void uart16550_set_property(bool enabled, enum serial_dev_type uart_type, uint64_t base_addr) +void uart16550_set_property(bool enabled, enum serial_dev_type uart_type, uint64_t data) { uart.enabled = enabled; uart.type = uart_type; if (uart_type == PIO) { - uart.port_address = base_addr; + uart.port_address = data; } else if (uart_type == PCI) { - const char *bdf = (const char *)base_addr; - strncpy_s(pci_bdf_info, MAX_BDF_LEN + 1U, bdf, MAX_BDF_LEN); + uart.bdf.value = data; uart.reg_width = 4; } else if (uart_type == MMIO) { - uart.mmio_base_vaddr = (void *)base_addr; + uart.mmio_base_vaddr = (void *)data; uart.reg_width = 1; } } @@ -267,7 +236,7 @@ bool is_pci_dbg_uart(union pci_bdf bdf_value) bool ret = false; if (uart.enabled && (uart.type == PCI)) { - if (bdf_value.value == serial_pci_bdf.value) { + if (bdf_value.value == uart.bdf.value) { ret = true; } }