Merge branch 'for-next/arm-start' into for-next/arm
This commit is contained in:
commit
7787010e9b
|
@ -1,2 +1 @@
|
|||
obj-y += lowlevel_init.o
|
||||
obj-y += init.o
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Board specific setup info
|
||||
*
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asm/barebox-arm-head.h>
|
||||
|
||||
.globl reset
|
||||
reset:
|
||||
common_reset r0
|
||||
b board_init_lowlevel_return
|
|
@ -1,7 +1,7 @@
|
|||
obj-y += cpu.o
|
||||
obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions.o
|
||||
obj-$(CONFIG_ARM_EXCEPTIONS) += interrupts.o
|
||||
obj-y += start.o
|
||||
obj-y += start.o setupc.o
|
||||
|
||||
#
|
||||
# Any variants can be called as start-armxyz.S
|
||||
|
@ -20,4 +20,4 @@ obj-$(CONFIG_CPU_32v7) += cache-armv7.o
|
|||
pbl-$(CONFIG_CPU_32v7) += cache-armv7.o
|
||||
obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
|
||||
|
||||
pbl-y += start-pbl.o
|
||||
pbl-y += start-pbl.o setupc.o
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
#include <linux/linkage.h>
|
||||
|
||||
.section .text.setupc
|
||||
|
||||
/*
|
||||
* setup_c: copy binary to link address, clear bss and
|
||||
* continue executing at new address.
|
||||
*
|
||||
* This function does not return to the address it is
|
||||
* called from, but to the same location in the copied
|
||||
* binary.
|
||||
*/
|
||||
ENTRY(setup_c)
|
||||
push {r4, r5}
|
||||
mov r5, lr
|
||||
bl get_runtime_offset
|
||||
subs r4, r0, #0
|
||||
beq 1f /* skip memcpy if already at correct address */
|
||||
ldr r0,=_text
|
||||
ldr r2,=__bss_start
|
||||
sub r2, r2, r0
|
||||
sub r1, r0, r4
|
||||
bl memcpy /* memcpy(_text, _text - offset, __bss_start - _text) */
|
||||
1: ldr r0, =__bss_start
|
||||
mov r1, #0
|
||||
ldr r2, =__bss_stop
|
||||
sub r2, r2, r0
|
||||
bl memset /* clear bss */
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 0 /* flush icache */
|
||||
add lr, r5, r4 /* adjust return address to new location */
|
||||
pop {r4, r5}
|
||||
mov pc, lr
|
||||
ENDPROC(setup_c)
|
|
@ -174,7 +174,7 @@ static void barebox_uncompress(void *compressed_start, unsigned int len)
|
|||
*/
|
||||
void __naked board_init_lowlevel_return(void)
|
||||
{
|
||||
uint32_t r, offset;
|
||||
uint32_t offset;
|
||||
uint32_t pg_start, pg_end, pg_len;
|
||||
|
||||
/* Setup the stack */
|
||||
|
@ -187,43 +187,16 @@ void __naked board_init_lowlevel_return(void)
|
|||
pg_end = (uint32_t)&input_data_end - offset;
|
||||
pg_len = pg_end - pg_start;
|
||||
|
||||
if (IS_ENABLED(CONFIG_PBL_FORCE_PIGGYDATA_COPY))
|
||||
goto copy_piggy_link;
|
||||
if (offset && (IS_ENABLED(CONFIG_PBL_FORCE_PIGGYDATA_COPY) ||
|
||||
region_overlap(pg_start, pg_len, TEXT_BASE, pg_len * 4))) {
|
||||
/*
|
||||
* copy piggydata binary to its link address
|
||||
*/
|
||||
memcpy(&input_data, (void *)pg_start, pg_len);
|
||||
pg_start = (uint32_t)&input_data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the piggydata binary will be overwritten
|
||||
* by the uncompressed binary or by the pbl relocation
|
||||
*/
|
||||
if (!offset ||
|
||||
!((pg_start >= TEXT_BASE && pg_start < TEXT_BASE + pg_len * 4) ||
|
||||
((uint32_t)_text >= pg_start && (uint32_t)_text <= pg_end)))
|
||||
goto copy_link;
|
||||
setup_c();
|
||||
|
||||
copy_piggy_link:
|
||||
/*
|
||||
* copy piggydata binary to its link address
|
||||
*/
|
||||
memcpy(&input_data, (void *)pg_start, pg_len);
|
||||
pg_start = (uint32_t)&input_data;
|
||||
|
||||
copy_link:
|
||||
/* relocate to link address if necessary */
|
||||
if (offset)
|
||||
memcpy((void *)_text, (void *)(_text - offset),
|
||||
__bss_start - _text);
|
||||
|
||||
/* clear bss */
|
||||
memset(__bss_start, 0, __bss_stop - __bss_start);
|
||||
|
||||
flush_icache();
|
||||
|
||||
r = (unsigned int)&barebox_uncompress;
|
||||
/* call barebox_uncompress with its absolute address */
|
||||
__asm__ __volatile__(
|
||||
"mov r0, %1\n"
|
||||
"mov r1, %2\n"
|
||||
"mov pc, %0\n"
|
||||
:
|
||||
: "r"(r), "r"(pg_start), "r"(pg_len)
|
||||
: "r0", "r1");
|
||||
barebox_uncompress((void *)pg_start, pg_len);
|
||||
}
|
||||
|
|
|
@ -24,32 +24,19 @@
|
|||
#include <asm-generic/memory_layout.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/cache.h>
|
||||
#include <memory.h>
|
||||
|
||||
#ifdef CONFIG_PBL_IMAGE
|
||||
/*
|
||||
* First function in the uncompressed image. We get here from
|
||||
* the pbl.
|
||||
*/
|
||||
void __naked __section(.text_entry) start(void)
|
||||
{
|
||||
u32 r;
|
||||
|
||||
/* Setup the stack */
|
||||
r = STACK_BASE + STACK_SIZE - 16;
|
||||
__asm__ __volatile__("mov sp, %0" : : "r"(r));
|
||||
/* clear bss */
|
||||
memset(__bss_start, 0, __bss_stop - __bss_start);
|
||||
|
||||
start_barebox();
|
||||
}
|
||||
#ifdef CONFIG_PBL_IMAGE
|
||||
board_init_lowlevel_return();
|
||||
#else
|
||||
|
||||
/*
|
||||
* First function in the image without pbl support
|
||||
*/
|
||||
void __naked __section(.text_entry) start(void)
|
||||
{
|
||||
barebox_arm_head();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -70,25 +57,9 @@ void __naked __bare_init reset(void)
|
|||
*/
|
||||
void __naked board_init_lowlevel_return(void)
|
||||
{
|
||||
uint32_t r, offset;
|
||||
|
||||
arm_setup_stack(STACK_BASE + STACK_SIZE - 16);
|
||||
|
||||
/* Get offset between linked address and runtime address */
|
||||
offset = get_runtime_offset();
|
||||
setup_c();
|
||||
|
||||
/* relocate to link address if necessary */
|
||||
if (offset)
|
||||
memcpy((void *)_text, (void *)(_text - offset),
|
||||
__bss_start - _text);
|
||||
|
||||
/* clear bss */
|
||||
memset(__bss_start, 0, __bss_stop - __bss_start);
|
||||
|
||||
flush_icache();
|
||||
|
||||
/* call start_barebox with its absolute address */
|
||||
r = (unsigned int)&start_barebox;
|
||||
__asm__ __volatile__("mov pc, %0" : : "r"(r));
|
||||
start_barebox();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -38,4 +38,6 @@ void board_init_lowlevel(void);
|
|||
void board_init_lowlevel_return(void);
|
||||
uint32_t get_runtime_offset(void);
|
||||
|
||||
void setup_c(void);
|
||||
|
||||
#endif /* _BAREBOX_ARM_H_ */
|
||||
|
|
|
@ -256,4 +256,17 @@ static inline void barebox_banner(void) {}
|
|||
(__x < 0) ? -__x : __x; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Check if two regions overlap. returns true if they do, false otherwise
|
||||
*/
|
||||
static inline bool region_overlap(unsigned long starta, unsigned long lena,
|
||||
unsigned long startb, unsigned long lenb)
|
||||
{
|
||||
if (starta + lena <= startb)
|
||||
return 0;
|
||||
if (startb + lenb <= starta)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* __COMMON_H_ */
|
||||
|
|
Loading…
Reference in New Issue