[Linux-Xtensa] [PATCH v3] xtensa: remap io area defined in device tree

Max Filippov jcmvbkbc at gmail.com
Mon Dec 30 06:13:34 UTC 2013


Hi Baruch,

On Sun, Dec 29, 2013 at 1:03 PM, Baruch Siach <baruch at tkos.co.il> wrote:
> Use the simple-bus node to discover the io area, and remap the cached and
> bypass io ranges. The parent-bus-address value of the first triplet in the
> "ranges" property is used. This value is rounded down to the nearest 256MB
> boundary. The length of the io area is fixed at 256MB; the "ranges" property
> length value is ignored.
>
> Other limitations: (1) only the first simple-bus node is considered, and (2)
> only the first triplet of the "ranges" property is considered.
>
> See ePAPR 1.1 §6.5 for the simple-bus node description, and §2.3.8 for the
> "ranges" property description.
>
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>

I've fixed up a couple of nits mentioned below and applied the whole series to
the xtensa-fixes-for-upstream branch of my tree. I've also tested that it builds
and boots in couple configurations, with and without xtensa_kio_paddr.

Please let me know if it's ok, or you want to further change the series.

> ---
> v3:
>     Address the comments of Max Filippov:
>
>         * Move xtensa_get_kio_paddr() to asm/io.h, and make it static inline
>
>         * Move the actual TLB update to arch/xtensa/mm/mmu.c
>
>         * Add documentation to Documentation/xtensa/mmu.txt
>
>     Check the return value of of_get_flat_dt_prop() to avoid NULL dereference
>     in the unlikely case that the "ranges" property is missing
>
> v2:
>     Redefine XCHAL_KIO_PADDR instead of its users (Max Filippov)
>
>     Mention the single node, single triplet limitations in the commit log
> ---
>  Documentation/xtensa/mmu.txt             | 18 ++++++++++++++++
>  arch/xtensa/include/asm/initialize_mmu.h |  9 ++++----
>  arch/xtensa/include/asm/io.h             |  8 +++++++
>  arch/xtensa/include/asm/vectors.h        |  8 ++++++-
>  arch/xtensa/kernel/setup.c               | 36 ++++++++++++++++++++++++++++++++
>  arch/xtensa/mm/mmu.c                     | 14 +++++++++++++
>  6 files changed, 88 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/xtensa/mmu.txt b/Documentation/xtensa/mmu.txt
> index 2b1af76..0312fe6 100644
> --- a/Documentation/xtensa/mmu.txt
> +++ b/Documentation/xtensa/mmu.txt
> @@ -44,3 +44,21 @@ After step 4, we jump to intended (linked) address of this code.
>   40..5F -> 40         40..5F -> pc  -> pc  40..5F -> pc
>   20..3F -> 20  -> 20  20..3F -> 20
>   00..1F -> 00  -> 00  00..1F -> 00
> +
> +The default location of IO peripherals is above 0xf0000000. This may change
> +using a "ranges" property in a device tree simple-bus node. See ePAPR 1.1, §6.5
> +for details on the syntax and semantic of simple-bus nodes. The following
> +limitations apply:
> +
> +1. Only top level simple-bus nodes are considered
> +
> +2. Only one (first) simple-bus node is considered
> +
> +3. Empty "ranges" properties are not supported
> +
> +4. Only the first triplet in the "ranges" property is considered
> +
> +5. The parent-bus-address value is rounded down to the nearest 256MB boundary
> +
> +6. The IO area covers the entire 256MB segment of parent-bus-address; the
> +   "ranges" triplet length field is ignored
> diff --git a/arch/xtensa/include/asm/initialize_mmu.h b/arch/xtensa/include/asm/initialize_mmu.h
> index a2078a2..600781e 100644
> --- a/arch/xtensa/include/asm/initialize_mmu.h
> +++ b/arch/xtensa/include/asm/initialize_mmu.h
> @@ -26,6 +26,9 @@
>  #include <asm/pgtable.h>
>  #include <asm/vectors.h>
>
> +#define CA_BYPASS      (_PAGE_CA_BYPASS | _PAGE_HW_WRITE | _PAGE_HW_EXEC)
> +#define CA_WRITEBACK   (_PAGE_CA_WB     | _PAGE_HW_WRITE | _PAGE_HW_EXEC)
> +
>  #ifdef __ASSEMBLY__
>
>  #define XTENSA_HWVERSION_RC_2009_0 230000
> @@ -80,8 +83,6 @@
>         /* Step 2: map 0x40000000..0x47FFFFFF to paddr containing this code
>          * and jump to the new mapping.
>          */
> -#define CA_BYPASS      (_PAGE_CA_BYPASS | _PAGE_HW_WRITE | _PAGE_HW_EXEC)
> -#define CA_WRITEBACK   (_PAGE_CA_WB     | _PAGE_HW_WRITE | _PAGE_HW_EXEC)
>
>         srli    a3, a0, 27
>         slli    a3, a3, 27
> @@ -124,12 +125,12 @@
>         witlb   a4, a5
>
>         movi    a5, XCHAL_KIO_CACHED_VADDR + 6
> -       movi    a4, XCHAL_KIO_PADDR + CA_WRITEBACK
> +       movi    a4, XCHAL_KIO_DEFAULT_PADDR + CA_WRITEBACK
>         wdtlb   a4, a5
>         witlb   a4, a5
>
>         movi    a5, XCHAL_KIO_BYPASS_VADDR + 6
> -       movi    a4, XCHAL_KIO_PADDR + CA_BYPASS
> +       movi    a4, XCHAL_KIO_DEFAULT_PADDR + CA_BYPASS
>         wdtlb   a4, a5
>         witlb   a4, a5
>
> diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
> index 1482a363..891727d 100644
> --- a/arch/xtensa/include/asm/io.h
> +++ b/arch/xtensa/include/asm/io.h
> @@ -24,6 +24,14 @@
>  #define IO_SPACE_LIMIT ~0
>
>  #ifdef CONFIG_MMU
> +
> +extern unsigned long xtensa_kio_paddr;
> +
> +static inline unsigned long xtensa_get_kio_paddr(void)
> +{
> +       return xtensa_kio_paddr;
> +}
> +

