[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