diff mbox

[Xen-devel,RFC,04/16] xen/arm: arm64: Import flush_icache_range from Linux v4.6-rc3

Message ID 1462466065-30212-5-git-send-email-julien.grall@arm.com
State New
Headers show

Commit Message

Julien Grall May 5, 2016, 4:34 p.m. UTC
Flushing the icache will required when the support Xen patching will be
added.

Also import the macro icache_line_size which is used by
flush_icache_range.

Signed-off-by: Julien Grall <julien.grall@arm.com>
---
 xen/arch/arm/arm64/cache.S | 45 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/page.h |  2 ++
 2 files changed, 47 insertions(+)

Comments

Julien Grall May 9, 2016, 9:40 a.m. UTC | #1
On 05/05/2016 17:34, Julien Grall wrote:
> Flushing the icache will required when the support Xen patching will be
> added.
>
> Also import the macro icache_line_size which is used by
> flush_icache_range.
>
> Signed-off-by: Julien Grall <julien.grall@arm.com>

Hmmm, I forgot to drop this patch from the series. Please ignore it.

Cheers,

> ---
>   xen/arch/arm/arm64/cache.S | 45 +++++++++++++++++++++++++++++++++++++++++++++
>   xen/include/asm-arm/page.h |  2 ++
>   2 files changed, 47 insertions(+)
>
> diff --git a/xen/arch/arm/arm64/cache.S b/xen/arch/arm/arm64/cache.S
> index eff4e16..bc5a8f7 100644
> --- a/xen/arch/arm/arm64/cache.S
> +++ b/xen/arch/arm/arm64/cache.S
> @@ -30,6 +30,51 @@
>   	.endm
>
>   /*
> + * icache_line_size - get the minimum I-cache line size from the CTR register.
> + */
> +	.macro	icache_line_size, reg, tmp
> +	mrs	\tmp, ctr_el0			// read CTR
> +	and	\tmp, \tmp, #0xf		// cache line size encoding
> +	mov	\reg, #4			// bytes per word
> +	lsl	\reg, \reg, \tmp		// actual cache line size
> +	.endm
> +
> +/*
> + *	flush_icache_range(start,end)
> + *
> + *	Ensure that the I and D caches are coherent within specified region.
> + *	This is typically used when code has been written to a memory region,
> + *	and will be executed.
> + *
> + *	- start   - virtual start address of region
> + *	- end     - virtual end address of region
> + */
> +ENTRY(flush_icache_range)
> +	dcache_line_size x2, x3
> +	sub	x3, x2, #1
> +	bic	x4, x0, x3
> +1:
> +	dc	cvau, x4		// clean D line to PoU
> +	add	x4, x4, x2
> +	cmp	x4, x1
> +	b.lo	1b
> +	dsb	ish
> +
> +	icache_line_size x2, x3
> +	sub	x3, x2, #1
> +	bic	x4, x0, x3
> +1:
> + 	ic	ivau, x4		// invalidate I line PoU
> +	add	x4, x4, x2
> +	cmp	x4, x1
> +	b.lo	1b
> +	dsb	ish
> +	isb
> +	mov	x0, #0
> +	ret
> +ENDPROC(flush_icache_range)
> +
> +/*
>    *	__flush_dcache_area(kaddr, size)
>    *
>    *	Ensure that the data held in the page kaddr is written back to the
> diff --git a/xen/include/asm-arm/page.h b/xen/include/asm-arm/page.h
> index 05d9f82..a94e826 100644
> --- a/xen/include/asm-arm/page.h
> +++ b/xen/include/asm-arm/page.h
> @@ -328,6 +328,8 @@ static inline int clean_and_invalidate_dcache_va_range
>       return 0;
>   }
>
> +int flush_icache_range(unsigned long start, unsigned long end);
> +
>   /* Macros for flushing a single small item.  The predicate is always
>    * compile-time constant so this will compile down to 3 instructions in
>    * the common case. */
>
diff mbox

Patch

diff --git a/xen/arch/arm/arm64/cache.S b/xen/arch/arm/arm64/cache.S
index eff4e16..bc5a8f7 100644
--- a/xen/arch/arm/arm64/cache.S
+++ b/xen/arch/arm/arm64/cache.S
@@ -30,6 +30,51 @@ 
 	.endm
 
 /*
+ * icache_line_size - get the minimum I-cache line size from the CTR register.
+ */
+	.macro	icache_line_size, reg, tmp
+	mrs	\tmp, ctr_el0			// read CTR
+	and	\tmp, \tmp, #0xf		// cache line size encoding
+	mov	\reg, #4			// bytes per word
+	lsl	\reg, \reg, \tmp		// actual cache line size
+	.endm
+
+/*
+ *	flush_icache_range(start,end)
+ *
+ *	Ensure that the I and D caches are coherent within specified region.
+ *	This is typically used when code has been written to a memory region,
+ *	and will be executed.
+ *
+ *	- start   - virtual start address of region
+ *	- end     - virtual end address of region
+ */
+ENTRY(flush_icache_range)
+	dcache_line_size x2, x3
+	sub	x3, x2, #1
+	bic	x4, x0, x3
+1:
+	dc	cvau, x4		// clean D line to PoU
+	add	x4, x4, x2
+	cmp	x4, x1
+	b.lo	1b
+	dsb	ish
+
+	icache_line_size x2, x3
+	sub	x3, x2, #1
+	bic	x4, x0, x3
+1:
+ 	ic	ivau, x4		// invalidate I line PoU
+	add	x4, x4, x2
+	cmp	x4, x1
+	b.lo	1b
+	dsb	ish
+	isb
+	mov	x0, #0
+	ret
+ENDPROC(flush_icache_range)
+
+/*
  *	__flush_dcache_area(kaddr, size)
  *
  *	Ensure that the data held in the page kaddr is written back to the
diff --git a/xen/include/asm-arm/page.h b/xen/include/asm-arm/page.h
index 05d9f82..a94e826 100644
--- a/xen/include/asm-arm/page.h
+++ b/xen/include/asm-arm/page.h
@@ -328,6 +328,8 @@  static inline int clean_and_invalidate_dcache_va_range
     return 0;
 }
 
+int flush_icache_range(unsigned long start, unsigned long end);
+
 /* Macros for flushing a single small item.  The predicate is always
  * compile-time constant so this will compile down to 3 instructions in
  * the common case. */