Teach the kernel and the ELF trampoline how to boot from onboard flash.

This commit is contained in:
Olivier Houchard 2007-02-19 00:57:27 +00:00
parent 0d9fc1e6e1
commit db599c2f20
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=166819
2 changed files with 82 additions and 37 deletions

View File

@ -103,7 +103,7 @@ memcpy(void *dst, const void *src, int len)
char *d = dst; char *d = dst;
while (len) { while (len) {
if (len >= 4 && !((vm_offset_t)d & 3) && if (0 && len >= 4 && !((vm_offset_t)d & 3) &&
!((vm_offset_t)s & 3)) { !((vm_offset_t)s & 3)) {
*(uint32_t *)d = *(uint32_t *)s; *(uint32_t *)d = *(uint32_t *)s;
s += 4; s += 4;
@ -143,6 +143,37 @@ _start(void)
int physaddr = KERNPHYSADDR; int physaddr = KERNPHYSADDR;
int tmp1; int tmp1;
unsigned int sp = ((unsigned int)&_end & ~3) + 4; unsigned int sp = ((unsigned int)&_end & ~3) + 4;
#if defined(FLASHADDR) && defined(LOADERRAMADDR)
unsigned int pc;
__asm __volatile("adr %0, _start\n"
: "=r" (pc));
if ((FLASHADDR > LOADERRAMADDR && pc >= FLASHADDR) ||
(FLASHADDR < LOADERRAMADDR && pc < LOADERRAMADDR)) {
/*
* We're running from flash, so just copy the whole thing
* from flash to memory.
* This is far from optimal, we could do the relocation or
* the unzipping directly from flash to memory to avoid this
* needless copy, but it would require to know the flash
* physical address.
*/
unsigned int target_addr;
unsigned int tmp_sp;
target_addr = (unsigned int)&_start - PHYSADDR + LOADERRAMADDR;
tmp_sp = target_addr + 0x100000 +
(unsigned int)&_end - (unsigned int)&_start;
memcpy((char *)target_addr, (char *)pc,
(unsigned int)&_end - (unsigned int)&_start);
/* Temporary set the sp and jump to the new location. */
__asm __volatile(
"mov sp, %1\n"
"mov pc, %0\n"
: : "r" (target_addr), "r" (tmp_sp));
}
#endif
#ifdef KZIP #ifdef KZIP
sp += KERNSIZE + 0x100; sp += KERNSIZE + 0x100;
sp &= ~(L1_TABLE_SIZE - 1); sp &= ~(L1_TABLE_SIZE - 1);

View File

@ -66,47 +66,53 @@ __FBSDID("$FreeBSD$");
ENTRY_NP(btext) ENTRY_NP(btext)
ASENTRY_NP(_start) ASENTRY_NP(_start)
#if defined (FLASHADDR) && defined(LOADERRAMADDR)
/* Check if we're running from flash. */
/* Check if we are running on RAM, if not move ourself to RAM */ ldr r7, =FLASHADDR
#if 0 /*
cmp pc, #PHYSADDR * If we're running with MMU disabled, test against the
bhi start_inram /* XXX: This is wrong */ * physical address instead.
#endif
b start_inram /*
* XXX: this is even more wrong, but RedBoot
* use 0x00000000-0x100000000 as virtual
* addresses for the RAM.
*/ */
mrc p15, 0, r2, c1, c0, 0
ands r2, r2, #CPU_CONTROL_MMU_ENABLE
ldreq r8, =PHYSADDR
ldrne r8, =LOADERRAMADDR
cmp r7, r8
bls flash_lower
cmp r7, pc
bhi from_ram
b do_copy
/* move me to RAM flash_lower:
* XXX: we can use memcpy if it is PIC cmp r8, pc
*/ bls from_ram
ldr r1, Lcopy_size do_copy:
adr r0, _C_LABEL(_start) ldr r9, =KERNBASE
add r1, r1, #3 adr r1, _start
mov r1, r1, LSR #2 ldr r0, Lreal_start
mov r2, #PHYSADDR ldr r2, Lend
add r2, r2, #0x00200000 sub r2, r2, r0
mov r4, r2 sub r0, r0, r9
add r0, r0, r8
5: ldr r3,[r0],#4 mov r4, r0
str r3,[r2],#4 /* Make sure _arm_memcpy is NULL */
subs r1,r1,#1 ldr r3, .L_arm_memcpy
bhi 5b ldr r3, [r3]
mov r5, #0
/* Jump to RAM */ str r5, [r3]
ldr r0, Lstart_off bl memcpy
ldr r0, Lram_offset
add pc, r4, r0 add pc, r4, r0
Lram_offset: .word from_ram-_C_LABEL(_start)
Lcopy_size: .word _edata-_C_LABEL(_start) from_ram:
Lstart_off: .word start_inram-_C_LABEL(_start) nop
start_inram: #endif
adr r7, Lunmapped adr r7, Lunmapped
bic r7, r7, #0xff000000 bic r7, r7, #0xff000000
orr r7, r7, #PHYSADDR orr r7, r7, #PHYSADDR
disable_mmu:
/* Disable MMU for a while */ /* Disable MMU for a while */
mrc p15, 0, r2, c1, c0, 0 mrc p15, 0, r2, c1, c0, 0
bic r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\ bic r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\
@ -120,7 +126,6 @@ start_inram:
nop nop
mov pc, r7 mov pc, r7
Lunmapped: Lunmapped:
#ifdef STARTUP_PAGETABLE_ADDR #ifdef STARTUP_PAGETABLE_ADDR
/* build page table from scratch */ /* build page table from scratch */
ldr r0, Lstartup_pagetable ldr r0, Lstartup_pagetable
@ -191,6 +196,10 @@ Lvirtaddr:
.word KERNVIRTADDR .word KERNVIRTADDR
Lphysaddr: Lphysaddr:
.word KERNPHYSADDR .word KERNPHYSADDR
Lreal_start:
.word _start
Lend:
.word _edata
Lstartup_pagetable: Lstartup_pagetable:
.word STARTUP_PAGETABLE_ADDR .word STARTUP_PAGETABLE_ADDR
mmu_init_table: mmu_init_table:
@ -207,6 +216,11 @@ mmu_init_table:
.word _end .word _end
.word svcstk + INIT_ARM_STACK_SIZE .word svcstk + INIT_ARM_STACK_SIZE
#if defined(FLASHADDR) && defined(LOADERRAMADDR)
.L_arm_memcpy:
.word _C_LABEL(_arm_memcpy)
#endif
.Lvirt_done: .Lvirt_done:
.word virt_done .word virt_done
.Lmainreturned: .Lmainreturned: