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;
}