Exosphere: Fix SE definition bug, misc other bugs. Now boots on 1.0.0

This commit is contained in:
Michael Scire 2018-06-01 00:46:05 -06:00
parent 1058ac7b2d
commit af9bee6e7f
6 changed files with 100 additions and 86 deletions

View file

@ -1,21 +1,9 @@
OUTPUT_ARCH(aarch64) OUTPUT_ARCH(aarch64)
ENTRY(__start_cold) ENTRY(__start_cold)
PHDRS
{
ccrt0 PT_LOAD FLAGS(7) /* Read | Write | Execute */;
pk2ldr PT_LOAD FLAGS(7) /* Read | Write | Execute */;
wcrt0 PT_LOAD FLAGS(7) /* Read | Write | Execute */;
code PT_LOAD FLAGS(5) /* Read | Execute */;
rodata PT_LOAD FLAGS(4) /* Read */;
data PT_LOAD FLAGS(6) /* Read | Write */;
evt PT_LOAD FLAGS(5) /* Read | Execute */;
}
MEMORY MEMORY
{ {
NULL : ORIGIN = 0, LENGTH = 4K
ccrt0 : ORIGIN = 0x040006000, LENGTH = 4K ccrt0 : ORIGIN = 0x040006000, LENGTH = 4K
glob : ORIGIN = 0x040020000, LENGTH = 128K glob : ORIGIN = 0x040020000, LENGTH = 128K
tzram : ORIGIN = 0x07C010000, LENGTH = 64K tzram : ORIGIN = 0x07C010000, LENGTH = 64K
@ -24,19 +12,19 @@ MEMORY
Normally the main code immediately follows the warmboot crt0, aligned to 256 bytes. Normally the main code immediately follows the warmboot crt0, aligned to 256 bytes.
We can't ensure or replicate that behavior properly so we'll just give 2K to the warmboot crt0. We can't ensure or replicate that behavior properly so we'll just give 2K to the warmboot crt0.
*/ */
wcrt0 : ORIGIN = ORIGIN(tzram) + 12K, LENGTH = 2K warmboot_crt0 : ORIGIN = ORIGIN(tzram) + 12K, LENGTH = 2K
/* 8K are the MMU L2 and L3 tables & 2K from the evt page */ /* 8K are the MMU L2 and L3 tables & 2K from the evt page */
main : ORIGIN = 0x1F01E0000 + LENGTH(wcrt0), LENGTH = LENGTH(tzram) - LENGTH(pk2ldr) - LENGTH(evt) - LENGTH(wcrt0) - 10K main : ORIGIN = 0x1F01E0000 + LENGTH(warmboot_crt0), LENGTH = LENGTH(tzram) - LENGTH(pk2ldr) - LENGTH(evt) - LENGTH(warmboot_crt0) - 10K
pk2ldr : ORIGIN = ORIGIN(main) - LENGTH(wcrt0) + LENGTH(tzram), LENGTH = 8K pk2ldr : ORIGIN = ORIGIN(main) - LENGTH(warmboot_crt0) + LENGTH(tzram), LENGTH = 8K
/* The first half of the page are exception entry stacks, the other half are the vectors themselves */ /* The first half of the page are exception entry stacks, the other half are the vectors themselves */
evt : ORIGIN = ORIGIN(pk2ldr) + 40K + 2K, LENGTH = 2K evt : ORIGIN = ORIGIN(pk2ldr) + 40K + 2K, LENGTH = 2K
} }
SECTIONS SECTIONS
{ {
PROVIDE(__start__ = 0x040006000); PROVIDE(__start__ = 0x040006000);
. = ABSOLUTE(__start__); . = __start__;
.cold_crt0 : .cold_crt0 :
{ {
@ -55,7 +43,7 @@ SECTIONS
coldboot_init.o(.bss* COMMON) coldboot_init.o(.bss* COMMON)
. = ALIGN(64); . = ALIGN(64);
__cold_crt0_end__ = ABSOLUTE(.); __cold_crt0_end__ = ABSOLUTE(.);
} >ccrt0 AT>glob :ccrt0 } >ccrt0 AT>glob
.pk2ldr : .pk2ldr :
{ {
@ -65,17 +53,17 @@ SECTIONS
KEEP (package2.o(.text*)) KEEP (package2.o(.text*))
package2.o(.rodata*) package2.o(.rodata*)
package2.o(.data*) package2.o(.data*)
. = ALIGN(32); . = ALIGN(8);
} >pk2ldr AT>glob :pk2ldr } >pk2ldr AT>glob
.pk2ldr.bss (NOLOAD) : .pk2ldr.bss :
{ {
. = ALIGN(32); . = ALIGN(8);
__pk2ldr_bss_start__ = ABSOLUTE(.); __pk2ldr_bss_start__ = ABSOLUTE(.);
package2.o(.bss* COMMON) package2.o(.bss* COMMON)
. = ALIGN(32); . = ALIGN(8);
__pk2ldr_end__ = ABSOLUTE(.); __pk2ldr_end__ = ABSOLUTE(.);
} >pk2ldr :NONE } >pk2ldr AT>glob
.vectors : .vectors :
{ {
@ -85,7 +73,7 @@ SECTIONS
KEEP (*(.vectors*)) KEEP (*(.vectors*))
. = ALIGN(8); . = ALIGN(8);
__vectors_end__ = ABSOLUTE(.); __vectors_end__ = ABSOLUTE(.);
} >evt AT>glob :evt } >evt AT>glob
.warm_crt0 : .warm_crt0 :
{ {
@ -104,9 +92,7 @@ SECTIONS
warmboot_init.o(.bss*) warmboot_init.o(.bss*)
. = ALIGN(64); . = ALIGN(64);
__warmboot_crt0_end__ = ABSOLUTE(.); __warmboot_crt0_end__ = ABSOLUTE(.);
} >wcrt0 AT>glob :wcrt0 } >warmboot_crt0 AT>glob
/* =========== CODE section =========== */
.text : .text :
{ {
@ -118,64 +104,47 @@ SECTIONS
*(.text.startup .text.startup.*) *(.text.startup .text.startup.*)
*(.text.hot .text.hot.*) *(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*) *(.text .stub .text.* .gnu.linkonce.t.*)
. = ALIGN(32); . = ALIGN(8);
} >main AT>glob :code } >main AT>glob
.init : .init :
{ {
KEEP( *(.init) ) KEEP( *(.init) )
. = ALIGN(8); . = ALIGN(8);
} >main AT>glob :code } >main AT>glob
.plt : .plt :
{ {
*(.plt) *(.plt)
*(.iplt) *(.iplt)
. = ALIGN(8); . = ALIGN(8);
} >main AT>glob :code } >main AT>glob
.fini : .fini :
{ {
KEEP( *(.fini) ) KEEP( *(.fini) )
. = ALIGN(8); . = ALIGN(8);
} >main AT>glob :code } >main AT>glob
/* =========== RODATA section =========== */
.rodata : .rodata :
{ {
*(.rodata .rodata.* .gnu.linkonce.r.*) *(.rodata .rodata.* .gnu.linkonce.r.*)
SORT(CONSTRUCTORS)
. = ALIGN(8); . = ALIGN(8);
} >main AT>glob :rodata } >main AT>glob
.eh_frame_hdr : ONLY_IF_RO { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } >main AT>glob :rodata .got : { __got_start__ = ABSOLUTE(.); *(.got) *(.igot) } >main AT>glob
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } >main AT>glob :rodata .got.plt : { *(.got.plt) *(.igot.plt) __got_end__ = ABSOLUTE(.);} >main AT>glob
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } >main AT>glob :rodata
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } >main AT>glob :rodata
.exception_ranges : ONLY_IF_RO { *(.exception_ranges .exception_ranges*) } >main AT>glob :rodata
.note.gnu.build-id : { *(.note.gnu.build-id) } >main AT>glob :rodata .preinit_array :
.hash : { *(.hash) } >main AT>glob :rodata
.gnu.hash : { *(.gnu.hash) } >main AT>glob :rodata
.gnu.version : { *(.gnu.version) } >main AT>glob :rodata
.gnu.version_d : { *(.gnu.version_d) } >main AT>glob :rodata
.gnu.version_r : { *(.gnu.version_r) } >main AT>glob :rodata
/* =========== DATA section =========== */
.eh_frame_hdr : ONLY_IF_RW { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } >main AT>glob :data
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } >main AT>glob :data
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } >main AT>glob :data
.gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } >main AT>glob :data
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } >main AT>glob :data
.preinit_array ALIGN(8) :
{ {
. = ALIGN(8);
PROVIDE (__preinit_array_start = .); PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array)) KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .); PROVIDE (__preinit_array_end = .);
. = ALIGN(8); . = ALIGN(8);
} >main AT>glob :data } >main AT>glob
.init_array : .init_array :
{ {
@ -183,56 +152,75 @@ SECTIONS
KEEP (*(SORT(.init_array.*))) KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array)) KEEP (*(.init_array))
PROVIDE (__init_array_end = .); PROVIDE (__init_array_end = .);
} >main AT>glob :data } >main AT>glob
.fini_array : .fini_array :
{ {
. = ALIGN(8);
PROVIDE (__fini_array_start = .); PROVIDE (__fini_array_start = .);
KEEP (*(.fini_array)) KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*))) KEEP (*(SORT(.fini_array.*)))
PROVIDE (__fini_array_end = .); PROVIDE (__fini_array_end = .);
. = ALIGN(8); . = ALIGN(8);
} >main AT>glob :data } >main AT>glob
.ctors : .ctors :
{ {
. = ALIGN(8);
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */ KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*))) KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors)) KEEP (*(.ctors))
. = ALIGN(8); . = ALIGN(8);
} >main AT>glob :data } >main AT>glob
.dtors : .dtors ALIGN(8) :
{ {
. = ALIGN(8);
KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*))) KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors)) KEEP (*(.dtors))
. = ALIGN(8); . = ALIGN(8);
} >main AT>glob :data } >main AT>glob
.got : { __got_start__ = ABSOLUTE(.); *(.got) *(.igot) } >main AT>glob :data .data ALIGN(8) :
.got.plt : { *(.got.plt) *(.igot.plt) __got_end__ = ABSOLUTE(.);} >main AT>glob :data
.data :
{ {
*(.data .data.* .gnu.linkonce.d.*) *(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS) CONSTRUCTORS
. = ALIGN(32); . = ALIGN(8);
} >main AT>glob :data } >main AT>glob
.bss (NOLOAD) :
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } >main AT>glob
.eh_frame : { KEEP (*(.eh_frame)) *(.eh_frame.*) } >main AT>glob
.gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } >main AT>glob
.gnu_extab : { *(.gnu_extab*) } >main AT>glob
.exception_ranges : { *(.exception_ranges .exception_ranges*) } >main AT>glob
.dynamic : { *(.dynamic) } >main AT>glob
.interp : { *(.interp) } >main AT>glob
.note.gnu.build-id : { *(.note.gnu.build-id) } >main AT>glob
.hash : { *(.hash) } >main AT>glob
.gnu.hash : { *(.gnu.hash) } >main AT>glob
.gnu.version : { *(.gnu.version) } >main AT>glob
.gnu.version_d : { *(.gnu.version_d) } >main AT>glob
.gnu.version_r : { *(.gnu.version_r) } >main AT>glob
.dynsym : { *(.dynsym) } >main AT>glob
.dynstr : { *(.dynstr) } >main AT>glob
.rela.dyn : { *(.rela.*); __main_end__ = ABSOLUTE(.);} >main AT>glob
.bss :
{ {
. = ALIGN(32); . = ALIGN(8);
__main_bss_start__ = ABSOLUTE(.); __main_bss_start__ = ABSOLUTE(.);
__loaded_end_lma__ = LOADADDR(.bss); __loaded_end_lma__ = LOADADDR(.bss);
*(.dynbss) *(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*) *(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON) *(COMMON)
. = ALIGN(32); . = ALIGN(8);
__main_end__ = ABSOLUTE(.); __main_end__ = ABSOLUTE(.);
} >main :NONE } >main AT>glob
__end__ = ABSOLUTE(.) ; __end__ = ABSOLUTE(.) ;

View file

@ -425,7 +425,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE = 1; MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE = 1;
/* Wait for 1 second, to allow time for NX_BOOTLOADER to draw to the screen. This is useful for debugging. */ /* Wait for 1 second, to allow time for NX_BOOTLOADER to draw to the screen. This is useful for debugging. */
wait(1000000); /* wait(1000000); */
/* Synchronize with NX BOOTLOADER. */ /* Synchronize with NX BOOTLOADER. */
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_MOVED_BOOTCONFIG); sync_with_nx_bootloader(NX_BOOTLOADER_STATE_MOVED_BOOTCONFIG);

View file

@ -108,10 +108,10 @@ typedef struct security_engine {
uint32_t _0x21C; uint32_t _0x21C;
uint32_t _0x220; uint32_t _0x220;
uint32_t _0x224; uint32_t _0x224;
uint8_t _0x228[0x5C]; uint8_t _0x228[0x58];
uint32_t AES_KEY_READ_DISABLE_REG; uint32_t AES_KEY_READ_DISABLE_REG;
uint32_t AES_KEYSLOT_FLAGS[0x10]; uint32_t AES_KEYSLOT_FLAGS[0x10];
uint8_t _0x2C8[0x38]; uint8_t _0x2C4[0x3C];
uint32_t _0x300; uint32_t _0x300;
uint32_t CRYPTO_REG; uint32_t CRYPTO_REG;
uint32_t CRYPTO_CTR_REG[4]; uint32_t CRYPTO_CTR_REG[4];

View file

@ -24,6 +24,8 @@
#define SMC_USER_HANDLERS 0x13 #define SMC_USER_HANDLERS 0x13
#define SMC_PRIV_HANDLERS 0x9 #define SMC_PRIV_HANDLERS 0x9
#define DEBUG_LOG_SMCS 0
/* User SMC prototypes */ /* User SMC prototypes */
uint32_t smc_set_config(smc_args_t *args); uint32_t smc_set_config(smc_args_t *args);
uint32_t smc_get_config(smc_args_t *args); uint32_t smc_get_config(smc_args_t *args);
@ -141,7 +143,7 @@ void set_version_specific_smcs(void) {
g_smc_user_table[0xD].handler = smc_decrypt_or_import_rsa_key; g_smc_user_table[0xD].handler = smc_decrypt_or_import_rsa_key;
break; break;
default: default:
panic_predefined(0xF); panic_predefined(0xA);
} }
} }
@ -199,6 +201,8 @@ void clear_smc_callback(uint64_t key) {
} }
} }
_Atomic uint64_t num_smcs_called = 0;
void call_smc_handler(uint32_t handler_id, smc_args_t *args) { void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
unsigned char smc_id; unsigned char smc_id;
unsigned int result; unsigned int result;
@ -230,8 +234,12 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
generic_panic(); generic_panic();
} }
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM)) = 0xD0D0D0D0; #if DEBUG_LOG_SMCS
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10; if (handler_id == SMC_HANDLER_USER) {
uint64_t num = atomic_fetch_add(&num_smcs_called, 1);
*(volatile smc_args_t *)(get_iram_address_for_debug() + 0x100 + ((0x40 * num) & 0x3FFF)) = *args;
}
#endif
/* Call function. */ /* Call function. */
args->X[0] = smc_handler(args); args->X[0] = smc_handler(args);

View file

@ -6,6 +6,7 @@
#include "pmc.h" #include "pmc.h"
#include "timers.h" #include "timers.h"
#define SAVE_SYSREG64(reg, ofs) do { __asm__ __volatile__ ("mrs %0, " #reg : "=r"(temp_reg) :: "memory"); MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM) + ofs) = (uint32_t)((temp_reg >> 0) & 0xFFFFFFFFULL); MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM) + ofs + 4) = (uint32_t)((temp_reg >> 32) & 0xFFFFFFFFULL); } while(false)
__attribute__ ((noreturn)) void panic(uint32_t code) { __attribute__ ((noreturn)) void panic(uint32_t code) {
/* Set Panic Code for NX_BOOTLOADER. */ /* Set Panic Code for NX_BOOTLOADER. */
@ -13,8 +14,15 @@ __attribute__ ((noreturn)) void panic(uint32_t code) {
APBDEV_PMC_SCRATCH200_0 = code; APBDEV_PMC_SCRATCH200_0 = code;
} }
strcpy((void *)MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM), (void *)"PANIC"); /* Uncomment for Debugging.
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10; uint64_t temp_reg;
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM)) = APBDEV_PMC_SCRATCH200_0;
SAVE_SYSREG64(ESR_EL3, 0x10);
SAVE_SYSREG64(ELR_EL3, 0x18);
SAVE_SYSREG64(FAR_EL3, 0x20);
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x450ull) = 0x2;
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10; */
/* TODO: Custom Panic Driver, which displays to screen without rebooting. */ /* TODO: Custom Panic Driver, which displays to screen without rebooting. */
/* For now, just use NX BOOTLOADER's panic. */ /* For now, just use NX BOOTLOADER's panic. */
fuse_disable_programming(); fuse_disable_programming();
@ -24,6 +32,15 @@ __attribute__ ((noreturn)) void panic(uint32_t code) {
} }
__attribute__ ((noreturn)) void generic_panic(void) { __attribute__ ((noreturn)) void generic_panic(void) {
/* Uncomment for Debugging.
uint64_t temp_reg;
do { __asm__ __volatile__ ("mov %0, LR" : "=r"(temp_reg) :: "memory"); } while (false);
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM) + 0x28) = (uint32_t)((temp_reg >> 0) & 0xFFFFFFFFULL);
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM) + 0x28 + 4) = (uint32_t)((temp_reg >> 32) & 0xFFFFFFFFULL);
do { __asm__ __volatile__ ("mov %0, SP" : "=r"(temp_reg) :: "memory"); } while (false);
for (unsigned int i = 0; i < 0x80; i += 4) {
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM) + 0x40 + i) = *((volatile uint32_t *)(temp_reg + i));
} */
panic(0xFF000006); panic(0xFF000006);
} }

View file

@ -22,6 +22,7 @@ void __attribute__((noreturn)) warmboot_main(void) {
- warmboot (core 3) - warmboot (core 3)
- cpu_on - cpu_on
*/ */
if (is_core_active(get_core_id())) { if (is_core_active(get_core_id())) {
panic(0xF7F00009); /* invalid CPU context */ panic(0xF7F00009); /* invalid CPU context */
} }