Made it conditional on CONFIG_OF+MMUv3 only.

>  /*
>   * Return the virtual address for the specified bus memory.
>   * Note that we currently don't support any address outside the KIO segment.
> diff --git a/arch/xtensa/include/asm/vectors.h b/arch/xtensa/include/asm/vectors.h
> index ecbca88..fcec1ec 100644
> --- a/arch/xtensa/include/asm/vectors.h
> +++ b/arch/xtensa/include/asm/vectors.h
> @@ -22,9 +22,15 @@
>
>  #define XCHAL_KIO_CACHED_VADDR 0xe0000000
>  #define XCHAL_KIO_BYPASS_VADDR 0xf0000000
> -#define XCHAL_KIO_PADDR                0xf0000000
> +#define XCHAL_KIO_DEFAULT_PADDR        0xf0000000
>  #define XCHAL_KIO_SIZE         0x10000000
>
> +#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && CONFIG_OF
> +#define XCHAL_KIO_PADDR                xtensa_get_kio_paddr()
> +#else
> +#define XCHAL_KIO_PADDR                XCHAL_KIO_DEFAULT_PADDR
> +#endif
> +

Fixed indentation to match the rest in this file.

>  #if defined(CONFIG_MMU)
>
>  /* Will Become VECBASE */
> diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
> index 1d75cdb..7b43d34 100644
> --- a/arch/xtensa/kernel/setup.c
> +++ b/arch/xtensa/kernel/setup.c
> @@ -214,6 +214,41 @@ static int __init parse_bootparam(const bp_tag_t* tag)
>  #ifdef CONFIG_OF
>  bool __initdata dt_memory_scan = false;
>
> +#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
> +unsigned long xtensa_kio_paddr = XCHAL_KIO_DEFAULT_PADDR;

Missing EXPORT_SYMBOL

> +
> +static int __init xtensa_dt_io_area(unsigned long node, const char *uname,
> +               int depth, void *data)
> +{
> +       const __be32 *ranges;
> +       unsigned long len;
> +
> +       if (depth > 1)
> +               return 0;
> +
> +       if (!of_flat_dt_is_compatible(node, "simple-bus"))
> +               return 0;
> +
> +       ranges = of_get_flat_dt_prop(node, "ranges", &len);
> +       if (!ranges)
> +               return 1;
> +       if (len == 0)
> +               return 1;
> +
> +       xtensa_kio_paddr = of_read_ulong(ranges+1, 1);
> +       /* round down to nearest 256MB boundary */
> +       xtensa_kio_paddr &= 0xf0000000;
> +
> +       return 1;
> +}
> +#else
> +static int __init xtensa_dt_io_area(unsigned long node, const char *uname,
> +               int depth, void *data)
> +{
> +       return 1;
> +}
> +#endif
> +
>  void __init early_init_dt_add_memory_arch(u64 base, u64 size)
>  {
>         if (!dt_memory_scan)
> @@ -234,6 +269,7 @@ void __init early_init_devtree(void *params)
>                 dt_memory_scan = true;
>
>         early_init_dt_scan(params);
> +       of_scan_flat_dt(xtensa_dt_io_area, NULL);

This hunk didn't apply to v3.12, please check my resolution.

>
>         if (!command_line[0])
>                 strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
> diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c
> index c43771c..d6706076 100644
> --- a/arch/xtensa/mm/mmu.c
> +++ b/arch/xtensa/mm/mmu.c
> @@ -13,6 +13,8 @@
>  #include <asm/tlbflush.h>
>  #include <asm/mmu_context.h>
>  #include <asm/page.h>
> +#include <asm/initialize_mmu.h>
> +#include <asm/io.h>
>
>  void __init paging_init(void)
>  {
> @@ -37,6 +39,18 @@ void __init init_mmu(void)
>         set_itlbcfg_register(0);
>         set_dtlbcfg_register(0);
>  #endif
> +       /*
> +        * Update the IO area mapping in case xtensa_kio_paddr has changed
> +        */
> +       write_dtlb_entry(__pte(xtensa_kio_paddr + CA_WRITEBACK),
> +                       XCHAL_KIO_CACHED_VADDR + 6);
> +       write_itlb_entry(__pte(xtensa_kio_paddr + CA_WRITEBACK),
> +                       XCHAL_KIO_CACHED_VADDR + 6);
> +       write_dtlb_entry(__pte(xtensa_kio_paddr + CA_BYPASS),
> +                       XCHAL_KIO_BYPASS_VADDR + 6);
> +       write_itlb_entry(__pte(xtensa_kio_paddr + CA_BYPASS),
> +                       XCHAL_KIO_BYPASS_VADDR + 6);
> +

Made it conditional on CONFIG_OF + MMUv3, otherwise the build fails for MMUv2/
non-DT configurations.

>         flush_tlb_all();
>
>         /* Set rasid register to a known value. */
> --
> 1.8.5.2
>

-- 
Thanks.
-- Max


More information about the linux-xtensa mailing list