iBoot/platform/t8010/trampoline.S

216 lines
4.4 KiB
ArmAsm

/*
* Copyright (C) 2012-2015 Apple, Inc. All rights reserved.
*
* This document is the property of Apple, Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple, Inc.
*/
#include <platform/memmap.h>
#include <platform/trampoline.h>
#include <platform/soc/hwregbase.h>
#include <arch/arm64/proc_reg.h>
// Clears from X0 to X1 (not including X1).
// Assumes that X0 and X1 are both 64-byte aligned as this
// will normally be used to clear a whole page.
.macro CLEAR_X0_TO_X1
1:
stp xzr, xzr, [x0], #16
stp xzr, xzr, [x0], #16
stp xzr, xzr, [x0], #16
stp xzr, xzr, [x0], #16
cmp x0, x1
b.lo 1b
.endmacro
// Clears from X0 to X1 (not including X1) using cacheline clear
// operations.
// Assumes that X0 and X1 are both cacheline aligned as this
// will normally be used to clear a whole page.
.macro CLEAR_X0_TO_X1_CACHE_ON
1:
dc zva, x0 // zero cacheline
add x0, x0, #L1_CACHELINE_SIZE
cmp x0, x1
b.lo 1b
.endmacro
.text
.balign 16
.globl _boot_handoff_trampoline, _boot_handoff_trampoline_end
_boot_handoff_trampoline:
// Disable external aborts, interrupts
msr DAIFSet, #(0xf)
// Save jump address in x29, and next stage boot info into x28.
mov x29, x0
mov x28, x1
// Start by clearing the heap.
ldr x0, L_heap_base
ldr x1, L_heap_end
CLEAR_X0_TO_X1_CACHE_ON
// Clear the stacks area.
ldr x0, L_stacks_base
ldr x1, L_stacks_end
CLEAR_X0_TO_X1_CACHE_ON
// Retire all data accesses prior to this
// <rdar://problem/19862668> H9: L2 as RAM request RO and DO alias result in prb hang
dsb sy
// Retire all instructions executed prior to this (may include ROM).
isb sy
// Disable caches, mmu, stack alignment fault
mov x3, #0
msr SCTLR_EL1, x3
dsb sy
isb sy
// Flush the TLBs
tlbi vmalle1
dsb sy
isb sy
// Now running EL1 with MMU off. All accesses are device.
// Clear the page tables.
ldr x0, L_page_tables_base
ldr x1, L_page_tables_end
CLEAR_X0_TO_X1
// Clear the text area (or data area in ROM)
// This can only be done if the trampoline was copied to a safe location
ldr x0, L_text_base
ldr x1, L_text_end
CLEAR_X0_TO_X1
// Clear all the pointers to interesting memory areas
// that were included in the trampoline
adr x0, L_pointers_base
adr x1, L_pointers_end
CLEAR_X0_TO_X1
#if WITH_ROM_TRAMPOLINE
// Disable R/W access to ROM region
ldr x1, L_rom_trampoline_reg
ldr w2, L_rom_trampoline_val
ldr w3, [x1]
orr w3, w3, w2
str w3, [x1]
dsb sy
ldr w3, [x1]
tst w3, w2 // Verify ROM access is disabled
b.eq _trampoline_spin // Oops, not disabled
// ROM doesn't pass any info to next stage (LLB)
mov x28, #0
// Clear remap if enabled to boot this ROM
ldr x1, L_rom_remap_reg
str wzr, [x1]
#endif // WITH_ROM_TRAMPOLINE
// Reset CPU state
mov x1, #0
mov x2, #0
mov x3, #0
mov x4, #0
mov x5, #0
mov x6, #0
mov x7, #0
mov x8, #0
mov x9, #0
mov x10, #0
mov x11, #0
mov x12, #0
mov x13, #0
mov x14, #0
mov x15, #0
mov x16, #0
mov x17, #0
mov x18, #0
mov x19, #0
mov x20, #0
mov x21, #0
mov x22, #0
mov x23, #0
mov x24, #0
mov x25, #0
mov x26, #0
mov x27, #0
mov x30, x29 // lr = next boot stage PC
mov x0, x28 // x0 = next boot stage info
mov x28, #0
mov x29, #0
msr TTBR0_EL1, x1
msr VBAR_EL1, x1
msr ELR_EL1, x1
msr SPSR_EL1, x1
msr SPSel, #0
mov sp, x1 // SP_EL0
msr SPSel, #1
mov sp, x1 // SP_EL1
// Invalidate I-cache
ic iallu
dsb sy
isb sy
ret
#if WITH_ROM_TRAMPOLINE
// Not really able to panic at this point, so let's just spin.
_trampoline_spin:
wfe
b _trampoline_spin
.balign 8
L_rom_remap_reg:
.8byte REMAP_REG
L_rom_trampoline_reg:
.8byte SECURITY_REG
L_rom_trampoline_val:
.4byte ROM_READ_DISABLE
#endif // WITH_ROM_TRAMPOLINE
.balign 64
L_pointers_base:
#if WITH_ROM_TRAMPOLINE
// in ROM we don't erase TEXT, but we can erase DATA
L_text_base:
.8byte DATA_BASE
L_text_end:
.8byte DATA_BASE + DATA_SIZE
#else
// In non-ROM we erase TEXT_FOOTPRINT, which includes both TEXT and DATA
L_text_base:
.8byte TEXT_BASE
L_text_end:
.8byte TEXT_BASE + TEXT_FOOTPRINT
#endif // WITH_ROM_TRAMPOLINE
L_heap_base:
.8byte HEAP_BASE
L_heap_end:
.8byte HEAP_BASE + HEAP_SIZE
L_stacks_base:
.8byte STACKS_BASE
L_stacks_end:
.8byte STACKS_BASE + STACKS_SIZE
L_page_tables_base:
.8byte PAGE_TABLES_BASE
L_page_tables_end:
.8byte PAGE_TABLES_BASE + PAGE_TABLES_SIZE
.balign 64
L_pointers_end:
_boot_handoff_trampoline_end:
.balign 16