| /* | 
 |  *  Copyright (C) 2015 Russell King | 
 |  * | 
 |  * 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 assembly is required to safely remap the physical address space | 
 |  * for Keystone 2 | 
 |  */ | 
 | #include <linux/linkage.h> | 
 | #include <asm/asm-offsets.h> | 
 | #include <asm/cp15.h> | 
 | #include <asm/memory.h> | 
 | #include <asm/pgtable.h> | 
 |  | 
 | 	.section ".idmap.text", "ax" | 
 |  | 
 | #define L1_ORDER 3 | 
 | #define L2_ORDER 3 | 
 |  | 
 | ENTRY(lpae_pgtables_remap_asm) | 
 | 	stmfd	sp!, {r4-r8, lr} | 
 |  | 
 | 	mrc	p15, 0, r8, c1, c0, 0		@ read control reg | 
 | 	bic	ip, r8, #CR_M			@ disable caches and MMU | 
 | 	mcr	p15, 0, ip, c1, c0, 0 | 
 | 	dsb | 
 | 	isb | 
 |  | 
 | 	/* Update level 2 entries covering the kernel */ | 
 | 	ldr	r6, =(_end - 1) | 
 | 	add	r7, r2, #0x1000 | 
 | 	add	r6, r7, r6, lsr #SECTION_SHIFT - L2_ORDER | 
 | 	add	r7, r7, #PAGE_OFFSET >> (SECTION_SHIFT - L2_ORDER) | 
 | 1:	ldrd	r4, [r7] | 
 | 	adds	r4, r4, r0 | 
 | 	adc	r5, r5, r1 | 
 | 	strd	r4, [r7], #1 << L2_ORDER | 
 | 	cmp	r7, r6 | 
 | 	bls	1b | 
 |  | 
 | 	/* Update level 2 entries for the boot data */ | 
 | 	add	r7, r2, #0x1000 | 
 | 	add	r7, r7, r3, lsr #SECTION_SHIFT - L2_ORDER | 
 | 	bic	r7, r7, #(1 << L2_ORDER) - 1 | 
 | 	ldrd	r4, [r7] | 
 | 	adds	r4, r4, r0 | 
 | 	adc	r5, r5, r1 | 
 | 	strd	r4, [r7], #1 << L2_ORDER | 
 | 	ldrd	r4, [r7] | 
 | 	adds	r4, r4, r0 | 
 | 	adc	r5, r5, r1 | 
 | 	strd	r4, [r7] | 
 |  | 
 | 	/* Update level 1 entries */ | 
 | 	mov	r6, #4 | 
 | 	mov	r7, r2 | 
 | 2:	ldrd	r4, [r7] | 
 | 	adds	r4, r4, r0 | 
 | 	adc	r5, r5, r1 | 
 | 	strd	r4, [r7], #1 << L1_ORDER | 
 | 	subs	r6, r6, #1 | 
 | 	bne	2b | 
 |  | 
 | 	mrrc	p15, 0, r4, r5, c2		@ read TTBR0 | 
 | 	adds	r4, r4, r0			@ update physical address | 
 | 	adc	r5, r5, r1 | 
 | 	mcrr	p15, 0, r4, r5, c2		@ write back TTBR0 | 
 | 	mrrc	p15, 1, r4, r5, c2		@ read TTBR1 | 
 | 	adds	r4, r4, r0			@ update physical address | 
 | 	adc	r5, r5, r1 | 
 | 	mcrr	p15, 1, r4, r5, c2		@ write back TTBR1 | 
 |  | 
 | 	dsb | 
 |  | 
 | 	mov	ip, #0 | 
 | 	mcr	p15, 0, ip, c7, c5, 0		@ I+BTB cache invalidate | 
 | 	mcr	p15, 0, ip, c8, c7, 0		@ local_flush_tlb_all() | 
 | 	dsb | 
 | 	isb | 
 |  | 
 | 	mcr	p15, 0, r8, c1, c0, 0		@ re-enable MMU | 
 | 	dsb | 
 | 	isb | 
 |  | 
 | 	ldmfd	sp!, {r4-r8, pc} | 
 | ENDPROC(lpae_pgtables_remap_asm) |