162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2015 Russell King 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * This assembly is required to safely remap the physical address space 662306a36Sopenharmony_ci * for Keystone 2 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci#include <linux/linkage.h> 962306a36Sopenharmony_ci#include <linux/pgtable.h> 1062306a36Sopenharmony_ci#include <asm/asm-offsets.h> 1162306a36Sopenharmony_ci#include <asm/cp15.h> 1262306a36Sopenharmony_ci#include <asm/page.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci .section ".idmap.text", "ax" 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#define L1_ORDER 3 1762306a36Sopenharmony_ci#define L2_ORDER 3 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ciENTRY(lpae_pgtables_remap_asm) 2062306a36Sopenharmony_ci stmfd sp!, {r4-r8, lr} 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci mrc p15, 0, r8, c1, c0, 0 @ read control reg 2362306a36Sopenharmony_ci bic ip, r8, #CR_M @ disable caches and MMU 2462306a36Sopenharmony_ci mcr p15, 0, ip, c1, c0, 0 2562306a36Sopenharmony_ci dsb 2662306a36Sopenharmony_ci isb 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci /* Update level 2 entries covering the kernel */ 2962306a36Sopenharmony_ci ldr r6, =(_end - 1) 3062306a36Sopenharmony_ci add r7, r2, #0x1000 3162306a36Sopenharmony_ci add r6, r7, r6, lsr #SECTION_SHIFT - L2_ORDER 3262306a36Sopenharmony_ci add r7, r7, #KERNEL_OFFSET >> (SECTION_SHIFT - L2_ORDER) 3362306a36Sopenharmony_ci1: ldrd r4, r5, [r7] 3462306a36Sopenharmony_ci adds r4, r4, r0 3562306a36Sopenharmony_ci adc r5, r5, r1 3662306a36Sopenharmony_ci strd r4, r5, [r7], #1 << L2_ORDER 3762306a36Sopenharmony_ci cmp r7, r6 3862306a36Sopenharmony_ci bls 1b 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci /* Update level 2 entries for the boot data */ 4162306a36Sopenharmony_ci add r7, r2, #0x1000 4262306a36Sopenharmony_ci movw r3, #FDT_FIXED_BASE >> (SECTION_SHIFT - L2_ORDER) 4362306a36Sopenharmony_ci add r7, r7, r3 4462306a36Sopenharmony_ci ldrd r4, r5, [r7] 4562306a36Sopenharmony_ci adds r4, r4, r0 4662306a36Sopenharmony_ci adc r5, r5, r1 4762306a36Sopenharmony_ci strd r4, r5, [r7], #1 << L2_ORDER 4862306a36Sopenharmony_ci ldrd r4, r5, [r7] 4962306a36Sopenharmony_ci adds r4, r4, r0 5062306a36Sopenharmony_ci adc r5, r5, r1 5162306a36Sopenharmony_ci strd r4, r5, [r7] 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci /* Update level 1 entries */ 5462306a36Sopenharmony_ci mov r6, #4 5562306a36Sopenharmony_ci mov r7, r2 5662306a36Sopenharmony_ci2: ldrd r4, r5, [r7] 5762306a36Sopenharmony_ci adds r4, r4, r0 5862306a36Sopenharmony_ci adc r5, r5, r1 5962306a36Sopenharmony_ci strd r4, r5, [r7], #1 << L1_ORDER 6062306a36Sopenharmony_ci subs r6, r6, #1 6162306a36Sopenharmony_ci bne 2b 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci mrrc p15, 0, r4, r5, c2 @ read TTBR0 6462306a36Sopenharmony_ci adds r4, r4, r0 @ update physical address 6562306a36Sopenharmony_ci adc r5, r5, r1 6662306a36Sopenharmony_ci mcrr p15, 0, r4, r5, c2 @ write back TTBR0 6762306a36Sopenharmony_ci mrrc p15, 1, r4, r5, c2 @ read TTBR1 6862306a36Sopenharmony_ci adds r4, r4, r0 @ update physical address 6962306a36Sopenharmony_ci adc r5, r5, r1 7062306a36Sopenharmony_ci mcrr p15, 1, r4, r5, c2 @ write back TTBR1 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci dsb 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci mov ip, #0 7562306a36Sopenharmony_ci mcr p15, 0, ip, c7, c5, 0 @ I+BTB cache invalidate 7662306a36Sopenharmony_ci mcr p15, 0, ip, c8, c7, 0 @ local_flush_tlb_all() 7762306a36Sopenharmony_ci dsb 7862306a36Sopenharmony_ci isb 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci mcr p15, 0, r8, c1, c0, 0 @ re-enable MMU 8162306a36Sopenharmony_ci dsb 8262306a36Sopenharmony_ci isb 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci ldmfd sp!, {r4-r8, pc} 8562306a36Sopenharmony_ciENDPROC(lpae_pgtables_remap_asm) 86