WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] ns16550: enable PCI serial card usage

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] ns16550: enable PCI serial card usage
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 05 Apr 2010 23:20:16 -0700
Delivery-date: Mon, 05 Apr 2010 23:20:12 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1270026701 -3600
# Node ID 589d075ba2953123c1b39ecdbc190689ac6f443c
# Parent  ebd84be3420a4453b3024d3378d8d84b81f44118
ns16550: enable PCI serial card usage

On some machine, there is no build-in serial port and no LPC
connection. To use serial port, we have to plug in a serial
card. Sometime BIOS doesn't enable the BARs for the PCI devices which
lead to that Xen can't use the add-in serial port for early log
print. This patch try to initialize the serial card and related PCI
bridge to make it usable for xen.

Usage:

Step 1. boot into bare metal Linux, get the information for the PCI
serial ports and the related PCI bridge. On my case:

#lspci -v
00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev 90)
(prog-if 01     [Subtractive decode])
        Bus: primary=00, secondary=06, subordinate=06, sec-latency=32
        I/O behind bridge: 00005000-00005fff

06:02.0 Serial controller: Lava Computer mfg Inc Lava DSerial-PCI Port
A (prog-if 02 [16550])
        Region 0: I/O ports at 5000 [size=8]

Step 2. revise the grub.conf to include
'com1=115200,8n1,0xPPPP,0,<port-bdf>,<bridge-bdf> console=com1' for
xen cmdline. The 0xPPPP is the base I/O port address got for the
serial port in bare metal Linux. For my case, it is 0x5000. The 0
after 0xPPPP means enable polling model for the serial port. The
<port-bdf> is the serial port BDF, 06:02.0 in my case; the
<bridge-bdf> is the bridge BDF bebind which the serial card locates,
00:1e.0 for my case.

Signed-off-by: Wei Gang <gang.wei@xxxxxxxxx>
---
 xen/drivers/char/ns16550.c |   53 +++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 51 insertions(+), 2 deletions(-)

diff -r ebd84be3420a -r 589d075ba295 xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        Tue Mar 30 18:31:39 2010 +0100
+++ b/xen/drivers/char/ns16550.c        Wed Mar 31 10:11:41 2010 +0100
@@ -19,7 +19,7 @@
 
 /*
  * Configure serial port with a string:
- *   <baud>[/<clock_hz>][,DPS[,<io-base>[,<irq>]]].
+ *   <baud>[/<clock_hz>][,DPS[,<io-base>[,<irq>[,<port-bdf>[,<bridge-bdf>]]]]].
  * The tail of the string can be omitted if platform defaults are sufficient.
  * If the baud rate is pre-configured, perhaps by a bootloader, then 'auto'
  * can be specified in place of a numeric baud rate. Polled mode is specified
@@ -39,7 +39,12 @@ static struct ns16550 {
     /* UART with no IRQ line: periodically-polled I/O. */
     struct timer timer;
     unsigned int timeout_ms;
-    int probing, intr_works;
+    bool_t probing, intr_works;
+    /* PCI card parameters. */
+    unsigned int pb_bdf[3]; /* pci bridge BDF */
+    unsigned int ps_bdf[3]; /* pci serial port BDF */
+    bool_t pb_bdf_enable;   /* if =1, pb-bdf effective, port behind bridge */
+    bool_t ps_bdf_enable;   /* if =1, ps_bdf effective, port on pci card */
 } ns16550_com[2] = { { 0 } };
 
 /* Register offsets */
@@ -204,11 +209,28 @@ static int ns16550_getc(struct serial_po
     return 1;
 }
 
+static void pci_serial_early_init(struct ns16550 *uart)
+{
+    if ( !uart->ps_bdf_enable )
+        return;
+    
+    if ( uart->pb_bdf_enable )
+        pci_conf_write16(uart->pb_bdf[0], uart->pb_bdf[1], uart->pb_bdf[2],
+            0x1c, (uart->io_base & 0xF000) | ((uart->io_base & 0xF000) >> 8));
+
+    pci_conf_write32(uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
+        0x10, uart->io_base | 0x1);
+    pci_conf_write16(uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
+        0x4, 0x1);
+}
+
 static void __devinit ns16550_init_preirq(struct serial_port *port)
 {
     struct ns16550 *uart = port->uart;
     unsigned char lcr;
     unsigned int  divisor;
+
+    pci_serial_early_init(uart);
 
     /* I/O ports are distinguished by their size (16 bits). */
     if ( uart->io_base >= 0x10000 )
@@ -336,6 +358,19 @@ static int __init parse_parity_char(int 
     return 0;
 }
 
+static void __init parse_pci_bdf(const char **conf, unsigned int bdf[3])
+{
+    bdf[0] = simple_strtoul(*conf, conf, 16);
+    if ( **conf != ':' )
+        return;
+    (*conf)++;
+    bdf[1] = simple_strtoul(*conf, conf, 16);
+    if ( **conf != '.' )
+        return;
+    (*conf)++;
+    bdf[2] = simple_strtoul(*conf, conf, 16);
+}
+
 static int __init check_existence(struct ns16550 *uart)
 {
     unsigned char status, scratch, scratch2, scratch3;
@@ -347,6 +382,8 @@ static int __init check_existence(struct
     if ( uart->io_base >= 0x10000 )
         return 1;
 
+    pci_serial_early_init(uart);
+    
     /*
      * Do a simple existence test first; if we fail this,
      * there's no point trying anything else.
@@ -428,6 +465,18 @@ static void __init ns16550_parse_port_co
         {
             conf++;
             uart->irq = simple_strtoul(conf, &conf, 10);
+            if ( *conf == ',' )
+            {
+                conf++;
+                uart->ps_bdf_enable = 1;
+                parse_pci_bdf(&conf, &uart->ps_bdf[0]);
+                if ( *conf == ',' )
+                {
+                    conf++;
+                    uart->pb_bdf_enable = 1;
+                    parse_pci_bdf(&conf, &uart->pb_bdf[0]);
+                }
+            }
         }
     }
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] ns16550: enable PCI serial card usage, Xen patchbot-unstable <=