13da0e575SAlbert ARIBAUD/* 23da0e575SAlbert ARIBAUD * relocate - common relocation function for ARM U-Boot 33da0e575SAlbert ARIBAUD * 43da0e575SAlbert ARIBAUD * Copyright (c) 2013 Albert ARIBAUD <albert.u.boot@aribaud.net> 53da0e575SAlbert ARIBAUD * 61a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 73da0e575SAlbert ARIBAUD */ 83da0e575SAlbert ARIBAUD 93ff46cc4SGeorges Savoundararadj#include <asm-offsets.h> 103ff46cc4SGeorges Savoundararadj#include <config.h> 11*c70f74a0SSimon Glass#include <elf.h> 123da0e575SAlbert ARIBAUD#include <linux/linkage.h> 1312d8a729Srev13@wp.pl#ifdef CONFIG_CPU_V7M 1412d8a729Srev13@wp.pl#include <asm/armv7m.h> 1512d8a729Srev13@wp.pl#endif 163da0e575SAlbert ARIBAUD 173da0e575SAlbert ARIBAUD/* 18db544b96SAlbert ARIBAUD * Default/weak exception vectors relocation routine 19db544b96SAlbert ARIBAUD * 20db544b96SAlbert ARIBAUD * This routine covers the standard ARM cases: normal (0x00000000), 21db544b96SAlbert ARIBAUD * high (0xffff0000) and VBAR. SoCs which do not comply with any of 22db544b96SAlbert ARIBAUD * the standard cases must provide their own, strong, version. 23db544b96SAlbert ARIBAUD */ 24db544b96SAlbert ARIBAUD 25db544b96SAlbert ARIBAUD .section .text.relocate_vectors,"ax",%progbits 26db544b96SAlbert ARIBAUD .weak relocate_vectors 27db544b96SAlbert ARIBAUD 28db544b96SAlbert ARIBAUDENTRY(relocate_vectors) 29db544b96SAlbert ARIBAUD 3012d8a729Srev13@wp.pl#ifdef CONFIG_CPU_V7M 3112d8a729Srev13@wp.pl /* 3212d8a729Srev13@wp.pl * On ARMv7-M we only have to write the new vector address 3312d8a729Srev13@wp.pl * to VTOR register. 3412d8a729Srev13@wp.pl */ 3512d8a729Srev13@wp.pl ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ 3612d8a729Srev13@wp.pl ldr r1, =V7M_SCB_BASE 3712d8a729Srev13@wp.pl str r0, [r1, V7M_SCB_VTOR] 3812d8a729Srev13@wp.pl#else 39db544b96SAlbert ARIBAUD#ifdef CONFIG_HAS_VBAR 40db544b96SAlbert ARIBAUD /* 41db544b96SAlbert ARIBAUD * If the ARM processor has the security extensions, 42db544b96SAlbert ARIBAUD * use VBAR to relocate the exception vectors. 43db544b96SAlbert ARIBAUD */ 44db544b96SAlbert ARIBAUD ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ 45db544b96SAlbert ARIBAUD mcr p15, 0, r0, c12, c0, 0 /* Set VBAR */ 46db544b96SAlbert ARIBAUD#else 47db544b96SAlbert ARIBAUD /* 48db544b96SAlbert ARIBAUD * Copy the relocated exception vectors to the 49db544b96SAlbert ARIBAUD * correct address 50db544b96SAlbert ARIBAUD * CP15 c1 V bit gives us the location of the vectors: 51db544b96SAlbert ARIBAUD * 0x00000000 or 0xFFFF0000. 52db544b96SAlbert ARIBAUD */ 53db544b96SAlbert ARIBAUD ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ 54db544b96SAlbert ARIBAUD mrc p15, 0, r2, c1, c0, 0 /* V bit (bit[13]) in CP15 c1 */ 55db544b96SAlbert ARIBAUD ands r2, r2, #(1 << 13) 56db544b96SAlbert ARIBAUD ldreq r1, =0x00000000 /* If V=0 */ 57db544b96SAlbert ARIBAUD ldrne r1, =0xFFFF0000 /* If V=1 */ 58db544b96SAlbert ARIBAUD ldmia r0!, {r2-r8,r10} 59db544b96SAlbert ARIBAUD stmia r1!, {r2-r8,r10} 60db544b96SAlbert ARIBAUD ldmia r0!, {r2-r8,r10} 61db544b96SAlbert ARIBAUD stmia r1!, {r2-r8,r10} 62db544b96SAlbert ARIBAUD#endif 6312d8a729Srev13@wp.pl#endif 64db544b96SAlbert ARIBAUD bx lr 65db544b96SAlbert ARIBAUD 66db544b96SAlbert ARIBAUDENDPROC(relocate_vectors) 67db544b96SAlbert ARIBAUD 68db544b96SAlbert ARIBAUD/* 693da0e575SAlbert ARIBAUD * void relocate_code(addr_moni) 703da0e575SAlbert ARIBAUD * 713da0e575SAlbert ARIBAUD * This function relocates the monitor code. 723da0e575SAlbert ARIBAUD * 733da0e575SAlbert ARIBAUD * NOTE: 743da0e575SAlbert ARIBAUD * To prevent the code below from containing references with an R_ARM_ABS32 753da0e575SAlbert ARIBAUD * relocation record type, we never refer to linker-defined symbols directly. 763da0e575SAlbert ARIBAUD * Instead, we declare literals which contain their relative location with 773da0e575SAlbert ARIBAUD * respect to relocate_code, and at run time, add relocate_code back to them. 783da0e575SAlbert ARIBAUD */ 793da0e575SAlbert ARIBAUD 803da0e575SAlbert ARIBAUDENTRY(relocate_code) 81fbf87b18SAlbert ARIBAUD ldr r1, =__image_copy_start /* r1 <- SRC &__image_copy_start */ 82a81872ffSJeroen Hofstee subs r4, r0, r1 /* r4 <- relocation offset */ 833da0e575SAlbert ARIBAUD beq relocate_done /* skip relocation */ 84d026dec8SAlbert ARIBAUD ldr r2, =__image_copy_end /* r2 <- SRC &__image_copy_end */ 853da0e575SAlbert ARIBAUD 863da0e575SAlbert ARIBAUDcopy_loop: 87fbf87b18SAlbert ARIBAUD ldmia r1!, {r10-r11} /* copy from source address [r1] */ 88fbf87b18SAlbert ARIBAUD stmia r0!, {r10-r11} /* copy to target address [r0] */ 89fbf87b18SAlbert ARIBAUD cmp r1, r2 /* until source end address [r2] */ 903da0e575SAlbert ARIBAUD blo copy_loop 913da0e575SAlbert ARIBAUD 923da0e575SAlbert ARIBAUD /* 933da0e575SAlbert ARIBAUD * fix .rel.dyn relocations 943da0e575SAlbert ARIBAUD */ 9547bd65efSAlbert ARIBAUD ldr r2, =__rel_dyn_start /* r2 <- SRC &__rel_dyn_start */ 9647bd65efSAlbert ARIBAUD ldr r3, =__rel_dyn_end /* r3 <- SRC &__rel_dyn_end */ 973da0e575SAlbert ARIBAUDfixloop: 98fbf87b18SAlbert ARIBAUD ldmia r2!, {r0-r1} /* (r0,r1) <- (SRC location,fixup) */ 99fbf87b18SAlbert ARIBAUD and r1, r1, #0xff 100*c70f74a0SSimon Glass cmp r1, #R_ARM_RELATIVE 101fbf87b18SAlbert ARIBAUD bne fixnext 102fbf87b18SAlbert ARIBAUD 1033da0e575SAlbert ARIBAUD /* relative fix: increase location by offset */ 104a81872ffSJeroen Hofstee add r0, r0, r4 1053da0e575SAlbert ARIBAUD ldr r1, [r0] 106a81872ffSJeroen Hofstee add r1, r1, r4 1073da0e575SAlbert ARIBAUD str r1, [r0] 108fbf87b18SAlbert ARIBAUDfixnext: 1093da0e575SAlbert ARIBAUD cmp r2, r3 1103da0e575SAlbert ARIBAUD blo fixloop 1113da0e575SAlbert ARIBAUD 1123da0e575SAlbert ARIBAUDrelocate_done: 1133da0e575SAlbert ARIBAUD 1149dc8fef2SMike Dunn#ifdef __XSCALE__ 1159dc8fef2SMike Dunn /* 1169dc8fef2SMike Dunn * On xscale, icache must be invalidated and write buffers drained, 1179dc8fef2SMike Dunn * even with cache disabled - 4.2.7 of xscale core developer's manual 1189dc8fef2SMike Dunn */ 1199dc8fef2SMike Dunn mcr p15, 0, r0, c7, c7, 0 /* invalidate icache */ 1209dc8fef2SMike Dunn mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ 1219dc8fef2SMike Dunn#endif 1229dc8fef2SMike Dunn 1233da0e575SAlbert ARIBAUD /* ARMv4- don't know bx lr but the assembler fails to see that */ 1243da0e575SAlbert ARIBAUD 1253da0e575SAlbert ARIBAUD#ifdef __ARM_ARCH_4__ 1263da0e575SAlbert ARIBAUD mov pc, lr 1273da0e575SAlbert ARIBAUD#else 1283da0e575SAlbert ARIBAUD bx lr 1293da0e575SAlbert ARIBAUD#endif 1303da0e575SAlbert ARIBAUD 1313da0e575SAlbert ARIBAUDENDPROC(relocate_code) 132