Ian Campbell
2013-Sep-20 16:17 UTC
[PATCH v3 0/7] support for cubieboard2 / sunxi processors
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. With this rebase I''ve picked up some patches from Julien which were required to do things properly, so the gic v7 and device blacklisting patches have been changed to use the proper mechanisms. Previously I was able to boot to a panic due to not finding a root filesystem. This seems to have regressed and now it hangs during dom0 boot. I''m not sure why this is but I think it is because I''ve rebased my dom0 kernel and not something in this series. I don''t think this needs to block this series though, especially since the APM guys want bits of it (specifically the ns16550 DT stuff). Progress has been made on the upstream SATA support, but nothing is actually in place yet. Ian.
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
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> Cc: PranavkumarSawargaonkar<pranavkumar@linaro.org> --- 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", ®_shift); + if ( !res ) + uart->reg_shift = 0; + else + uart->reg_shift = reg_shift; + + res = dt_property_read_u32(dev, "reg-io-width", ®_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
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
Signed-off-by: Ian Campbell <ian.campbell@citrix.com> --- v3: use DT_MATCH_GIC --- xen/include/asm-arm/gic.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 92a3349..2bc4219 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -135,7 +135,8 @@ #ifndef __ASSEMBLY__ #include <xen/device_tree.h> -#define DT_MATCH_GIC DT_MATCH_COMPATIBLE("arm,cortex-a15-gic") +#define DT_MATCH_GIC DT_MATCH_COMPATIBLE("arm,cortex-a15-gic"), \ + DT_MATCH_COMPATIBLE("arm,cortex-a7-gic") extern int domain_vgic_init(struct domain *d); extern void domain_vgic_free(struct domain *d); -- 1.7.10.4
Ian Campbell
2013-Sep-20 16:18 UTC
[PATCH 6/7] xen/arm: Basic support for sunxi/sun7i platform.
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
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. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> --- v3: Use blacklist dev hook --- xen/arch/arm/platforms/sunxi.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/xen/arch/arm/platforms/sunxi.c b/xen/arch/arm/platforms/sunxi.c index ee0f39b..3a0ed68 100644 --- a/xen/arch/arm/platforms/sunxi.c +++ b/xen/arch/arm/platforms/sunxi.c @@ -28,8 +28,22 @@ static const char const *sunxi_dt_compat[] __initdata NULL }; +static const struct dt_device_match sunxi_blacklist_dev[] __initconst +{ + /* + * These UARTs share a page with the Xen console UART, so we don''t + * want to map them through. + */ + DT_MATCH_PATH("/soc@01c00000/serial@01c28000"), + DT_MATCH_PATH("/soc@01c00000/serial@01c28400"), + DT_MATCH_PATH("/soc@01c00000/serial@01c28800"), + DT_MATCH_PATH("/soc@01c00000/serial@01c28c00"), + { /* sentinel */ }, +}; + PLATFORM_START(sunxi, "Allwinner A20") .compatible = sunxi_dt_compat, + .blacklist_dev = sunxi_blacklist_dev, PLATFORM_END /* -- 1.7.10.4
On 09/20/2013 05:18 PM, Ian Campbell wrote:> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>Acked-by: Julien Grall <julien.grall@linaro.org>> --- > v3: use DT_MATCH_GIC > --- > xen/include/asm-arm/gic.h | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h > index 92a3349..2bc4219 100644 > --- a/xen/include/asm-arm/gic.h > +++ b/xen/include/asm-arm/gic.h > @@ -135,7 +135,8 @@ > #ifndef __ASSEMBLY__ > #include <xen/device_tree.h> > > -#define DT_MATCH_GIC DT_MATCH_COMPATIBLE("arm,cortex-a15-gic") > +#define DT_MATCH_GIC DT_MATCH_COMPATIBLE("arm,cortex-a15-gic"), \ > + DT_MATCH_COMPATIBLE("arm,cortex-a7-gic") > > extern int domain_vgic_init(struct domain *d); > extern void domain_vgic_free(struct domain *d); >-- Julien Grall
Julien Grall
2013-Sep-20 18:55 UTC
Re: [PATCH 6/7] xen/arm: Basic support for sunxi/sun7i platform.
On 09/20/2013 05:18 PM, Ian Campbell wrote:> 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>Do we need all these includes? asm/platform.h should be enough.> + > +static const char const *sunxi_dt_compat[] __initdataIt should be __initconst.> +{ > + "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: > + */ >-- Julien Grall
Ian Campbell
2013-Sep-20 19:01 UTC
Re: [PATCH 6/7] xen/arm: Basic support for sunxi/sun7i platform.
On Fri, 2013-09-20 at 19:55 +0100, Julien Grall wrote:> On 09/20/2013 05:18 PM, Ian Campbell wrote: > > 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> > > Do we need all these includes? asm/platform.h should be enough.Probably not, many of them are a hangover from the previous hacky version or copied from whichever file I started from ;-)> > > + > > +static const char const *sunxi_dt_compat[] __initdata > > It should be __initconst.Ack.> > +{ > > + "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: > > + */ > > > >
On 09/20/2013 05:18 PM, Ian Campbell wrote:> 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. > > Signed-off-by: Ian Campbell <ian.campbell@citrix.com> > --- > v3: Use blacklist dev hook > --- > xen/arch/arm/platforms/sunxi.c | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > > diff --git a/xen/arch/arm/platforms/sunxi.c b/xen/arch/arm/platforms/sunxi.c > index ee0f39b..3a0ed68 100644 > --- a/xen/arch/arm/platforms/sunxi.c > +++ b/xen/arch/arm/platforms/sunxi.c > @@ -28,8 +28,22 @@ static const char const *sunxi_dt_compat[] __initdata > NULL > }; > > +static const struct dt_device_match sunxi_blacklist_dev[] __initconst > +{ > + /* > + * These UARTs share a page with the Xen console UART, so we don''t > + * want to map them through. > + */ > + DT_MATCH_PATH("/soc@01c00000/serial@01c28000"), > + DT_MATCH_PATH("/soc@01c00000/serial@01c28400"), > + DT_MATCH_PATH("/soc@01c00000/serial@01c28800"), > + DT_MATCH_PATH("/soc@01c00000/serial@01c28c00"),Can we blacklist all the UARTs via a DT_MATCH_COMPATIBLE? It''s better than relying on the path that can be changed easily in the device tree.> + { /* sentinel */ }, > +}; > + > PLATFORM_START(sunxi, "Allwinner A20") > .compatible = sunxi_dt_compat, > + .blacklist_dev = sunxi_blacklist_dev, > PLATFORM_END > > /* >-- Julien Grall
On Fri, 2013-09-20 at 20:02 +0100, Julien Grall wrote:> > + /* > > + * These UARTs share a page with the Xen console UART, so we don''t > > + * want to map them through. > > + */ > > + DT_MATCH_PATH("/soc@01c00000/serial@01c28000"), > > + DT_MATCH_PATH("/soc@01c00000/serial@01c28400"), > > + DT_MATCH_PATH("/soc@01c00000/serial@01c28800"), > > + DT_MATCH_PATH("/soc@01c00000/serial@01c28c00"), > > Can we blacklist all the UARTs via a DT_MATCH_COMPATIBLE? It''s better > than relying on the path that can be changed easily in the device tree.There are other UARTS (at 0x1c29xxx) which could safely be exposed to dom0. Perhaps it is better to just blacklist the whole lot though. Ultimately this is just a hack for the fact that Xen is not currently smart enough to figure out which devices conflict in this way... Ian.
Ian Campbell
2013-Sep-21 15:59 UTC
Re: [PATCH v3 0/7] support for cubieboard2 / sunxi processors
On Fri, 2013-09-20 at 17:17 +0100, Ian Campbell wrote:> Previously I was able to boot to a panic due to not finding a root > filesystem. This seems to have regressed and now it hangs during dom0 > boot. I''m not sure why this is but I think it is because I''ve rebased my > dom0 kernel and not something in this series. I don''t think this needs > to block this series though, especially since the APM guys want bits of > it (specifically the ns16550 DT stuff).I''ve applied the first 5: 45b1870 xen/arm: Implement ioremap. 204cb1e xen/arm: replace io{read,write}{l,b} with {read,write}{l,b} 7c1de00 ns16550: make usable on ARM 50417cd ns16550: support DesignWare 8250 7b3c792 xen/arm: Support Cortex-A7 GIC Which in particular includes the ns16550 dt stuff that others are looking for.
On 09/20/2013 10:41 PM, Ian Campbell wrote:> On Fri, 2013-09-20 at 20:02 +0100, Julien Grall wrote: > >>> + /* >>> + * These UARTs share a page with the Xen console UART, so we don''t >>> + * want to map them through. >>> + */ >>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28000"), >>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28400"), >>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28800"), >>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28c00"), >> >> Can we blacklist all the UARTs via a DT_MATCH_COMPATIBLE? It''s better >> than relying on the path that can be changed easily in the device tree. > > There are other UARTS (at 0x1c29xxx) which could safely be exposed to > dom0. Perhaps it is better to just blacklist the whole lot though.These UARTs also share the same page, what prevents the user to use these UARTs? I have noticed that all the UARTs, except UART0, have a property : status = "disabled". So Xen won''t map the UART in dom0 memory.> Ultimately this is just a hack for the fact that Xen is not currently > smart enough to figure out which devices conflict in this way...After my comment above, do we really need to blacklist all the other UARTs? As we only support the cubieboard 2, if we only want a hack, I think we can safely avoid this patch for now. -- Julien Grall
On Sat, 2013-09-21 at 21:28 +0100, Julien Grall wrote:> On 09/20/2013 10:41 PM, Ian Campbell wrote: > > On Fri, 2013-09-20 at 20:02 +0100, Julien Grall wrote: > > > >>> + /* > >>> + * These UARTs share a page with the Xen console UART, so we don''t > >>> + * want to map them through. > >>> + */ > >>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28000"), > >>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28400"), > >>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28800"), > >>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28c00"), > >> > >> Can we blacklist all the UARTs via a DT_MATCH_COMPATIBLE? It''s better > >> than relying on the path that can be changed easily in the device tree. > > > > There are other UARTS (at 0x1c29xxx) which could safely be exposed to > > dom0. Perhaps it is better to just blacklist the whole lot though. > > These UARTs also share the same page, what prevents the user to use > these UARTs?Nothing, but because they don''t share a page with the xen UART they don''t cause it to get exposed to dom0.> I have noticed that all the UARTs, except UART0, have a property : > status = "disabled". So Xen won''t map the UART in dom0 memory.That bit is new since I initially wrote this patch.> > Ultimately this is just a hack for the fact that Xen is not currently > > smart enough to figure out which devices conflict in this way... > > After my comment above, do we really need to blacklist all the other > UARTs? As we only support the cubieboard 2, if we only want a hack, I > think we can safely avoid this patch for now.There are quite a few Allwinner A20 based devices out there, e.g. I''ve got a MELE M5 which I ultimately hope will work too, so I''d be reluctant to hardcode cubie specifics. Probably just blacklisting all the UARTs is the easiest way to go for now -- typically only one of them is usefully exposed on the systems I''ve seen anyway and most of the others are pin muxed with something more useful, like an MMC device. Ian.
On 09/22/2013 03:40 PM, Ian Campbell wrote:> On Sat, 2013-09-21 at 21:28 +0100, Julien Grall wrote: >> On 09/20/2013 10:41 PM, Ian Campbell wrote: >>> On Fri, 2013-09-20 at 20:02 +0100, Julien Grall wrote: >>> >>>>> + /* >>>>> + * These UARTs share a page with the Xen console UART, so we don''t >>>>> + * want to map them through. >>>>> + */ >>>>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28000"), >>>>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28400"), >>>>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28800"), >>>>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28c00"), >>>> >>>> Can we blacklist all the UARTs via a DT_MATCH_COMPATIBLE? It''s better >>>> than relying on the path that can be changed easily in the device tree. >>> >>> There are other UARTS (at 0x1c29xxx) which could safely be exposed to >>> dom0. Perhaps it is better to just blacklist the whole lot though. >> >> These UARTs also share the same page, what prevents the user to use >> these UARTs? > > Nothing, but because they don''t share a page with the xen UART they > don''t cause it to get exposed to dom0.My question wasn''t clear. What does prevent the user to use another UART for Xen? -- Julien Grall
On 27/09/13 18:02, Julien Grall wrote:> On 09/22/2013 03:40 PM, Ian Campbell wrote: >> On Sat, 2013-09-21 at 21:28 +0100, Julien Grall wrote: >>> On 09/20/2013 10:41 PM, Ian Campbell wrote: >>>> On Fri, 2013-09-20 at 20:02 +0100, Julien Grall wrote: >>>> >>>>>> + /* >>>>>> + * These UARTs share a page with the Xen console UART, so we don''t >>>>>> + * want to map them through. >>>>>> + */ >>>>>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28000"), >>>>>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28400"), >>>>>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28800"), >>>>>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28c00"), >>>>> Can we blacklist all the UARTs via a DT_MATCH_COMPATIBLE? It''s better >>>>> than relying on the path that can be changed easily in the device tree. >>>> There are other UARTS (at 0x1c29xxx) which could safely be exposed to >>>> dom0. Perhaps it is better to just blacklist the whole lot though. >>> These UARTs also share the same page, what prevents the user to use >>> these UARTs? >> Nothing, but because they don''t share a page with the xen UART they >> don''t cause it to get exposed to dom0. > My question wasn''t clear. What does prevent the user to use another UART > for Xen? >Nothing "prevents" it. That is the problem. If several UARTs are on the same page, Xen cannot safely isolate its UART from dom0/domU. ~Andrew
On Fri, 2013-09-27 at 18:04 +0100, Andrew Cooper wrote:> On 27/09/13 18:02, Julien Grall wrote: > > On 09/22/2013 03:40 PM, Ian Campbell wrote: > >> On Sat, 2013-09-21 at 21:28 +0100, Julien Grall wrote: > >>> On 09/20/2013 10:41 PM, Ian Campbell wrote: > >>>> On Fri, 2013-09-20 at 20:02 +0100, Julien Grall wrote: > >>>> > >>>>>> + /* > >>>>>> + * These UARTs share a page with the Xen console UART, so we don''t > >>>>>> + * want to map them through. > >>>>>> + */ > >>>>>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28000"), > >>>>>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28400"), > >>>>>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28800"), > >>>>>> + DT_MATCH_PATH("/soc@01c00000/serial@01c28c00"), > >>>>> Can we blacklist all the UARTs via a DT_MATCH_COMPATIBLE? It''s better > >>>>> than relying on the path that can be changed easily in the device tree. > >>>> There are other UARTS (at 0x1c29xxx) which could safely be exposed to > >>>> dom0. Perhaps it is better to just blacklist the whole lot though. > >>> These UARTs also share the same page, what prevents the user to use > >>> these UARTs? > >> Nothing, but because they don''t share a page with the xen UART they > >> don''t cause it to get exposed to dom0. > > My question wasn''t clear. What does prevent the user to use another UART > > for Xen? > > > > Nothing "prevents" it. That is the problem. If several UARTs are on > the same page, Xen cannot safely isolate its UART from dom0/domU.He meant one of the other UARTs not on the same page as the primary one. The answer is "not much". However UART0 @ 0x1c28000 is the "debug" UART which is the one typically wired up in a useful way on these platforms. The others are pin-muxed with other functionality, such as MMC, LCD etc and are more often used as such (I''m sure there will be exceptions). That said Julien is probably right that the best solution is to just blacklist all 8 UARTs. Ian.
Ian Campbell
2013-Oct-08 09:50 UTC
Re: [PATCH 6/7] xen/arm: Basic support for sunxi/sun7i platform.
On Fri, 2013-09-20 at 19:55 +0100, Julien Grall wrote:> > + > > +static const char const *sunxi_dt_compat[] __initdata > > It should be __initconst.Together with the 7/7 patch (uart blacklisting) doing this causes: sunxi.c:21:26: error: sunxi_dt_compat causes a section type conflict with sunxi_blacklist_dev static const char const *sunxi_dt_compat[] __initconst ^ sunxi.c:27:37: note: ‘sunxi_blacklist_dev’ was declared here static const struct dt_device_match sunxi_blacklist_dev[] __initconst ^ I'm not sure why this would be, but I notice that vexpress and exynos5 both use __initdata for their dt_compat lists and __initconst for their blacklists. Any thoughts? google flags up a bunch of similar sounds gcc bugs, but they are all for older versions than the 4.8 (linaro 2013.08 FWIW) that I'm using. I'm inclined to keep using __initdata for the dt_compat list as all the other platforms do. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
Julien Grall
2013-Oct-10 14:23 UTC
Re: [PATCH 6/7] xen/arm: Basic support for sunxi/sun7i platform.
On 10/08/2013 10:50 AM, Ian Campbell wrote:> On Fri, 2013-09-20 at 19:55 +0100, Julien Grall wrote: > >>> + >>> +static const char const *sunxi_dt_compat[] __initdata >> >> It should be __initconst. > > Together with the 7/7 patch (uart blacklisting) doing this causes: > sunxi.c:21:26: error: sunxi_dt_compat causes a section type conflict with sunxi_blacklist_dev > static const char const *sunxi_dt_compat[] __initconst > ^ > sunxi.c:27:37: note: ‘sunxi_blacklist_dev’ was declared here > static const struct dt_device_match sunxi_blacklist_dev[] __initconst > ^ > I'm not sure why this would be, but I notice that vexpress and exynos5 > both use __initdata for their dt_compat lists and __initconst for their > blacklists. > > Any thoughts?It's because the const should be after * in sunxi_dt_compat ie static const char * const sunxi_dt_compat[] __initconst -- Julien Grall _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
Ian Campbell
2013-Oct-11 08:31 UTC
Re: [PATCH 6/7] xen/arm: Basic support for sunxi/sun7i platform.
On Thu, 2013-10-10 at 15:23 +0100, Julien Grall wrote:> It''s because the const should be after * in sunxi_dt_compat ie > > static const char * const sunxi_dt_compat[] __initconstThat did the trick. I''ll fix the others too. Ian.
Apparently Analagous Threads
- [PATCH RFC 0/8] xen/arm: initial cubieboard2 support.
- [PATCH v4 0/3] support for cubieboard2 / sunxi processors
- [PATCH 6/8] ns16550: PCI initialization adjustments
- [PATCH] ns16550: Use correct #define symbol for HAS_IOPORTS
- [PATCH RFC 5/8] ns16550: MMIO adjustments