All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 0/8] xen/arm: initial cubieboard2 support.
@ 2013-09-13 16:01 Ian Campbell
  2013-09-13 16:04 ` [PATCH 1/8] xen/arm: Implement ioremap Ian Campbell
                   ` (8 more replies)
  0 siblings, 9 replies; 11+ messages in thread
From: Ian Campbell @ 2013-09-13 16:01 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, Ian Campbell, stefano.stabellini, julien.grall, tim,
	jbuelich, Josh Zhao

See http://www.gossamer-threads.com/lists/xen/devel/297170 for some
information on how to get this going.

I've rebased and addressed the review comments.

As before several of the patches are not to be applied because they can
be done better using infrastructure from Julien's "Allow Xen to boot
with a raw Device Tree" patch. They are included for completeness.

With this I can boot up until dom0 panics due to lack of a root
filesystem. This is because upstream Linux currently lacks any useful
storage drivers (SATA, USB host, MMC). Hopefully this will resolve
itself soon!

Despite this I think those patches which aren't marked as being not for
application can be applied as soon as people are happy with them. Hence
I've dropped the RFC. 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/8] xen/arm: Implement ioremap.
  2013-09-13 16:01 [PATCH RFC 0/8] xen/arm: initial cubieboard2 support Ian Campbell
@ 2013-09-13 16:04 ` Ian Campbell
  2013-09-13 16:04 ` [PATCH 3/8] ns16550: make usable on ARM Ian Campbell
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Ian Campbell @ 2013-09-13 16:04 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, Ian Campbell, stefano.stabellini, julien.grall, tim,
	jbeulich, Josh Zhao

Common code uses this, it expects an uncached mapping.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Reviewed-by: Julien Grall <julien.grall@linaro.org>
---
 xen/arch/arm/mm.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 69c157a..4521c8d 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -694,6 +694,11 @@ void *ioremap_attr(paddr_t pa, size_t len, unsigned int attributes)
     return (__vmap(&pfn, nr, 1, 1, attributes) + offs);
 }
 
+void *ioremap(paddr_t pa, size_t len)
+{
+    return ioremap_attr(pa, len, PAGE_HYPERVISOR_NOCACHE);
+}
+
 static int create_xen_table(lpae_t *entry)
 {
     void *p;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/8] ns16550: make usable on ARM
  2013-09-13 16:01 [PATCH RFC 0/8] xen/arm: initial cubieboard2 support Ian Campbell
  2013-09-13 16:04 ` [PATCH 1/8] xen/arm: Implement ioremap Ian Campbell
@ 2013-09-13 16:04 ` Ian Campbell
  2013-09-13 16:16   ` Jan Beulich
  2013-09-13 16:04 ` [PATCH 4/8] ns16550: support DesignWare 8250 Ian Campbell
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 11+ messages in thread
From: Ian Campbell @ 2013-09-13 16:04 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, Ian Campbell, stefano.stabellini, julien.grall, tim,
	jbeulich, Josh Zhao

There are several aspects to this:
- Correctly conditionalise use of PCI
- Correctly conditionalise use of IO ports
- Add discovery via device tree
- Support different registers shift/stride and widths
- Add vuart hooks.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Keir Frser <keir@xen.org>
Cc: jbeulich@suse.com
---
v2: Use __initdata
    Implement unknown register access sizes as write ignore, read all 1s.
    Coding style fixes
    Comment on reg_width meaning
    Fix ifdef placement
    io_size does not need 64-bits
---
 config/arm32.mk            |    1 +
 xen/Rules.mk               |    3 +
 xen/arch/x86/Rules.mk      |    1 +
 xen/drivers/char/ns16550.c |  193 +++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 186 insertions(+), 12 deletions(-)

diff --git a/config/arm32.mk b/config/arm32.mk
index 76e229d..aa79d22 100644
--- a/config/arm32.mk
+++ b/config/arm32.mk
@@ -12,6 +12,7 @@ CFLAGS += -marm
 HAS_PL011 := y
 HAS_EXYNOS4210 := y
 HAS_OMAP := y
+HAS_NS16550 := y
 
 # Use only if calling $(LD) directly.
 LDFLAGS_DIRECT += -EL
diff --git a/xen/Rules.mk b/xen/Rules.mk
index 736882a..df1428f 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -60,6 +60,9 @@ CFLAGS-$(lock_profile)  += -DLOCK_PROFILE
 CFLAGS-$(HAS_ACPI)      += -DHAS_ACPI
 CFLAGS-$(HAS_GDBSX)     += -DHAS_GDBSX
 CFLAGS-$(HAS_PASSTHROUGH) += -DHAS_PASSTHROUGH
+CFLAGS-$(HAS_DEVICE_TREE) += -DHAS_DEVICE_TREE
+CFLAGS-$(HAS_PCI)       += -DHAS_PCI
+CFLAGS-$(HAS_IOPORTS)   += -DHAS_IOPORTS
 CFLAGS-$(frame_pointer) += -fno-omit-frame-pointer -DCONFIG_FRAME_POINTER
 
 ifneq ($(max_phys_cpus),)
diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk
index eb11b5b..c93d2af 100644
--- a/xen/arch/x86/Rules.mk
+++ b/xen/arch/x86/Rules.mk
@@ -1,6 +1,7 @@
 ########################################
 # x86-specific definitions
 
+HAS_IOPORTS := y
 HAS_ACPI := y
 HAS_VGA  := y
 HAS_VIDEO  := y
diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index e0f80f6..45da924 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -13,14 +13,19 @@
 #include <xen/init.h>
 #include <xen/irq.h>
 #include <xen/sched.h>
-#include <xen/pci.h>
 #include <xen/timer.h>
 #include <xen/serial.h>
 #include <xen/iocap.h>
+#ifdef HAS_PCI
 #include <xen/pci.h>
 #include <xen/pci_regs.h>
+#endif
 #include <xen/8250-uart.h>
+#include <xen/vmap.h>
 #include <asm/io.h>
+#ifdef HAS_DEVICE_TREE
+#include <asm/device.h>
+#endif
 #ifdef CONFIG_X86
 #include <asm/fixmap.h>
 #endif
@@ -40,15 +45,23 @@ string_param("com2", opt_com2);
 
 static struct ns16550 {
     int baud, clock_hz, data_bits, parity, stop_bits, fifo_size, irq;
-    unsigned long io_base;   /* I/O port or memory-mapped I/O address. */
+    u64 io_base;   /* I/O port or memory-mapped I/O address. */
+    u32 io_size;
+    int reg_shift; /* Bits to shift register offset by */
+    int reg_width; /* Size of access to use, the registers
+                    * themselves are still bytes */
     char __iomem *remapped_io_base;  /* Remapped virtual address of MMIO. */
     /* UART with IRQ line: interrupt-driven I/O. */
     struct irqaction irqaction;
+#ifdef CONFIG_ARM
+    struct vuart_info vuart;
+#endif
     /* UART with no IRQ line: periodically-polled I/O. */
     struct timer timer;
     struct timer resume_timer;
     unsigned int timeout_ms;
     bool_t intr_works;
+#ifdef HAS_PCI
     /* PCI card parameters. */
     unsigned int pb_bdf[3]; /* pci bridge BDF */
     unsigned int ps_bdf[3]; /* pci serial port BDF */
@@ -57,22 +70,51 @@ static struct ns16550 {
     u32 bar;
     u16 cr;
     u8 bar_idx;
+#endif
+#ifdef HAS_DEVICE_TREE
+    struct dt_irq dt_irq;
+#endif
 } ns16550_com[2] = { { 0 } };
 
 static void ns16550_delayed_resume(void *data);
 
 static char ns_read_reg(struct ns16550 *uart, int reg)
 {
+    void __iomem *addr = uart->remapped_io_base + (reg << uart->reg_shift);
+#ifdef HAS_IOPORTS
     if ( uart->remapped_io_base == NULL )
         return inb(uart->io_base + reg);
-    return readb(uart->remapped_io_base + reg);
+#endif
+    switch ( uart->reg_width )
+    {
+    case 1:
+        return readb(addr);
+    case 4:
+        return readl(addr);
+    default:
+        return 0xff;
+    }
 }
 
 static void ns_write_reg(struct ns16550 *uart, int reg, char c)
 {
+    void __iomem *addr = uart->remapped_io_base + (reg << uart->reg_shift);
+#ifdef HAS_IOPORTS
     if ( uart->remapped_io_base == NULL )
         return outb(c, uart->io_base + reg);
-    writeb(c, uart->remapped_io_base + reg);
+#endif
+    switch ( uart->reg_width )
+    {
+    case 1:
+        writeb(c, addr);
+        break;
+    case 4:
+        writel(c, addr);
+        break;
+    default:
+        /* Ignored */
+        break;
+    }
 }
 
 static int ns16550_ioport_invalid(struct ns16550 *uart)
@@ -163,9 +205,10 @@ static int ns16550_getc(struct serial_port *port, char *pc)
 
 static void pci_serial_early_init(struct ns16550 *uart)
 {
+#ifdef HAS_PCI
     if ( !uart->ps_bdf_enable || uart->io_base >= 0x10000 )
         return;
-    
+
     if ( uart->pb_bdf_enable )
         pci_conf_write16(0, uart->pb_bdf[0], uart->pb_bdf[1], uart->pb_bdf[2],
                          PCI_IO_BASE,
@@ -177,6 +220,7 @@ static void pci_serial_early_init(struct ns16550 *uart)
                      uart->io_base | PCI_BASE_ADDRESS_SPACE_IO);
     pci_conf_write16(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
                      PCI_COMMAND, PCI_COMMAND_IO);
+#endif
 }
 
 static void ns16550_setup_preirq(struct ns16550 *uart)
@@ -223,8 +267,10 @@ static void __init ns16550_init_preirq(struct serial_port *port)
 {
     struct ns16550 *uart = port->uart;
 
+#ifdef HAS_IOPORTS
     /* I/O ports are distinguished by their size (16 bits). */
     if ( uart->io_base >= 0x10000 )
+#endif
     {
 #ifdef CONFIG_X86
         enum fixed_addresses idx = FIX_COM_BEGIN + (uart - ns16550_com);
@@ -233,7 +279,7 @@ static void __init ns16550_init_preirq(struct serial_port *port)
         uart->remapped_io_base = (void __iomem *)fix_to_virt(idx);
         uart->remapped_io_base += uart->io_base & ~PAGE_MASK;
 #else
-        uart->remapped_io_base = (char *)ioremap(uart->io_base, 8);
+        uart->remapped_io_base = (char *)ioremap(uart->io_base, uart->io_size);
 #endif
     }
 
@@ -284,15 +330,22 @@ static void __init ns16550_init_postirq(struct serial_port *port)
         uart->irqaction.handler = ns16550_interrupt;
         uart->irqaction.name    = "ns16550";
         uart->irqaction.dev_id  = port;
+#ifdef HAS_DEVICE_TREE
+        if ( (rc = setup_dt_irq(&uart->dt_irq, &uart->irqaction)) != 0 )
+            printk("ERROR: Failed to allocate ns16550 DT IRQ.\n");
+#else
         if ( (rc = setup_irq(uart->irq, &uart->irqaction)) != 0 )
             printk("ERROR: Failed to allocate ns16550 IRQ %d\n", uart->irq);
+#endif
     }
 
     ns16550_setup_postirq(uart);
 
+#ifdef HAS_PCI
     if ( uart->bar || uart->ps_bdf_enable )
         pci_hide_device(uart->ps_bdf[0], PCI_DEVFN(uart->ps_bdf[1],
                                                    uart->ps_bdf[2]));
+#endif
 }
 
 static void ns16550_suspend(struct serial_port *port)
@@ -301,13 +354,16 @@ static void ns16550_suspend(struct serial_port *port)
 
     stop_timer(&uart->timer);
 
+#ifdef HAS_PCI
     if ( uart->bar )
        uart->cr = pci_conf_read16(0, uart->ps_bdf[0], uart->ps_bdf[1],
                                   uart->ps_bdf[2], PCI_COMMAND);
+#endif
 }
 
 static void _ns16550_resume(struct serial_port *port)
 {
+#ifdef HAS_PCI
     struct ns16550 *uart = port->uart;
 
     if ( uart->bar )
@@ -317,6 +373,7 @@ static void _ns16550_resume(struct serial_port *port)
        pci_conf_write16(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
                         PCI_COMMAND, uart->cr);
     }
+#endif
 
     ns16550_setup_preirq(port->uart);
     ns16550_setup_postirq(port->uart);
@@ -360,19 +417,17 @@ static void ns16550_resume(struct serial_port *port)
         _ns16550_resume(port);
 }
 
-#ifdef CONFIG_X86
 static void __init ns16550_endboot(struct serial_port *port)
 {
+#ifdef HAS_IOPORTS
     struct ns16550 *uart = port->uart;
 
     if ( uart->remapped_io_base )
         return;
     if ( ioports_deny_access(dom0, uart->io_base, uart->io_base + 7) != 0 )
         BUG();
-}
-#else
-#define ns16550_endboot NULL
 #endif
+}
 
 static int __init ns16550_irq(struct serial_port *port)
 {
@@ -380,6 +435,23 @@ static int __init ns16550_irq(struct serial_port *port)
     return ((uart->irq > 0) ? uart->irq : -1);
 }
 
+#ifdef HAS_DEVICE_TREE
+static const struct dt_irq __init *ns16550_dt_irq(struct serial_port *port)
+{
+    struct ns16550 *uart = port->uart;
+    return &uart->dt_irq;
+}
+#endif
+
+#ifdef CONFIG_ARM
+static const struct vuart_info *ns16550_vuart_info(struct serial_port *port)
+{
+    struct ns16550 *uart = port->uart;
+
+    return &uart->vuart;
+}
+#endif
+
 static struct uart_driver __read_mostly ns16550_driver = {
     .init_preirq  = ns16550_init_preirq,
     .init_postirq = ns16550_init_postirq,
@@ -389,7 +461,13 @@ static struct uart_driver __read_mostly ns16550_driver = {
     .tx_ready     = ns16550_tx_ready,
     .putc         = ns16550_putc,
     .getc         = ns16550_getc,
-    .irq          = ns16550_irq
+    .irq          = ns16550_irq,
+#ifdef HAS_DEVICE_TREE
+    .dt_irq_get   = ns16550_dt_irq,
+#endif
+#ifdef CONFIG_ARM
+    .vuart_info   = ns16550_vuart_info,
+#endif
 };
 
 static int __init parse_parity_char(int c)
@@ -414,15 +492,21 @@ static int __init check_existence(struct ns16550 *uart)
 {
     unsigned char status, scratch, scratch2, scratch3;
 
+#ifdef HAS_IO_PORTS
     /*
      * We can't poke MMIO UARTs until they get I/O remapped later. Assume that
      * if we're getting MMIO UARTs, the arch code knows what it's doing.
      */
     if ( uart->io_base >= 0x10000 )
         return 1;
+#else
+    return 1; /* Everything is MMIO */
+#endif
 
+#ifdef HAS_PCI
     pci_serial_early_init(uart);
-    
+#endif
+
     /*
      * Do a simple existence test first; if we fail this,
      * there's no point trying anything else.
@@ -450,6 +534,7 @@ static int __init check_existence(struct ns16550 *uart)
     return (status == 0x90);
 }
 
+#ifdef HAS_PCI
 static int
 pci_uart_config (struct ns16550 *uart, int skip_amt, int bar_idx)
 {
@@ -518,6 +603,7 @@ pci_uart_config (struct ns16550 *uart, int skip_amt, int bar_idx)
 
     return 0;
 }
+#endif
 
 #define PARSE_ERR(_f, _a...)                 \
     do {                                     \
@@ -564,6 +650,7 @@ static void __init ns16550_parse_port_config(
 
     if ( *conf == ',' && *++conf != ',' )
     {
+#ifdef HAS_PCI
         if ( strncmp(conf, "pci", 3) == 0 )
         {
             if ( pci_uart_config(uart, 1/* skip AMT */, uart - ns16550_com) )
@@ -577,6 +664,7 @@ static void __init ns16550_parse_port_config(
             conf += 3;
         }
         else
+#endif
         {
             uart->io_base = simple_strtoul(conf, &conf, 0);
         }
