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
|
endchoice
|
||||||
|
|
||||||
config SERIAL_PCI_BDF
|
config SERIAL_PCI_BDF
|
||||||
string "BDF of serial PCI device"
|
hex "BDF of serial PCI device"
|
||||||
depends on SERIAL_PCI
|
depends on SERIAL_PCI
|
||||||
default "0:18.2"
|
default 0x00c2
|
||||||
help
|
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.
|
PCI device ttyS2: 0:18.2.
|
||||||
|
|
||||||
config SERIAL_PIO_BASE
|
config SERIAL_PIO_BASE
|
||||||
|
|
|
@ -28,6 +28,7 @@ static struct uart_cmd {
|
||||||
bool handle_dbg_cmd(const char *cmd, int32_t len)
|
bool handle_dbg_cmd(const char *cmd, int32_t len)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
uint64_t data;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(cmd_list); i++) {
|
for (i = 0; i < ARRAY_SIZE(cmd_list); i++) {
|
||||||
int32_t tmp = strnlen_s(cmd_list[i].str, MAX_CMD_LEN);
|
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*/
|
/* set uart disabled*/
|
||||||
uart16550_set_property(false, type, 0UL);
|
uart16550_set_property(false, type, 0UL);
|
||||||
} else if (type == PIO) {
|
} else if (type == PIO) {
|
||||||
uint64_t addr = strtoul_hex(cmd + tmp);
|
data = strtoul_hex(cmd + tmp);
|
||||||
|
|
||||||
if (addr > MAX_PORT) {
|
if (data > MAX_PORT) {
|
||||||
addr = DEFAULT_UART_PORT;
|
data = DEFAULT_UART_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
uart16550_set_property(true, type, addr);
|
uart16550_set_property(true, type, data);
|
||||||
} else if (type == PCI) {
|
|
||||||
uart16550_set_property(true, type, (uint64_t)(cmd+tmp));
|
|
||||||
} else {
|
} else {
|
||||||
uint64_t addr = strtoul_hex(cmd + tmp);
|
data = strtoul_hex(cmd + tmp);
|
||||||
uart16550_set_property(true, type, addr);
|
uart16550_set_property(true, type, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ struct console_uart {
|
||||||
enum serial_dev_type type;
|
enum serial_dev_type type;
|
||||||
union {
|
union {
|
||||||
uint16_t port_address;
|
uint16_t port_address;
|
||||||
|
union pci_bdf bdf;
|
||||||
void *mmio_base_vaddr;
|
void *mmio_base_vaddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,14 +37,13 @@ static struct console_uart uart = {
|
||||||
.port_address = CONFIG_SERIAL_PIO_BASE,
|
.port_address = CONFIG_SERIAL_PIO_BASE,
|
||||||
.reg_width = 1,
|
.reg_width = 1,
|
||||||
};
|
};
|
||||||
static char pci_bdf_info[MAX_BDF_LEN + 1U];
|
|
||||||
#elif defined(CONFIG_SERIAL_PCI_BDF)
|
#elif defined(CONFIG_SERIAL_PCI_BDF)
|
||||||
static struct console_uart uart = {
|
static struct console_uart uart = {
|
||||||
.enabled = true,
|
.enabled = true,
|
||||||
.type = PCI,
|
.type = PCI,
|
||||||
|
.bdf.value = CONFIG_SERIAL_PCI_BDF,
|
||||||
.reg_width = 4,
|
.reg_width = 4,
|
||||||
};
|
};
|
||||||
static char pci_bdf_info[MAX_BDF_LEN + 1U] = CONFIG_SERIAL_PCI_BDF;
|
|
||||||
#elif defined(CONFIG_SERIAL_MMIO_BASE)
|
#elif defined(CONFIG_SERIAL_MMIO_BASE)
|
||||||
static struct console_uart uart = {
|
static struct console_uart uart = {
|
||||||
.enabled = true,
|
.enabled = true,
|
||||||
|
@ -51,38 +51,9 @@ static struct console_uart uart = {
|
||||||
.mmio_base_vaddr = (void *)CONFIG_SERIAL_MMIO_BASE,
|
.mmio_base_vaddr = (void *)CONFIG_SERIAL_MMIO_BASE,
|
||||||
.reg_width = 1,
|
.reg_width = 1,
|
||||||
};
|
};
|
||||||
static char pci_bdf_info[MAX_BDF_LEN + 1U];
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef uint32_t uart_reg_t;
|
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
|
* @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 configure serial PCI BDF, get its base MMIO address */
|
||||||
if (uart.type == PCI) {
|
if (uart.type == PCI) {
|
||||||
serial_pci_bdf.value = get_pci_bdf_value(pci_bdf_info);
|
|
||||||
uart.mmio_base_vaddr =
|
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.rx_lock);
|
||||||
spinlock_init(&uart.tx_lock);
|
spinlock_init(&uart.tx_lock);
|
||||||
|
@ -245,19 +215,18 @@ size_t uart16550_puts(const char *buf, uint32_t len)
|
||||||
return 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.enabled = enabled;
|
||||||
uart.type = uart_type;
|
uart.type = uart_type;
|
||||||
|
|
||||||
if (uart_type == PIO) {
|
if (uart_type == PIO) {
|
||||||
uart.port_address = base_addr;
|
uart.port_address = data;
|
||||||
} else if (uart_type == PCI) {
|
} else if (uart_type == PCI) {
|
||||||
const char *bdf = (const char *)base_addr;
|
uart.bdf.value = data;
|
||||||
strncpy_s(pci_bdf_info, MAX_BDF_LEN + 1U, bdf, MAX_BDF_LEN);
|
|
||||||
uart.reg_width = 4;
|
uart.reg_width = 4;
|
||||||
} else if (uart_type == MMIO) {
|
} else if (uart_type == MMIO) {
|
||||||
uart.mmio_base_vaddr = (void *)base_addr;
|
uart.mmio_base_vaddr = (void *)data;
|
||||||
uart.reg_width = 1;
|
uart.reg_width = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,7 +236,7 @@ bool is_pci_dbg_uart(union pci_bdf bdf_value)
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if (uart.enabled && (uart.type == PCI)) {
|
if (uart.enabled && (uart.type == PCI)) {
|
||||||
if (bdf_value.value == serial_pci_bdf.value) {
|
if (bdf_value.value == uart.bdf.value) {
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue