hv: debug: Convert PCI UART paramter from a BDF string to a hex value
BDF string can be parsed by the configuration tool. A 16bit WORD value with format (B:8, D:5, F:3) can be passed from configuration to the hypervisor directly to save some BDF string parse code. Tracked-On: #4937 Signed-off-by: Shuo A Liu <shuo.a.liu@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
9af694dfbc
commit
d6b9682581
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue