From e0339049b32a574ca70a8e36a1e83b3a6607a56d Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Fri, 2 Aug 2019 00:47:48 +0200 Subject: [PATCH] thermosphere: rework linkscrips, use discardable sections, better sp pivot on crash --- thermosphere/Makefile | 9 +++- thermosphere/linker.ld | 80 ++++++++++++++++------------ thermosphere/qemu.mem | 5 +- thermosphere/src/core_ctx.c | 6 ++- thermosphere/src/core_ctx.h | 10 ++-- thermosphere/src/exception_vectors.s | 17 +++--- thermosphere/tegra-t210-arm-tf.mem | 8 +++ thermosphere/tegra-t210-nintendo.mem | 8 +++ thermosphere/tegra.mem | 5 -- 9 files changed, 92 insertions(+), 56 deletions(-) create mode 100644 thermosphere/tegra-t210-arm-tf.mem create mode 100644 thermosphere/tegra-t210-nintendo.mem delete mode 100644 thermosphere/tegra.mem diff --git a/thermosphere/Makefile b/thermosphere/Makefile index 36898b260..1da06deec 100644 --- a/thermosphere/Makefile +++ b/thermosphere/Makefile @@ -24,12 +24,19 @@ export PLATFORM := qemu PLATFORM_SOURCES := src/platform/qemu PLATFORM_DEFINES := -DPLATFORM_QEMU +else ifeq ($(PLATFORM), tegra-t210-arm-tf) + +export PLATFORM := tegra-t210-arm-tf + +PLATFORM_SOURCES := src/platform/tegra +PLATFORM_DEFINES := -DPLATFORM_TEGRA -DPLATFORM_TEGRA_T210_ARM_TF + else export PLATFORM := tegra PLATFORM_SOURCES := src/platform/tegra -PLATFORM_DEFINES := -DPLATFORM_TEGRA +PLATFORM_DEFINES := -DPLATFORM_TEGRA -D DPLATFORM_TEGRA_T210_NINTENDO endif diff --git a/thermosphere/linker.ld b/thermosphere/linker.ld index cb13132ca..df8f18178 100644 --- a/thermosphere/linker.ld +++ b/thermosphere/linker.ld @@ -1,6 +1,11 @@ OUTPUT_ARCH(aarch64) ENTRY(_start) +PHDRS +{ + main PT_LOAD; +} + SECTIONS { PROVIDE(__start__ = ORIGIN(main)); @@ -19,37 +24,37 @@ SECTIONS __vectors_start__ = ABSOLUTE(.); KEEP(*(.vectors*)); . = ALIGN(8); - } >main + } >main :main .init : { KEEP( *(.init) ) . = ALIGN(8); - } >main + } >main :main .plt : { *(.plt) *(.iplt) . = ALIGN(8); - } >main + } >main :main .fini : { KEEP( *(.fini) ) . = ALIGN(8); - } >main + } >main :main .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) SORT(CONSTRUCTORS) . = ALIGN(8); - } >main + } >main :main - .got : { __got_start__ = ABSOLUTE(.); *(.got) *(.igot) } >main - .got.plt : { *(.got.plt) *(.igot.plt) __got_end__ = ABSOLUTE(.);} >main + .got : { __got_start__ = ABSOLUTE(.); *(.got) *(.igot) } >main :main + .got.plt : { *(.got.plt) *(.igot.plt) __got_end__ = ABSOLUTE(.);} >main :main .preinit_array : { @@ -58,7 +63,7 @@ SECTIONS KEEP (*(.preinit_array)) PROVIDE (__preinit_array_end = ABSOLUTE(.)); . = ALIGN(8); - } >main + } >main :main .init_array : { @@ -66,7 +71,7 @@ SECTIONS KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) PROVIDE (__init_array_end = ABSOLUTE(.)); - } >main + } >main :main .fini_array : { @@ -76,7 +81,7 @@ SECTIONS KEEP (*(SORT(.fini_array.*))) PROVIDE (__fini_array_end = ABSOLUTE(.)); . = ALIGN(8); - } >main + } >main :main .ctors : { @@ -86,7 +91,7 @@ SECTIONS KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) . = ALIGN(8); - } >main + } >main :main .dtors ALIGN(8) : { @@ -96,35 +101,35 @@ SECTIONS KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) . = ALIGN(8); - } >main + } >main :main .data ALIGN(8) : { *(.data .data.* .gnu.linkonce.d.*) CONSTRUCTORS . = ALIGN(8); - } >main + } >main :main - .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } >main - .eh_frame : { KEEP (*(.eh_frame)) *(.eh_frame.*) } >main - .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } >main - .gnu_extab : { *(.gnu_extab*) } >main - .exception_ranges : { *(.exception_ranges .exception_ranges*) } >main + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } >main :main + .eh_frame : { KEEP (*(.eh_frame)) *(.eh_frame.*) } >main :main + .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } >main :main + .gnu_extab : { *(.gnu_extab*) } >main :main + .exception_ranges : { *(.exception_ranges .exception_ranges*) } >main :main - .dynamic : { *(.dynamic) } >main - .interp : { *(.interp) } >main - .note.gnu.build-id : { *(.note.gnu.build-id) } >main - .hash : { *(.hash) } >main - .gnu.hash : { *(.gnu.hash) } >main - .gnu.version : { *(.gnu.version) } >main - .gnu.version_d : { *(.gnu.version_d) } >main - .gnu.version_r : { *(.gnu.version_r) } >main - .dynsym : { *(.dynsym) } >main - .dynstr : { *(.dynstr) } >main - .rela.dyn : { *(.rela.*); __main_end__ = ABSOLUTE(.);} >main + .dynamic : { *(.dynamic) } >main :main + .interp : { *(.interp) } >main :main + .note.gnu.build-id : { *(.note.gnu.build-id) } >main :main + .hash : { *(.hash) } >main :main + .gnu.hash : { *(.gnu.hash) } >main :main + .gnu.version : { *(.gnu.version) } >main :main + .gnu.version_d : { *(.gnu.version_d) } >main :main + .gnu.version_r : { *(.gnu.version_r) } >main :main + .dynsym : { *(.dynsym) } >main :main + .dynstr : { *(.dynstr) } >main :main + .rela.dyn : { *(.rela.*); __main_end__ = ABSOLUTE(.);} >main :main - .bss : + .bss (NOLOAD) : { . = ALIGN(8); __bss_start__ = ABSOLUTE(.); @@ -133,13 +138,22 @@ SECTIONS *(COMMON) . = ALIGN(8); __end__ = ABSOLUTE(.); - } >main + } >main :NONE . = ALIGN(0x1000); __end__ = ABSOLUTE(.) ; - __stacks_top__ = ABSOLUTE(. + 0x1000); - __excep_stacks_top__ = ABSOLUTE(. + 0x2000); /* Note: potentially overwrites warmboot firmware. */ + .temp (NOLOAD) : + { + . = ALIGN(0x1000); + __stacks_top__ = ABSOLUTE(. + 0x2000); + __crash_stacks_top__ = ABSOLUTE(. + 0x3000); + . += 0x3000; + *(.temp.*) + . = ALIGN(0x1000); + } >temp :NONE + + . = ALIGN(8); diff --git a/thermosphere/qemu.mem b/thermosphere/qemu.mem index 4c88484c0..d7cad4483 100644 --- a/thermosphere/qemu.mem +++ b/thermosphere/qemu.mem @@ -1,5 +1,6 @@ MEMORY { NULL : ORIGIN = 0, LENGTH = 0x1000 - main : ORIGIN = 0x60000000, LENGTH = 128M /* QEMU's memory map changes dynamically? */ -} \ No newline at end of file + main : ORIGIN = 0x60000000, LENGTH = 64M /* QEMU's memory map changes dynamically? */ + temp : ORIGIN = 0x64000000, LENGTH = 64M +} diff --git a/thermosphere/src/core_ctx.c b/thermosphere/src/core_ctx.c index bef3e2506..e19af510a 100644 --- a/thermosphere/src/core_ctx.c +++ b/thermosphere/src/core_ctx.c @@ -19,6 +19,8 @@ // start.s extern uintptr_t g_initialKernelEntrypoint; +extern u8 __stacks_top__[], __crash_stacks_top__[]; + // Prevents it from being put in BSS CoreCtx g_coreCtxs[4] = { { .coreId = 0 }, @@ -29,10 +31,12 @@ CoreCtx g_coreCtxs[4] = { void coreCtxInit(u32 coreId, bool isColdbootCore, u64 argument) { + size_t crashStackSize = (__crash_stacks_top__ - __stacks_top__) / 4; currentCoreCtx = &g_coreCtxs[coreId]; currentCoreCtx->isColdbootCore = isColdbootCore; currentCoreCtx->kernelArgument = argument; - if (isColdbootCore) { + currentCoreCtx->crashStack = __crash_stacks_top__ - crashStackSize * coreId; + if (isColdbootCore && currentCoreCtx->kernelEntrypoint == 0) { currentCoreCtx->kernelEntrypoint = g_initialKernelEntrypoint; } } diff --git a/thermosphere/src/core_ctx.h b/thermosphere/src/core_ctx.h index c705b0f10..a65263f5d 100644 --- a/thermosphere/src/core_ctx.h +++ b/thermosphere/src/core_ctx.h @@ -18,10 +18,12 @@ #include "utils.h" typedef struct CoreCtx { - u64 kernelArgument; - uintptr_t kernelEntrypoint; - u32 coreId; // @0x10 - bool isColdbootCore; // @0x14 + u64 kernelArgument; // @0x00 + uintptr_t kernelEntrypoint; // @0x08 + u8 *crashStack; // @0x10 + u64 scratch; // @0x18 + u32 coreId; // @0x20 + bool isColdbootCore; // @0x24 } CoreCtx; extern CoreCtx g_coreCtxs[4]; diff --git a/thermosphere/src/exception_vectors.s b/thermosphere/src/exception_vectors.s index f51f1cdba..6d9059d55 100644 --- a/thermosphere/src/exception_vectors.s +++ b/thermosphere/src/exception_vectors.s @@ -63,17 +63,14 @@ .endm .macro pivot_stack_for_crash - // Note: reset x18 assumed uncorrupted + // Note: x18 assumed uncorrupted // Note: replace sp_el0 with crashing sp - mrs x18, esr_el2 - mov x18, sp - msr sp_el0, x18 - bic x18, x18, #0xFF - bic x18, x18, #0x300 - add x18, x18, #0x400 - mov sp, x18 - ldp x18, xzr, [sp, #-0x10] - add sp, sp, #0x1000 + str x16, [x18, #0x18] // currentCoreCtx->scratch = x16 + mov x16, sp + msr sp_el0, x16 + ldr x16, [x18, #0x10] // currentCoreCtx->crashStack + mov sp, x16 + ldr x16, [x18, #0x18] .endm /* Actual Vectors for Thermosphere. */ diff --git a/thermosphere/tegra-t210-arm-tf.mem b/thermosphere/tegra-t210-arm-tf.mem new file mode 100644 index 000000000..ff6b66243 --- /dev/null +++ b/thermosphere/tegra-t210-arm-tf.mem @@ -0,0 +1,8 @@ +MEMORY +{ + NULL : ORIGIN = 0, LENGTH = 0x1000 + main : ORIGIN = 0x80000000, LENGTH = 0xD000 + + /* This area is overwritten by the secure monitor when preparing for deep sleep. */ + temp : ORIGIN = 0xFF800000, LENGTH = 0x400000 +} diff --git a/thermosphere/tegra-t210-nintendo.mem b/thermosphere/tegra-t210-nintendo.mem new file mode 100644 index 000000000..55a3a57a7 --- /dev/null +++ b/thermosphere/tegra-t210-nintendo.mem @@ -0,0 +1,8 @@ +MEMORY +{ + NULL : ORIGIN = 0, LENGTH = 0x1000 + main : ORIGIN = 0x80000000, LENGTH = 0xD000 + + /* This area is overwritten by the secure monitor when preparing for deep sleep. */ + temp : ORIGIN = 0x8000F000, LENGTH = 0x11000 +} diff --git a/thermosphere/tegra.mem b/thermosphere/tegra.mem deleted file mode 100644 index 6f3ce7c75..000000000 --- a/thermosphere/tegra.mem +++ /dev/null @@ -1,5 +0,0 @@ -MEMORY -{ - NULL : ORIGIN = 0, LENGTH = 0x1000 - main : ORIGIN = 0x80000000, LENGTH = 0xD000 - 0x2000 /* 0x2000 for stacks. */ -} \ No newline at end of file