From 0435b73f63efba38b213b55c0ff2decd81262ecb Mon Sep 17 00:00:00 2001 From: TuxSH Date: Tue, 6 Aug 2019 22:26:28 +0200 Subject: [PATCH] thermosphere: refactor crt0 + watchpoint init --- thermosphere/linker.ld | 7 +-- .../src/breakpoints_watchpoints_common.h | 4 +- thermosphere/src/init.c | 58 +++++++++++++++++++ .../src/platform/memory_map_mmu_cfg.h | 1 + thermosphere/src/platform/qemu/memory_map.c | 6 +- thermosphere/src/platform/tegra/memory_map.c | 6 +- thermosphere/src/smc.c | 1 - thermosphere/src/start.s | 48 +++------------ thermosphere/src/synchronization.h | 27 --------- thermosphere/src/sysreg_traps.c | 1 - thermosphere/src/traps.c | 1 - thermosphere/src/utils.h | 12 +++- thermosphere/src/watchpoints.c | 2 +- 13 files changed, 89 insertions(+), 85 deletions(-) create mode 100644 thermosphere/src/init.c delete mode 100644 thermosphere/src/synchronization.h diff --git a/thermosphere/linker.ld b/thermosphere/linker.ld index df8f18178..b0cf240b5 100644 --- a/thermosphere/linker.ld +++ b/thermosphere/linker.ld @@ -140,16 +140,15 @@ SECTIONS __end__ = ABSOLUTE(.); } >main :NONE - . = ALIGN(0x1000); - __end__ = ABSOLUTE(.) ; - .temp (NOLOAD) : { . = ALIGN(0x1000); __stacks_top__ = ABSOLUTE(. + 0x2000); __crash_stacks_top__ = ABSOLUTE(. + 0x3000); . += 0x3000; - *(.temp.*) + __temp_bss_start__ = ABSOLUTE(.); + *(.tempbss .tempbss.*) + __temp_bss_end__ = ABSOLUTE(.); . = ALIGN(0x1000); } >temp :NONE diff --git a/thermosphere/src/breakpoints_watchpoints_common.h b/thermosphere/src/breakpoints_watchpoints_common.h index 36e4f3dc0..1757d1642 100644 --- a/thermosphere/src/breakpoints_watchpoints_common.h +++ b/thermosphere/src/breakpoints_watchpoints_common.h @@ -56,7 +56,7 @@ typedef enum DebugPmc { } DebugPmc; typedef enum WatchpointLoadStoreControl { - WatchpointLoadStoreControl_Load = 0, + WatchpointLoadStoreControl_Load = 1, WatchpointLoadStoreControl_Store = 2, WatchpointLoadStoreControl_LoadStore = 3, } WatchpointLoadStoreControl; @@ -86,4 +86,4 @@ typedef struct DebugRegisterPair { static inline void enableBreakpointsAndWatchpoints(void) { SET_SYSREG(mdscr_el1, GET_SYSREG(mdscr_el1) | MDSCR_EL1_MDE); -} \ No newline at end of file +} diff --git a/thermosphere/src/init.c b/thermosphere/src/init.c new file mode 100644 index 000000000..231d256e4 --- /dev/null +++ b/thermosphere/src/init.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include "core_ctx.h" +#include "platform/memory_map_mmu_cfg.h" +#include "sysreg.h" +#include "utils.h" + +extern u8 __bss_start__[], __end__[], __temp_bss_start__[], __temp_bss_end__[]; +extern const u32 __vectors_start__[]; + +static void initSysregs(void) +{ + // Set VBAR + SET_SYSREG(vbar_el2, (uintptr_t)__vectors_start__); + + // Set system to sane defaults, aarch64 for el1, mmu&caches initially disabled for EL1, etc. + SET_SYSREG(hcr_el2, 0x80000000); + SET_SYSREG(dacr32_el2, 0xFFFFFFFF); // unused + SET_SYSREG(sctlr_el1, 0x00C50838); + + SET_SYSREG(mdcr_el2, 0x00000000); + SET_SYSREG(mdscr_el1, 0x00000000); +} + +void initSystem(u32 coreId, bool isBootCore, u64 argument) +{ + coreCtxInit(coreId, isBootCore, argument); + initSysregs(); + + __dsb_sy(); + __isb(); + + if (isBootCore) { + if (!currentCoreCtx->warmboot) { + memset(__bss_start__, 0, __end__ - __bss_start__); + } + + memset(__temp_bss_start__, 0, __temp_bss_end__ - __temp_bss_start__); + } + + configureMemoryMapEnableMmu(); + configureMemoryMapEnableStage2(); +} diff --git a/thermosphere/src/platform/memory_map_mmu_cfg.h b/thermosphere/src/platform/memory_map_mmu_cfg.h index 5e3f51b96..03268cfe1 100644 --- a/thermosphere/src/platform/memory_map_mmu_cfg.h +++ b/thermosphere/src/platform/memory_map_mmu_cfg.h @@ -27,3 +27,4 @@ #endif void configureMemoryMapEnableMmu(void); +void configureMemoryMapEnableStage2(void); diff --git a/thermosphere/src/platform/qemu/memory_map.c b/thermosphere/src/platform/qemu/memory_map.c index 1eba99311..66b348125 100644 --- a/thermosphere/src/platform/qemu/memory_map.c +++ b/thermosphere/src/platform/qemu/memory_map.c @@ -48,11 +48,9 @@ uintptr_t configureMemoryMap(u32 *addrSpaceSize) { // QEMU virt RAM address space starts at 0x40000000 *addrSpaceSize = ADDRSPACESZ; - static bool initialized = false; - if (currentCoreCtx->isBootCore && !initialized) { + if (currentCoreCtx->isBootCore && !currentCoreCtx->warmboot) { identityMapL1(g_ttbl, 0x00000000ull, BITL(30), ATTRIB_MEMTYPE_DEVICE); identityMapL1(g_ttbl, 0x40000000ull, (BITL(ADDRSPACESZ - 30) - 1ull) << 30, ATTRIB_MEMTYPE_NORMAL); - initialized = true; } return (uintptr_t)g_ttbl; @@ -79,4 +77,4 @@ uintptr_t configureStage2MemoryMap(u32 *addrSpaceSize) } return (uintptr_t)g_vttbl; -} \ No newline at end of file +} diff --git a/thermosphere/src/platform/tegra/memory_map.c b/thermosphere/src/platform/tegra/memory_map.c index 13a75b788..eabef083c 100644 --- a/thermosphere/src/platform/tegra/memory_map.c +++ b/thermosphere/src/platform/tegra/memory_map.c @@ -48,11 +48,9 @@ static inline void identityMapL3(u64 *tbl, uintptr_t addr, size_t size, u64 attr uintptr_t configureMemoryMap(u32 *addrSpaceSize) { *addrSpaceSize = ADDRSPACESZ; - static bool initialized = false; - if (currentCoreCtx->isBootCore && !initialized) { + if (currentCoreCtx->isBootCore && !currentCoreCtx->warmboot) { identityMapL1(g_ttbl, 0x00000000ull, 2 * BITL(30), ATTRIB_MEMTYPE_DEVICE); identityMapL1(g_ttbl, 0x80000000ull, (BITL(ADDRSPACESZ - 30) - 2ull) << 30, ATTRIB_MEMTYPE_NORMAL); - initialized = true; } return (uintptr_t)g_ttbl; @@ -78,4 +76,4 @@ uintptr_t configureStage2MemoryMap(u32 *addrSpaceSize) } return (uintptr_t)g_vttbl; -} \ No newline at end of file +} diff --git a/thermosphere/src/smc.c b/thermosphere/src/smc.c index 21235cb16..984590217 100644 --- a/thermosphere/src/smc.c +++ b/thermosphere/src/smc.c @@ -1,6 +1,5 @@ #include #include "smc.h" -#include "synchronization.h" #include "core_ctx.h" #include "arm.h" diff --git a/thermosphere/src/start.s b/thermosphere/src/start.s index 1f34ab6e2..d77e91c5f 100644 --- a/thermosphere/src/start.s +++ b/thermosphere/src/start.s @@ -39,23 +39,10 @@ _startCommon: msr daifset, 0b1111 msr spsel, #1 - // Set VBAR - adrp x8, __vectors_start__ - add x8, x8, #:lo12:__vectors_start__ - msr vbar_el2, x8 - - // Set system to sane defaults, aarch64 for el1, mmu disabled - mov x4, #0x0838 - movk x4, #0xC5, lsl #16 - orr x1, x4, #0x30000000 - mov x2, #(1 << 31) - mov x3, #0xFFFFFFFF - + // Set sctlr_el2 ASAP to disable mmu/caching if not already done. + mov x1, #0x0838 + movk x1, #0x30C5,lsl #16 msr sctlr_el2, x1 - msr hcr_el2, x2 - msr dacr32_el2, x3 - msr sctlr_el1, x4 - dsb sy isb @@ -75,31 +62,14 @@ _startCommon: lsl x9, x0, #10 sub sp, x8, x9 - // Set up x18 - mov w1, w19 - bl coreCtxInit - stp x18, xzr, [sp, #-0x10]! - - // Reserve space for exception frame - sub sp, sp, #0x120 - + // Set up x18, other sysregs, BSS, MMU, etc. // Don't call init array to save space? - // Clear BSS & call main for the first core executing this code - cbz x19, _enable_mmu - adrp x0, __bss_start__ - add x0, x0, #:lo12:__bss_start__ - mov w1, wzr - adrp x2, __end__ - add x2, x2, #:lo12:__end__ - sub x2, x2, x0 - bl memset + mov w1, w19 + bl initSystem -_enable_mmu: - - // Enable EL2 address translation and caches - bl configureMemoryMapEnableMmu - // Enable EL1 Stage2 intermediate physical address translation - bl configureMemoryMapEnableStage2 + // Save x18, reserve space for exception frame + stp x18, xzr, [sp, #-0x10]! + sub sp, sp, #0x120 dsb sy isb diff --git a/thermosphere/src/synchronization.h b/thermosphere/src/synchronization.h deleted file mode 100644 index bb3a0efdf..000000000 --- a/thermosphere/src/synchronization.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -static inline void __dsb_sy(void) -{ - __asm__ __volatile__ ("dsb sy" ::: "memory"); -} - -static inline void __isb(void) -{ - __asm__ __volatile__ ("isb" ::: "memory"); -} diff --git a/thermosphere/src/sysreg_traps.c b/thermosphere/src/sysreg_traps.c index 9e5c11425..f1fe0e64a 100644 --- a/thermosphere/src/sysreg_traps.c +++ b/thermosphere/src/sysreg_traps.c @@ -15,7 +15,6 @@ */ #include "sysreg_traps.h" -#include "synchronization.h" #include "sysreg.h" #include "arm.h" #include "debug_log.h" diff --git a/thermosphere/src/traps.c b/thermosphere/src/traps.c index 85a142f01..9b015cb64 100644 --- a/thermosphere/src/traps.c +++ b/thermosphere/src/traps.c @@ -16,7 +16,6 @@ #include "traps.h" #include "sysreg.h" -#include "synchronization.h" static void enableDebugTraps(void) { diff --git a/thermosphere/src/utils.h b/thermosphere/src/utils.h index f604519bb..a102f4f81 100644 --- a/thermosphere/src/utils.h +++ b/thermosphere/src/utils.h @@ -33,7 +33,17 @@ #define ALINLINE __attribute__((always_inline)) -#define TEMPORARY __attribute__((section(".temp"))) +#define TEMPORARY __attribute__((section(".tempbss"))) + +static inline void __dsb_sy(void) +{ + __asm__ __volatile__ ("dsb sy" ::: "memory"); +} + +static inline void __isb(void) +{ + __asm__ __volatile__ ("isb" ::: "memory"); +} bool overlaps(u64 as, u64 ae, u64 bs, u64 be); diff --git a/thermosphere/src/watchpoints.c b/thermosphere/src/watchpoints.c index 32ca585fa..d783b4971 100644 --- a/thermosphere/src/watchpoints.c +++ b/thermosphere/src/watchpoints.c @@ -28,7 +28,7 @@ void initWatchpoints(void) recursiveSpinlockLock(&g_watchpointManager.lock); if (currentCoreCtx->isBootCore && !currentCoreCtx->warmboot) { - size_t num = ((GET_SYSREG(id_aa64dfr0_el1) >> 12) & 0xF) + 1; + size_t num = ((GET_SYSREG(id_aa64dfr0_el1) >> 20) & 0xF) + 1; g_watchpointManager.maxWatchpoints = (u32)num; g_watchpointManager.allocationBitmap = 0xFFFF; }