From: Santosh Shilimkar <santosh.shilimkar@ti.com>
To: Catalin Marinas <catalin.marinas@arm.com>
Cc: linux-arch@vger.kernel.org, Will Deacon <will.deacon@arm.com>,
Arnd Bergmann <arnd@arndb.de>,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v2 09/31] arm64: Cache maintenance routines
Date: Fri, 17 Aug 2012 15:27:20 +0530 [thread overview]
Message-ID: <502E1580.70702@ti.com> (raw)
In-Reply-To: <1344966752-16102-10-git-send-email-catalin.marinas@arm.com>
On Tuesday 14 August 2012 11:22 PM, Catalin Marinas wrote:
> The patch adds functionality required for cache maintenance. The AArch64
> architecture mandates non-aliasing VIPT or PIPT D-cache and VIPT (may
> have aliases) or ASID-tagged VIVT I-cache. Cache maintenance operations
> are automatically broadcast in hardware between CPUs.
>
> Signed-off-by: Will Deacon<will.deacon@arm.com>
> Signed-off-by: Catalin Marinas<catalin.marinas@arm.com>
> ---
> arch/arm64/include/asm/cache.h | 32 ++++
> arch/arm64/include/asm/cacheflush.h | 209 ++++++++++++++++++++++++++
> arch/arm64/include/asm/cachetype.h | 48 ++++++
> arch/arm64/mm/cache.S | 279 +++++++++++++++++++++++++++++++++++
> arch/arm64/mm/flush.c | 132 +++++++++++++++++
> 5 files changed, 700 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm64/include/asm/cache.h
> create mode 100644 arch/arm64/include/asm/cacheflush.h
> create mode 100644 arch/arm64/include/asm/cachetype.h
> create mode 100644 arch/arm64/mm/cache.S
> create mode 100644 arch/arm64/mm/flush.c
>
> diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h
> new file mode 100644
> index 0000000..390308a
> --- /dev/null
> +++ b/arch/arm64/include/asm/cache.h
> @@ -0,0 +1,32 @@
> +/*
> + * Copyright (C) 2012 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see<http://www.gnu.org/licenses/>.
> + */
> +#ifndef __ASM_CACHE_H
> +#define __ASM_CACHE_H
> +
> +#define L1_CACHE_SHIFT 6
> +#define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT)
> +
> +/*
> + * Memory returned by kmalloc() may be used for DMA, so we must make
> + * sure that all such allocations are cache aligned. Otherwise,
> + * unrelated code may cause parts of the buffer to be read into the
> + * cache before the transfer is done, causing old data to be seen by
> + * the CPU.
> + */
> +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
> +#define ARCH_SLAB_MINALIGN 8
> +
> +#endif
> diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
> new file mode 100644
> index 0000000..93b5590
> --- /dev/null
> +++ b/arch/arm64/include/asm/cacheflush.h
> @@ -0,0 +1,209 @@
> +/*
> + * Based on arch/arm/include/asm/cacheflush.h
> + *
> + * Copyright (C) 1999-2002 Russell King.
> + * Copyright (C) 2012 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see<http://www.gnu.org/licenses/>.
> + */
> +#ifndef __ASM_CACHEFLUSH_H
> +#define __ASM_CACHEFLUSH_H
> +
> +#include<linux/mm.h>
> +
> +/*
> + * This flag is used to indicate that the page pointed to by a pte is clean
> + * and does not require cleaning before returning it to the user.
> + */
> +#define PG_dcache_clean PG_arch_1
> +
> +/*
> + * MM Cache Management
> + * ===================
> + *
> + * The arch/arm/mm/cache-*.S and arch/arm/mm/proc-*.S files
> + * implement these methods.
> + *
> + * Start addresses are inclusive and end addresses are exclusive;
> + * start addresses should be rounded down, end addresses up.
> + *
> + * See Documentation/cachetlb.txt for more information.
> + * Please note that the implementation of these, and the required
> + * effects are cache-type (VIVT/VIPT/PIPT) specific.
> + *
> + * flush_cache_kern_all()
> + *
> + * Unconditionally clean and invalidate the entire cache.
> + *
> + * flush_cache_user_mm(mm)
> + *
> + * Clean and invalidate all user space cache entries
> + * before a change of page tables.
> + *
> + * flush_cache_user_range(start, end, flags)
> + *
> + * Clean and invalidate a range of cache entries in the
> + * specified address space before a change of page tables.
> + * - start - user start address (inclusive, page aligned)
> + * - end - user end address (exclusive, page aligned)
> + * - flags - vma->vm_flags field
> + *
> + * coherent_kern_range(start, end)
> + *
> + * Ensure coherency between the Icache and the Dcache in the
> + * region described by start, end. If you have non-snooping
> + * Harvard caches, you need to implement this function.
> + * - start - virtual start address
> + * - end - virtual end address
> + *
> + * coherent_user_range(start, end)
> + *
> + * Ensure coherency between the Icache and the Dcache in the
> + * region described by start, end. If you have non-snooping
> + * Harvard caches, you need to implement this function.
> + * - start - virtual start address
> + * - end - virtual end address
> + *
> + * flush_kern_dcache_area(kaddr, size)
> + *
> + * Ensure that the data held in page is written back.
> + * - kaddr - page address
> + * - size - region size
> + *
> + * DMA Cache Coherency
> + * ===================
> + *
> + * dma_flush_range(start, end)
> + *
> + * Clean and invalidate the specified virtual address range.
> + * - start - virtual start address
> + * - end - virtual end address
> + */
> +extern void __cpuc_flush_kern_all(void);
> +extern void __cpuc_flush_user_all(void);
> +extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
> +extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
> +extern void __cpuc_coherent_user_range(unsigned long, unsigned long);
> +extern void __cpuc_flush_dcache_area(void *, size_t);
> +
> +/*
> + * These are private to the dma-mapping API. Do not use directly.
> + * Their sole purpose is to ensure that data held in the cache
> + * is visible to DMA, or data written by DMA to system memory is
> + * visible to the CPU.
> + */
> +extern void dmac_map_area(const void *, size_t, int);
> +extern void dmac_unmap_area(const void *, size_t, int);
> +extern void dmac_flush_range(const void *, const void *);
> +
> +/*
> + * Copy user data from/to a page which is mapped into a different
> + * processes address space. Really, we want to allow our "user
> + * space" model to handle this.
> + */
> +extern void copy_to_user_page(struct vm_area_struct *, struct page *,
> + unsigned long, void *, const void *, unsigned long);
> +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
> + do { \
> + memcpy(dst, src, len); \
> + } while (0)
> +
> +/*
> + * Convert calls to our calling convention.
> + */
> +#define flush_cache_all() __cpuc_flush_kern_all()
> +extern void flush_cache_mm(struct mm_struct *mm);
> +extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
> +extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn);
> +
> +#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
> +
> +/*
> + * flush_cache_user_range is used when we want to ensure that the
> + * Harvard caches are synchronised for the user space address range.
> + * This is used for the ARM private sys_cacheflush system call.
> + */
> +#define flush_cache_user_range(start, end) \
> + __cpuc_coherent_user_range((start)& PAGE_MASK, PAGE_ALIGN(end))
> +
> +/*
> + * Perform necessary cache operations to ensure that data previously
> + * stored within this range of addresses can be executed by the CPU.
> + */
> +#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e)
> +
> +/*
> + * flush_dcache_page is used when the kernel has written to the page
> + * cache page at virtual address page->virtual.
> + *
> + * If this page isn't mapped (ie, page_mapping == NULL), or it might
> + * have userspace mappings, then we _must_ always clean + invalidate
> + * the dcache entries associated with the kernel mapping.
> + *
> + * Otherwise we can defer the operation, and clean the cache when we are
> + * about to change to user space. This is the same method as used on SPARC64.
> + * See update_mmu_cache for the user space part.
> + */
> +#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
> +extern void flush_dcache_page(struct page *);
> +
> +static inline void __flush_icache_all(void)
> +{
> + asm("ic ialluis");
> +}
> +
> +#define ARCH_HAS_FLUSH_ANON_PAGE
> +static inline void flush_anon_page(struct vm_area_struct *vma,
> + struct page *page, unsigned long vmaddr)
> +{
> + extern void __flush_anon_page(struct vm_area_struct *vma,
> + struct page *, unsigned long);
> + if (PageAnon(page))
> + __flush_anon_page(vma, page, vmaddr);
> +}
> +
> +#define flush_dcache_mmap_lock(mapping) \
> + spin_lock_irq(&(mapping)->tree_lock)
> +#define flush_dcache_mmap_unlock(mapping) \
> + spin_unlock_irq(&(mapping)->tree_lock)
> +
> +#define flush_icache_user_range(vma,page,addr,len) \
> + flush_dcache_page(page)
> +
> +/*
> + * We don't appear to need to do anything here. In fact, if we did, we'd
> + * duplicate cache flushing elsewhere performed by flush_dcache_page().
> + */
> +#define flush_icache_page(vma,page) do { } while (0)
> +
> +/*
> + * flush_cache_vmap() is used when creating mappings (eg, via vmap,
> + * vmalloc, ioremap etc) in kernel space for pages. On non-VIPT
> + * caches, since the direct-mappings of these pages may contain cached
> + * data, we need to do a full cache flush to ensure that writebacks
> + * don't corrupt data placed into these pages via the new mappings.
> + */
> +static inline void flush_cache_vmap(unsigned long start, unsigned long end)
> +{
> + /*
> + * set_pte_at() called from vmap_pte_range() does not
> + * have a DSB after cleaning the cache line.
> + */
> + dsb();
> +}
> +
> +static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
> +{
> +}
> +
> +#endif
> diff --git a/arch/arm64/include/asm/cachetype.h b/arch/arm64/include/asm/cachetype.h
> new file mode 100644
> index 0000000..85f5f51
> --- /dev/null
> +++ b/arch/arm64/include/asm/cachetype.h
> @@ -0,0 +1,48 @@
> +/*
> + * Copyright (C) 2012 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see<http://www.gnu.org/licenses/>.
> + */
> +#ifndef __ASM_CACHETYPE_H
> +#define __ASM_CACHETYPE_H
> +
> +#include<asm/cputype.h>
> +
> +#define CTR_L1IP_SHIFT 14
> +#define CTR_L1IP_MASK 3
> +
> +#define ICACHE_POLICY_RESERVED 0
> +#define ICACHE_POLICY_AIVIVT 1
> +#define ICACHE_POLICY_VIPT 2
> +#define ICACHE_POLICY_PIPT 3
> +
> +static inline u32 icache_policy(void)
> +{
> + return (read_cpuid_cachetype()>> CTR_L1IP_SHIFT)& CTR_L1IP_MASK;
> +}
> +
> +/*
> + * Whilst the D-side always behaves as PIPT on AArch64, aliasing is
> + * permitted in the I-cache.
> + */
> +static inline int icache_is_aliasing(void)
> +{
> + return icache_policy() != ICACHE_POLICY_PIPT;
> +}
> +
> +static inline int icache_is_aivivt(void)
> +{
> + return icache_policy() == ICACHE_POLICY_AIVIVT;
> +}
> +
> +#endif /* __ASM_CACHETYPE_H */
> diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
> new file mode 100644
> index 0000000..f4efa04
> --- /dev/null
> +++ b/arch/arm64/mm/cache.S
> @@ -0,0 +1,279 @@
> +/*
> + * Cache maintenance
> + *
> + * Copyright (C) 2001 Deep Blue Solutions Ltd.
> + * Copyright (C) 2012 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see<http://www.gnu.org/licenses/>.
> + */
> +
> +#include<linux/linkage.h>
> +#include<linux/init.h>
> +#include<asm/assembler.h>
> +
> +#include "proc-macros.S"
> +
> +/*
> + * __cpuc_flush_dcache_all()
> + *
> + * Flush the whole D-cache.
> + *
> + * Corrupted registers: x0-x7, x9-x11
> + */
> +ENTRY(__cpuc_flush_dcache_all)
> + dsb sy // ensure ordering with previous memory accesses
> + mrs x0, clidr_el1 // read clidr
> + and x3, x0, #0x7000000 // extract loc from clidr
> + lsr x3, x3, #23 // left align loc bit field
> + cbz x3, finished // if loc is 0, then no need to clean
> + mov x10, #0 // start clean at cache level 0
> +loop1:
> + add x2, x10, x10, lsr #1 // work out 3x current cache level
> + lsr x1, x0, x2 // extract cache type bits from clidr
> + and x1, x1, #7 // mask of the bits for current cache only
> + cmp x1, #2 // see what cache we have at this level
> + b.lt skip // skip if no cache, or just i-cache
> + save_and_disable_irqs x9 // make CSSELR and CCSIDR access atomic
> + msr csselr_el1, x10 // select current cache level in csselr
> + isb // isb to sych the new cssr&csidr
> + mrs x1, ccsidr_el1 // read the new ccsidr
> + restore_irqs x9
> + and x2, x1, #7 // extract the length of the cache lines
> + add x2, x2, #4 // add 4 (line length offset)
> + mov x4, #0x3ff
> + and x4, x4, x1, lsr #3 // find maximum number on the way size
> + clz x5, x4 // find bit position of way size increment
> + mov x7, #0x7fff
> + and x7, x7, x1, lsr #13 // extract max number of the index size
> +loop2:
> + mov x9, x4 // create working copy of max way size
> +loop3:
> + lsl x6, x9, x5
> + orr x11, x10, x6 // factor way and cache number into x11
> + lsl x6, x7, x2
> + orr x11, x11, x6 // factor index number into x11
> + dc cisw, x11 // clean& invalidate by set/way
> + subs x9, x9, #1 // decrement the way
> + b.ge loop3
> + subs x7, x7, #1 // decrement the index
> + b.ge loop2
> +skip:
> + add x10, x10, #2 // increment cache number
> + cmp x3, x10
> + b.gt loop1
> +finished:
> + mov x10, #0 // swith back to cache level 0
> + msr csselr_el1, x10 // select current cache level in csselr
> + dsb sy
> + isb
> + ret
> +ENDPROC(__cpuc_flush_dcache_all)
> +
>
We have discussed the need of cache maintenance by
level kind of API for ARMv7 (A15).
Shouldn't we add such API for arm64 as well ?
Regards
Santosh
WARNING: multiple messages have this Message-ID (diff)
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
To: Catalin Marinas <catalin.marinas@arm.com>
Cc: linux-arch@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Arnd Bergmann <arnd@arndb.de>,
Will Deacon <will.deacon@arm.com>
Subject: Re: [PATCH v2 09/31] arm64: Cache maintenance routines
Date: Fri, 17 Aug 2012 15:27:20 +0530 [thread overview]
Message-ID: <502E1580.70702@ti.com> (raw)
Message-ID: <20120817095720.Gsen65xbTMpJtHlojc0K0is5RVlHZXYZHzXi_3qv3N8@z> (raw)
In-Reply-To: <1344966752-16102-10-git-send-email-catalin.marinas@arm.com>
On Tuesday 14 August 2012 11:22 PM, Catalin Marinas wrote:
> The patch adds functionality required for cache maintenance. The AArch64
> architecture mandates non-aliasing VIPT or PIPT D-cache and VIPT (may
> have aliases) or ASID-tagged VIVT I-cache. Cache maintenance operations
> are automatically broadcast in hardware between CPUs.
>
> Signed-off-by: Will Deacon<will.deacon@arm.com>
> Signed-off-by: Catalin Marinas<catalin.marinas@arm.com>
> ---
> arch/arm64/include/asm/cache.h | 32 ++++
> arch/arm64/include/asm/cacheflush.h | 209 ++++++++++++++++++++++++++
> arch/arm64/include/asm/cachetype.h | 48 ++++++
> arch/arm64/mm/cache.S | 279 +++++++++++++++++++++++++++++++++++
> arch/arm64/mm/flush.c | 132 +++++++++++++++++
> 5 files changed, 700 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm64/include/asm/cache.h
> create mode 100644 arch/arm64/include/asm/cacheflush.h
> create mode 100644 arch/arm64/include/asm/cachetype.h
> create mode 100644 arch/arm64/mm/cache.S
> create mode 100644 arch/arm64/mm/flush.c
>
> diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h
> new file mode 100644
> index 0000000..390308a
> --- /dev/null
> +++ b/arch/arm64/include/asm/cache.h
> @@ -0,0 +1,32 @@
> +/*
> + * Copyright (C) 2012 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see<http://www.gnu.org/licenses/>.
> + */
> +#ifndef __ASM_CACHE_H
> +#define __ASM_CACHE_H
> +
> +#define L1_CACHE_SHIFT 6
> +#define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT)
> +
> +/*
> + * Memory returned by kmalloc() may be used for DMA, so we must make
> + * sure that all such allocations are cache aligned. Otherwise,
> + * unrelated code may cause parts of the buffer to be read into the
> + * cache before the transfer is done, causing old data to be seen by
> + * the CPU.
> + */
> +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
> +#define ARCH_SLAB_MINALIGN 8
> +
> +#endif
> diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
> new file mode 100644
> index 0000000..93b5590
> --- /dev/null
> +++ b/arch/arm64/include/asm/cacheflush.h
> @@ -0,0 +1,209 @@
> +/*
> + * Based on arch/arm/include/asm/cacheflush.h
> + *
> + * Copyright (C) 1999-2002 Russell King.
> + * Copyright (C) 2012 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see<http://www.gnu.org/licenses/>.
> + */
> +#ifndef __ASM_CACHEFLUSH_H
> +#define __ASM_CACHEFLUSH_H
> +
> +#include<linux/mm.h>
> +
> +/*
> + * This flag is used to indicate that the page pointed to by a pte is clean
> + * and does not require cleaning before returning it to the user.
> + */
> +#define PG_dcache_clean PG_arch_1
> +
> +/*
> + * MM Cache Management
> + * ===================
> + *
> + * The arch/arm/mm/cache-*.S and arch/arm/mm/proc-*.S files
> + * implement these methods.
> + *
> + * Start addresses are inclusive and end addresses are exclusive;
> + * start addresses should be rounded down, end addresses up.
> + *
> + * See Documentation/cachetlb.txt for more information.
> + * Please note that the implementation of these, and the required
> + * effects are cache-type (VIVT/VIPT/PIPT) specific.
> + *
> + * flush_cache_kern_all()
> + *
> + * Unconditionally clean and invalidate the entire cache.
> + *
> + * flush_cache_user_mm(mm)
> + *
> + * Clean and invalidate all user space cache entries
> + * before a change of page tables.
> + *
> + * flush_cache_user_range(start, end, flags)
> + *
> + * Clean and invalidate a range of cache entries in the
> + * specified address space before a change of page tables.
> + * - start - user start address (inclusive, page aligned)
> + * - end - user end address (exclusive, page aligned)
> + * - flags - vma->vm_flags field
> + *
> + * coherent_kern_range(start, end)
> + *
> + * Ensure coherency between the Icache and the Dcache in the
> + * region described by start, end. If you have non-snooping
> + * Harvard caches, you need to implement this function.
> + * - start - virtual start address
> + * - end - virtual end address
> + *
> + * coherent_user_range(start, end)
> + *
> + * Ensure coherency between the Icache and the Dcache in the
> + * region described by start, end. If you have non-snooping
> + * Harvard caches, you need to implement this function.
> + * - start - virtual start address
> + * - end - virtual end address
> + *
> + * flush_kern_dcache_area(kaddr, size)
> + *
> + * Ensure that the data held in page is written back.
> + * - kaddr - page address
> + * - size - region size
> + *
> + * DMA Cache Coherency
> + * ===================
> + *
> + * dma_flush_range(start, end)
> + *
> + * Clean and invalidate the specified virtual address range.
> + * - start - virtual start address
> + * - end - virtual end address
> + */
> +extern void __cpuc_flush_kern_all(void);
> +extern void __cpuc_flush_user_all(void);
> +extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
> +extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
> +extern void __cpuc_coherent_user_range(unsigned long, unsigned long);
> +extern void __cpuc_flush_dcache_area(void *, size_t);
> +
> +/*
> + * These are private to the dma-mapping API. Do not use directly.
> + * Their sole purpose is to ensure that data held in the cache
> + * is visible to DMA, or data written by DMA to system memory is
> + * visible to the CPU.
> + */
> +extern void dmac_map_area(const void *, size_t, int);
> +extern void dmac_unmap_area(const void *, size_t, int);
> +extern void dmac_flush_range(const void *, const void *);
> +
> +/*
> + * Copy user data from/to a page which is mapped into a different
> + * processes address space. Really, we want to allow our "user
> + * space" model to handle this.
> + */
> +extern void copy_to_user_page(struct vm_area_struct *, struct page *,
> + unsigned long, void *, const void *, unsigned long);
> +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
> + do { \
> + memcpy(dst, src, len); \
> + } while (0)
> +
> +/*
> + * Convert calls to our calling convention.
> + */
> +#define flush_cache_all() __cpuc_flush_kern_all()
> +extern void flush_cache_mm(struct mm_struct *mm);
> +extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
> +extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn);
> +
> +#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
> +
> +/*
> + * flush_cache_user_range is used when we want to ensure that the
> + * Harvard caches are synchronised for the user space address range.
> + * This is used for the ARM private sys_cacheflush system call.
> + */
> +#define flush_cache_user_range(start, end) \
> + __cpuc_coherent_user_range((start)& PAGE_MASK, PAGE_ALIGN(end))
> +
> +/*
> + * Perform necessary cache operations to ensure that data previously
> + * stored within this range of addresses can be executed by the CPU.
> + */
> +#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e)
> +
> +/*
> + * flush_dcache_page is used when the kernel has written to the page
> + * cache page at virtual address page->virtual.
> + *
> + * If this page isn't mapped (ie, page_mapping == NULL), or it might
> + * have userspace mappings, then we _must_ always clean + invalidate
> + * the dcache entries associated with the kernel mapping.
> + *
> + * Otherwise we can defer the operation, and clean the cache when we are
> + * about to change to user space. This is the same method as used on SPARC64.
> + * See update_mmu_cache for the user space part.
> + */
> +#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
> +extern void flush_dcache_page(struct page *);
> +
> +static inline void __flush_icache_all(void)
> +{
> + asm("ic ialluis");
> +}
> +
> +#define ARCH_HAS_FLUSH_ANON_PAGE
> +static inline void flush_anon_page(struct vm_area_struct *vma,
> + struct page *page, unsigned long vmaddr)
> +{
> + extern void __flush_anon_page(struct vm_area_struct *vma,
> + struct page *, unsigned long);
> + if (PageAnon(page))
> + __flush_anon_page(vma, page, vmaddr);
> +}
> +
> +#define flush_dcache_mmap_lock(mapping) \
> + spin_lock_irq(&(mapping)->tree_lock)
> +#define flush_dcache_mmap_unlock(mapping) \
> + spin_unlock_irq(&(mapping)->tree_lock)
> +
> +#define flush_icache_user_range(vma,page,addr,len) \
> + flush_dcache_page(page)
> +
> +/*
> + * We don't appear to need to do anything here. In fact, if we did, we'd
> + * duplicate cache flushing elsewhere performed by flush_dcache_page().
> + */
> +#define flush_icache_page(vma,page) do { } while (0)
> +
> +/*
> + * flush_cache_vmap() is used when creating mappings (eg, via vmap,
> + * vmalloc, ioremap etc) in kernel space for pages. On non-VIPT
> + * caches, since the direct-mappings of these pages may contain cached
> + * data, we need to do a full cache flush to ensure that writebacks
> + * don't corrupt data placed into these pages via the new mappings.
> + */
> +static inline void flush_cache_vmap(unsigned long start, unsigned long end)
> +{
> + /*
> + * set_pte_at() called from vmap_pte_range() does not
> + * have a DSB after cleaning the cache line.
> + */
> + dsb();
> +}
> +
> +static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
> +{
> +}
> +
> +#endif
> diff --git a/arch/arm64/include/asm/cachetype.h b/arch/arm64/include/asm/cachetype.h
> new file mode 100644
> index 0000000..85f5f51
> --- /dev/null
> +++ b/arch/arm64/include/asm/cachetype.h
> @@ -0,0 +1,48 @@
> +/*
> + * Copyright (C) 2012 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see<http://www.gnu.org/licenses/>.
> + */
> +#ifndef __ASM_CACHETYPE_H
> +#define __ASM_CACHETYPE_H
> +
> +#include<asm/cputype.h>
> +
> +#define CTR_L1IP_SHIFT 14
> +#define CTR_L1IP_MASK 3
> +
> +#define ICACHE_POLICY_RESERVED 0
> +#define ICACHE_POLICY_AIVIVT 1
> +#define ICACHE_POLICY_VIPT 2
> +#define ICACHE_POLICY_PIPT 3
> +
> +static inline u32 icache_policy(void)
> +{
> + return (read_cpuid_cachetype()>> CTR_L1IP_SHIFT)& CTR_L1IP_MASK;
> +}
> +
> +/*
> + * Whilst the D-side always behaves as PIPT on AArch64, aliasing is
> + * permitted in the I-cache.
> + */
> +static inline int icache_is_aliasing(void)
> +{
> + return icache_policy() != ICACHE_POLICY_PIPT;
> +}
> +
> +static inline int icache_is_aivivt(void)
> +{
> + return icache_policy() == ICACHE_POLICY_AIVIVT;
> +}
> +
> +#endif /* __ASM_CACHETYPE_H */
> diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
> new file mode 100644
> index 0000000..f4efa04
> --- /dev/null
> +++ b/arch/arm64/mm/cache.S
> @@ -0,0 +1,279 @@
> +/*
> + * Cache maintenance
> + *
> + * Copyright (C) 2001 Deep Blue Solutions Ltd.
> + * Copyright (C) 2012 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see<http://www.gnu.org/licenses/>.
> + */
> +
> +#include<linux/linkage.h>
> +#include<linux/init.h>
> +#include<asm/assembler.h>
> +
> +#include "proc-macros.S"
> +
> +/*
> + * __cpuc_flush_dcache_all()
> + *
> + * Flush the whole D-cache.
> + *
> + * Corrupted registers: x0-x7, x9-x11
> + */
> +ENTRY(__cpuc_flush_dcache_all)
> + dsb sy // ensure ordering with previous memory accesses
> + mrs x0, clidr_el1 // read clidr
> + and x3, x0, #0x7000000 // extract loc from clidr
> + lsr x3, x3, #23 // left align loc bit field
> + cbz x3, finished // if loc is 0, then no need to clean
> + mov x10, #0 // start clean at cache level 0
> +loop1:
> + add x2, x10, x10, lsr #1 // work out 3x current cache level
> + lsr x1, x0, x2 // extract cache type bits from clidr
> + and x1, x1, #7 // mask of the bits for current cache only
> + cmp x1, #2 // see what cache we have at this level
> + b.lt skip // skip if no cache, or just i-cache
> + save_and_disable_irqs x9 // make CSSELR and CCSIDR access atomic
> + msr csselr_el1, x10 // select current cache level in csselr
> + isb // isb to sych the new cssr&csidr
> + mrs x1, ccsidr_el1 // read the new ccsidr
> + restore_irqs x9
> + and x2, x1, #7 // extract the length of the cache lines
> + add x2, x2, #4 // add 4 (line length offset)
> + mov x4, #0x3ff
> + and x4, x4, x1, lsr #3 // find maximum number on the way size
> + clz x5, x4 // find bit position of way size increment
> + mov x7, #0x7fff
> + and x7, x7, x1, lsr #13 // extract max number of the index size
> +loop2:
> + mov x9, x4 // create working copy of max way size
> +loop3:
> + lsl x6, x9, x5
> + orr x11, x10, x6 // factor way and cache number into x11
> + lsl x6, x7, x2
> + orr x11, x11, x6 // factor index number into x11
> + dc cisw, x11 // clean& invalidate by set/way
> + subs x9, x9, #1 // decrement the way
> + b.ge loop3
> + subs x7, x7, #1 // decrement the index
> + b.ge loop2
> +skip:
> + add x10, x10, #2 // increment cache number
> + cmp x3, x10
> + b.gt loop1
> +finished:
> + mov x10, #0 // swith back to cache level 0
> + msr csselr_el1, x10 // select current cache level in csselr
> + dsb sy
> + isb
> + ret
> +ENDPROC(__cpuc_flush_dcache_all)
> +
>
We have discussed the need of cache maintenance by
level kind of API for ARMv7 (A15).
Shouldn't we add such API for arm64 as well ?
Regards
Santosh
WARNING: multiple messages have this Message-ID (diff)
From: santosh.shilimkar@ti.com (Santosh Shilimkar)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 09/31] arm64: Cache maintenance routines
Date: Fri, 17 Aug 2012 15:27:20 +0530 [thread overview]
Message-ID: <502E1580.70702@ti.com> (raw)
In-Reply-To: <1344966752-16102-10-git-send-email-catalin.marinas@arm.com>
On Tuesday 14 August 2012 11:22 PM, Catalin Marinas wrote:
> The patch adds functionality required for cache maintenance. The AArch64
> architecture mandates non-aliasing VIPT or PIPT D-cache and VIPT (may
> have aliases) or ASID-tagged VIVT I-cache. Cache maintenance operations
> are automatically broadcast in hardware between CPUs.
>
> Signed-off-by: Will Deacon<will.deacon@arm.com>
> Signed-off-by: Catalin Marinas<catalin.marinas@arm.com>
> ---
> arch/arm64/include/asm/cache.h | 32 ++++
> arch/arm64/include/asm/cacheflush.h | 209 ++++++++++++++++++++++++++
> arch/arm64/include/asm/cachetype.h | 48 ++++++
> arch/arm64/mm/cache.S | 279 +++++++++++++++++++++++++++++++++++
> arch/arm64/mm/flush.c | 132 +++++++++++++++++
> 5 files changed, 700 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm64/include/asm/cache.h
> create mode 100644 arch/arm64/include/asm/cacheflush.h
> create mode 100644 arch/arm64/include/asm/cachetype.h
> create mode 100644 arch/arm64/mm/cache.S
> create mode 100644 arch/arm64/mm/flush.c
>
> diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h
> new file mode 100644
> index 0000000..390308a
> --- /dev/null
> +++ b/arch/arm64/include/asm/cache.h
> @@ -0,0 +1,32 @@
> +/*
> + * Copyright (C) 2012 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see<http://www.gnu.org/licenses/>.
> + */
> +#ifndef __ASM_CACHE_H
> +#define __ASM_CACHE_H
> +
> +#define L1_CACHE_SHIFT 6
> +#define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT)
> +
> +/*
> + * Memory returned by kmalloc() may be used for DMA, so we must make
> + * sure that all such allocations are cache aligned. Otherwise,
> + * unrelated code may cause parts of the buffer to be read into the
> + * cache before the transfer is done, causing old data to be seen by
> + * the CPU.
> + */
> +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
> +#define ARCH_SLAB_MINALIGN 8
> +
> +#endif
> diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
> new file mode 100644
> index 0000000..93b5590
> --- /dev/null
> +++ b/arch/arm64/include/asm/cacheflush.h
> @@ -0,0 +1,209 @@
> +/*
> + * Based on arch/arm/include/asm/cacheflush.h
> + *
> + * Copyright (C) 1999-2002 Russell King.
> + * Copyright (C) 2012 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see<http://www.gnu.org/licenses/>.
> + */
> +#ifndef __ASM_CACHEFLUSH_H
> +#define __ASM_CACHEFLUSH_H
> +
> +#include<linux/mm.h>
> +
> +/*
> + * This flag is used to indicate that the page pointed to by a pte is clean
> + * and does not require cleaning before returning it to the user.
> + */
> +#define PG_dcache_clean PG_arch_1
> +
> +/*
> + * MM Cache Management
> + * ===================
> + *
> + * The arch/arm/mm/cache-*.S and arch/arm/mm/proc-*.S files
> + * implement these methods.
> + *
> + * Start addresses are inclusive and end addresses are exclusive;
> + * start addresses should be rounded down, end addresses up.
> + *
> + * See Documentation/cachetlb.txt for more information.
> + * Please note that the implementation of these, and the required
> + * effects are cache-type (VIVT/VIPT/PIPT) specific.
> + *
> + * flush_cache_kern_all()
> + *
> + * Unconditionally clean and invalidate the entire cache.
> + *
> + * flush_cache_user_mm(mm)
> + *
> + * Clean and invalidate all user space cache entries
> + * before a change of page tables.
> + *
> + * flush_cache_user_range(start, end, flags)
> + *
> + * Clean and invalidate a range of cache entries in the
> + * specified address space before a change of page tables.
> + * - start - user start address (inclusive, page aligned)
> + * - end - user end address (exclusive, page aligned)
> + * - flags - vma->vm_flags field
> + *
> + * coherent_kern_range(start, end)
> + *
> + * Ensure coherency between the Icache and the Dcache in the
> + * region described by start, end. If you have non-snooping
> + * Harvard caches, you need to implement this function.
> + * - start - virtual start address
> + * - end - virtual end address
> + *
> + * coherent_user_range(start, end)
> + *
> + * Ensure coherency between the Icache and the Dcache in the
> + * region described by start, end. If you have non-snooping
> + * Harvard caches, you need to implement this function.
> + * - start - virtual start address
> + * - end - virtual end address
> + *
> + * flush_kern_dcache_area(kaddr, size)
> + *
> + * Ensure that the data held in page is written back.
> + * - kaddr - page address
> + * - size - region size
> + *
> + * DMA Cache Coherency
> + * ===================
> + *
> + * dma_flush_range(start, end)
> + *
> + * Clean and invalidate the specified virtual address range.
> + * - start - virtual start address
> + * - end - virtual end address
> + */
> +extern void __cpuc_flush_kern_all(void);
> +extern void __cpuc_flush_user_all(void);
> +extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
> +extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
> +extern void __cpuc_coherent_user_range(unsigned long, unsigned long);
> +extern void __cpuc_flush_dcache_area(void *, size_t);
> +
> +/*
> + * These are private to the dma-mapping API. Do not use directly.
> + * Their sole purpose is to ensure that data held in the cache
> + * is visible to DMA, or data written by DMA to system memory is
> + * visible to the CPU.
> + */
> +extern void dmac_map_area(const void *, size_t, int);
> +extern void dmac_unmap_area(const void *, size_t, int);
> +extern void dmac_flush_range(const void *, const void *);
> +
> +/*
> + * Copy user data from/to a page which is mapped into a different
> + * processes address space. Really, we want to allow our "user
> + * space" model to handle this.
> + */
> +extern void copy_to_user_page(struct vm_area_struct *, struct page *,
> + unsigned long, void *, const void *, unsigned long);
> +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
> + do { \
> + memcpy(dst, src, len); \
> + } while (0)
> +
> +/*
> + * Convert calls to our calling convention.
> + */
> +#define flush_cache_all() __cpuc_flush_kern_all()
> +extern void flush_cache_mm(struct mm_struct *mm);
> +extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
> +extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn);
> +
> +#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
> +
> +/*
> + * flush_cache_user_range is used when we want to ensure that the
> + * Harvard caches are synchronised for the user space address range.
> + * This is used for the ARM private sys_cacheflush system call.
> + */
> +#define flush_cache_user_range(start, end) \
> + __cpuc_coherent_user_range((start)& PAGE_MASK, PAGE_ALIGN(end))
> +
> +/*
> + * Perform necessary cache operations to ensure that data previously
> + * stored within this range of addresses can be executed by the CPU.
> + */
> +#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e)
> +
> +/*
> + * flush_dcache_page is used when the kernel has written to the page
> + * cache page at virtual address page->virtual.
> + *
> + * If this page isn't mapped (ie, page_mapping == NULL), or it might
> + * have userspace mappings, then we _must_ always clean + invalidate
> + * the dcache entries associated with the kernel mapping.
> + *
> + * Otherwise we can defer the operation, and clean the cache when we are
> + * about to change to user space. This is the same method as used on SPARC64.
> + * See update_mmu_cache for the user space part.
> + */
> +#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
> +extern void flush_dcache_page(struct page *);
> +
> +static inline void __flush_icache_all(void)
> +{
> + asm("ic ialluis");
> +}
> +
> +#define ARCH_HAS_FLUSH_ANON_PAGE
> +static inline void flush_anon_page(struct vm_area_struct *vma,
> + struct page *page, unsigned long vmaddr)
> +{
> + extern void __flush_anon_page(struct vm_area_struct *vma,
> + struct page *, unsigned long);
> + if (PageAnon(page))
> + __flush_anon_page(vma, page, vmaddr);
> +}
> +
> +#define flush_dcache_mmap_lock(mapping) \
> + spin_lock_irq(&(mapping)->tree_lock)
> +#define flush_dcache_mmap_unlock(mapping) \
> + spin_unlock_irq(&(mapping)->tree_lock)
> +
> +#define flush_icache_user_range(vma,page,addr,len) \
> + flush_dcache_page(page)
> +
> +/*
> + * We don't appear to need to do anything here. In fact, if we did, we'd
> + * duplicate cache flushing elsewhere performed by flush_dcache_page().
> + */
> +#define flush_icache_page(vma,page) do { } while (0)
> +
> +/*
> + * flush_cache_vmap() is used when creating mappings (eg, via vmap,
> + * vmalloc, ioremap etc) in kernel space for pages. On non-VIPT
> + * caches, since the direct-mappings of these pages may contain cached
> + * data, we need to do a full cache flush to ensure that writebacks
> + * don't corrupt data placed into these pages via the new mappings.
> + */
> +static inline void flush_cache_vmap(unsigned long start, unsigned long end)
> +{
> + /*
> + * set_pte_at() called from vmap_pte_range() does not
> + * have a DSB after cleaning the cache line.
> + */
> + dsb();
> +}
> +
> +static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
> +{
> +}
> +
> +#endif
> diff --git a/arch/arm64/include/asm/cachetype.h b/arch/arm64/include/asm/cachetype.h
> new file mode 100644
> index 0000000..85f5f51
> --- /dev/null
> +++ b/arch/arm64/include/asm/cachetype.h
> @@ -0,0 +1,48 @@
> +/*
> + * Copyright (C) 2012 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see<http://www.gnu.org/licenses/>.
> + */
> +#ifndef __ASM_CACHETYPE_H
> +#define __ASM_CACHETYPE_H
> +
> +#include<asm/cputype.h>
> +
> +#define CTR_L1IP_SHIFT 14
> +#define CTR_L1IP_MASK 3
> +
> +#define ICACHE_POLICY_RESERVED 0
> +#define ICACHE_POLICY_AIVIVT 1
> +#define ICACHE_POLICY_VIPT 2
> +#define ICACHE_POLICY_PIPT 3
> +
> +static inline u32 icache_policy(void)
> +{
> + return (read_cpuid_cachetype()>> CTR_L1IP_SHIFT)& CTR_L1IP_MASK;
> +}
> +
> +/*
> + * Whilst the D-side always behaves as PIPT on AArch64, aliasing is
> + * permitted in the I-cache.
> + */
> +static inline int icache_is_aliasing(void)
> +{
> + return icache_policy() != ICACHE_POLICY_PIPT;
> +}
> +
> +static inline int icache_is_aivivt(void)
> +{
> + return icache_policy() == ICACHE_POLICY_AIVIVT;
> +}
> +
> +#endif /* __ASM_CACHETYPE_H */
> diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
> new file mode 100644
> index 0000000..f4efa04
> --- /dev/null
> +++ b/arch/arm64/mm/cache.S
> @@ -0,0 +1,279 @@
> +/*
> + * Cache maintenance
> + *
> + * Copyright (C) 2001 Deep Blue Solutions Ltd.
> + * Copyright (C) 2012 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see<http://www.gnu.org/licenses/>.
> + */
> +
> +#include<linux/linkage.h>
> +#include<linux/init.h>
> +#include<asm/assembler.h>
> +
> +#include "proc-macros.S"
> +
> +/*
> + * __cpuc_flush_dcache_all()
> + *
> + * Flush the whole D-cache.
> + *
> + * Corrupted registers: x0-x7, x9-x11
> + */
> +ENTRY(__cpuc_flush_dcache_all)
> + dsb sy // ensure ordering with previous memory accesses
> + mrs x0, clidr_el1 // read clidr
> + and x3, x0, #0x7000000 // extract loc from clidr
> + lsr x3, x3, #23 // left align loc bit field
> + cbz x3, finished // if loc is 0, then no need to clean
> + mov x10, #0 // start clean at cache level 0
> +loop1:
> + add x2, x10, x10, lsr #1 // work out 3x current cache level
> + lsr x1, x0, x2 // extract cache type bits from clidr
> + and x1, x1, #7 // mask of the bits for current cache only
> + cmp x1, #2 // see what cache we have at this level
> + b.lt skip // skip if no cache, or just i-cache
> + save_and_disable_irqs x9 // make CSSELR and CCSIDR access atomic
> + msr csselr_el1, x10 // select current cache level in csselr
> + isb // isb to sych the new cssr&csidr
> + mrs x1, ccsidr_el1 // read the new ccsidr
> + restore_irqs x9
> + and x2, x1, #7 // extract the length of the cache lines
> + add x2, x2, #4 // add 4 (line length offset)
> + mov x4, #0x3ff
> + and x4, x4, x1, lsr #3 // find maximum number on the way size
> + clz x5, x4 // find bit position of way size increment
> + mov x7, #0x7fff
> + and x7, x7, x1, lsr #13 // extract max number of the index size
> +loop2:
> + mov x9, x4 // create working copy of max way size
> +loop3:
> + lsl x6, x9, x5
> + orr x11, x10, x6 // factor way and cache number into x11
> + lsl x6, x7, x2
> + orr x11, x11, x6 // factor index number into x11
> + dc cisw, x11 // clean& invalidate by set/way
> + subs x9, x9, #1 // decrement the way
> + b.ge loop3
> + subs x7, x7, #1 // decrement the index
> + b.ge loop2
> +skip:
> + add x10, x10, #2 // increment cache number
> + cmp x3, x10
> + b.gt loop1
> +finished:
> + mov x10, #0 // swith back to cache level 0
> + msr csselr_el1, x10 // select current cache level in csselr
> + dsb sy
> + isb
> + ret
> +ENDPROC(__cpuc_flush_dcache_all)
> +
>
We have discussed the need of cache maintenance by
level kind of API for ARMv7 (A15).
Shouldn't we add such API for arm64 as well ?
Regards
Santosh
next prev parent reply other threads:[~2012-08-17 9:57 UTC|newest]
Thread overview: 365+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-14 17:52 [PATCH v2 00/31] AArch64 Linux kernel port Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 17:52 ` [PATCH v2 01/31] arm64: Assembly macros and definitions Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 12:57 ` Arnd Bergmann
2012-08-15 12:57 ` Arnd Bergmann
2012-08-14 17:52 ` [PATCH v2 02/31] arm64: Kernel booting and initialisation Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 23:06 ` Olof Johansson
2012-08-14 23:06 ` Olof Johansson
2012-08-15 17:37 ` Catalin Marinas
2012-08-15 17:37 ` Catalin Marinas
2012-08-15 19:03 ` Olof Johansson
2012-08-15 19:03 ` Olof Johansson
2012-08-15 19:03 ` Olof Johansson
2012-08-15 19:53 ` Catalin Marinas
2012-08-15 19:53 ` Catalin Marinas
2012-08-15 19:53 ` Catalin Marinas
2012-08-15 13:20 ` Arnd Bergmann
2012-08-15 13:20 ` Arnd Bergmann
2012-08-15 17:06 ` Olof Johansson
2012-08-15 17:06 ` Olof Johansson
2012-08-16 12:53 ` Catalin Marinas
2012-08-16 12:53 ` Catalin Marinas
2012-08-16 12:53 ` Catalin Marinas
2012-08-16 18:59 ` Nicolas Pitre
2012-08-16 18:59 ` Nicolas Pitre
2012-08-17 11:20 ` Arnd Bergmann
2012-08-17 11:20 ` Arnd Bergmann
2012-08-17 13:45 ` Catalin Marinas
2012-08-17 13:45 ` Catalin Marinas
2012-08-17 18:21 ` Nicolas Pitre
2012-08-17 18:21 ` Nicolas Pitre
2012-08-17 8:56 ` Tony Lindgren
2012-08-17 8:56 ` Tony Lindgren
2012-08-17 9:41 ` Santosh Shilimkar
2012-08-17 9:41 ` Santosh Shilimkar
2012-08-17 10:05 ` Catalin Marinas
2012-08-17 10:05 ` Catalin Marinas
2012-08-17 10:05 ` Catalin Marinas
2012-08-17 10:10 ` Shilimkar, Santosh
2012-08-17 10:10 ` Shilimkar, Santosh
2012-08-17 13:13 ` Tony Lindgren
2012-08-17 13:13 ` Tony Lindgren
2012-08-17 13:48 ` Catalin Marinas
2012-08-17 13:48 ` Catalin Marinas
2012-08-24 9:50 ` Catalin Marinas
2012-08-24 9:50 ` Catalin Marinas
2012-08-14 17:52 ` [PATCH v2 03/31] arm64: Exception handling Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 23:29 ` Olof Johansson
2012-08-14 23:29 ` Olof Johansson
2012-08-14 23:47 ` Thomas Gleixner
2012-08-14 23:47 ` Thomas Gleixner
2012-08-15 13:03 ` Arnd Bergmann
2012-08-15 13:03 ` Arnd Bergmann
2012-08-16 10:05 ` Will Deacon
2012-08-16 10:05 ` Will Deacon
2012-08-16 10:05 ` Will Deacon
2012-08-16 11:54 ` Arnd Bergmann
2012-08-16 11:54 ` Arnd Bergmann
2012-08-14 17:52 ` [PATCH v2 04/31] arm64: MMU definitions Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 13:30 ` Arnd Bergmann
2012-08-15 13:30 ` Arnd Bergmann
2012-08-15 13:39 ` Catalin Marinas
2012-08-15 13:39 ` Catalin Marinas
2012-08-15 16:34 ` Geert Uytterhoeven
2012-08-15 16:34 ` Geert Uytterhoeven
2012-08-15 16:45 ` Catalin Marinas
2012-08-15 16:45 ` Catalin Marinas
2012-08-17 9:04 ` Tony Lindgren
2012-08-17 9:04 ` Tony Lindgren
2012-08-17 9:21 ` Catalin Marinas
2012-08-17 9:21 ` Catalin Marinas
2012-08-17 9:38 ` Tony Lindgren
2012-08-17 9:38 ` Tony Lindgren
2012-08-14 17:52 ` [PATCH v2 05/31] arm64: MMU initialisation Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 13:45 ` Arnd Bergmann
2012-08-15 13:45 ` Arnd Bergmann
2012-08-17 10:06 ` Santosh Shilimkar
2012-08-17 10:06 ` Santosh Shilimkar
2012-08-17 10:15 ` Catalin Marinas
2012-08-17 10:15 ` Catalin Marinas
2012-08-17 10:25 ` Shilimkar, Santosh
2012-08-17 10:25 ` Shilimkar, Santosh
2012-08-14 17:52 ` [PATCH v2 06/31] arm64: MMU fault handling and page table management Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 13:47 ` Arnd Bergmann
2012-08-15 13:47 ` Arnd Bergmann
2012-08-17 16:07 ` Catalin Marinas
2012-08-17 16:07 ` Catalin Marinas
2012-08-14 17:52 ` [PATCH v2 07/31] arm64: Process management Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 23:50 ` Olof Johansson
2012-08-14 23:50 ` Olof Johansson
2012-09-14 17:33 ` Catalin Marinas
2012-09-14 17:33 ` Catalin Marinas
2012-09-16 0:29 ` Olof Johansson
2012-09-16 0:29 ` Olof Johansson
2012-08-15 13:53 ` Arnd Bergmann
2012-08-15 13:53 ` Arnd Bergmann
2012-08-17 16:15 ` Catalin Marinas
2012-08-17 16:15 ` Catalin Marinas
2012-08-16 15:09 ` Tobias Klauser
2012-08-16 15:09 ` Tobias Klauser
2012-08-14 17:52 ` [PATCH v2 08/31] arm64: CPU support Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 0:10 ` Olof Johansson
2012-08-15 0:10 ` Olof Johansson
2012-08-20 15:57 ` Catalin Marinas
2012-08-20 15:57 ` Catalin Marinas
2012-08-20 20:47 ` Arnd Bergmann
2012-08-20 20:47 ` Arnd Bergmann
2012-08-21 9:50 ` Catalin Marinas
2012-08-21 9:50 ` Catalin Marinas
2012-09-14 17:38 ` Catalin Marinas
2012-09-14 17:38 ` Catalin Marinas
2012-08-15 13:56 ` Arnd Bergmann
2012-08-15 13:56 ` Arnd Bergmann
2012-08-20 16:00 ` Catalin Marinas
2012-08-20 16:00 ` Catalin Marinas
2012-08-14 17:52 ` [PATCH v2 09/31] arm64: Cache maintenance routines Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-17 9:57 ` Santosh Shilimkar [this message]
2012-08-17 9:57 ` Santosh Shilimkar
2012-08-17 9:57 ` Santosh Shilimkar
2012-08-17 10:07 ` Catalin Marinas
2012-08-17 10:07 ` Catalin Marinas
2012-08-17 10:12 ` Shilimkar, Santosh
2012-08-17 10:12 ` Shilimkar, Santosh
2012-08-14 17:52 ` [PATCH v2 10/31] arm64: TLB maintenance functionality Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 17:52 ` [PATCH v2 11/31] arm64: IRQ handling Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 23:22 ` Aaro Koskinen
2012-08-14 23:22 ` Aaro Koskinen
2012-08-14 17:52 ` [PATCH v2 12/31] arm64: Atomic operations Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 0:21 ` Olof Johansson
2012-08-15 0:21 ` Olof Johansson
2012-08-14 17:52 ` [PATCH v2 13/31] arm64: Device specific operations Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 0:33 ` Olof Johansson
2012-08-15 0:33 ` Olof Johansson
2012-09-14 17:29 ` Catalin Marinas
2012-09-14 17:29 ` Catalin Marinas
2012-09-14 17:31 ` Arnd Bergmann
2012-09-14 17:31 ` Arnd Bergmann
2012-09-14 17:39 ` Catalin Marinas
2012-09-14 17:39 ` Catalin Marinas
2012-09-16 0:28 ` Olof Johansson
2012-09-16 0:28 ` Olof Johansson
2012-08-15 16:13 ` Arnd Bergmann
2012-08-15 16:13 ` Arnd Bergmann
2012-08-17 9:19 ` Tony Lindgren
2012-08-17 9:19 ` Tony Lindgren
2012-08-17 9:19 ` Tony Lindgren
2012-08-14 17:52 ` [PATCH v2 14/31] arm64: DMA mapping API Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 0:40 ` Olof Johansson
2012-08-15 0:40 ` Olof Johansson
2012-08-15 0:40 ` Olof Johansson
2012-08-21 13:05 ` Catalin Marinas
2012-08-21 13:05 ` Catalin Marinas
2012-08-15 16:16 ` Arnd Bergmann
2012-08-15 16:16 ` Arnd Bergmann
2012-08-21 12:59 ` Catalin Marinas
2012-08-21 12:59 ` Catalin Marinas
2012-08-21 12:59 ` Catalin Marinas
2012-08-14 17:52 ` [PATCH v2 15/31] arm64: SMP support Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 0:49 ` Olof Johansson
2012-08-15 0:49 ` Olof Johansson
2012-08-15 13:04 ` Arnd Bergmann
2012-08-15 13:04 ` Arnd Bergmann
2012-08-17 9:21 ` Tony Lindgren
2012-08-17 9:21 ` Tony Lindgren
2012-08-17 9:32 ` Catalin Marinas
2012-08-17 9:32 ` Catalin Marinas
2012-08-17 9:39 ` Tony Lindgren
2012-08-17 9:39 ` Tony Lindgren
2012-08-14 17:52 ` [PATCH v2 16/31] arm64: ELF definitions Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 14:15 ` Arnd Bergmann
2012-08-15 14:15 ` Arnd Bergmann
2012-08-16 10:23 ` Will Deacon
2012-08-16 10:23 ` Will Deacon
2012-08-16 10:23 ` Will Deacon
2012-08-16 12:37 ` Arnd Bergmann
2012-08-16 12:37 ` Arnd Bergmann
2012-08-21 16:06 ` Catalin Marinas
2012-08-21 16:06 ` Catalin Marinas
2012-08-21 18:17 ` Geert Uytterhoeven
2012-08-21 18:17 ` Geert Uytterhoeven
2012-08-21 18:17 ` Geert Uytterhoeven
2012-08-21 18:27 ` Catalin Marinas
2012-08-21 18:27 ` Catalin Marinas
2012-08-21 18:53 ` Mike Frysinger
2012-08-21 18:53 ` Mike Frysinger
2012-08-21 20:17 ` Arnd Bergmann
2012-08-21 20:17 ` Arnd Bergmann
2012-09-05 19:56 ` Chris Metcalf
2012-09-05 19:56 ` Chris Metcalf
2012-09-05 19:56 ` Chris Metcalf
2012-08-14 17:52 ` [PATCH v2 17/31] arm64: System calls handling Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 14:22 ` Arnd Bergmann
2012-08-15 14:22 ` Arnd Bergmann
2012-08-21 17:51 ` Catalin Marinas
2012-08-21 17:51 ` Catalin Marinas
2012-08-21 20:14 ` Arnd Bergmann
2012-08-21 20:14 ` Arnd Bergmann
2012-08-21 20:14 ` Arnd Bergmann
2012-08-21 22:01 ` Catalin Marinas
2012-08-21 22:01 ` Catalin Marinas
2012-08-22 7:56 ` Arnd Bergmann
2012-08-22 7:56 ` Arnd Bergmann
2012-08-22 10:29 ` Catalin Marinas
2012-08-22 10:29 ` Catalin Marinas
2012-08-22 12:27 ` Arnd Bergmann
2012-08-22 12:27 ` Arnd Bergmann
2012-08-22 17:13 ` Catalin Marinas
2012-08-22 17:13 ` Catalin Marinas
2012-09-03 11:48 ` Catalin Marinas
2012-09-03 11:48 ` Catalin Marinas
2012-09-03 12:39 ` Arnd Bergmann
2012-09-03 12:39 ` Arnd Bergmann
2012-08-14 17:52 ` [PATCH v2 18/31] arm64: VDSO support Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 17:52 ` [PATCH v2 19/31] arm64: Signal handling support Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 17:52 ` [PATCH v2 20/31] arm64: User access library functions Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 14:49 ` [PATCH v2 20/31] arm64: User access library function Arnd Bergmann
2012-08-15 14:49 ` Arnd Bergmann
2012-09-03 12:58 ` Catalin Marinas
2012-09-03 12:58 ` Catalin Marinas
2012-09-05 19:13 ` Russell King - ARM Linux
2012-09-05 19:13 ` Russell King - ARM Linux
2012-09-05 21:01 ` Catalin Marinas
2012-09-05 21:01 ` Catalin Marinas
2012-09-05 21:05 ` Russell King - ARM Linux
2012-09-05 21:05 ` Russell King - ARM Linux
2012-09-06 8:36 ` Catalin Marinas
2012-09-06 8:36 ` Catalin Marinas
2012-08-14 17:52 ` [PATCH v2 21/31] arm64: 32-bit (compat) applications support Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 14:34 ` Arnd Bergmann
2012-08-15 14:34 ` Arnd Bergmann
2012-08-16 10:28 ` Will Deacon
2012-08-16 10:28 ` Will Deacon
2012-08-16 12:39 ` Arnd Bergmann
2012-08-16 12:39 ` Arnd Bergmann
2012-08-23 6:46 ` PER_LINUX32, Was: " Arnd Bergmann
2012-08-23 6:46 ` Arnd Bergmann
2012-08-23 10:42 ` Catalin Marinas
2012-08-23 10:42 ` Catalin Marinas
2012-08-28 18:28 ` Jiri Kosina
2012-08-28 18:28 ` Jiri Kosina
2012-08-24 10:43 ` Catalin Marinas
2012-08-24 10:43 ` Catalin Marinas
2012-08-26 4:49 ` Arnd Bergmann
2012-08-26 4:49 ` Arnd Bergmann
2012-08-26 4:49 ` Arnd Bergmann
2012-08-20 10:53 ` Pavel Machek
2012-08-20 10:53 ` Pavel Machek
2012-08-20 20:34 ` Arnd Bergmann
2012-08-20 20:34 ` Arnd Bergmann
2012-08-21 10:28 ` Pavel Machek
2012-08-21 10:28 ` Pavel Machek
2012-08-14 17:52 ` [PATCH v2 22/31] arm64: Floating point and SIMD Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 14:35 ` Arnd Bergmann
2012-08-15 14:35 ` Arnd Bergmann
2012-08-14 17:52 ` [PATCH v2 23/31] arm64: Debugging support Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 15:07 ` Arnd Bergmann
2012-08-15 15:07 ` Arnd Bergmann
2012-08-15 15:07 ` Arnd Bergmann
2012-08-16 10:47 ` Will Deacon
2012-08-16 10:47 ` Will Deacon
2012-08-16 12:49 ` Arnd Bergmann
2012-08-16 12:49 ` Arnd Bergmann
2012-08-17 7:06 ` Arnd Bergmann
2012-08-17 7:06 ` Arnd Bergmann
2012-08-20 9:07 ` Will Deacon
2012-08-20 9:07 ` Will Deacon
2012-08-20 9:27 ` Will Deacon
2012-08-20 9:27 ` Will Deacon
2012-08-20 20:10 ` Arnd Bergmann
2012-08-20 20:10 ` Arnd Bergmann
2012-08-21 8:58 ` Will Deacon
2012-08-21 8:58 ` Will Deacon
2012-08-21 8:58 ` Will Deacon
2012-08-14 17:52 ` [PATCH v2 24/31] arm64: Add support for /proc/sys/debug/exception-trace Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 15:08 ` Arnd Bergmann
2012-08-15 15:08 ` Arnd Bergmann
2012-08-14 17:52 ` [PATCH v2 25/31] arm64: Performance counters support Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 15:11 ` Arnd Bergmann
2012-08-15 15:11 ` Arnd Bergmann
2012-08-16 10:51 ` Will Deacon
2012-08-16 10:51 ` Will Deacon
2012-08-14 17:52 ` [PATCH v2 26/31] arm64: Miscellaneous library functions Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 15:21 ` Arnd Bergmann
2012-08-15 15:21 ` Arnd Bergmann
2012-08-16 10:57 ` Will Deacon
2012-08-16 10:57 ` Will Deacon
2012-08-16 13:00 ` Arnd Bergmann
2012-08-16 13:00 ` Arnd Bergmann
2012-08-16 14:11 ` Catalin Marinas
2012-08-16 14:11 ` Catalin Marinas
2012-08-14 17:52 ` [PATCH v2 27/31] arm64: Loadable modules Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 15:23 ` Arnd Bergmann
2012-08-15 15:23 ` Arnd Bergmann
2012-08-15 15:35 ` Catalin Marinas
2012-08-15 15:35 ` Catalin Marinas
2012-08-15 16:16 ` Arnd Bergmann
2012-08-15 16:16 ` Arnd Bergmann
2012-08-14 17:52 ` [PATCH v2 28/31] arm64: Generic timers support Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 15:52 ` Arnd Bergmann
2012-08-15 15:52 ` Arnd Bergmann
2012-08-16 12:40 ` Linus Walleij
2012-08-16 12:40 ` Linus Walleij
2012-08-17 9:29 ` Tony Lindgren
2012-08-17 9:29 ` Tony Lindgren
2012-08-17 10:21 ` Santosh Shilimkar
2012-08-17 10:21 ` Santosh Shilimkar
2012-08-21 19:20 ` Christopher Covington
2012-08-21 19:20 ` Christopher Covington
2012-08-14 17:52 ` [PATCH v2 29/31] arm64: Miscellaneous header files Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 15:56 ` Arnd Bergmann
2012-08-15 15:56 ` Arnd Bergmann
2012-08-14 17:52 ` [PATCH v2 30/31] arm64: Build infrastructure Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-14 21:01 ` Sam Ravnborg
2012-08-14 21:01 ` Sam Ravnborg
2012-08-15 16:07 ` Arnd Bergmann
2012-08-15 16:07 ` Arnd Bergmann
2012-08-17 9:32 ` Tony Lindgren
2012-08-17 9:32 ` Tony Lindgren
2012-08-17 9:46 ` Catalin Marinas
2012-08-17 9:46 ` Catalin Marinas
2012-08-14 17:52 ` [PATCH v2 31/31] arm64: MAINTAINERS update Catalin Marinas
2012-08-14 17:52 ` Catalin Marinas
2012-08-15 15:57 ` Arnd Bergmann
2012-08-15 15:57 ` Arnd Bergmann
2012-08-17 9:36 ` [PATCH v2 00/31] AArch64 Linux kernel port Tony Lindgren
2012-08-17 9:36 ` Tony Lindgren
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=502E1580.70702@ti.com \
--to=santosh.shilimkar@ti.com \
--cc=arnd@arndb.de \
--cc=catalin.marinas@arm.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=will.deacon@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.