0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/linkage.h>
0009 #include <linux/pgtable.h>
0010 #include <asm/asm-offsets.h>
0011 #include <asm/cp15.h>
0012 #include <asm/memory.h>
0013
0014 .section ".idmap.text", "ax"
0015
0016 #define L1_ORDER 3
0017 #define L2_ORDER 3
0018
0019 ENTRY(lpae_pgtables_remap_asm)
0020 stmfd sp!, {r4-r8, lr}
0021
0022 mrc p15, 0, r8, c1, c0, 0 @ read control reg
0023 bic ip, r8, #CR_M @ disable caches and MMU
0024 mcr p15, 0, ip, c1, c0, 0
0025 dsb
0026 isb
0027
0028
0029 ldr r6, =(_end - 1)
0030 add r7, r2, #0x1000
0031 add r6, r7, r6, lsr #SECTION_SHIFT - L2_ORDER
0032 add r7, r7, #KERNEL_OFFSET >> (SECTION_SHIFT - L2_ORDER)
0033 1: ldrd r4, r5, [r7]
0034 adds r4, r4, r0
0035 adc r5, r5, r1
0036 strd r4, r5, [r7], #1 << L2_ORDER
0037 cmp r7, r6
0038 bls 1b
0039
0040
0041 add r7, r2, #0x1000
0042 movw r3, #FDT_FIXED_BASE >> (SECTION_SHIFT - L2_ORDER)
0043 add r7, r7, r3
0044 ldrd r4, r5, [r7]
0045 adds r4, r4, r0
0046 adc r5, r5, r1
0047 strd r4, r5, [r7], #1 << L2_ORDER
0048 ldrd r4, r5, [r7]
0049 adds r4, r4, r0
0050 adc r5, r5, r1
0051 strd r4, r5, [r7]
0052
0053
0054 mov r6, #4
0055 mov r7, r2
0056 2: ldrd r4, r5, [r7]
0057 adds r4, r4, r0
0058 adc r5, r5, r1
0059 strd r4, r5, [r7], #1 << L1_ORDER
0060 subs r6, r6, #1
0061 bne 2b
0062
0063 mrrc p15, 0, r4, r5, c2 @ read TTBR0
0064 adds r4, r4, r0 @ update physical address
0065 adc r5, r5, r1
0066 mcrr p15, 0, r4, r5, c2 @ write back TTBR0
0067 mrrc p15, 1, r4, r5, c2 @ read TTBR1
0068 adds r4, r4, r0 @ update physical address
0069 adc r5, r5, r1
0070 mcrr p15, 1, r4, r5, c2 @ write back TTBR1
0071
0072 dsb
0073
0074 mov ip, #0
0075 mcr p15, 0, ip, c7, c5, 0 @ I+BTB cache invalidate
0076 mcr p15, 0, ip, c8, c7, 0 @ local_flush_tlb_all()
0077 dsb
0078 isb
0079
0080 mcr p15, 0, r8, c1, c0, 0 @ re-enable MMU
0081 dsb
0082 isb
0083
0084 ldmfd sp!, {r4-r8, pc}
0085 ENDPROC(lpae_pgtables_remap_asm)