]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arc/lib/relocate.c
7709633d5be124d610f9ceef86a6b90c7ee669ec
2 * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
4 * SPDX-License-Identifier: GPL-2.0+
9 #include <asm/sections.h>
11 DECLARE_GLOBAL_DATA_PTR
;
13 int copy_uboot_to_ram(void)
15 size_t len
= (size_t)&__image_copy_end
- (size_t)&__image_copy_start
;
17 memcpy((void *)gd
->relocaddr
, (void *)&__image_copy_start
, len
);
24 ulong dst_addr
= (ulong
)&__bss_start
+ gd
->reloc_off
;
25 size_t len
= (size_t)&__bss_end
- (size_t)&__bss_start
;
27 memset((void *)dst_addr
, 0x00, len
);
33 * Base functionality is taken from x86 version with added ARC-specifics
35 int do_elf_reloc_fixups(void)
37 Elf32_Rela
*re_src
= (Elf32_Rela
*)(&__rel_dyn_start
);
38 Elf32_Rela
*re_end
= (Elf32_Rela
*)(&__rel_dyn_end
);
40 debug("Section .rela.dyn is located at %08x-%08x\n",
41 (unsigned int)re_src
, (unsigned int)re_end
);
43 Elf32_Addr
*offset_ptr_rom
, *last_offset
= NULL
;
44 Elf32_Addr
*offset_ptr_ram
;
47 /* Get the location from the relocation entry */
48 offset_ptr_rom
= (Elf32_Addr
*)re_src
->r_offset
;
50 /* Check that the location of the relocation is in .text */
51 if (offset_ptr_rom
>= (Elf32_Addr
*)&__image_copy_start
&&
52 offset_ptr_rom
> last_offset
) {
54 /* Switch to the in-RAM version */
55 offset_ptr_ram
= (Elf32_Addr
*)((ulong
)offset_ptr_rom
+
58 debug("Patching value @ %08x (relocated to %08x)\n",
59 (unsigned int)offset_ptr_rom
,
60 (unsigned int)offset_ptr_ram
);
63 * Use "memcpy" because target location might be
64 * 16-bit aligned on ARC so we may need to read
65 * byte-by-byte. On attempt to read entire word by
66 * CPU throws an exception
68 memcpy(&val
, offset_ptr_ram
, sizeof(int));
70 #ifdef __LITTLE_ENDIAN__
71 /* If location in ".text" section swap value */
72 if ((unsigned int)offset_ptr_rom
<
73 (unsigned int)&__ivt_end
)
74 val
= (val
<< 16) | (val
>> 16);
77 /* Check that the target points into executable */
78 if (val
>= (unsigned int)&__image_copy_start
&& val
<=
79 (unsigned int)&__image_copy_end
) {
81 #ifdef __LITTLE_ENDIAN__
82 /* If location in ".text" section swap value */
83 if ((unsigned int)offset_ptr_rom
<
84 (unsigned int)&__ivt_end
)
85 val
= (val
<< 16) | (val
>> 16);
87 memcpy(offset_ptr_ram
, &val
, sizeof(int));
90 last_offset
= offset_ptr_rom
;
92 } while (++re_src
< re_end
);