thermosphere: refactor crt0 + watchpoint init

This commit is contained in:
TuxSH 2019-08-06 22:26:28 +02:00
parent bd93b01e57
commit 0435b73f63
13 changed files with 89 additions and 85 deletions

View file

@ -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

View file

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

58
thermosphere/src/init.c Normal file
View 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();
}

View file

@ -27,3 +27,4 @@
#endif
void configureMemoryMapEnableMmu(void);
void configureMemoryMapEnableStage2(void);

View file

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

View file

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

View file

@ -1,6 +1,5 @@
#include <string.h>
#include "smc.h"
#include "synchronization.h"
#include "core_ctx.h"
#include "arm.h"

View file

@ -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

View file

@ -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");
}

View file

@ -15,7 +15,6 @@
*/
#include "sysreg_traps.h"
#include "synchronization.h"
#include "sysreg.h"
#include "arm.h"
#include "debug_log.h"

View file

@ -16,7 +16,6 @@
#include "traps.h"
#include "sysreg.h"
#include "synchronization.h"
static void enableDebugTraps(void)
{

View file

@ -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);

View file

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