From af9bee6e7f777db53aa3528b02541d8539307204 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 1 Jun 2018 00:46:05 -0600 Subject: [PATCH] Exosphere: Fix SE definition bug, misc other bugs. Now boots on 1.0.0 --- exosphere/linker.ld | 140 ++++++++++++++++------------------ exosphere/src/package2.c | 2 +- exosphere/src/se.h | 4 +- exosphere/src/smc_api.c | 18 +++-- exosphere/src/utils.c | 21 ++++- exosphere/src/warmboot_main.c | 1 + 6 files changed, 100 insertions(+), 86 deletions(-) diff --git a/exosphere/linker.ld b/exosphere/linker.ld index 43dac083a..e1a694ea5 100644 --- a/exosphere/linker.ld +++ b/exosphere/linker.ld @@ -1,21 +1,9 @@ OUTPUT_ARCH(aarch64) 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 { + NULL : ORIGIN = 0, LENGTH = 4K ccrt0 : ORIGIN = 0x040006000, LENGTH = 4K glob : ORIGIN = 0x040020000, LENGTH = 128K tzram : ORIGIN = 0x07C010000, LENGTH = 64K @@ -24,19 +12,19 @@ MEMORY 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. */ - 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 */ - main : ORIGIN = 0x1F01E0000 + LENGTH(wcrt0), LENGTH = LENGTH(tzram) - LENGTH(pk2ldr) - LENGTH(evt) - LENGTH(wcrt0) - 10K - pk2ldr : ORIGIN = ORIGIN(main) - LENGTH(wcrt0) + LENGTH(tzram), LENGTH = 8K + main : ORIGIN = 0x1F01E0000 + LENGTH(warmboot_crt0), LENGTH = LENGTH(tzram) - LENGTH(pk2ldr) - LENGTH(evt) - LENGTH(warmboot_crt0) - 10K + 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 */ - evt : ORIGIN = ORIGIN(pk2ldr) + 40K + 2K, LENGTH = 2K + evt : ORIGIN = ORIGIN(pk2ldr) + 40K + 2K, LENGTH = 2K } SECTIONS { PROVIDE(__start__ = 0x040006000); - . = ABSOLUTE(__start__); + . = __start__; .cold_crt0 : { @@ -55,7 +43,7 @@ SECTIONS coldboot_init.o(.bss* COMMON) . = ALIGN(64); __cold_crt0_end__ = ABSOLUTE(.); - } >ccrt0 AT>glob :ccrt0 + } >ccrt0 AT>glob .pk2ldr : { @@ -65,17 +53,17 @@ SECTIONS KEEP (package2.o(.text*)) package2.o(.rodata*) package2.o(.data*) - . = ALIGN(32); - } >pk2ldr AT>glob :pk2ldr + . = ALIGN(8); + } >pk2ldr AT>glob - .pk2ldr.bss (NOLOAD) : + .pk2ldr.bss : { - . = ALIGN(32); + . = ALIGN(8); __pk2ldr_bss_start__ = ABSOLUTE(.); package2.o(.bss* COMMON) - . = ALIGN(32); + . = ALIGN(8); __pk2ldr_end__ = ABSOLUTE(.); - } >pk2ldr :NONE + } >pk2ldr AT>glob .vectors : { @@ -85,7 +73,7 @@ SECTIONS KEEP (*(.vectors*)) . = ALIGN(8); __vectors_end__ = ABSOLUTE(.); - } >evt AT>glob :evt + } >evt AT>glob .warm_crt0 : { @@ -104,9 +92,7 @@ SECTIONS warmboot_init.o(.bss*) . = ALIGN(64); __warmboot_crt0_end__ = ABSOLUTE(.); - } >wcrt0 AT>glob :wcrt0 - - /* =========== CODE section =========== */ + } >warmboot_crt0 AT>glob .text : { @@ -118,64 +104,47 @@ SECTIONS *(.text.startup .text.startup.*) *(.text.hot .text.hot.*) *(.text .stub .text.* .gnu.linkonce.t.*) - . = ALIGN(32); - } >main AT>glob :code + . = ALIGN(8); + } >main AT>glob .init : { KEEP( *(.init) ) . = ALIGN(8); - } >main AT>glob :code + } >main AT>glob .plt : { *(.plt) *(.iplt) . = ALIGN(8); - } >main AT>glob :code + } >main AT>glob + .fini : { KEEP( *(.fini) ) . = ALIGN(8); - } >main AT>glob :code - - /* =========== RODATA section =========== */ + } >main AT>glob .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) + SORT(CONSTRUCTORS) . = 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 - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } >main AT>glob :rodata - .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 + .got : { __got_start__ = ABSOLUTE(.); *(.got) *(.igot) } >main AT>glob + .got.plt : { *(.got.plt) *(.igot.plt) __got_end__ = ABSOLUTE(.);} >main AT>glob - .note.gnu.build-id : { *(.note.gnu.build-id) } >main AT>glob :rodata - .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) : + .preinit_array : { + . = ALIGN(8); PROVIDE (__preinit_array_start = .); KEEP (*(.preinit_array)) PROVIDE (__preinit_array_end = .); . = ALIGN(8); - } >main AT>glob :data + } >main AT>glob .init_array : { @@ -183,56 +152,75 @@ SECTIONS KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) PROVIDE (__init_array_end = .); - } >main AT>glob :data + } >main AT>glob .fini_array : { + . = ALIGN(8); PROVIDE (__fini_array_start = .); KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) PROVIDE (__fini_array_end = .); . = ALIGN(8); - } >main AT>glob :data + } >main AT>glob .ctors : { + . = ALIGN(8); KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) . = ALIGN(8); - } >main AT>glob :data + } >main AT>glob - .dtors : + .dtors ALIGN(8) : { + . = ALIGN(8); KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) . = ALIGN(8); - } >main AT>glob :data + } >main AT>glob - .got : { __got_start__ = ABSOLUTE(.); *(.got) *(.igot) } >main AT>glob :data - .got.plt : { *(.got.plt) *(.igot.plt) __got_end__ = ABSOLUTE(.);} >main AT>glob :data - - .data : + .data ALIGN(8) : { *(.data .data.* .gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - . = ALIGN(32); - } >main AT>glob :data + CONSTRUCTORS + . = ALIGN(8); + } >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(.); __loaded_end_lma__ = LOADADDR(.bss); *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) - . = ALIGN(32); + . = ALIGN(8); __main_end__ = ABSOLUTE(.); - } >main :NONE + } >main AT>glob __end__ = ABSOLUTE(.) ; @@ -278,4 +266,4 @@ SECTIONS .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } -} +} \ No newline at end of file diff --git a/exosphere/src/package2.c b/exosphere/src/package2.c index bc569be91..2d131822b 100644 --- a/exosphere/src/package2.c +++ b/exosphere/src/package2.c @@ -425,7 +425,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) { 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(1000000); + /* wait(1000000); */ /* Synchronize with NX BOOTLOADER. */ sync_with_nx_bootloader(NX_BOOTLOADER_STATE_MOVED_BOOTCONFIG); diff --git a/exosphere/src/se.h b/exosphere/src/se.h index 7164de2e8..5fd606a2b 100644 --- a/exosphere/src/se.h +++ b/exosphere/src/se.h @@ -108,10 +108,10 @@ typedef struct security_engine { uint32_t _0x21C; uint32_t _0x220; uint32_t _0x224; - uint8_t _0x228[0x5C]; + uint8_t _0x228[0x58]; uint32_t AES_KEY_READ_DISABLE_REG; uint32_t AES_KEYSLOT_FLAGS[0x10]; - uint8_t _0x2C8[0x38]; + uint8_t _0x2C4[0x3C]; uint32_t _0x300; uint32_t CRYPTO_REG; uint32_t CRYPTO_CTR_REG[4]; diff --git a/exosphere/src/smc_api.c b/exosphere/src/smc_api.c index bbedf6ede..6e07b4e91 100644 --- a/exosphere/src/smc_api.c +++ b/exosphere/src/smc_api.c @@ -24,6 +24,8 @@ #define SMC_USER_HANDLERS 0x13 #define SMC_PRIV_HANDLERS 0x9 +#define DEBUG_LOG_SMCS 0 + /* User SMC prototypes */ uint32_t smc_set_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; break; 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) { unsigned char smc_id; unsigned int result; @@ -229,10 +233,14 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) { if ((smc_handler = g_smc_tables[handler_id].handlers[smc_id].handler) == NULL) { generic_panic(); } - - MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM)) = 0xD0D0D0D0; - MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10; - + +#if DEBUG_LOG_SMCS + 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. */ args->X[0] = smc_handler(args); if (args->X[0]) diff --git a/exosphere/src/utils.c b/exosphere/src/utils.c index 766e43f37..5a8697c14 100644 --- a/exosphere/src/utils.c +++ b/exosphere/src/utils.c @@ -6,6 +6,7 @@ #include "pmc.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) { /* Set Panic Code for NX_BOOTLOADER. */ @@ -13,8 +14,15 @@ __attribute__ ((noreturn)) void panic(uint32_t code) { APBDEV_PMC_SCRATCH200_0 = code; } - strcpy((void *)MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM), (void *)"PANIC"); - MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10; + /* Uncomment for Debugging. + 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. */ /* For now, just use NX BOOTLOADER's panic. */ fuse_disable_programming(); @@ -24,6 +32,15 @@ __attribute__ ((noreturn)) void panic(uint32_t code) { } __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); } diff --git a/exosphere/src/warmboot_main.c b/exosphere/src/warmboot_main.c index c8db6a488..01e127df6 100644 --- a/exosphere/src/warmboot_main.c +++ b/exosphere/src/warmboot_main.c @@ -22,6 +22,7 @@ void __attribute__((noreturn)) warmboot_main(void) { - warmboot (core 3) - cpu_on */ + if (is_core_active(get_core_id())) { panic(0xF7F00009); /* invalid CPU context */ }