boot/efi/arm: flush caches before jump to trampoline
Change-Id: Ia7af285f1c3b988828482ff0cd78a416cf51c2c2 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5196 Reviewed-by: Adrien Destugues <pulkomandy@gmail.com> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
parent
16e80b04a7
commit
6886114066
@ -22,6 +22,7 @@ for platform in [ MultiBootSubDirSetup efi ] {
|
||||
local arch_src =
|
||||
crt0-efi-$(TARGET_ARCH).S
|
||||
entry.S
|
||||
cache.S
|
||||
relocation_func.cpp
|
||||
arch_cpu.cpp
|
||||
arch_dtb.cpp
|
||||
|
@ -26,6 +26,9 @@
|
||||
#define ALIGN_MEMORY_MAP 4
|
||||
|
||||
|
||||
extern "C" void clean_dcache_all(void);
|
||||
extern "C" void invalidate_icache_all(void);
|
||||
|
||||
extern "C" typedef void (*arch_enter_kernel_t)(uint32_t, addr_t, addr_t, addr_t);
|
||||
|
||||
|
||||
@ -239,6 +242,9 @@ arch_start_kernel(addr_t kernelEntry)
|
||||
TRACE("DACR = 0x%08" B_PRIx32 "\n",
|
||||
mmu_read_DACR());
|
||||
|
||||
clean_dcache_all();
|
||||
invalidate_icache_all();
|
||||
|
||||
// Enter the kernel!
|
||||
dprintf("enter_kernel(ttbr0: 0x%08x, kernelArgs: 0x%08x, "
|
||||
"kernelEntry: 0x%08x, sp: 0x%08x)\n",
|
||||
|
87
src/system/boot/platform/efi/arch/arm/cache.S
Normal file
87
src/system/boot/platform/efi/arch/arm/cache.S
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2022 Haiku, Inc. All rights reserved.
|
||||
* Released under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <asm_defs.h>
|
||||
|
||||
|
||||
// the following code is based on ARM ARM
|
||||
// section B2.2.4, Cache maintenance functionality
|
||||
|
||||
FUNCTION(clean_dcache_all):
|
||||
dmb
|
||||
stmfd sp!, {r4-r11, lr}
|
||||
|
||||
// Query the number of cache levels to be cleaned
|
||||
// this is encoded in LoC which is bits 26..24 of CLIDR
|
||||
mrc p15, 1, r0, c0, c0, 1
|
||||
mov r3, r0, lsr #23
|
||||
ands r3, r3, #7 << 1
|
||||
beq cleaning_done
|
||||
|
||||
// Start cleaning at cache level 0
|
||||
mov r10, #0
|
||||
clean_levels_loop:
|
||||
// Get type of current cache level
|
||||
add r2, r10, r10, lsr #1
|
||||
mov r1, r0, lsr r2
|
||||
and r1, r1, #7
|
||||
|
||||
// Skip this level if cache type is less than 2 i.e. no cache or only i-cache
|
||||
cmp r1, #2
|
||||
blt clean_next_level
|
||||
|
||||
// Select current level in Cache Size selection register
|
||||
mcr p15, 2, r10, c0, c0, 0
|
||||
isb
|
||||
|
||||
// Read Cache Size ID for the current level
|
||||
mrc p15, 1, r1, c0, c0, 0
|
||||
|
||||
// Decode LineSize from bits[2:0]
|
||||
and r2, r1, #7
|
||||
add r2, r2, #4
|
||||
|
||||
// Decode Associativity from bits[12:3]
|
||||
movw r4, #0x3ff
|
||||
ands r4, r4, r1, lsr #3
|
||||
clz r5, r4
|
||||
|
||||
// Decode NumSets from bits[27:13]
|
||||
movw r7, #0x7fff
|
||||
ands r7, r7, r1, lsr #13
|
||||
|
||||
clean_way_loop:
|
||||
mov r9, r7
|
||||
clean_index_loop:
|
||||
orr r11, r10, r4, lsl r5
|
||||
orr r11, r11, r9, lsl r2
|
||||
|
||||
// Clean and Invalidate by set/way
|
||||
mcr p15, 0, r11, c7, c14, 2
|
||||
|
||||
subs r9, r9, #1
|
||||
bge clean_index_loop
|
||||
|
||||
subs r4, r4, #1
|
||||
bge clean_way_loop
|
||||
clean_next_level:
|
||||
add r10, r10, #2
|
||||
cmp r3, r10
|
||||
bgt clean_levels_loop
|
||||
cleaning_done:
|
||||
dsb
|
||||
isb
|
||||
ldmfd sp!, {r4-r11, lr}
|
||||
bx lr
|
||||
FUNCTION_END(clean_dcache_all)
|
||||
|
||||
|
||||
FUNCTION(invalidate_icache_all):
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 0
|
||||
dsb
|
||||
isb
|
||||
bx lr
|
||||
FUNCTION_END(invalidate_icache_all)
|
Loading…
Reference in New Issue
Block a user