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 <minggui.cao@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Minggui Cao 2018-11-29 14:33:37 +08:00 committed by wenlingz
parent 10bde520a5
commit 8d08ec30b7
6 changed files with 48 additions and 51 deletions

View File

@ -159,34 +159,39 @@ choice
If this is not selected, the serial port is disabled. This is the If this is not selected, the serial port is disabled. This is the
default. default.
config SERIAL_MMIO
bool "Access serial port via MMIO" config SERIAL_PCI
bool "PCI"
help 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. registers.
config SERIAL_PIO
bool "Access serial port via PIO" config SERIAL_LEGACY
bool "Legacy"
help 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. instructions.
endchoice endchoice
config SERIAL_MMIO_BASE
hex "Base address of serial port MMIO region" config SERIAL_PCI_BDF
depends on SERIAL_MMIO hex "BDF value of serial PCI device"
default 0xfc000000 depends on SERIAL_PCI
default 0x00C2
help help
A 64-bit integer indicating the base physical address of the A 16-bit integer encoding bus, device and function of the serial PCI device.
memory-mapped UART registers. 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 config SERIAL_PIO_BASE
hex "Base address of serial port PIO region" hex "Base address of serial PIO region"
depends on SERIAL_PIO depends on SERIAL_LEGACY
default 0x3f8 default 0x3f8
help 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. as a 64-bit integer.
config COM_BASE config COM_BASE

View File

@ -1,5 +1,5 @@
# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) # Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)
CONFIG_BOARD="apl-mrb" CONFIG_BOARD="apl-mrb"
CONFIG_SERIAL_MMIO=y CONFIG_SERIAL_PCI=y
CONFIG_COM_BASE=0x3e8 CONFIG_COM_BASE=0x3e8
CONFIG_COM_IRQ=6 CONFIG_COM_IRQ=6

View File

@ -1,6 +1,6 @@
# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) # Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)
CONFIG_PARTITION_MODE=y CONFIG_PARTITION_MODE=y
CONFIG_BOARD="cb2_dnv" CONFIG_BOARD="cb2_dnv"
CONFIG_SERIAL_PIO=y CONFIG_SERIAL_LEGACY=y
CONFIG_SERIAL_PIO_BASE=0x1000 CONFIG_SERIAL_PIO_BASE=0x1000
CONFIG_DMAR_PARSE_ENABLED=y CONFIG_DMAR_PARSE_ENABLED=y

View File

@ -1,4 +1,4 @@
# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) # Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)
CONFIG_PLATFORM_UEFI=y CONFIG_PLATFORM_UEFI=y
CONFIG_BOARD="NUC6CAYH" CONFIG_BOARD="NUC6CAYH"
CONFIG_SERIAL_PIO=y CONFIG_SERIAL_LEGACY=y

View File

@ -1,5 +1,5 @@
# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) # Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)
CONFIG_PLATFORM_UEFI=y CONFIG_PLATFORM_UEFI=y
CONFIG_BOARD="UP2" CONFIG_BOARD="UP2"
CONFIG_SERIAL_MMIO=y CONFIG_SERIAL_PCI=y
CONFIG_SERIAL_MMIO_BASE=0x9141e000 CONFIG_SERIAL_PCI_BDF=0x00C1

View File

