183d290c5STom Rini/* SPDX-License-Identifier: GPL-2.0+ */ 20ae76531SDavid Feng/* 30ae76531SDavid Feng * relocate - common relocation function for AArch64 U-Boot 40ae76531SDavid Feng * 50ae76531SDavid Feng * (C) Copyright 2013 60ae76531SDavid Feng * Albert ARIBAUD <albert.u.boot@aribaud.net> 70ae76531SDavid Feng * David Feng <fenghua@phytium.com.cn> 80ae76531SDavid Feng */ 90ae76531SDavid Feng 100ae76531SDavid Feng#include <asm-offsets.h> 110ae76531SDavid Feng#include <config.h> 12c70f74a0SSimon Glass#include <elf.h> 130ae76531SDavid Feng#include <linux/linkage.h> 1483571bcaSYork Sun#include <asm/macro.h> 150ae76531SDavid Feng 160ae76531SDavid Feng/* 170ae76531SDavid Feng * void relocate_code (addr_moni) 180ae76531SDavid Feng * 190ae76531SDavid Feng * This function relocates the monitor code. 200ae76531SDavid Feng * x0 holds the destination address. 210ae76531SDavid Feng */ 220ae76531SDavid FengENTRY(relocate_code) 2383571bcaSYork Sun stp x29, x30, [sp, #-32]! /* create a stack frame */ 2483571bcaSYork Sun mov x29, sp 2583571bcaSYork Sun str x0, [sp, #16] 260ae76531SDavid Feng /* 270ae76531SDavid Feng * Copy u-boot from flash to RAM 280ae76531SDavid Feng */ 2949e93875SStephen Warren adr x1, __image_copy_start /* x1 <- Run &__image_copy_start */ 3049e93875SStephen Warren subs x9, x0, x1 /* x8 <- Run to copy offset */ 310ae76531SDavid Feng b.eq relocate_done /* skip relocation */ 3249e93875SStephen Warren /* 3349e93875SStephen Warren * Don't ldr x1, __image_copy_start here, since if the code is already 3449e93875SStephen Warren * running at an address other than it was linked to, that instruction 3549e93875SStephen Warren * will load the relocated value of __image_copy_start. To 3649e93875SStephen Warren * correctly apply relocations, we need to know the linked value. 3749e93875SStephen Warren * 3849e93875SStephen Warren * Linked &__image_copy_start, which we know was at 3949e93875SStephen Warren * CONFIG_SYS_TEXT_BASE, which is stored in _TEXT_BASE, as a non- 4049e93875SStephen Warren * relocated value, since it isn't a symbol reference. 4149e93875SStephen Warren */ 4249e93875SStephen Warren ldr x1, _TEXT_BASE /* x1 <- Linked &__image_copy_start */ 4349e93875SStephen Warren subs x9, x0, x1 /* x9 <- Link to copy offset */ 440ae76531SDavid Feng 4549e93875SStephen Warren adr x1, __image_copy_start /* x1 <- Run &__image_copy_start */ 4649e93875SStephen Warren adr x2, __image_copy_end /* x2 <- Run &__image_copy_end */ 470ae76531SDavid Fengcopy_loop: 480ae76531SDavid Feng ldp x10, x11, [x1], #16 /* copy from source address [x1] */ 490ae76531SDavid Feng stp x10, x11, [x0], #16 /* copy to target address [x0] */ 500ae76531SDavid Feng cmp x1, x2 /* until source end address [x2] */ 510ae76531SDavid Feng b.lo copy_loop 5283571bcaSYork Sun str x0, [sp, #24] 530ae76531SDavid Feng 540ae76531SDavid Feng /* 550ae76531SDavid Feng * Fix .rela.dyn relocations 560ae76531SDavid Feng */ 5749e93875SStephen Warren adr x2, __rel_dyn_start /* x2 <- Run &__rel_dyn_start */ 5849e93875SStephen Warren adr x3, __rel_dyn_end /* x3 <- Run &__rel_dyn_end */ 590ae76531SDavid Fengfixloop: 600ae76531SDavid Feng ldp x0, x1, [x2], #16 /* (x0,x1) <- (SRC location, fixup) */ 610ae76531SDavid Feng ldr x4, [x2], #8 /* x4 <- addend */ 620ae76531SDavid Feng and x1, x1, #0xffffffff 63c70f74a0SSimon Glass cmp x1, #R_AARCH64_RELATIVE 640ae76531SDavid Feng bne fixnext 650ae76531SDavid Feng 660ae76531SDavid Feng /* relative fix: store addend plus offset at dest location */ 670ae76531SDavid Feng add x0, x0, x9 680ae76531SDavid Feng add x4, x4, x9 690ae76531SDavid Feng str x4, [x0] 700ae76531SDavid Fengfixnext: 710ae76531SDavid Feng cmp x2, x3 720ae76531SDavid Feng b.lo fixloop 730ae76531SDavid Feng 740ae76531SDavid Fengrelocate_done: 7583571bcaSYork Sun switch_el x1, 3f, 2f, 1f 7683571bcaSYork Sun bl hang 7783571bcaSYork Sun3: mrs x0, sctlr_el3 7883571bcaSYork Sun b 0f 7983571bcaSYork Sun2: mrs x0, sctlr_el2 8083571bcaSYork Sun b 0f 8183571bcaSYork Sun1: mrs x0, sctlr_el1 8283571bcaSYork Sun0: tbz w0, #2, 5f /* skip flushing cache if disabled */ 831f4f5e52SMasahiro Yamada tbz w0, #12, 4f /* skip invalidating i-cache if disabled */ 8483571bcaSYork Sun ic iallu /* i-cache invalidate all */ 8583571bcaSYork Sun isb sy 8683571bcaSYork Sun4: ldp x0, x1, [sp, #16] 8783571bcaSYork Sun bl __asm_flush_dcache_range 88*b3b7706bSMeenakshi Aggarwal bl __asm_flush_l3_dcache 897baf952fSzijun_hu5: ldp x29, x30, [sp],#32 900ae76531SDavid Feng ret 910ae76531SDavid FengENDPROC(relocate_code) 92