From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: [PATCH 2/4] ns16550: enable Pericom controller support Date: Tue, 23 Feb 2016 04:28:59 -0700 Message-ID: <56CC508B02000078000D52B1@prv-mh.provo.novell.com> References: <56CC4F0B02000078000D5290@prv-mh.provo.novell.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=__PartDBEC4C6B.1__=" Return-path: Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aYB9N-0002Zr-LT for xen-devel@lists.xenproject.org; Tue, 23 Feb 2016 11:29:05 +0000 In-Reply-To: <56CC4F0B02000078000D5290@prv-mh.provo.novell.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel Cc: Ian Campbell , Keir Fraser , Ian Jackson , Tim Deegan List-Id: xen-devel@lists.xenproject.org This is a MIME message. If you are reading this text, you may want to consider changing to a mail reader or gateway that understands how to properly handle MIME multipart messages. --=__PartDBEC4C6B.1__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Other than the controllers supported so far, multiple port Pericom boards map all of their ports via BAR0, which requires a number of adjustments: Instead of tracking "max_bars" we now flag whether all ports use BAR0, and whether to expect a port-I/O or MMIO resource. As a result pci_uart_config() now gets handed a port index, which it then maps into a BAR index or an offset into BAR0 depending on the bar0 flag. Signed-off-by: Jan Beulich --- a/xen/drivers/char/ns16550.c +++ b/xen/drivers/char/ns16550.c @@ -78,10 +78,20 @@ static struct ns16550 { #endif } ns16550_com[2] =3D { { 0 } }; =20 -struct ns16550_config_mmio { +#ifdef CONFIG_HAS_PCI +struct ns16550_config { u16 vendor_id; u16 dev_id; - unsigned int param; + enum { + param_default, /* Must not be referenced by any table entry. */ + param_trumanage, + param_oxford, + param_oxford_2port, + param_pericom_1port, + param_pericom_2port, + param_pericom_4port, + param_pericom_8port, + } param; }; =20 /* Defining uart config options for MMIO devices */ @@ -90,57 +100,91 @@ struct ns16550_config_param { unsigned int reg_width; unsigned int fifo_size; u8 lsr_mask; - unsigned int max_bars; + bool_t mmio; + bool_t bar0; + unsigned int max_ports; unsigned int base_baud; unsigned int uart_offset; unsigned int first_offset; }; =20 - -#ifdef CONFIG_HAS_PCI -enum { - param_default =3D 0, - param_trumanage, - param_oxford, - param_oxford_2port, -}; /* - * Create lookup tables for specific MMIO devices.. - * It is assumed that if the device found is MMIO, - * then you have indexed it here. Else, the driver - * does nothing. + * Create lookup tables for specific devices. It is assumed that if + * the device found is MMIO, then you have indexed it here. Else, the + * driver does nothing for MMIO based devices. */ static const struct ns16550_config_param __initconst uart_param[] =3D { - [param_default] =3D { }, /* Ignored. */ + [param_default] =3D { + .reg_width =3D 1, + .lsr_mask =3D UART_LSR_THRE, + .max_ports =3D 1, + }, [param_trumanage] =3D { .reg_shift =3D 2, .reg_width =3D 1, .fifo_size =3D 16, .lsr_mask =3D (UART_LSR_THRE | UART_LSR_TEMT), - .max_bars =3D 1, + .mmio =3D 1, + .max_ports =3D 1, }, [param_oxford] =3D { .base_baud =3D 4000000, .uart_offset =3D 0x200, .first_offset =3D 0x1000, .reg_width =3D 1, - .reg_shift =3D 0, .fifo_size =3D 16, .lsr_mask =3D UART_LSR_THRE, - .max_bars =3D 1, /* It can do more, but we would need more custom = code.*/ + .mmio =3D 1, + .max_ports =3D 1, /* It can do more, but we would need more = custom code.*/ }, [param_oxford_2port] =3D { .base_baud =3D 4000000, .uart_offset =3D 0x200, .first_offset =3D 0x1000, .reg_width =3D 1, - .reg_shift =3D 0, .fifo_size =3D 16, .lsr_mask =3D UART_LSR_THRE, - .max_bars =3D 2, + .mmio =3D 1, + .max_ports =3D 2, + }, + [param_pericom_1port] =3D { + .base_baud =3D 921600, + .uart_offset =3D 8, + .reg_width =3D 1, + .fifo_size =3D 16, + .lsr_mask =3D UART_LSR_THRE, + .bar0 =3D 1, + .max_ports =3D 1, + }, + [param_pericom_2port] =3D { + .base_baud =3D 921600, + .uart_offset =3D 8, + .reg_width =3D 1, + .fifo_size =3D 16, + .lsr_mask =3D UART_LSR_THRE, + .bar0 =3D 1, + .max_ports =3D 2, + }, + [param_pericom_4port] =3D { + .base_baud =3D 921600, + .uart_offset =3D 8, + .reg_width =3D 1, + .fifo_size =3D 16, + .lsr_mask =3D UART_LSR_THRE, + .bar0 =3D 1, + .max_ports =3D 4, + }, + [param_pericom_8port] =3D { + .base_baud =3D 921600, + .uart_offset =3D 8, + .reg_width =3D 1, + .fifo_size =3D 16, + .lsr_mask =3D UART_LSR_THRE, + .bar0 =3D 1, + .max_ports =3D 8, } }; -static const struct ns16550_config_mmio __initconst uart_config[] =3D +static const struct ns16550_config __initconst uart_config[] =3D { /* Broadcom TruManage device */ { @@ -339,6 +383,30 @@ static const struct ns16550_config_mmio .vendor_id =3D PCI_VENDOR_ID_OXSEMI, .dev_id =3D 0xc4cf, .param =3D param_oxford, + }, + /* Pericom PI7C9X7951 Uno UART */ + { + .vendor_id =3D PCI_VENDOR_ID_PERICOM, + .dev_id =3D 0x7951, + .param =3D param_pericom_1port + }, + /* Pericom PI7C9X7952 Duo UART */ + { + .vendor_id =3D PCI_VENDOR_ID_PERICOM, + .dev_id =3D 0x7952, + .param =3D param_pericom_2port + }, + /* Pericom PI7C9X7954 Quad UART */ + { + .vendor_id =3D PCI_VENDOR_ID_PERICOM, + .dev_id =3D 0x7954, + .param =3D param_pericom_4port + }, + /* Pericom PI7C9X7958 Octal UART */ + { + .vendor_id =3D PCI_VENDOR_ID_PERICOM, + .dev_id =3D 0x7958, + .param =3D param_pericom_8port } }; #endif @@ -629,7 +697,8 @@ static void __init ns16550_init_postirq( uart->ps_bdf[2])); else { - if ( rangeset_add_range(mmio_ro_ranges, + if ( uart->param->mmio && + rangeset_add_range(mmio_ro_ranges, uart->io_base, uart->io_base + uart->io_size - 1) ) printk(XENLOG_INFO "Error while adding MMIO range of = device to mmio_ro_ranges\n"); @@ -830,12 +899,11 @@ static int __init check_existence(struct =20 #ifdef CONFIG_HAS_PCI static int __init -pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int = bar_idx) +pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx) { u64 orig_base =3D uart->io_base; unsigned int b, d, f, nextf, i; =20 - uart->io_base =3D 0; /* NB. Start at bus 1 to avoid AMT: a plug-in card cannot be on bus = 0. */ for ( b =3D skip_amt ? 1 : 0; b < 0x100; b++ ) { @@ -843,8 +911,10 @@ pci_uart_config(struct ns16550 *uart, bo { for ( f =3D 0; f < 8; f =3D nextf ) { + unsigned int bar_idx =3D 0, port_idx =3D idx; uint32_t bar, bar_64 =3D 0, len, len_64; - u64 size; + u64 size =3D 0; + const struct ns16550_config_param *param =3D uart_param; =20 nextf =3D (f || (pci_conf_read16(0, b, d, f, PCI_HEADER_TY= PE) & 0x80)) ? f + 1 : 8; @@ -863,15 +933,38 @@ pci_uart_config(struct ns16550 *uart, bo continue; } =20 + /* Check for params in uart_config lookup table */ + for ( i =3D 0; i < ARRAY_SIZE(uart_config); i++) + { + u16 vendor =3D pci_conf_read16(0, b, d, f, PCI_VENDOR_= ID); + u16 device =3D pci_conf_read16(0, b, d, f, PCI_DEVICE_= ID); + + if ( uart_config[i].vendor_id =3D=3D vendor && + uart_config[i].dev_id =3D=3D device ) + { + param +=3D uart_config[i].param; + if ( !param->bar0 ) + { + bar_idx =3D idx; + port_idx =3D 0; + } + break; + } + } + + if ( port_idx >=3D param->max_ports ) + { + idx -=3D param->max_ports; + continue; + } + + uart->io_base =3D 0; bar =3D pci_conf_read32(0, b, d, f, PCI_BASE_ADDRESS_0 + bar_idx*4); =20 /* MMIO based */ - if ( !(bar & PCI_BASE_ADDRESS_SPACE_IO) ) + if ( param->mmio && !(bar & PCI_BASE_ADDRESS_SPACE_IO) ) { - u16 vendor =3D pci_conf_read16(0, b, d, f, PCI_VENDOR_= ID); - u16 device =3D pci_conf_read16(0, b, d, f, PCI_DEVICE_= ID); - pci_conf_write32(0, b, d, f, PCI_BASE_ADDRESS_0 + bar_idx*4, = ~0u); len =3D pci_conf_read32(0, b, d, f, PCI_BASE_ADDRESS_0= + bar_idx*4); @@ -895,56 +988,11 @@ pci_uart_config(struct ns16550 *uart, bo else size =3D len & PCI_BASE_ADDRESS_MEM_MASK; =20 - size &=3D -size; - - /* Check for params in uart_config lookup table */ - for ( i =3D 0; i < ARRAY_SIZE(uart_config); i++) - { - const struct ns16550_config_param *param; - - if ( uart_config[i].vendor_id !=3D vendor ) - continue; - - if ( uart_config[i].dev_id !=3D device ) - continue; - - param =3D uart_param + uart_config[i].param; - - /* - * Force length of mmio region to be at least - * 8 bytes times (1 << reg_shift) - */ - if ( size < (0x8 * (1 << param->reg_shift)) ) - continue; - - if ( bar_idx >=3D param->max_bars ) - continue; - - uart->param =3D param; - - if ( param->fifo_size ) - uart->fifo_size =3D param->fifo_size; - - uart->reg_shift =3D param->reg_shift; - uart->reg_width =3D param->reg_width; - uart->lsr_mask =3D param->lsr_mask; - uart->io_base =3D ((u64)bar_64 << 32) | - (bar & PCI_BASE_ADDRESS_MEM_MASK);= - uart->io_base +=3D param->first_offset; - uart->io_base +=3D bar_idx * param->uart_offset; - if ( param->base_baud ) - uart->clock_hz =3D param->base_baud * 16; - size =3D max(8U << param->reg_shift, - param->uart_offset); - break; - } - - /* If we have an io_base, then we succeeded in the = lookup */ - if ( !uart->io_base ) - continue; + uart->io_base =3D ((u64)bar_64 << 32) | + (bar & PCI_BASE_ADDRESS_MEM_MASK); } /* IO based */ - else + else if ( !param->mmio && (bar & PCI_BASE_ADDRESS_SPACE_IO= ) ) { pci_conf_write32(0, b, d, f, PCI_BASE_ADDRESS_0 + bar_idx*4, = ~0u); @@ -952,22 +1000,45 @@ pci_uart_config(struct ns16550 *uart, bo pci_conf_write32(0, b, d, f, PCI_BASE_ADDRESS_0 + bar_idx*4, = bar); size =3D len & PCI_BASE_ADDRESS_IO_MASK; - size &=3D -size; - - /* Not at least 8 bytes */ - if ( size < 8 ) - continue; =20 uart->io_base =3D bar & ~PCI_BASE_ADDRESS_SPACE_IO; } =20 + /* If we have an io_base, then we succeeded in the = lookup. */ + if ( !uart->io_base ) + continue; + + size &=3D -size; + + /* + * Require length of actually used region to be at least + * 8 bytes times (1 << reg_shift). + */ + if ( size < param->first_offset + + port_idx * param->uart_offset + + (8 << param->reg_shift) ) + continue; + + uart->param =3D param; + + uart->reg_shift =3D param->reg_shift; + uart->reg_width =3D param->reg_width; + uart->lsr_mask =3D param->lsr_mask; + uart->io_base +=3D param->first_offset + + port_idx * param->uart_offset; + if ( param->base_baud ) + uart->clock_hz =3D param->base_baud * 16; + if ( param->fifo_size ) + uart->fifo_size =3D param->fifo_size; + uart->ps_bdf[0] =3D b; uart->ps_bdf[1] =3D d; uart->ps_bdf[2] =3D f; uart->bar_idx =3D bar_idx; uart->bar =3D bar; uart->bar64 =3D bar_64; - uart->io_size =3D size; + uart->io_size =3D max(8U << param->reg_shift, + param->uart_offset); uart->irq =3D pci_conf_read8(0, b, d, f, PCI_INTERRUPT_PIN= ) ? pci_conf_read8(0, b, d, f, PCI_INTERRUPT_LINE) : 0; =20 --- a/xen/include/xen/pci_ids.h +++ b/xen/include/xen/pci_ids.h @@ -2,6 +2,8 @@ =20 #define PCI_VENDOR_ID_NVIDIA 0x10de =20 +#define PCI_VENDOR_ID_PERICOM 0x12d8 + #define PCI_VENDOR_ID_OXSEMI 0x1415 =20 #define PCI_VENDOR_ID_BROADCOM 0x14e4 --=__PartDBEC4C6B.1__= Content-Type: text/plain; name="ns16550-Pericom.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="ns16550-Pericom.patch" ns16550: enable Pericom controller support=0A=0AOther than the controllers = supported so far, multiple port Pericom=0Aboards map all of their ports = via BAR0, which requires a number of=0Aadjustments: Instead of tracking = "max_bars" we now flag whether all=0Aports use BAR0, and whether to expect = a port-I/O or MMIO resource. As=0Aa result pci_uart_config() now gets = handed a port index, which it then=0Amaps into a BAR index or an offset = into BAR0 depending on the bar0=0Aflag.=0A=0ASigned-off-by: Jan Beulich = =0A=0A--- a/xen/drivers/char/ns16550.c=0A+++ b/xen/drive= rs/char/ns16550.c=0A@@ -78,10 +78,20 @@ static struct ns16550 {=0A = #endif=0A } ns16550_com[2] =3D { { 0 } };=0A =0A-struct ns16550_config_mmio= {=0A+#ifdef CONFIG_HAS_PCI=0A+struct ns16550_config {=0A u16 = vendor_id;=0A u16 dev_id;=0A- unsigned int param;=0A+ enum {=0A+ = param_default, /* Must not be referenced by any table entry. */=0A+ = param_trumanage,=0A+ param_oxford,=0A+ param_oxford_2p= ort,=0A+ param_pericom_1port,=0A+ param_pericom_2port,=0A+ = param_pericom_4port,=0A+ param_pericom_8port,=0A+ } = param;=0A };=0A =0A /* Defining uart config options for MMIO devices = */=0A@@ -90,57 +100,91 @@ struct ns16550_config_param {=0A unsigned = int reg_width;=0A unsigned int fifo_size;=0A u8 lsr_mask;=0A- = unsigned int max_bars;=0A+ bool_t mmio;=0A+ bool_t bar0;=0A+ = unsigned int max_ports;=0A unsigned int base_baud;=0A unsigned int = uart_offset;=0A unsigned int first_offset;=0A };=0A =0A-=0A-#ifdef = CONFIG_HAS_PCI=0A-enum {=0A- param_default =3D 0,=0A- param_trumanage= ,=0A- param_oxford,=0A- param_oxford_2port,=0A-};=0A /*=0A- * Create = lookup tables for specific MMIO devices..=0A- * It is assumed that if the = device found is MMIO,=0A- * then you have indexed it here. Else, the = driver=0A- * does nothing.=0A+ * Create lookup tables for specific = devices. It is assumed that if=0A+ * the device found is MMIO, then you = have indexed it here. Else, the=0A+ * driver does nothing for MMIO based = devices.=0A */=0A static const struct ns16550_config_param __initconst = uart_param[] =3D {=0A- [param_default] =3D { }, /* Ignored. */=0A+ = [param_default] =3D {=0A+ .reg_width =3D 1,=0A+ .lsr_mask = =3D UART_LSR_THRE,=0A+ .max_ports =3D 1,=0A+ },=0A [param_tru= manage] =3D {=0A .reg_shift =3D 2,=0A .reg_width =3D 1,=0A = .fifo_size =3D 16,=0A .lsr_mask =3D (UART_LSR_THRE | = UART_LSR_TEMT),=0A- .max_bars =3D 1,=0A+ .mmio =3D 1,=0A+ = .max_ports =3D 1,=0A },=0A [param_oxford] =3D {=0A = .base_baud =3D 4000000,=0A .uart_offset =3D 0x200,=0A = .first_offset =3D 0x1000,=0A .reg_width =3D 1,=0A- = .reg_shift =3D 0,=0A .fifo_size =3D 16,=0A .lsr_mask =3D = UART_LSR_THRE,=0A- .max_bars =3D 1, /* It can do more, but we would = need more custom code.*/=0A+ .mmio =3D 1,=0A+ .max_ports =3D = 1, /* It can do more, but we would need more custom code.*/=0A },=0A = [param_oxford_2port] =3D {=0A .base_baud =3D 4000000,=0A = .uart_offset =3D 0x200,=0A .first_offset =3D 0x1000,=0A = .reg_width =3D 1,=0A- .reg_shift =3D 0,=0A .fifo_size =3D = 16,=0A .lsr_mask =3D UART_LSR_THRE,=0A- .max_bars =3D = 2,=0A+ .mmio =3D 1,=0A+ .max_ports =3D 2,=0A+ },=0A+ = [param_pericom_1port] =3D {=0A+ .base_baud =3D 921600,=0A+ = .uart_offset =3D 8,=0A+ .reg_width =3D 1,=0A+ .fifo_size =3D = 16,=0A+ .lsr_mask =3D UART_LSR_THRE,=0A+ .bar0 =3D 1,=0A+ = .max_ports =3D 1,=0A+ },=0A+ [param_pericom_2port] =3D {=0A+ = .base_baud =3D 921600,=0A+ .uart_offset =3D 8,=0A+ = .reg_width =3D 1,=0A+ .fifo_size =3D 16,=0A+ .lsr_mask =3D = UART_LSR_THRE,=0A+ .bar0 =3D 1,=0A+ .max_ports =3D 2,=0A+ = },=0A+ [param_pericom_4port] =3D {=0A+ .base_baud =3D 921600,=0A+= .uart_offset =3D 8,=0A+ .reg_width =3D 1,=0A+ = .fifo_size =3D 16,=0A+ .lsr_mask =3D UART_LSR_THRE,=0A+ = .bar0 =3D 1,=0A+ .max_ports =3D 4,=0A+ },=0A+ [param_pericom_8= port] =3D {=0A+ .base_baud =3D 921600,=0A+ .uart_offset =3D = 8,=0A+ .reg_width =3D 1,=0A+ .fifo_size =3D 16,=0A+ = .lsr_mask =3D UART_LSR_THRE,=0A+ .bar0 =3D 1,=0A+ .max_ports = =3D 8,=0A }=0A };=0A-static const struct ns16550_config_mmio __initcons= t uart_config[] =3D=0A+static const struct ns16550_config __initconst = uart_config[] =3D=0A {=0A /* Broadcom TruManage device */=0A = {=0A@@ -339,6 +383,30 @@ static const struct ns16550_config_mmio=0A = .vendor_id =3D PCI_VENDOR_ID_OXSEMI,=0A .dev_id =3D 0xc4cf,=0A = .param =3D param_oxford,=0A+ },=0A+ /* Pericom PI7C9X7951 Uno = UART */=0A+ {=0A+ .vendor_id =3D PCI_VENDOR_ID_PERICOM,=0A+ = .dev_id =3D 0x7951,=0A+ .param =3D param_pericom_1port=0A+ = },=0A+ /* Pericom PI7C9X7952 Duo UART */=0A+ {=0A+ .vendor_id = =3D PCI_VENDOR_ID_PERICOM,=0A+ .dev_id =3D 0x7952,=0A+ = .param =3D param_pericom_2port=0A+ },=0A+ /* Pericom PI7C9X7954 Quad = UART */=0A+ {=0A+ .vendor_id =3D PCI_VENDOR_ID_PERICOM,=0A+ = .dev_id =3D 0x7954,=0A+ .param =3D param_pericom_4port=0A+ = },=0A+ /* Pericom PI7C9X7958 Octal UART */=0A+ {=0A+ = .vendor_id =3D PCI_VENDOR_ID_PERICOM,=0A+ .dev_id =3D 0x7958,=0A+ = .param =3D param_pericom_8port=0A }=0A };=0A #endif=0A@@ -629,7 = +697,8 @@ static void __init ns16550_init_postirq(=0A = uart->ps_bdf[2]));=0A else=0A {=0A- if ( = rangeset_add_range(mmio_ro_ranges,=0A+ if ( uart->param->mmio = &&=0A+ rangeset_add_range(mmio_ro_ranges,=0A = uart->io_base,=0A = uart->io_base + uart->io_size - 1) )=0A printk(XENLOG_INFO= "Error while adding MMIO range of device to mmio_ro_ranges\n");=0A@@ = -830,12 +899,11 @@ static int __init check_existence(struct=0A =0A #ifdef = CONFIG_HAS_PCI=0A static int __init=0A-pci_uart_config(struct ns16550 = *uart, bool_t skip_amt, unsigned int bar_idx)=0A+pci_uart_config(struct = ns16550 *uart, bool_t skip_amt, unsigned int idx)=0A {=0A u64 = orig_base =3D uart->io_base;=0A unsigned int b, d, f, nextf, i;=0A = =0A- uart->io_base =3D 0;=0A /* NB. Start at bus 1 to avoid AMT: a = plug-in card cannot be on bus 0. */=0A for ( b =3D skip_amt ? 1 : 0; b = < 0x100; b++ )=0A {=0A@@ -843,8 +911,10 @@ pci_uart_config(struct = ns16550 *uart, bo=0A {=0A for ( f =3D 0; f < 8; f =3D = nextf )=0A {=0A+ unsigned int bar_idx =3D 0, = port_idx =3D idx;=0A uint32_t bar, bar_64 =3D 0, len, = len_64;=0A- u64 size;=0A+ u64 size =3D = 0;=0A+ const struct ns16550_config_param *param =3D = uart_param;=0A =0A nextf =3D (f || (pci_conf_read16(0, b, = d, f, PCI_HEADER_TYPE) &=0A 0x80)) ? f + 1 = : 8;=0A@@ -863,15 +933,38 @@ pci_uart_config(struct ns16550 *uart, bo=0A = continue;=0A }=0A =0A+ /* = Check for params in uart_config lookup table */=0A+ for ( i = =3D 0; i < ARRAY_SIZE(uart_config); i++)=0A+ {=0A+ = u16 vendor =3D pci_conf_read16(0, b, d, f, PCI_VENDOR_ID);=0A+ = u16 device =3D pci_conf_read16(0, b, d, f, PCI_DEVICE_ID);= =0A+=0A+ if ( uart_config[i].vendor_id =3D=3D vendor = &&=0A+ uart_config[i].dev_id =3D=3D device )=0A+ = {=0A+ param +=3D uart_config[i].par= am;=0A+ if ( !param->bar0 )=0A+ = {=0A+ bar_idx =3D idx;=0A+ = port_idx =3D 0;=0A+ }=0A+ = break;=0A+ }=0A+ }=0A+=0A+ = if ( port_idx >=3D param->max_ports )=0A+ {=0A+ = idx -=3D param->max_ports;=0A+ = continue;=0A+ }=0A+=0A+ uart->io_base =3D = 0;=0A bar =3D pci_conf_read32(0, b, d, f,=0A = PCI_BASE_ADDRESS_0 + bar_idx*4);=0A =0A = /* MMIO based */=0A- if ( !(bar & PCI_BASE_ADDRESS_SPAC= E_IO) )=0A+ if ( param->mmio && !(bar & PCI_BASE_ADDRESS_SPA= CE_IO) )=0A {=0A- u16 vendor =3D = pci_conf_read16(0, b, d, f, PCI_VENDOR_ID);=0A- u16 = device =3D pci_conf_read16(0, b, d, f, PCI_DEVICE_ID);=0A-=0A = pci_conf_write32(0, b, d, f,=0A = PCI_BASE_ADDRESS_0 + bar_idx*4, ~0u);=0A len =3D = pci_conf_read32(0, b, d, f, PCI_BASE_ADDRESS_0 + bar_idx*4);=0A@@ -895,56 = +988,11 @@ pci_uart_config(struct ns16550 *uart, bo=0A = else=0A size =3D len & PCI_BASE_ADDRESS_MEM_MASK;= =0A =0A- size &=3D -size;=0A-=0A- /* = Check for params in uart_config lookup table */=0A- for = ( i =3D 0; i < ARRAY_SIZE(uart_config); i++)=0A- {=0A- = const struct ns16550_config_param *param;=0A-=0A- = if ( uart_config[i].vendor_id !=3D vendor )=0A- = continue;=0A-=0A- if ( = uart_config[i].dev_id !=3D device )=0A- = continue;=0A-=0A- param =3D uart_param + uart_config= [i].param;=0A-=0A- /*=0A- * = Force length of mmio region to be at least=0A- * 8 = bytes times (1 << reg_shift)=0A- */=0A- = if ( size < (0x8 * (1 << param->reg_shift)) )=0A- = continue;=0A-=0A- if ( bar_idx >=3D = param->max_bars )=0A- continue;=0A-=0A- = uart->param =3D param;=0A-=0A- if ( = param->fifo_size )=0A- uart->fifo_size =3D = param->fifo_size;=0A-=0A- uart->reg_shift =3D = param->reg_shift;=0A- uart->reg_width =3D param->reg= _width;=0A- uart->lsr_mask =3D param->lsr_mask;=0A- = uart->io_base =3D ((u64)bar_64 << 32) |=0A- = (bar & PCI_BASE_ADDRESS_MEM_MASK);=0A- = uart->io_base +=3D param->first_offset;=0A- = uart->io_base +=3D bar_idx * param->uart_offset;=0A- = if ( param->base_baud )=0A- = uart->clock_hz =3D param->base_baud * 16;=0A- size = =3D max(8U << param->reg_shift,=0A- = param->uart_offset);=0A- break;=0A- = }=0A-=0A- /* If we have an io_base, then we = succeeded in the lookup */=0A- if ( !uart->io_base = )=0A- continue;=0A+ uart->io_base= =3D ((u64)bar_64 << 32) |=0A+ (bar & = PCI_BASE_ADDRESS_MEM_MASK);=0A }=0A /* IO = based */=0A- else=0A+ else if ( !param->mmio = && (bar & PCI_BASE_ADDRESS_SPACE_IO) )=0A {=0A = pci_conf_write32(0, b, d, f,=0A = PCI_BASE_ADDRESS_0 + bar_idx*4, ~0u);=0A@@ -952,22 +1000,45 @@ pci_uart_c= onfig(struct ns16550 *uart, bo=0A pci_conf_write32(0, = b, d, f,=0A PCI_BASE_ADDRESS_0 + = bar_idx*4, bar);=0A size =3D len & PCI_BASE_ADDRESS_IO_= MASK;=0A- size &=3D -size;=0A-=0A- = /* Not at least 8 bytes */=0A- if ( size < 8 )=0A- = continue;=0A =0A uart->io_base =3D = bar & ~PCI_BASE_ADDRESS_SPACE_IO;=0A }=0A =0A+ = /* If we have an io_base, then we succeeded in the lookup. */=0A+ = if ( !uart->io_base )=0A+ continue;=0A+=0A+ = size &=3D -size;=0A+=0A+ /*=0A+ = * Require length of actually used region to be at least=0A+ = * 8 bytes times (1 << reg_shift).=0A+ */=0A+ = if ( size < param->first_offset +=0A+ = port_idx * param->uart_offset +=0A+ (8 << = param->reg_shift) )=0A+ continue;=0A+=0A+ = uart->param =3D param;=0A+=0A+ uart->reg_shift =3D = param->reg_shift;=0A+ uart->reg_width =3D param->reg_width;= =0A+ uart->lsr_mask =3D param->lsr_mask;=0A+ = uart->io_base +=3D param->first_offset +=0A+ = port_idx * param->uart_offset;=0A+ if ( param->base_baud = )=0A+ uart->clock_hz =3D param->base_baud * 16;=0A+ = if ( param->fifo_size )=0A+ uart->fifo_size = =3D param->fifo_size;=0A+=0A uart->ps_bdf[0] =3D b;=0A = uart->ps_bdf[1] =3D d;=0A uart->ps_bdf[2] =3D = f;=0A uart->bar_idx =3D bar_idx;=0A = uart->bar =3D bar;=0A uart->bar64 =3D bar_64;=0A- = uart->io_size =3D size;=0A+ uart->io_size =3D max(8U = << param->reg_shift,=0A+ param->uart_off= set);=0A uart->irq =3D pci_conf_read8(0, b, d, f, = PCI_INTERRUPT_PIN) ?=0A pci_conf_read8(0, b, d, f, = PCI_INTERRUPT_LINE) : 0;=0A =0A--- a/xen/include/xen/pci_ids.h=0A+++ = b/xen/include/xen/pci_ids.h=0A@@ -2,6 +2,8 @@=0A =0A #define PCI_VENDOR_ID_= NVIDIA 0x10de=0A =0A+#define PCI_VENDOR_ID_PERICOM = 0x12d8=0A+=0A #define PCI_VENDOR_ID_OXSEMI 0x1415=0A =0A = #define PCI_VENDOR_ID_BROADCOM 0x14e4=0A --=__PartDBEC4C6B.1__= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel --=__PartDBEC4C6B.1__=--