@ -10,21 +10,22 @@
#if defined(CONFIG_SERIAL_PIO_BASE) #if defined(CONFIG_SERIAL_PIO_BASE)
static bool serial_port_mapped = true; static bool serial_port_mapped = true;
static bool uart_enabled = true; static bool uart_enabled = true;
#define UART_BASE_ADDRESS CONFIG_SERIAL_PIO_BASE static uint64_t uart_base_address = CONFIG_SERIAL_PIO_BASE;
#elif defined(CONFIG_SERIAL_MMIO_BASE) static union pci_bdf serial_pci_bdf;
#elif defined(CONFIG_SERIAL_PCI_BDF)
static bool serial_port_mapped; static bool serial_port_mapped;
static bool uart_enabled = true; 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 #else
static bool serial_port_mapped; static bool serial_port_mapped;
static bool uart_enabled; static bool uart_enabled;
#define UART_BASE_ADDRESS 0UL static uint64_t uart_base_address;
static union pci_bdf serial_pci_bdf;
#endif #endif
typedef uint32_t uart_reg_t; typedef uint32_t uart_reg_t;
static uint64_t uart_base_address;
static spinlock_t uart_rx_lock; static spinlock_t uart_rx_lock;
static spinlock_t uart_tx_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) { if (serial_port_mapped) {
return pio_read8((uint16_t)base + reg_idx); return pio_read8((uint16_t)base + reg_idx);
} else { } else {
return mmio_read32((void *)((uint32_t *)hpa2hva(base) + return mmio_read32((void *)((uint32_t *)hpa2hva(base) + reg_idx));
reg_idx));
} }
} }
/** /**
* @pre uart_enabled == true * @pre uart_enabled == true
*/ */
static inline void uart16550_write_reg(uint64_t base, static inline void uart16550_write_reg(uint64_t base, uint32_t val, uint16_t reg_idx)
uint32_t val, uint16_t reg_idx)
{ {
if (serial_port_mapped) { if (serial_port_mapped) {
pio_write8((uint8_t)val, (uint16_t)base + reg_idx); pio_write8((uint8_t)val, (uint16_t)base + reg_idx);
} else { } else {
mmio_write32(val, (void *)((uint32_t *)hpa2hva(base) + mmio_write32(val, (void *)((uint32_t *)hpa2hva(base) + reg_idx));
reg_idx));
} }
} }
static void uart16550_calc_baud_div(uint32_t ref_freq, static void uart16550_calc_baud_div(uint32_t ref_freq, uint32_t *baud_div_ptr, uint32_t baud_rate_arg)
uint32_t *baud_div_ptr, uint32_t baud_rate_arg)
{ {
uint32_t baud_rate = baud_rate_arg; uint32_t baud_rate = baud_rate_arg;
uint32_t baud_multiplier = baud_rate < BAUD_460800 ? 16U : 13U; 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); uart16550_write_reg(uart_base_address, temp_reg, UART16550_LCR);
/* Write the appropriate divisor value */ /* Write the appropriate divisor value */
uart16550_write_reg(uart_base_address, uart16550_write_reg(uart_base_address, ((baud_div >> 8U) & 0xFFU), UART16550_DLM);
((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 & 0xFFU), UART16550_DLL);
/* Disable DLL and DLM registers */ /* Disable DLL and DLM registers */
temp_reg &= ~LCR_DLAB; temp_reg &= ~LCR_DLAB;
@ -99,30 +94,28 @@ void uart16550_init(void)
if (!uart_enabled) { if (!uart_enabled) {
return; 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_rx_lock);
spinlock_init(&uart_tx_lock); spinlock_init(&uart_tx_lock);
/* Enable TX and RX FIFOs */ /* Enable TX and RX FIFOs */
uart16550_write_reg(uart_base_address, uart16550_write_reg(uart_base_address, FCR_FIFOE | FCR_RFR | FCR_TFR, UART16550_FCR);
FCR_FIFOE | FCR_RFR | FCR_TFR, UART16550_FCR);
/* Set-up data bits / parity / stop bits. */ /* Set-up data bits / parity / stop bits. */
uart16550_write_reg(uart_base_address, uart16550_write_reg(uart_base_address, (LCR_WL8 | LCR_NB_STOP_BITS_1 | LCR_PARITY_NONE), UART16550_LCR);
(LCR_WL8 | LCR_NB_STOP_BITS_1 | LCR_PARITY_NONE),
UART16550_LCR);
/* Disable interrupts (we use polling) */ /* Disable interrupts (we use polling) */
uart16550_write_reg(uart_base_address, uart16550_write_reg(uart_base_address, UART_IER_DISABLE_ALL, UART16550_IER);
UART_IER_DISABLE_ALL, UART16550_IER);
/* Set baud rate */ /* Set baud rate */
uart16550_set_baud_rate(BAUD_115200); uart16550_set_baud_rate(BAUD_115200);
/* Data terminal ready + Request to send */ /* Data terminal ready + Request to send */
uart16550_write_reg(uart_base_address, uart16550_write_reg(uart_base_address, MCR_RTS | MCR_DTR, UART16550_MCR);
MCR_RTS | MCR_DTR, UART16550_MCR);
} }
char uart16550_getc(void) char uart16550_getc(void)
@ -136,8 +129,7 @@ char uart16550_getc(void)
spinlock_obtain(&uart_rx_lock); spinlock_obtain(&uart_rx_lock);
/* If a character has been received, read it */ /* If a character has been received, read it */
if ((uart16550_read_reg(uart_base_address, UART16550_LSR) & LSR_DR) if ((uart16550_read_reg(uart_base_address, UART16550_LSR) & LSR_DR) == LSR_DR) {
== LSR_DR) {
/* Read a character */ /* Read a character */
ret = uart16550_read_reg(uart_base_address, UART16550_RBR); ret = uart16550_read_reg(uart_base_address, UART16550_RBR);