@@ -585,6 +673,7 @@ static void __init ns16550_parse_port_config(
     if ( *conf == ',' && *++conf != ',' )
         uart->irq = simple_strtol(conf, &conf, 10);
 
+#ifdef HAS_PCI
     if ( *conf == ',' && *++conf != ',' )
     {
         conf = parse_pci(conf, NULL, &uart->ps_bdf[0],
@@ -601,6 +690,7 @@ static void __init ns16550_parse_port_config(
             PARSE_ERR("Bad bridge PCI coordinates");
         uart->pb_bdf_enable = 1;
     }
+#endif
 
  config_parsed:
     /* Sanity checks. */
@@ -638,12 +728,91 @@ void __init ns16550_init(int index, struct ns16550_defaults *defaults)
     uart->stop_bits = defaults->stop_bits;
     uart->irq       = defaults->irq;
     uart->io_base   = defaults->io_base;
+    uart->io_size   = 8;
+    uart->reg_width = 1;
+    uart->reg_shift = 0;
+
     /* Default is no transmit FIFO. */
     uart->fifo_size = 1;
 
     ns16550_parse_port_config(uart, (index == 0) ? opt_com1 : opt_com2);
 }
 
+#ifdef HAS_DEVICE_TREE
+static int __init ns16550_uart_dt_init(struct dt_device_node *dev,
+                                       const void *data)
+{
+    struct ns16550 *uart;
+    int res;
+    u32 reg_shift, reg_width;
+    u64 io_size;
+
+    uart = &ns16550_com[0];
+
+    uart->baud      = BAUD_AUTO;
+    uart->clock_hz  = UART_CLOCK_HZ;
+    uart->data_bits = 8;
+    uart->parity    = UART_PARITY_NONE;
+    uart->stop_bits = 1;
+    /* Default is no transmit FIFO. */
+    uart->fifo_size = 1;
+
+    res = dt_device_get_address(dev, 0, &uart->io_base, &io_size);
+    if ( res )
+        return res;
+
+    uart->io_size = io_size;
+
+    ASSERT(uart->io_size == io_size); /* Detect truncation */
+
+    res = dt_property_read_u32(dev, "reg-shift", &reg_shift);
+    if ( !res )
+        uart->reg_shift = 0;
+    else
+        uart->reg_shift = reg_shift;
+
+    res = dt_property_read_u32(dev, "reg-io-width", &reg_width);
+    if ( !res )
+        uart->reg_width = 1;
+    else
+        uart->reg_width = reg_width;
+
+    if ( uart->reg_width != 1 && uart->reg_width != 4 )
+        return -EINVAL;
+
+    res = dt_device_get_irq(dev, 0, &uart->dt_irq);
+    if ( res )
+        return res;
+
+    /* The common bit of the driver mostly deals with irq not dt_irq. */
+    uart->irq = uart->dt_irq.irq;
+
+    uart->vuart.base_addr = uart->io_base;
+    uart->vuart.size = uart->io_size;
+    uart->vuart.data_off = UART_THR <<uart->reg_shift;
+    uart->vuart.status_off = UART_LSR<<uart->reg_shift;
+    uart->vuart.status = UART_LSR_THRE|UART_LSR_TEMT;
+
+    /* Register with generic serial driver. */
+    serial_register_uart(uart - ns16550_com, &ns16550_driver, uart);
+
+    dt_device_set_used_by(dev, DOMID_XEN);
+
+    return 0;
+}
+
+static const char const *ns16550_dt_compat[] __initconst =
+{
+    "ns16550",
+    NULL
+};
+
+DT_DEVICE_START(ns16550, "NS16550 UART", DEVICE_SERIAL)
+        .compatible = ns16550_dt_compat,
+        .init = ns16550_uart_dt_init,
+DT_DEVICE_END
+
+#endif /* HAS_DEVICE_TREE */
 /*
  * Local variables:
  * mode: C
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/8] ns16550: support DesignWare 8250
  2013-09-13 16:01 [PATCH RFC 0/8] xen/arm: initial cubieboard2 support Ian Campbell
  2013-09-13 16:04 ` [PATCH 1/8] xen/arm: Implement ioremap Ian Campbell
  2013-09-13 16:04 ` [PATCH 3/8] ns16550: make usable on ARM Ian Campbell
@ 2013-09-13 16:04 ` Ian Campbell
  2013-09-13 16:04 ` [PATCH 5/8] xen/arm: Support Cortex-A7 GIC Ian Campbell
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Ian Campbell @ 2013-09-13 16:04 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, Ian Campbell, stefano.stabellini, julien.grall, tim,
	jbeulich, Josh Zhao

This hardware has an additional feature which signals an error if you try to
write LCR while the UART is busy. We need to clear this error during setup,
otherwise LCR.DLAB doesn't get set and we cannot read/write the divisor.

This has been tested on the cubieboard2

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Keir Fraser <keir@xen.org>
Cc: jbeulich@suse.com
---
v2: Remove pointless cast.
---
 xen/drivers/char/ns16550.c  |   14 ++++++++++++++
 xen/include/xen/8250-uart.h |    2 ++
 2 files changed, 16 insertions(+)

diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 45da924..5892eb7 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -61,6 +61,7 @@ static struct ns16550 {
     struct timer resume_timer;
     unsigned int timeout_ms;
     bool_t intr_works;
+    bool_t dw_usr_bsy;
 #ifdef HAS_PCI
     /* PCI card parameters. */
     unsigned int pb_bdf[3]; /* pci bridge BDF */
@@ -237,6 +238,16 @@ static void ns16550_setup_preirq(struct ns16550 *uart)
     /* No interrupts. */
     ns_write_reg(uart, UART_IER, 0);
 
+    if ( uart->dw_usr_bsy &&
+         (ns_read_reg(uart, UART_IIR) & UART_IIR_BSY) == UART_IIR_BSY )
+    {
+        /* DesignWare 8250 detects if LCR is written while the UART is
+         * busy and raises a "busy detect" interrupt. Read the UART
+         * Status Register to clear this state.
+         */
+        ns_read_reg(uart, UART_USR);
+    }
+
     /* Line control and baud-rate generator. */
     ns_write_reg(uart, UART_LCR, lcr | UART_LCR_DLAB);
     if ( uart->baud != BAUD_AUTO )
@@ -787,6 +798,8 @@ static int __init ns16550_uart_dt_init(struct dt_device_node *dev,
     /* The common bit of the driver mostly deals with irq not dt_irq. */
     uart->irq = uart->dt_irq.irq;
 
+    uart->dw_usr_bsy = dt_device_is_compatible(dev, "snps,dw-apb-uart");
+
     uart->vuart.base_addr = uart->io_base;
     uart->vuart.size = uart->io_size;
     uart->vuart.data_off = UART_THR <<uart->reg_shift;
@@ -804,6 +817,7 @@ static int __init ns16550_uart_dt_init(struct dt_device_node *dev,
 static const char const *ns16550_dt_compat[] __initconst =
 {
     "ns16550",
+    "snps,dw-apb-uart",
     NULL
 };
 
diff --git a/xen/include/xen/8250-uart.h b/xen/include/xen/8250-uart.h
index 8693d15..a682bae 100644
--- a/xen/include/xen/8250-uart.h
+++ b/xen/include/xen/8250-uart.h
@@ -32,6 +32,7 @@
 #define UART_MCR          0x04    /* Modem control        */
 #define UART_LSR          0x05    /* line status          */
 #define UART_MSR          0x06    /* Modem status         */
+#define UART_USR          0x1f    /* Status register (DW) */
 #define UART_DLL          0x00    /* divisor latch (ls) (DLAB=1) */
 #define UART_DLM          0x01    /* divisor latch (ms) (DLAB=1) */
 
@@ -48,6 +49,7 @@
 #define UART_IIR_RDA      0x04    /*  - rx data recv'd    */
 #define UART_IIR_THR      0x02    /*  - tx reg. empty     */
 #define UART_IIR_MSI      0x00    /*  - MODEM status      */
+#define UART_IIR_BSY      0x07    /*  - busy detect (DW) */
 
 /* FIFO Control Register */
 #define UART_FCR_ENABLE   0x01    /* enable FIFO          */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/8] xen/arm: Support Cortex-A7 GIC
  2013-09-13 16:01 [PATCH RFC 0/8] xen/arm: initial cubieboard2 support Ian Campbell
                   ` (2 preceding siblings ...)
  2013-09-13 16:04 ` [PATCH 4/8] ns16550: support DesignWare 8250 Ian Campbell
@ 2013-09-13 16:04 ` Ian Campbell
  2013-09-13 16:04 ` [PATCH 6/8] xen/arm: Basic support for sunxi/sun7i platform Ian Campbell
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Ian Campbell @ 2013-09-13 16:04 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, Ian Campbell, stefano.stabellini, julien.grall, tim,
	jbeulich, Josh Zhao

NB: NOT TO BE APPLIED

Julien has a patch to make this use a match list. This should be rebased onto
that.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/gic.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 7c24811..ab0f00d 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -360,6 +360,8 @@ void __init gic_init(void)
 
     node = dt_find_interrupt_controller("arm,cortex-a15-gic");
     if ( !node )
+        node = dt_find_interrupt_controller("arm,cortex-a7-gic");
+    if ( !node )
         panic("Unable to find compatible GIC in the device tree\n");
 
     dt_device_set_used_by(node, DOMID_XEN);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/8] xen/arm: Basic support for sunxi/sun7i platform.
  2013-09-13 16:01 [PATCH RFC 0/8] xen/arm: initial cubieboard2 support Ian Campbell
                   ` (3 preceding siblings ...)
  2013-09-13 16:04 ` [PATCH 5/8] xen/arm: Support Cortex-A7 GIC Ian Campbell
@ 2013-09-13 16:04 ` Ian Campbell
  2013-09-13 16:04 ` [PATCH 7/8] xen/arm: Blacklist some sun7i UARTs Ian Campbell
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Ian Campbell @ 2013-09-13 16:04 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, Ian Campbell, stefano.stabellini, julien.grall, tim,
	jbeulich, Josh Zhao

Specifically cubieboard2

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/platforms/Makefile |    1 +
 xen/arch/arm/platforms/sunxi.c  |   42 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)
 create mode 100644 xen/arch/arm/platforms/sunxi.c

diff --git a/xen/arch/arm/platforms/Makefile b/xen/arch/arm/platforms/Makefile
index 4aa82e8..8c77ace 100644
--- a/xen/arch/arm/platforms/Makefile
+++ b/xen/arch/arm/platforms/Makefile
@@ -2,3 +2,4 @@ obj-y += vexpress.o
 obj-y += exynos5.o
 obj-y += midway.o
 obj-y += omap5.o
+obj-y += sunxi.o
diff --git a/xen/arch/arm/platforms/sunxi.c b/xen/arch/arm/platforms/sunxi.c
new file mode 100644
index 0000000..ee0f39b
--- /dev/null
+++ b/xen/arch/arm/platforms/sunxi.c
@@ -0,0 +1,42 @@
+/*
+ * xen/arch/arm/platforms/sunxi.c
+ *
+ * SUNXI (AllWinner A20/A31) specific settings
+ *
+ * Copyright (c) 2013 Citrix Systems.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <asm/p2m.h>
+#include <xen/config.h>
+#include <asm/platform.h>
+#include <xen/mm.h>
+#include <xen/device_tree.h>
+
+static const char const *sunxi_dt_compat[] __initdata =
+{
+    "allwinner,sun7i-a20",
+    NULL
+};
+
+PLATFORM_START(sunxi, "Allwinner A20")
+    .compatible = sunxi_dt_compat,
+PLATFORM_END
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 7/8] xen/arm: Blacklist some sun7i UARTs
  2013-09-13 16:01 [PATCH RFC 0/8] xen/arm: initial cubieboard2 support Ian Campbell
                   ` (4 preceding siblings ...)
  2013-09-13 16:04 ` [PATCH 6/8] xen/arm: Basic support for sunxi/sun7i platform Ian Campbell
@ 2013-09-13 16:04 ` Ian Campbell
  2013-09-13 16:04 ` [PATCH 8/8] xen/arm: Some early trap logging Ian Campbell
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Ian Campbell @ 2013-09-13 16:04 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, Ian Campbell, stefano.stabellini, julien.grall, tim,
	jbeulich, Josh Zhao

These are in the same page as the UART which is used as the Xen console. We are
not currently smart enough to avoid passing them through to the guest,
accidentally giving the guest access to the Xen console UART.

NOT TO BE APPLIED: Short term this should use Juliens forthcoming platform
blacklist patch. Long term we need to be much cleverer about devices which
share the same MMIO page...

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/platforms/sunxi.c |   31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/xen/arch/arm/platforms/sunxi.c b/xen/arch/arm/platforms/sunxi.c
index ee0f39b..4252580 100644
--- a/xen/arch/arm/platforms/sunxi.c
+++ b/xen/arch/arm/platforms/sunxi.c
@@ -22,6 +22,36 @@
 #include <xen/mm.h>
 #include <xen/device_tree.h>
 
+static int hide_by_name(const char *name)
+{
+    struct dt_device_node *n;
+
+    n = dt_find_node_by_path(name);
+    if ( !n )
+    {
+        printk("Unable to find %s to hide\n", name);
+        return -ENODEV;
+    }
+    dt_device_set_used_by(n, DOMID_XEN);
+    return 0;
+}
+
+static int sunxi_init(void)
+{
+    int rc;
+
+    if ( (rc = hide_by_name("/soc@01c00000/serial@01c28000")) < 0 )
+        return rc;
+    if ( (rc = hide_by_name("/soc@01c00000/serial@01c28400")) < 0 )
+        return rc;
+    if ( (rc = hide_by_name("/soc@01c00000/serial@01c28800")) < 0 )
+        return rc;
+    if ( (rc = hide_by_name("/soc@01c00000/serial@01c28c00")) < 0 )
+        return rc;
+
+    return 0;
+}
+
 static const char const *sunxi_dt_compat[] __initdata =
 {
     "allwinner,sun7i-a20",
@@ -30,6 +60,7 @@ static const char const *sunxi_dt_compat[] __initdata =
 
 PLATFORM_START(sunxi, "Allwinner A20")
     .compatible = sunxi_dt_compat,
+    .init = sunxi_init,
 PLATFORM_END
 
 /*
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 8/8] xen/arm: Some early trap logging
  2013-09-13 16:01 [PATCH RFC 0/8] xen/arm: initial cubieboard2 support Ian Campbell
                   ` (5 preceding siblings ...)
  2013-09-13 16:04 ` [PATCH 7/8] xen/arm: Blacklist some sun7i UARTs Ian Campbell
@ 2013-09-13 16:04 ` Ian Campbell
  2013-09-13 16:43 ` [PATCH RFC 0/8] xen/arm: initial cubieboard2 support Julien Grall
       [not found] ` <1379088247-29325-2-git-send-email-ian.campbell@citrix.com>
  8 siblings, 0 replies; 11+ messages in thread
From: Ian Campbell @ 2013-09-13 16:04 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, Ian Campbell, stefano.stabellini, julien.grall, tim,
	jbeulich, Josh Zhao

Not for really for application, might be useful to someone?

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/arm32/head.S |   15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S
index 79e95b6..06d53ad 100644
--- a/xen/arch/arm/arm32/head.S
+++ b/xen/arch/arm/arm32/head.S
@@ -366,6 +366,9 @@ paging:
         bne   1b
 
 launch:
+        adr   r0, early_trap_vector
+        mcr   CP32(r0, VBAR_EL2)
+        
         ldr   r0, =init_stack        /* Find the boot-time stack */
         ldr   sp, [r0]
         add   sp, #STACK_SIZE        /* (which grows down from the top). */
@@ -376,12 +379,24 @@ launch:
         beq   start_xen              /* and disappear into the land of C */
         b     start_secondary        /* (to the appropriate entry point) */
 
+trap_early:
+        PRINT("\r\nEARLY TRAP\r\n")
 /* Fail-stop
  * r0: string explaining why */
 fail:   PRINT("- Boot failed -\r\n")
 1:      wfe
         b     1b
 
+        .align 5
+early_trap_vector:
+        .word 0                         /* 0x00 - Reset */
+        b trap_early                    /* 0x04 - Undefined Instruction */
+        b trap_early                    /* 0x08 - Supervisor Call */
+        b trap_early                    /* 0x0c - Prefetch Abort */
+        b trap_early                    /* 0x10 - Data Abort */
+        b trap_early                    /* 0x14 - Hypervisor */
+        b trap_early                    /* 0x18 - IRQ */
+        b trap_early                    /* 0x1c - FIQ */
 
 #ifdef EARLY_PRINTK
 /* Bring up the UART.
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/8] ns16550: make usable on ARM
  2013-09-13 16:04 ` [PATCH 3/8] ns16550: make usable on ARM Ian Campbell
@ 2013-09-13 16:16   ` Jan Beulich
  0 siblings, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2013-09-13 16:16 UTC (permalink / raw)
  To: Ian Campbell
  Cc: keir, stefano.stabellini, julien.grall, tim, Josh Zhao, xen-devel

>>> On 13.09.13 at 18:04, Ian Campbell <ian.campbell@citrix.com> wrote:
> There are several aspects to this:
> - Correctly conditionalise use of PCI
> - Correctly conditionalise use of IO ports
> - Add discovery via device tree
> - Support different registers shift/stride and widths
> - Add vuart hooks.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> Acked-by: Keir Frser <keir@xen.org>

Reviewed-by: Jan Beulich <jbeulich@suse.com>

> ---
> v2: Use __initdata
>     Implement unknown register access sizes as write ignore, read all 1s.
>     Coding style fixes
>     Comment on reg_width meaning
>     Fix ifdef placement
>     io_size does not need 64-bits
> ---
>  config/arm32.mk            |    1 +
>  xen/Rules.mk               |    3 +
>  xen/arch/x86/Rules.mk      |    1 +
>  xen/drivers/char/ns16550.c |  193 +++++++++++++++++++++++++++++++++++++++++---
>  4 files changed, 186 insertions(+), 12 deletions(-)
> 
> diff --git a/config/arm32.mk b/config/arm32.mk
> index 76e229d..aa79d22 100644
> --- a/config/arm32.mk
> +++ b/config/arm32.mk
> @@ -12,6 +12,7 @@ CFLAGS += -marm
>  HAS_PL011 := y
>  HAS_EXYNOS4210 := y
>  HAS_OMAP := y
> +HAS_NS16550 := y
>  
>  # Use only if calling $(LD) directly.
>  LDFLAGS_DIRECT += -EL
> diff --git a/xen/Rules.mk b/xen/Rules.mk
> index 736882a..df1428f 100644
> --- a/xen/Rules.mk
> +++ b/xen/Rules.mk
> @@ -60,6 +60,9 @@ CFLAGS-$(lock_profile)  += -DLOCK_PROFILE
>  CFLAGS-$(HAS_ACPI)      += -DHAS_ACPI
>  CFLAGS-$(HAS_GDBSX)     += -DHAS_GDBSX
>  CFLAGS-$(HAS_PASSTHROUGH) += -DHAS_PASSTHROUGH
> +CFLAGS-$(HAS_DEVICE_TREE) += -DHAS_DEVICE_TREE
> +CFLAGS-$(HAS_PCI)       += -DHAS_PCI
> +CFLAGS-$(HAS_IOPORTS)   += -DHAS_IOPORTS
>  CFLAGS-$(frame_pointer) += -fno-omit-frame-pointer -DCONFIG_FRAME_POINTER
>  
>  ifneq ($(max_phys_cpus),)
> diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk
> index eb11b5b..c93d2af 100644
> --- a/xen/arch/x86/Rules.mk
> +++ b/xen/arch/x86/Rules.mk
> @@ -1,6 +1,7 @@
>  ########################################
>  # x86-specific definitions
>  
> +HAS_IOPORTS := y
>  HAS_ACPI := y
>  HAS_VGA  := y
>  HAS_VIDEO  := y
> diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
> index e0f80f6..45da924 100644
> --- a/xen/drivers/char/ns16550.c
> +++ b/xen/drivers/char/ns16550.c
> @@ -13,14 +13,19 @@
>  #include <xen/init.h>
>  #include <xen/irq.h>
>  #include <xen/sched.h>
> -#include <xen/pci.h>
>  #include <xen/timer.h>
>  #include <xen/serial.h>
>  #include <xen/iocap.h>
> +#ifdef HAS_PCI
>  #include <xen/pci.h>
>  #include <xen/pci_regs.h>
> +#endif
>  #include <xen/8250-uart.h>
> +#include <xen/vmap.h>
>  #include <asm/io.h>
> +#ifdef HAS_DEVICE_TREE
> +#include <asm/device.h>
> +#endif
>  #ifdef CONFIG_X86
>  #include <asm/fixmap.h>
>  #endif
> @@ -40,15 +45,23 @@ string_param("com2", opt_com2);
>  
>  static struct ns16550 {
>      int baud, clock_hz, data_bits, parity, stop_bits, fifo_size, irq;
> -    unsigned long io_base;   /* I/O port or memory-mapped I/O address. */
> +    u64 io_base;   /* I/O port or memory-mapped I/O address. */
> +    u32 io_size;
> +    int reg_shift; /* Bits to shift register offset by */
> +    int reg_width; /* Size of access to use, the registers
> +                    * themselves are still bytes */
>      char __iomem *remapped_io_base;  /* Remapped virtual address of MMIO. 
> */
>      /* UART with IRQ line: interrupt-driven I/O. */
>      struct irqaction irqaction;
> +#ifdef CONFIG_ARM
> +    struct vuart_info vuart;
> +#endif
>      /* UART with no IRQ line: periodically-polled I/O. */
>      struct timer timer;
>      struct timer resume_timer;
>      unsigned int timeout_ms;
>      bool_t intr_works;
> +#ifdef HAS_PCI
>      /* PCI card parameters. */
>      unsigned int pb_bdf[3]; /* pci bridge BDF */
>      unsigned int ps_bdf[3]; /* pci serial port BDF */
> @@ -57,22 +70,51 @@ static struct ns16550 {
>      u32 bar;
>      u16 cr;
>      u8 bar_idx;
> +#endif
> +#ifdef HAS_DEVICE_TREE
> +    struct dt_irq dt_irq;
> +#endif
>  } ns16550_com[2] = { { 0 } };
>  
>  static void ns16550_delayed_resume(void *data);
>  
>  static char ns_read_reg(struct ns16550 *uart, int reg)
>  {
> +    void __iomem *addr = uart->remapped_io_base + (reg << uart->reg_shift);
> +#ifdef HAS_IOPORTS
>      if ( uart->remapped_io_base == NULL )
>          return inb(uart->io_base + reg);
> -    return readb(uart->remapped_io_base + reg);
> +#endif
> +    switch ( uart->reg_width )
> +    {
> +    case 1:
> +        return readb(addr);
> +    case 4:
> +        return readl(addr);
> +    default:
> +        return 0xff;
> +    }
>  }
>  
>  static void ns_write_reg(struct ns16550 *uart, int reg, char c)
>  {
> +    void __iomem *addr = uart->remapped_io_base + (reg << uart->reg_shift);
> +#ifdef HAS_IOPORTS
>      if ( uart->remapped_io_base == NULL )
>          return outb(c, uart->io_base + reg);
> -    writeb(c, uart->remapped_io_base + reg);
> +#endif
> +    switch ( uart->reg_width )
> +    {
> +    case 1:
> +        writeb(c, addr);
> +        break;
> +    case 4:
> +        writel(c, addr);
> +        break;
> +    default:
> +        /* Ignored */
> +        break;
> +    }
>  }
>  
>  static int ns16550_ioport_invalid(struct ns16550 *uart)
> @@ -163,9 +205,10 @@ static int ns16550_getc(struct serial_port *port, char 
> *pc)
>  
>  static void pci_serial_early_init(struct ns16550 *uart)
>  {
> +#ifdef HAS_PCI
>      if ( !uart->ps_bdf_enable || uart->io_base >= 0x10000 )
>          return;
> -    
> +
>      if ( uart->pb_bdf_enable )
>          pci_conf_write16(0, uart->pb_bdf[0], uart->pb_bdf[1], uart->pb_bdf[2],
>                           PCI_IO_BASE,
> @@ -177,6 +220,7 @@ static void pci_serial_early_init(struct ns16550 *uart)
>                       uart->io_base | PCI_BASE_ADDRESS_SPACE_IO);
>      pci_conf_write16(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
>                       PCI_COMMAND, PCI_COMMAND_IO);
> +#endif
>  }
>  
>  static void ns16550_setup_preirq(struct ns16550 *uart)
> @@ -223,8 +267,10 @@ static void __init ns16550_init_preirq(struct 
> serial_port *port)
>  {
>      struct ns16550 *uart = port->uart;
>  
> +#ifdef HAS_IOPORTS
>      /* I/O ports are distinguished by their size (16 bits). */
>      if ( uart->io_base >= 0x10000 )
> +#endif
>      {
>  #ifdef CONFIG_X86
>          enum fixed_addresses idx = FIX_COM_BEGIN + (uart - ns16550_com);
> @@ -233,7 +279,7 @@ static void __init ns16550_init_preirq(struct serial_port 
> *port)
>          uart->remapped_io_base = (void __iomem *)fix_to_virt(idx);
>          uart->remapped_io_base += uart->io_base & ~PAGE_MASK;
>  #else
> -        uart->remapped_io_base = (char *)ioremap(uart->io_base, 8);
> +        uart->remapped_io_base = (char *)ioremap(uart->io_base, uart->io_size);
>  #endif
>      }
>  
> @@ -284,15 +330,22 @@ static void __init ns16550_init_postirq(struct 
> serial_port *port)
>          uart->irqaction.handler = ns16550_interrupt;
>          uart->irqaction.name    = "ns16550";
>          uart->irqaction.dev_id  = port;
> +#ifdef HAS_DEVICE_TREE
> +        if ( (rc = setup_dt_irq(&uart->dt_irq, &uart->irqaction)) != 0 )
> +            printk("ERROR: Failed to allocate ns16550 DT IRQ.\n");
> +#else
>          if ( (rc = setup_irq(uart->irq, &uart->irqaction)) != 0 )
>              printk("ERROR: Failed to allocate ns16550 IRQ %d\n", uart->irq);
> +#endif
>      }
>  
>      ns16550_setup_postirq(uart);
>  
> +#ifdef HAS_PCI
>      if ( uart->bar || uart->ps_bdf_enable )
>          pci_hide_device(uart->ps_bdf[0], PCI_DEVFN(uart->ps_bdf[1],
>                                                     uart->ps_bdf[2]));
> +#endif
>  }
>  
>  static void ns16550_suspend(struct serial_port *port)
> @@ -301,13 +354,16 @@ static void ns16550_suspend(struct serial_port *port)
>  
>      stop_timer(&uart->timer);
>  
> +#ifdef HAS_PCI
>      if ( uart->bar )
>         uart->cr = pci_conf_read16(0, uart->ps_bdf[0], uart->ps_bdf[1],
>                                    uart->ps_bdf[2], PCI_COMMAND);
> +#endif
>  }
>  
>  static void _ns16550_resume(struct serial_port *port)
>  {
> +#ifdef HAS_PCI
>      struct ns16550 *uart = port->uart;
>  
>      if ( uart->bar )
> @@ -317,6 +373,7 @@ static void _ns16550_resume(struct serial_port *port)
>         pci_conf_write16(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
>                          PCI_COMMAND, uart->cr);
>      }
> +#endif
>  
>      ns16550_setup_preirq(port->uart);
>      ns16550_setup_postirq(port->uart);
> @@ -360,19 +417,17 @@ static void ns16550_resume(struct serial_port *port)
>          _ns16550_resume(port);
>  }
>  
> -#ifdef CONFIG_X86
>  static void __init ns16550_endboot(struct serial_port *port)
>  {
> +#ifdef HAS_IOPORTS
>      struct ns16550 *uart = port->uart;
>  
>      if ( uart->remapped_io_base )
>          return;
>      if ( ioports_deny_access(dom0, uart->io_base, uart->io_base + 7) != 0 )
>          BUG();
> -}
> -#else
> -#define ns16550_endboot NULL
>  #endif
> +}
>  
>  static int __init ns16550_irq(struct serial_port *port)
>  {
> @@ -380,6 +435,23 @@ static int __init ns16550_irq(struct serial_port *port)
>      return ((uart->irq > 0) ? uart->irq : -1);
>  }
>  
> +#ifdef HAS_DEVICE_TREE
> +static const struct dt_irq __init *ns16550_dt_irq(struct serial_port *port)
> +{
> +    struct ns16550 *uart = port->uart;
> +    return &uart->dt_irq;
> +}
> +#endif
> +
> +#ifdef CONFIG_ARM
> +static const struct vuart_info *ns16550_vuart_info(struct serial_port 
> *port)
> +{
> +    struct ns16550 *uart = port->uart;
> +
> +    return &uart->vuart;
> +}
> +#endif
> +
>  static struct uart_driver __read_mostly ns16550_driver = {
>      .init_preirq  = ns16550_init_preirq,
>      .init_postirq = ns16550_init_postirq,
> @@ -389,7 +461,13 @@ static struct uart_driver __read_mostly ns16550_driver = 
> {
>      .tx_ready     = ns16550_tx_ready,
>      .putc         = ns16550_putc,
>      .getc         = ns16550_getc,
> -    .irq          = ns16550_irq
> +    .irq          = ns16550_irq,
> +#ifdef HAS_DEVICE_TREE
> +    .dt_irq_get   = ns16550_dt_irq,
> +#endif
> +#ifdef CONFIG_ARM
> +    .vuart_info   = ns16550_vuart_info,
> +#endif
>  };
>  
>  static int __init parse_parity_char(int c)
> @@ -414,15 +492,21 @@ static int __init check_existence(struct ns16550 *uart)
>  {
>      unsigned char status, scratch, scratch2, scratch3;
>  
> +#ifdef HAS_IO_PORTS
>      /*
>       * We can't poke MMIO UARTs until they get I/O remapped later. Assume 
> that
>       * if we're getting MMIO UARTs, the arch code knows what it's doing.
>       */
>      if ( uart->io_base >= 0x10000 )
>          return 1;
> +#else
> +    return 1; /* Everything is MMIO */
> +#endif
>  
> +#ifdef HAS_PCI
>      pci_serial_early_init(uart);
> -    
> +#endif
> +
>      /*
>       * Do a simple existence test first; if we fail this,
>       * there's no point trying anything else.
> @@ -450,6 +534,7 @@ static int __init check_existence(struct ns16550 *uart)
>      return (status == 0x90);
>  }
>  
> +#ifdef HAS_PCI
>  static int
>  pci_uart_config (struct ns16550 *uart, int skip_amt, int bar_idx)
>  {
> @@ -518,6 +603,7 @@ pci_uart_config (struct ns16550 *uart, int skip_amt, int 
> bar_idx)
>  
>      return 0;
>  }
> +#endif
>  
>  #define PARSE_ERR(_f, _a...)                 \
>      do {                                     \
> @@ -564,6 +650,7 @@ static void __init ns16550_parse_port_config(
>  
>      if ( *conf == ',' && *++conf != ',' )
>      {
> +#ifdef HAS_PCI
>          if ( strncmp(conf, "pci", 3) == 0 )
>          {
>              if ( pci_uart_config(uart, 1/* skip AMT */, uart - ns16550_com) 
> )
> @@ -577,6 +664,7 @@ static void __init ns16550_parse_port_config(
>              conf += 3;
>          }
>          else
> +#endif
>          {
>              uart->io_base = simple_strtoul(conf, &conf, 0);
>          }
> @@ -585,6 +673,7 @@ static void __init ns16550_parse_port_config(
>      if ( *conf == ',' && *++conf != ',' )
>          uart->irq = simple_strtol(conf, &conf, 10);
>  
> +#ifdef HAS_PCI
>      if ( *conf == ',' && *++conf != ',' )
>      {
>          conf = parse_pci(conf, NULL, &uart->ps_bdf[0],
> @@ -601,6 +690,7 @@ static void __init ns16550_parse_port_config(
>              PARSE_ERR("Bad bridge PCI coordinates");
>          uart->pb_bdf_enable = 1;
>      }
> +#endif
>  
>   config_parsed:
>      /* Sanity checks. */
> @@ -638,12 +728,91 @@ void __init ns16550_init(int index, struct 
> ns16550_defaults *defaults)
>      uart->stop_bits = defaults->stop_bits;
>      uart->irq       = defaults->irq;
>      uart->io_base   = defaults->io_base;
> +    uart->io_size   = 8;
> +    uart->reg_width = 1;
> +    uart->reg_shift = 0;
> +
>      /* Default is no transmit FIFO. */
>      uart->fifo_size = 1;
>  
>      ns16550_parse_port_config(uart, (index == 0) ? opt_com1 : opt_com2);
>  }
>  
> +#ifdef HAS_DEVICE_TREE
> +static int __init ns16550_uart_dt_init(struct dt_device_node *dev,
> +                                       const void *data)
> +{
> +    struct ns16550 *uart;
> +    int res;
> +    u32 reg_shift, reg_width;
> +    u64 io_size;
> +
> +    uart = &ns16550_com[0];
> +
> +    uart->baud      = BAUD_AUTO;
> +    uart->clock_hz  = UART_CLOCK_HZ;
> +    uart->data_bits = 8;
> +    uart->parity    = UART_PARITY_NONE;
> +    uart->stop_bits = 1;
> +    /* Default is no transmit FIFO. */
> +    uart->fifo_size = 1;
> +
> +    res = dt_device_get_address(dev, 0, &uart->io_base, &io_size);
> +    if ( res )
> +        return res;
> +
> +    uart->io_size = io_size;
> +
> +    ASSERT(uart->io_size == io_size); /* Detect truncation */
> +
> +    res = dt_property_read_u32(dev, "reg-shift", &reg_shift);
> +    if ( !res )
> +        uart->reg_shift = 0;
> +    else
> +        uart->reg_shift = reg_shift;
> +
> +    res = dt_property_read_u32(dev, "reg-io-width", &reg_width);
> +    if ( !res )
> +        uart->reg_width = 1;
> +    else
> +        uart->reg_width = reg_width;
> +
> +    if ( uart->reg_width != 1 && uart->reg_width != 4 )
> +        return -EINVAL;
> +
> +    res = dt_device_get_irq(dev, 0, &uart->dt_irq);
> +    if ( res )
> +        return res;
> +
> +    /* The common bit of the driver mostly deals with irq not dt_irq. */
> +    uart->irq = uart->dt_irq.irq;
> +
> +    uart->vuart.base_addr = uart->io_base;
> +    uart->vuart.size = uart->io_size;
> +    uart->vuart.data_off = UART_THR <<uart->reg_shift;
> +    uart->vuart.status_off = UART_LSR<<uart->reg_shift;
> +    uart->vuart.status = UART_LSR_THRE|UART_LSR_TEMT;
> +
> +    /* Register with generic serial driver. */
> +    serial_register_uart(uart - ns16550_com, &ns16550_driver, uart);
> +
> +    dt_device_set_used_by(dev, DOMID_XEN);
> +
> +    return 0;
> +}
> +
> +static const char const *ns16550_dt_compat[] __initconst =
> +{
> +    "ns16550",
> +    NULL
> +};
> +
> +DT_DEVICE_START(ns16550, "NS16550 UART", DEVICE_SERIAL)
> +        .compatible = ns16550_dt_compat,
> +        .init = ns16550_uart_dt_init,
> +DT_DEVICE_END
> +
> +#endif /* HAS_DEVICE_TREE */
>  /*
>   * Local variables:
>   * mode: C
> -- 
> 1.7.10.4

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC 0/8] xen/arm: initial cubieboard2 support.
  2013-09-13 16:01 [PATCH RFC 0/8] xen/arm: initial cubieboard2 support Ian Campbell
                   ` (6 preceding siblings ...)
  2013-09-13 16:04 ` [PATCH 8/8] xen/arm: Some early trap logging Ian Campbell
@ 2013-09-13 16:43 ` Julien Grall
       [not found] ` <1379088247-29325-2-git-send-email-ian.campbell@citrix.com>
  8 siblings, 0 replies; 11+ messages in thread
From: Julien Grall @ 2013-09-13 16:43 UTC (permalink / raw)
  To: Ian Campbell
  Cc: keir, stefano.stabellini, tim, xen-devel, jbuelich, Josh Zhao

On 09/13/2013 05:01 PM, Ian Campbell wrote:
> See http://www.gossamer-threads.com/lists/xen/devel/297170 for some
> information on how to get this going.
> 
> I've rebased and addressed the review comments.
> 
> As before several of the patches are not to be applied because they can
> be done better using infrastructure from Julien's "Allow Xen to boot
> with a raw Device Tree" patch. They are included for completeness.

I have a branch on my git tree with my latest device tree patch series
(git://xenbits.xen.org/people/julieng/xen-unstable.git dt-edition-v4).
You can at least rework the patch #6 and #8. For the latter, as
discussed previously, in a near future, a solution based on memory
trapping should be the best solution to handle correctly non
page-aligned device.

> With this I can boot up until dom0 panics due to lack of a root
> filesystem. This is because upstream Linux currently lacks any useful
> storage drivers (SATA, USB host, MMC). Hopefully this will resolve
> itself soon!
> 
> Despite this I think those patches which aren't marked as being not for
> application can be applied as soon as people are happy with them. Hence
> I've dropped the RFC. 
> 


-- 
Julien Grall

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/8] xen/arm: replace io{read, write}{l, b} with {read, write}{l, b}
       [not found]   ` <52333E52.5060308@linaro.org>
@ 2013-09-20 15:51     ` Ian Campbell
  0 siblings, 0 replies; 11+ messages in thread
From: Ian Campbell @ 2013-09-20 15:51 UTC (permalink / raw)
  To: Julien Grall
  Cc: keir, stefano.stabellini, tim, xen-devel, jbeulich, Josh Zhao

On Fri, 2013-09-13 at 17:33 +0100, Julien Grall wrote:
> > read/write are used in common driver code (specifically ns16550) so instead of
> > keeping our own variant around lets replace it with the more standard ones.
> > 
> > At the same time resync with Linux making the "based on" comment in both setsof
> s/setsof/sets of/
> 
> Can you precise the linux commit for the future?

It's v3.11, I've mentioned that in the updated version.
 
> > -static inline void iowritel(const volatile void __iomem *addr, uint32_t val)
> > +static inline void __raw_writeq(u64 val, volatile void __iomem *addr)
> >  {
> > -    dsb();
> > -    asm volatile("str %w0, [%1]" : : "r" (val), "r" (addr));
> > +        asm volatile("str %0, [%1]" : : "r" (val), "r" (addr));
> 
> The indentation seems wrong here and some other places.

I deliberately retained the Linux style of indentation for these
functions which came direct from Linux. Makes a visual check that they
are the same much easier.

Ian.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2013-09-20 15:51 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-09-13 16:01 [PATCH RFC 0/8] xen/arm: initial cubieboard2 support Ian Campbell
2013-09-13 16:04 ` [PATCH 1/8] xen/arm: Implement ioremap Ian Campbell
2013-09-13 16:04 ` [PATCH 3/8] ns16550: make usable on ARM Ian Campbell
2013-09-13 16:16   ` Jan Beulich
2013-09-13 16:04 ` [PATCH 4/8] ns16550: support DesignWare 8250 Ian Campbell
2013-09-13 16:04 ` [PATCH 5/8] xen/arm: Support Cortex-A7 GIC Ian Campbell
2013-09-13 16:04 ` [PATCH 6/8] xen/arm: Basic support for sunxi/sun7i platform Ian Campbell
2013-09-13 16:04 ` [PATCH 7/8] xen/arm: Blacklist some sun7i UARTs Ian Campbell
2013-09-13 16:04 ` [PATCH 8/8] xen/arm: Some early trap logging Ian Campbell
2013-09-13 16:43 ` [PATCH RFC 0/8] xen/arm: initial cubieboard2 support Julien Grall
     [not found] ` <1379088247-29325-2-git-send-email-ian.campbell@citrix.com>
     [not found]   ` <52333E52.5060308@linaro.org>
2013-09-20 15:51     ` [PATCH 2/8] xen/arm: replace io{read, write}{l, b} with {read, write}{l, b} Ian Campbell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.