HV: change serial PCI cfg to bus:dev.func format

before PCI_BDF uses its hex value like "0xC2" for "0:18.2" to
configure, now use "0:18.2" directly to make it more readable
and easier to configure.

Tracked-On: #2031
Signed-off-by: Minggui Cao <minggui.cao@intel.com>
Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
Minggui Cao 2018-12-12 22:09:53 +08:00 committed by wenlingz
parent 1caf58f221
commit 23c2166aa9
3 changed files with 39 additions and 14 deletions

View File

@ -159,14 +159,12 @@ choice
If this is not selected, the serial port is disabled. This is the
default.
config SERIAL_PCI
bool "PCI"
help
Select this if the serial port shall be accessed via PCI memory-mapped
registers.
config SERIAL_LEGACY
bool "Legacy"
help
@ -175,16 +173,13 @@ config SERIAL_LEGACY
endchoice
config SERIAL_PCI_BDF
hex "BDF value of serial PCI device"
string "BDF of serial PCI device"
depends on SERIAL_PCI
default 0x00C2
default "0:18.2"
help
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.
BDF: bus, device and function of the serial PCI device; for an example,
PCI device ttyS2: 0:18.2.
config SERIAL_PIO_BASE
hex "Base address of serial PIO region"

View File

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

View File

@ -7,27 +7,56 @@
#include <hypervisor.h>
#include "uart16550.h"
#define MAX_BDF_LEN 8
#if defined(CONFIG_SERIAL_PIO_BASE)
static bool serial_port_mapped = true;
static bool uart_enabled = true;
static uint64_t uart_base_address = CONFIG_SERIAL_PIO_BASE;
static union pci_bdf serial_pci_bdf;
static char pci_bdf_info[MAX_BDF_LEN];
#elif defined(CONFIG_SERIAL_PCI_BDF)
static bool serial_port_mapped;
static bool uart_enabled = true;
static uint64_t uart_base_address;
static union pci_bdf serial_pci_bdf = (union pci_bdf)(uint16_t)CONFIG_SERIAL_PCI_BDF;
static char pci_bdf_info[MAX_BDF_LEN] = CONFIG_SERIAL_PCI_BDF;
#else
static bool serial_port_mapped;
static bool uart_enabled;
static uint64_t uart_base_address;
static union pci_bdf serial_pci_bdf;
static char pci_bdf_info[MAX_BDF_LEN];
#endif
typedef uint32_t uart_reg_t;
static spinlock_t uart_rx_lock;
static spinlock_t uart_tx_lock;
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
@ -96,7 +125,8 @@ void uart16550_init(void)
}
/* if configure serial PCI BDF, get its base MMIO address */
if (!serial_port_mapped && (uart_base_address == 0UL) && (serial_pci_bdf.value != 0U)) {
if (!serial_port_mapped) {
serial_pci_bdf.value = get_pci_bdf_value(pci_bdf_info);
uart_base_address = pci_pdev_read_cfg(serial_pci_bdf, pci_bar_offset(0), 4U) & PCIM_BAR_MEM_BASE;
}