From 8d08ec30b7af169bdb6877dd2fbf865ef82c0c97 Mon Sep 17 00:00:00 2001 From: Minggui Cao Date: Thu, 29 Nov 2018 14:33:37 +0800 Subject: [PATCH] HV: replace serial PCI MMIO base with BDF config replace serial PCI MMIO base address configure with its BDF configure. Tracked-On: #1923 Signed-off-by: Minggui Cao Acked-by: Eddie Dong --- hypervisor/arch/x86/Kconfig | 35 +++++++------ hypervisor/arch/x86/configs/apl-mrb.config | 2 +- hypervisor/arch/x86/configs/cb2_dnv.config | 2 +- hypervisor/arch/x86/configs/nuc6cayh.config | 2 +- hypervisor/arch/x86/configs/up2.config | 4 +- hypervisor/debug/uart16550.c | 54 +++++++++------------ 6 files changed, 48 insertions(+), 51 deletions(-) diff --git a/hypervisor/arch/x86/Kconfig b/hypervisor/arch/x86/Kconfig index e38d44fa0..56e9e72b8 100644 --- a/hypervisor/arch/x86/Kconfig +++ b/hypervisor/arch/x86/Kconfig @@ -159,34 +159,39 @@ choice If this is not selected, the serial port is disabled. This is the default. -config SERIAL_MMIO - bool "Access serial port via MMIO" + +config SERIAL_PCI + bool "PCI" help - Select this if the serial port shall be accessed via memory-mapped + Select this if the serial port shall be accessed via PCI memory-mapped registers. -config SERIAL_PIO - bool "Access serial port via PIO" + +config SERIAL_LEGACY + bool "Legacy" help - Select this if the serial port shall be accessed via in/out + Select this if the serial port shall be accessed via legacy port in/out instructions. endchoice -config SERIAL_MMIO_BASE - hex "Base address of serial port MMIO region" - depends on SERIAL_MMIO - default 0xfc000000 + +config SERIAL_PCI_BDF + hex "BDF value of serial PCI device" + depends on SERIAL_PCI + default 0x00C2 help - A 64-bit integer indicating the base physical address of the - memory-mapped UART registers. + A 16-bit integer encoding bus, device and function of the serial PCI device. + This integer consists of 8-bit bus ID, 5-bit device ID and 3-bit function ID. + As an example,for PCI device 00:18.2, this BDF would be (0 << 8) | (0x18 << 3) + | (2 << 0), it's 0x00C2. config SERIAL_PIO_BASE - hex "Base address of serial port PIO region" - depends on SERIAL_PIO + hex "Base address of serial PIO region" + depends on SERIAL_LEGACY default 0x3f8 help - The base address of the UART ports. This is logically 16-bit but used + The base address of the serial ports. This is logically 16-bit but used as a 64-bit integer. config COM_BASE diff --git a/hypervisor/arch/x86/configs/apl-mrb.config b/hypervisor/arch/x86/configs/apl-mrb.config index 71b03b332..ad53b50f6 100644 --- a/hypervisor/arch/x86/configs/apl-mrb.config +++ b/hypervisor/arch/x86/configs/apl-mrb.config @@ -1,5 +1,5 @@ # Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) CONFIG_BOARD="apl-mrb" -CONFIG_SERIAL_MMIO=y +CONFIG_SERIAL_PCI=y CONFIG_COM_BASE=0x3e8 CONFIG_COM_IRQ=6 diff --git a/hypervisor/arch/x86/configs/cb2_dnv.config b/hypervisor/arch/x86/configs/cb2_dnv.config index 94c562bd8..b07c81764 100644 --- a/hypervisor/arch/x86/configs/cb2_dnv.config +++ b/hypervisor/arch/x86/configs/cb2_dnv.config @@ -1,6 +1,6 @@ # Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) CONFIG_PARTITION_MODE=y CONFIG_BOARD="cb2_dnv" -CONFIG_SERIAL_PIO=y +CONFIG_SERIAL_LEGACY=y CONFIG_SERIAL_PIO_BASE=0x1000 CONFIG_DMAR_PARSE_ENABLED=y diff --git a/hypervisor/arch/x86/configs/nuc6cayh.config b/hypervisor/arch/x86/configs/nuc6cayh.config index f056ac725..e65bca8d3 100644 --- a/hypervisor/arch/x86/configs/nuc6cayh.config +++ b/hypervisor/arch/x86/configs/nuc6cayh.config @@ -1,4 +1,4 @@ # Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) CONFIG_PLATFORM_UEFI=y CONFIG_BOARD="NUC6CAYH" -CONFIG_SERIAL_PIO=y +CONFIG_SERIAL_LEGACY=y diff --git a/hypervisor/arch/x86/configs/up2.config b/hypervisor/arch/x86/configs/up2.config index 45491fa00..c0bf023b1 100644 --- a/hypervisor/arch/x86/configs/up2.config +++ b/hypervisor/arch/x86/configs/up2.config @@ -1,5 +1,5 @@ # Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) CONFIG_PLATFORM_UEFI=y CONFIG_BOARD="UP2" -CONFIG_SERIAL_MMIO=y -CONFIG_SERIAL_MMIO_BASE=0x9141e000 +CONFIG_SERIAL_PCI=y +CONFIG_SERIAL_PCI_BDF=0x00C1 diff --git a/hypervisor/debug/uart16550.c b/hypervisor/debug/uart16550.c index 038d10c4d..05fefb322 100644 --- a/hypervisor/debug/uart16550.c +++ b/hypervisor/debug/uart16550.c @@ -10,21 +10,22 @@ #if defined(CONFIG_SERIAL_PIO_BASE) static bool serial_port_mapped = true; static bool uart_enabled = true; -#define UART_BASE_ADDRESS CONFIG_SERIAL_PIO_BASE -#elif defined(CONFIG_SERIAL_MMIO_BASE) +static uint64_t uart_base_address = CONFIG_SERIAL_PIO_BASE; +static union pci_bdf serial_pci_bdf; +#elif defined(CONFIG_SERIAL_PCI_BDF) static bool serial_port_mapped; static bool uart_enabled = true; -#define UART_BASE_ADDRESS CONFIG_SERIAL_MMIO_BASE +static uint64_t uart_base_address; +static union pci_bdf serial_pci_bdf = (union pci_bdf)(uint16_t)CONFIG_SERIAL_PCI_BDF; #else static bool serial_port_mapped; static bool uart_enabled; -#define UART_BASE_ADDRESS 0UL +static uint64_t uart_base_address; +static union pci_bdf serial_pci_bdf; #endif typedef uint32_t uart_reg_t; -static uint64_t uart_base_address; - static spinlock_t uart_rx_lock; static spinlock_t uart_tx_lock; @@ -36,27 +37,23 @@ static inline uint32_t uart16550_read_reg(uint64_t base, uint16_t reg_idx) if (serial_port_mapped) { return pio_read8((uint16_t)base + reg_idx); } else { - return mmio_read32((void *)((uint32_t *)hpa2hva(base) + - reg_idx)); + return mmio_read32((void *)((uint32_t *)hpa2hva(base) + reg_idx)); } } /** * @pre uart_enabled == true */ -static inline void uart16550_write_reg(uint64_t base, - uint32_t val, uint16_t reg_idx) +static inline void uart16550_write_reg(uint64_t base, uint32_t val, uint16_t reg_idx) { if (serial_port_mapped) { pio_write8((uint8_t)val, (uint16_t)base + reg_idx); } else { - mmio_write32(val, (void *)((uint32_t *)hpa2hva(base) + - reg_idx)); + mmio_write32(val, (void *)((uint32_t *)hpa2hva(base) + reg_idx)); } } -static void uart16550_calc_baud_div(uint32_t ref_freq, - uint32_t *baud_div_ptr, uint32_t baud_rate_arg) +static void uart16550_calc_baud_div(uint32_t ref_freq, uint32_t *baud_div_ptr, uint32_t baud_rate_arg) { uint32_t baud_rate = baud_rate_arg; uint32_t baud_multiplier = baud_rate < BAUD_460800 ? 16U : 13U; @@ -84,10 +81,8 @@ static void uart16550_set_baud_rate(uint32_t baud_rate) uart16550_write_reg(uart_base_address, temp_reg, UART16550_LCR); /* Write the appropriate divisor value */ - uart16550_write_reg(uart_base_address, - ((baud_div >> 8U) & 0xFFU), UART16550_DLM); - uart16550_write_reg(uart_base_address, - (baud_div & 0xFFU), UART16550_DLL); + uart16550_write_reg(uart_base_address, ((baud_div >> 8U) & 0xFFU), UART16550_DLM); + uart16550_write_reg(uart_base_address, (baud_div & 0xFFU), UART16550_DLL); /* Disable DLL and DLM registers */ temp_reg &= ~LCR_DLAB; @@ -99,30 +94,28 @@ void uart16550_init(void) if (!uart_enabled) { return; } - if (uart_base_address == 0UL) { - uart_base_address = UART_BASE_ADDRESS; + + /* if configure serial PCI BDF, get its base MMIO address */ + if (!serial_port_mapped && (uart_base_address == 0UL) && (serial_pci_bdf.value != 0U)) { + uart_base_address = pci_pdev_read_cfg(serial_pci_bdf, pci_bar_offset(0), 4U) & PCIM_BAR_MEM_BASE; } + spinlock_init(&uart_rx_lock); spinlock_init(&uart_tx_lock); /* Enable TX and RX FIFOs */ - uart16550_write_reg(uart_base_address, - FCR_FIFOE | FCR_RFR | FCR_TFR, UART16550_FCR); + uart16550_write_reg(uart_base_address, FCR_FIFOE | FCR_RFR | FCR_TFR, UART16550_FCR); /* Set-up data bits / parity / stop bits. */ - uart16550_write_reg(uart_base_address, - (LCR_WL8 | LCR_NB_STOP_BITS_1 | LCR_PARITY_NONE), - UART16550_LCR); + uart16550_write_reg(uart_base_address, (LCR_WL8 | LCR_NB_STOP_BITS_1 | LCR_PARITY_NONE), UART16550_LCR); /* Disable interrupts (we use polling) */ - uart16550_write_reg(uart_base_address, - UART_IER_DISABLE_ALL, UART16550_IER); + uart16550_write_reg(uart_base_address, UART_IER_DISABLE_ALL, UART16550_IER); /* Set baud rate */ uart16550_set_baud_rate(BAUD_115200); /* Data terminal ready + Request to send */ - uart16550_write_reg(uart_base_address, - MCR_RTS | MCR_DTR, UART16550_MCR); + uart16550_write_reg(uart_base_address, MCR_RTS | MCR_DTR, UART16550_MCR); } char uart16550_getc(void) @@ -136,8 +129,7 @@ char uart16550_getc(void) spinlock_obtain(&uart_rx_lock); /* If a character has been received, read it */ - if ((uart16550_read_reg(uart_base_address, UART16550_LSR) & LSR_DR) - == LSR_DR) { + if ((uart16550_read_reg(uart_base_address, UART16550_LSR) & LSR_DR) == LSR_DR) { /* Read a character */ ret = uart16550_read_reg(uart_base_address, UART16550_RBR);