xen/uart: switch ns16550 to use pci_sbdf_t

No functional change intended.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
Roger Pau Monne committed 2026-03-30 16:43:14 +02:00
1 parent ebf5439725
commit 1e185afefc
1 file changed
+58 -75
+58 -75
View File
@@ -67,8 +67,8 @@ static struct ns16550 {
/* PCI card parameters. */
bool pb_bdf_enable; /* if =1, pb-bdf effective, port behind bridge */
bool ps_bdf_enable; /* if =1, ps_bdf effective, port on pci card */
unsigned int pb_bdf[3]; /* pci bridge BDF */
unsigned int ps_bdf[3]; /* pci serial port BDF */
pci_sbdf_t pci_bridge;
pci_sbdf_t pci_device;
u32 bar;
u32 bar64;
u16 cr;
@@ -288,31 +288,22 @@ static void pci_serial_early_init(struct ns16550 *uart)
if ( !uart->ps_bdf_enable )
return;
cmd = pci_conf_read16(PCI_SBDF(0, uart->ps_bdf[0], uart->ps_bdf[1],
uart->ps_bdf[2]), PCI_COMMAND);
cmd = pci_conf_read16(uart->pci_device, PCI_COMMAND);
if ( uart->io_base >= 0x10000 )
{
pci_conf_write16(PCI_SBDF(0, uart->ps_bdf[0], uart->ps_bdf[1],
uart->ps_bdf[2]),
PCI_COMMAND, cmd | PCI_COMMAND_MEMORY);
pci_conf_write16(uart->pci_device, PCI_COMMAND, cmd | PCI_COMMAND_MEMORY);
return;
}
if ( uart->pb_bdf_enable )
pci_conf_write16(PCI_SBDF(0, uart->pb_bdf[0], uart->pb_bdf[1],
uart->pb_bdf[2]),
PCI_IO_BASE,
pci_conf_write16(uart->pci_bridge, PCI_IO_BASE,
(uart->io_base & 0xF000) |
((uart->io_base & 0xF000) >> 8));
pci_conf_write32(PCI_SBDF(0, uart->ps_bdf[0], uart->ps_bdf[1],
uart->ps_bdf[2]),
PCI_BASE_ADDRESS_0,
pci_conf_write32(uart->pci_device, PCI_BASE_ADDRESS_0,
uart->io_base | PCI_BASE_ADDRESS_SPACE_IO);
pci_conf_write16(PCI_SBDF(0, uart->ps_bdf[0], uart->ps_bdf[1],
uart->ps_bdf[2]),
PCI_COMMAND, cmd | PCI_COMMAND_IO);
pci_conf_write16(uart->pci_device, PCI_COMMAND, cmd | PCI_COMMAND_IO);
#endif
}
@@ -452,17 +443,16 @@ static void __init cf_check ns16550_init_postirq(struct serial_port *port)
PFN_UP(uart->io_base + uart->io_size) - 1) )
printk(XENLOG_INFO "Error while adding MMIO range of device to mmio_ro_ranges\n");
if ( pci_ro_device(0, uart->ps_bdf[0],
PCI_DEVFN(uart->ps_bdf[1], uart->ps_bdf[2])) )
printk(XENLOG_INFO "Could not mark config space of %02x:%02x.%u read-only.\n",
uart->ps_bdf[0], uart->ps_bdf[1],
uart->ps_bdf[2]);
if ( pci_ro_device(uart->pci_device.seg, uart->pci_device.bus,
uart->pci_device.devfn) )
printk(XENLOG_INFO
"Could not mark config space of %pp read-only.\n",
&uart->pci_device);
if ( uart->msi )
{
struct msi_info msi = {
.sbdf = PCI_SBDF(0, uart->ps_bdf[0], uart->ps_bdf[1],
uart->ps_bdf[2]),
.sbdf = uart->pci_device,
.irq = uart->irq,
.entry_nr = 1
};
@@ -504,9 +494,8 @@ static void __init cf_check ns16550_init_postirq(struct serial_port *port)
}
if ( rc )
printk(XENLOG_WARNING
"MSI setup failed (%d) for %02x:%02x.%o\n",
rc, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2]);
printk(XENLOG_WARNING "MSI setup failed (%d) for %pp\n",
rc, &uart->pci_device);
}
}
#endif
@@ -533,8 +522,7 @@ static void cf_check ns16550_suspend(struct serial_port *port)
#ifdef NS16550_PCI
if ( uart->bar )
uart->cr = pci_conf_read16(PCI_SBDF(0, uart->ps_bdf[0], uart->ps_bdf[1],
uart->ps_bdf[2]), PCI_COMMAND);
uart->cr = pci_conf_read16(uart->pci_device, PCI_COMMAND);
#endif
}
@@ -545,19 +533,15 @@ static void _ns16550_resume(struct serial_port *port)
if ( uart->bar )
{
pci_conf_write32(PCI_SBDF(0, uart->ps_bdf[0], uart->ps_bdf[1],
uart->ps_bdf[2]),
pci_conf_write32(uart->pci_device,
PCI_BASE_ADDRESS_0 + uart->bar_idx*4, uart->bar);
/* If 64 bit BAR, write higher 32 bits to BAR+4 */
if ( uart->bar & PCI_BASE_ADDRESS_MEM_TYPE_64 )
pci_conf_write32(PCI_SBDF(0, uart->ps_bdf[0], uart->ps_bdf[1],
uart->ps_bdf[2]),
pci_conf_write32(uart->pci_device,
PCI_BASE_ADDRESS_0 + (uart->bar_idx+1)*4, uart->bar64);
pci_conf_write16(PCI_SBDF(0, uart->ps_bdf[0], uart->ps_bdf[1],
uart->ps_bdf[2]),
PCI_COMMAND, uart->cr);
pci_conf_write16(uart->pci_device, PCI_COMMAND, uart->cr);
}
#endif
@@ -1217,13 +1201,12 @@ pci_uart_config(struct ns16550 *uart, bool skip_amt, unsigned int idx)
uint32_t bar, bar_64 = 0, len, len_64;
u64 size = 0;
const struct ns16550_config_param *param = uart_param;
pci_sbdf_t sbdf = PCI_SBDF(0, b, d, f);
nextf = (f || (pci_conf_read16(PCI_SBDF(0, b, d, f),
PCI_HEADER_TYPE) &
nextf = (f || (pci_conf_read16(sbdf, PCI_HEADER_TYPE) &
0x80)) ? f + 1 : 8;
switch ( pci_conf_read16(PCI_SBDF(0, b, d, f),
PCI_CLASS_DEVICE) )
switch ( pci_conf_read16(sbdf, PCI_CLASS_DEVICE) )
{
case 0x0700: /* single port serial */
case 0x0702: /* multi port serial */
@@ -1240,10 +1223,8 @@ pci_uart_config(struct ns16550 *uart, bool skip_amt, unsigned int idx)
/* Check for params in uart_config lookup table */
for ( i = 0; i < ARRAY_SIZE(uart_config); i++ )
{
u16 vendor = pci_conf_read16(PCI_SBDF(0, b, d, f),
PCI_VENDOR_ID);
u16 device = pci_conf_read16(PCI_SBDF(0, b, d, f),
PCI_DEVICE_ID);
u16 vendor = pci_conf_read16(sbdf, PCI_VENDOR_ID);
u16 device = pci_conf_read16(sbdf, PCI_DEVICE_ID);
if ( uart_config[i].vendor_id == vendor &&
uart_config[i].dev_id == device )
@@ -1266,29 +1247,26 @@ pci_uart_config(struct ns16550 *uart, bool skip_amt, unsigned int idx)
}
uart->io_base = 0;
bar = pci_conf_read32(PCI_SBDF(0, b, d, f),
PCI_BASE_ADDRESS_0 + bar_idx * 4);
bar = pci_conf_read32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx * 4);
/* MMIO based */
if ( param->mmio && !(bar & PCI_BASE_ADDRESS_SPACE_IO) )
{
pci_conf_write32(PCI_SBDF(0, b, d, f),
PCI_BASE_ADDRESS_0 + bar_idx*4, ~0u);
len = pci_conf_read32(PCI_SBDF(0, b, d, f),
pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4, ~0u);
len = pci_conf_read32(sbdf,
PCI_BASE_ADDRESS_0 + bar_idx * 4);
pci_conf_write32(PCI_SBDF(0, b, d, f),
PCI_BASE_ADDRESS_0 + bar_idx*4, bar);
pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4, bar);
/* Handle 64 bit BAR if found */
if ( bar & PCI_BASE_ADDRESS_MEM_TYPE_64 )
{
bar_64 = pci_conf_read32(PCI_SBDF(0, b, d, f),
bar_64 = pci_conf_read32(sbdf,
PCI_BASE_ADDRESS_0 + (bar_idx + 1) * 4);
pci_conf_write32(PCI_SBDF(0, b, d, f),
pci_conf_write32(sbdf,
PCI_BASE_ADDRESS_0 + (bar_idx+1)*4, ~0u);
len_64 = pci_conf_read32(PCI_SBDF(0, b, d, f),
len_64 = pci_conf_read32(sbdf,
PCI_BASE_ADDRESS_0 + (bar_idx + 1) * 4);
pci_conf_write32(PCI_SBDF(0, b, d, f),
pci_conf_write32(sbdf,
PCI_BASE_ADDRESS_0 + (bar_idx+1)*4, bar_64);
size = ((u64)~0 << 32) | PCI_BASE_ADDRESS_MEM_MASK;
size &= ((u64)len_64 << 32) | len;
@@ -1302,12 +1280,9 @@ pci_uart_config(struct ns16550 *uart, bool skip_amt, unsigned int idx)
/* IO based */
else if ( !param->mmio && (bar & PCI_BASE_ADDRESS_SPACE_IO) )
{
pci_conf_write32(PCI_SBDF(0, b, d, f),
PCI_BASE_ADDRESS_0 + bar_idx*4, ~0u);
len = pci_conf_read32(PCI_SBDF(0, b, d, f),
PCI_BASE_ADDRESS_0);
pci_conf_write32(PCI_SBDF(0, b, d, f),
PCI_BASE_ADDRESS_0 + bar_idx*4, bar);
pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4, ~0u);
len = pci_conf_read32(sbdf, PCI_BASE_ADDRESS_0);
pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4, bar);
size = len & PCI_BASE_ADDRESS_IO_MASK;
uart->io_base = bar & ~PCI_BASE_ADDRESS_SPACE_IO;
@@ -1340,19 +1315,15 @@ pci_uart_config(struct ns16550 *uart, bool skip_amt, unsigned int idx)
if ( param->fifo_size )
uart->fifo_size = param->fifo_size;
uart->ps_bdf[0] = b;
uart->ps_bdf[1] = d;
uart->ps_bdf[2] = f;
uart->pci_device = sbdf;
uart->ps_bdf_enable = true;
uart->bar_idx = bar_idx;
uart->bar = bar;
uart->bar64 = bar_64;
uart->io_size = max(8U << param->reg_shift,
param->uart_offset);
uart->irq = pci_conf_read8(PCI_SBDF(0, b, d, f),
PCI_INTERRUPT_PIN) ?
pci_conf_read8(PCI_SBDF(0, b, d, f),
PCI_INTERRUPT_LINE) : 0;
uart->irq = pci_conf_read8(sbdf, PCI_INTERRUPT_PIN) ?
pci_conf_read8(sbdf, PCI_INTERRUPT_LINE) : 0;
#ifdef CONFIG_X86
/*
@@ -1591,18 +1562,22 @@ static bool __init parse_positional(struct ns16550 *uart, char **str)
#ifdef CONFIG_HAS_PCI
if ( *conf == ',' && *++conf != ',' )
{
conf = parse_pci(conf, NULL, &uart->ps_bdf[0],
&uart->ps_bdf[1], &uart->ps_bdf[2]);
unsigned int b, d, f;
conf = parse_pci(conf, NULL, &b, &d, &f);
if ( !conf )
PARSE_ERR_RET("Bad port PCI coordinates");
uart->pci_device = PCI_SBDF(0, b, d, f);
uart->ps_bdf_enable = true;
}
if ( *conf == ',' && *++conf != ',' )
{
if ( !parse_pci(conf, NULL, &uart->pb_bdf[0],
&uart->pb_bdf[1], &uart->pb_bdf[2]) )
unsigned int b, d, f;
if ( !parse_pci(conf, NULL, &b, &d, &f) )
PARSE_ERR_RET("Bad bridge PCI coordinates");
uart->pci_bridge = PCI_SBDF(0, b, d, f);
uart->pb_bdf_enable = true;
}
#endif
@@ -1685,18 +1660,26 @@ static bool __init parse_namevalue_pairs(char *str, struct ns16550 *uart)
break;
case port_bdf:
if ( !parse_pci(param_value, NULL, &uart->ps_bdf[0],
&uart->ps_bdf[1], &uart->ps_bdf[2]) )
{
unsigned int b, d, f;
if ( !parse_pci(param_value, NULL, &b, &d, &f) )
PARSE_ERR_RET("Bad port PCI coordinates\n");
uart->pci_device = PCI_SBDF(0, b, d, f);
uart->ps_bdf_enable = true;
break;
}
case bridge_bdf:
if ( !parse_pci(param_value, NULL, &uart->pb_bdf[0],
&uart->pb_bdf[1], &uart->pb_bdf[2]) )
{
unsigned int b, d, f;
if ( !parse_pci(param_value, NULL, &b, &d, &f) )
PARSE_ERR_RET("Bad bridge PCI coordinates\n");
uart->pci_bridge = PCI_SBDF(0, b, d, f);
uart->pb_bdf_enable = true;
break;
}
#endif
default:
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.