mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-23 12:51:13 +00:00
thermosphere: refactor crt0 + watchpoint init
This commit is contained in:
parent
bd93b01e57
commit
0435b73f63
13 changed files with 89 additions and 85 deletions
|
@ -140,16 +140,15 @@ SECTIONS
|
||||||
__end__ = ABSOLUTE(.);
|
__end__ = ABSOLUTE(.);
|
||||||
} >main :NONE
|
} >main :NONE
|
||||||
|
|
||||||
. = ALIGN(0x1000);
|
|
||||||
__end__ = ABSOLUTE(.) ;
|
|
||||||
|
|
||||||
.temp (NOLOAD) :
|
.temp (NOLOAD) :
|
||||||
{
|
{
|
||||||
. = ALIGN(0x1000);
|
. = ALIGN(0x1000);
|
||||||
__stacks_top__ = ABSOLUTE(. + 0x2000);
|
__stacks_top__ = ABSOLUTE(. + 0x2000);
|
||||||
__crash_stacks_top__ = ABSOLUTE(. + 0x3000);
|
__crash_stacks_top__ = ABSOLUTE(. + 0x3000);
|
||||||
. += 0x3000;
|
. += 0x3000;
|
||||||
*(.temp.*)
|
__temp_bss_start__ = ABSOLUTE(.);
|
||||||
|
*(.tempbss .tempbss.*)
|
||||||
|
__temp_bss_end__ = ABSOLUTE(.);
|
||||||
. = ALIGN(0x1000);
|
. = ALIGN(0x1000);
|
||||||
} >temp :NONE
|
} >temp :NONE
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ typedef enum DebugPmc {
|
||||||
} DebugPmc;
|
} DebugPmc;
|
||||||
|
|
||||||
typedef enum WatchpointLoadStoreControl {
|
typedef enum WatchpointLoadStoreControl {
|
||||||
WatchpointLoadStoreControl_Load = 0,
|
WatchpointLoadStoreControl_Load = 1,
|
||||||
WatchpointLoadStoreControl_Store = 2,
|
WatchpointLoadStoreControl_Store = 2,
|
||||||
WatchpointLoadStoreControl_LoadStore = 3,
|
WatchpointLoadStoreControl_LoadStore = 3,
|
||||||
} WatchpointLoadStoreControl;
|
} WatchpointLoadStoreControl;
|
||||||
|
|
58
thermosphere/src/init.c
Normal file
58
thermosphere/src/init.c
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#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();
|
||||||
|
}
|
|
@ -27,3 +27,4 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void configureMemoryMapEnableMmu(void);
|
void configureMemoryMapEnableMmu(void);
|
||||||
|
void configureMemoryMapEnableStage2(void);
|
||||||
|
|
|
@ -48,11 +48,9 @@ uintptr_t configureMemoryMap(u32 *addrSpaceSize)
|
||||||
{
|
{
|
||||||
// QEMU virt RAM address space starts at 0x40000000
|
// QEMU virt RAM address space starts at 0x40000000
|
||||||
*addrSpaceSize = ADDRSPACESZ;
|
*addrSpaceSize = ADDRSPACESZ;
|
||||||
static bool initialized = false;
|
if (currentCoreCtx->isBootCore && !currentCoreCtx->warmboot) {
|
||||||
if (currentCoreCtx->isBootCore && !initialized) {
|
|
||||||
identityMapL1(g_ttbl, 0x00000000ull, BITL(30), ATTRIB_MEMTYPE_DEVICE);
|
identityMapL1(g_ttbl, 0x00000000ull, BITL(30), ATTRIB_MEMTYPE_DEVICE);
|
||||||
identityMapL1(g_ttbl, 0x40000000ull, (BITL(ADDRSPACESZ - 30) - 1ull) << 30, ATTRIB_MEMTYPE_NORMAL);
|
identityMapL1(g_ttbl, 0x40000000ull, (BITL(ADDRSPACESZ - 30) - 1ull) << 30, ATTRIB_MEMTYPE_NORMAL);
|
||||||
initialized = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (uintptr_t)g_ttbl;
|
return (uintptr_t)g_ttbl;
|
||||||
|
|
|
@ -48,11 +48,9 @@ static inline void identityMapL3(u64 *tbl, uintptr_t addr, size_t size, u64 attr
|
||||||
uintptr_t configureMemoryMap(u32 *addrSpaceSize)
|
uintptr_t configureMemoryMap(u32 *addrSpaceSize)
|
||||||
{
|
{
|
||||||
*addrSpaceSize = ADDRSPACESZ;
|
*addrSpaceSize = ADDRSPACESZ;
|
||||||
static bool initialized = false;
|
if (currentCoreCtx->isBootCore && !currentCoreCtx->warmboot) {
|
||||||
if (currentCoreCtx->isBootCore && !initialized) {
|
|
||||||
identityMapL1(g_ttbl, 0x00000000ull, 2 * BITL(30), ATTRIB_MEMTYPE_DEVICE);
|
identityMapL1(g_ttbl, 0x00000000ull, 2 * BITL(30), ATTRIB_MEMTYPE_DEVICE);
|
||||||
identityMapL1(g_ttbl, 0x80000000ull, (BITL(ADDRSPACESZ - 30) - 2ull) << 30, ATTRIB_MEMTYPE_NORMAL);
|
identityMapL1(g_ttbl, 0x80000000ull, (BITL(ADDRSPACESZ - 30) - 2ull) << 30, ATTRIB_MEMTYPE_NORMAL);
|
||||||
initialized = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (uintptr_t)g_ttbl;
|
return (uintptr_t)g_ttbl;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "smc.h"
|
#include "smc.h"
|
||||||
#include "synchronization.h"
|
|
||||||
#include "core_ctx.h"
|
#include "core_ctx.h"
|
||||||
#include "arm.h"
|
#include "arm.h"
|
||||||
|
|
||||||
|
|
|
@ -39,23 +39,10 @@ _startCommon:
|
||||||
msr daifset, 0b1111
|
msr daifset, 0b1111
|
||||||
msr spsel, #1
|
msr spsel, #1
|
||||||
|
|
||||||
// Set VBAR
|
// Set sctlr_el2 ASAP to disable mmu/caching if not already done.
|
||||||
adrp x8, __vectors_start__
|
mov x1, #0x0838
|
||||||
add x8, x8, #:lo12:__vectors_start__
|
movk x1, #0x30C5,lsl #16
|
||||||
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
|
|
||||||
|
|
||||||
msr sctlr_el2, x1
|
msr sctlr_el2, x1
|
||||||
msr hcr_el2, x2
|
|
||||||
msr dacr32_el2, x3
|
|
||||||
msr sctlr_el1, x4
|
|
||||||
|
|
||||||
dsb sy
|
dsb sy
|
||||||
isb
|
isb
|
||||||
|
|
||||||
|
@ -75,31 +62,14 @@ _startCommon:
|
||||||
lsl x9, x0, #10
|
lsl x9, x0, #10
|
||||||
sub sp, x8, x9
|
sub sp, x8, x9
|
||||||
|
|
||||||
// Set up x18
|
// Set up x18, other sysregs, BSS, MMU, etc.
|
||||||
mov w1, w19
|
|
||||||
bl coreCtxInit
|
|
||||||
stp x18, xzr, [sp, #-0x10]!
|
|
||||||
|
|
||||||
// Reserve space for exception frame
|
|
||||||
sub sp, sp, #0x120
|
|
||||||
|
|
||||||
// Don't call init array to save space?
|
// Don't call init array to save space?
|
||||||
// Clear BSS & call main for the first core executing this code
|
mov w1, w19
|
||||||
cbz x19, _enable_mmu
|
bl initSystem
|
||||||
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
|
|
||||||
|
|
||||||
_enable_mmu:
|
// Save x18, reserve space for exception frame
|
||||||
|
stp x18, xzr, [sp, #-0x10]!
|
||||||
// Enable EL2 address translation and caches
|
sub sp, sp, #0x120
|
||||||
bl configureMemoryMapEnableMmu
|
|
||||||
// Enable EL1 Stage2 intermediate physical address translation
|
|
||||||
bl configureMemoryMapEnableStage2
|
|
||||||
|
|
||||||
dsb sy
|
dsb sy
|
||||||
isb
|
isb
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
static inline void __dsb_sy(void)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__ ("dsb sy" ::: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void __isb(void)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__ ("isb" ::: "memory");
|
|
||||||
}
|
|
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sysreg_traps.h"
|
#include "sysreg_traps.h"
|
||||||
#include "synchronization.h"
|
|
||||||
#include "sysreg.h"
|
#include "sysreg.h"
|
||||||
#include "arm.h"
|
#include "arm.h"
|
||||||
#include "debug_log.h"
|
#include "debug_log.h"
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
#include "traps.h"
|
#include "traps.h"
|
||||||
#include "sysreg.h"
|
#include "sysreg.h"
|
||||||
#include "synchronization.h"
|
|
||||||
|
|
||||||
static void enableDebugTraps(void)
|
static void enableDebugTraps(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,7 +33,17 @@
|
||||||
|
|
||||||
#define ALINLINE __attribute__((always_inline))
|
#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);
|
bool overlaps(u64 as, u64 ae, u64 bs, u64 be);
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ void initWatchpoints(void)
|
||||||
recursiveSpinlockLock(&g_watchpointManager.lock);
|
recursiveSpinlockLock(&g_watchpointManager.lock);
|
||||||
|
|
||||||
if (currentCoreCtx->isBootCore && !currentCoreCtx->warmboot) {
|
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.maxWatchpoints = (u32)num;
|
||||||
g_watchpointManager.allocationBitmap = 0xFFFF;
|
g_watchpointManager.allocationBitmap = 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue