From 94b10b57795d95535b108b05b2d297198f79a480 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 14 Apr 2020 10:07:24 -0700 Subject: [PATCH] ams: fix boot sysmodule/kernel for 10.0.0 --- Makefile | 2 + fusee/fusee-secondary/src/kernel_patches.c | 117 ++++++++++++++++-- .../arm64/init/kern_k_init_page_table.hpp | 9 ++ .../svc/svc_stratosphere_shims.hpp | 8 +- .../source/dd/dd_io_mappings.cpp | 17 ++- .../source/arch/arm64/init/kern_init_core.cpp | 6 +- .../kernel/source/arch/arm64/init/start.s | 11 +- .../kernel_ldr/source/arch/arm64/start.s | 4 +- stratosphere/Makefile | 2 +- 9 files changed, 153 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index dd03d7f95..92ac681bf 100644 --- a/Makefile +++ b/Makefile @@ -82,6 +82,7 @@ dist-no-debug: all cp -r config_templates/hbl_html atmosphere-$(AMSVER)/atmosphere/hbl_html cp stratosphere/boot2/boot2.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000008/exefs.nsp cp stratosphere/dmnt/dmnt.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000000D/exefs.nsp + cp stratosphere/erpt/erpt.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000002B/exefs.nsp cp stratosphere/eclct.stub/eclct.stub.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/exefs.nsp cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000034/exefs.nsp cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000036/exefs.nsp @@ -133,6 +134,7 @@ dist: dist-no-debug cp stratosphere/ro/ro.elf atmosphere-$(AMSVER)-debug/ro.elf cp stratosphere/sm/sm.elf atmosphere-$(AMSVER)-debug/sm.elf cp stratosphere/spl/spl.elf atmosphere-$(AMSVER)-debug/spl.elf + cp stratosphere/erpt/erpt.elf atmosphere-$(AMSVER)-debug/erpt.elf cd atmosphere-$(AMSVER)-debug; zip -r ../atmosphere-$(AMSVER)-debug.zip ./*; cd ../; rm -r atmosphere-$(AMSVER)-debug mv atmosphere-$(AMSVER)-debug.zip out/atmosphere-$(AMSVER)-debug.zip diff --git a/fusee/fusee-secondary/src/kernel_patches.c b/fusee/fusee-secondary/src/kernel_patches.c index 67d40352d..6408c14c1 100644 --- a/fusee/fusee-secondary/src/kernel_patches.c +++ b/fusee/fusee-secondary/src/kernel_patches.c @@ -486,20 +486,77 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(900, proc_id_send)[] = {0xA9BF static const uint8_t MAKE_KERNEL_PATTERN_NAME(900, proc_id_recv)[] = {0x68, 0x03, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0xE0, 0x03, 0x1B, 0xAA, 0x00, 0x01, 0x3F, 0xD6, 0xE8, 0x03, 0x17, 0x2A, 0xF7, 0x0A, 0x00, 0x11, 0x08, 0xF5, 0x7E, 0xD3}; static const instruction_t MAKE_KERNEL_PATCH_NAME(900, proc_id_recv)[] = {0xA9BF2FEA, 0xF9404BEB, 0x2A1703EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400368, 0xF9401D08, 0xAA1B03E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0}; +/* + stp x10, x11, [sp, #-0x10]! + ldr x11, [sp, #0xC0] + mov w10, w22 + lsl x10, x10, #2 + ldr x10, [x11, x10] + mov x9, #0x0000ffffffffffff + and x8, x10, x9 + mov x9, #0xffff000000000000 + and x10, x10, x9 + mov x9, #0xfffe000000000000 + cmp x10, x9 + beq #0x20 + + stp x8, x9, [sp, #-0x10]! + ldr x8, [x23] + ldr x8, [x8, #0x38] + mov x0, x23 + blr x8 + ldp x8, x9, [sp],#0x10 + mov x8, x0 + + ldp x10, x11, [sp],#0x10 + mov x0, x8 +*/ +static const uint8_t MAKE_KERNEL_PATTERN_NAME(1000, proc_id_send)[] = {0xE8, 0x02, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0xE0, 0x03, 0x17, 0xAA, 0x00, 0x01, 0x3F, 0xD6, 0x08, 0x4B, 0x36, 0x8B, 0x09, 0xFC, 0x60, 0xD3, 0x00, 0x25, 0x00, 0x29}; +static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, proc_id_send)[] = {0xA9BF2FEA, 0xF94063EB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002E8, 0xF9401D08, 0xAA1703E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0}; +/* + stp x10, x11, [sp, #-0x10]! + ldr x11, [sp, #0xC8] + mov w10, w26 + lsl x10, x10, #2 + ldr x10, [x11, x10] + mov x9, #0x0000ffffffffffff + and x8, x10, x9 + mov x9, #0xffff000000000000 + and x10, x10, x9 + mov x9, #0xfffe000000000000 + cmp x10, x9 + beq #0x20 + + stp x8, x9, [sp, #-0x10]! + ldr x8, [x28] + ldr x8, [x8, #0x38] + mov x0, x28 + blr x8 + ldp x8, x9, [sp],#0x10 + mov x8, x0 + + ldp x10, x11, [sp],#0x10 + mov x0, x8 +*/ +static const uint8_t MAKE_KERNEL_PATTERN_NAME(1000, proc_id_recv)[] = {0x88, 0x03, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0xE0, 0x03, 0x1C, 0xAA, 0x00, 0x01, 0x3F, 0xD6, 0xE8, 0x87, 0x40, 0xF9, 0x08, 0x49, 0x3A, 0x8B, 0x09, 0xFC, 0x60, 0xD3}; +static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, proc_id_recv)[] = {0xA9BF2FEA, 0xF94067EB, 0x2A1A03EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400388, 0xF9401D08, 0xAA1C03E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0}; + + /* svcControlCodeMemory Patches */ /* b.eq -> nop */ -static const instruction_t MAKE_KERNEL_PATCH_NAME(500, svc_control_codememory)[] = {MAKE_NOP}; -static const instruction_t MAKE_KERNEL_PATCH_NAME(600, svc_control_codememory)[] = {MAKE_NOP}; -static const instruction_t MAKE_KERNEL_PATCH_NAME(700, svc_control_codememory)[] = {MAKE_NOP}; -static const instruction_t MAKE_KERNEL_PATCH_NAME(800, svc_control_codememory)[] = {MAKE_NOP}; -static const instruction_t MAKE_KERNEL_PATCH_NAME(900, svc_control_codememory)[] = {MAKE_NOP}; +static const instruction_t MAKE_KERNEL_PATCH_NAME(500, svc_control_codememory)[] = {MAKE_NOP}; +static const instruction_t MAKE_KERNEL_PATCH_NAME(600, svc_control_codememory)[] = {MAKE_NOP}; +static const instruction_t MAKE_KERNEL_PATCH_NAME(700, svc_control_codememory)[] = {MAKE_NOP}; +static const instruction_t MAKE_KERNEL_PATCH_NAME(800, svc_control_codememory)[] = {MAKE_NOP}; +static const instruction_t MAKE_KERNEL_PATCH_NAME(900, svc_control_codememory)[] = {MAKE_NOP}; +static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, svc_control_codememory)[] = {MAKE_NOP}; - -static const instruction_t MAKE_KERNEL_PATCH_NAME(500, system_memory_increase)[] = {0x52A3C008}; /* MOV W8, #0x1E000000 */ -static const instruction_t MAKE_KERNEL_PATCH_NAME(600, system_memory_increase)[] = {0x52A3B008}; /* MOV W8, #0x1D800000 */ -static const instruction_t MAKE_KERNEL_PATCH_NAME(700, system_memory_increase)[] = {0x52A3B008}; /* MOV W8, #0x1D800000 */ -static const instruction_t MAKE_KERNEL_PATCH_NAME(800, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */ -static const instruction_t MAKE_KERNEL_PATCH_NAME(900, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */ +static const instruction_t MAKE_KERNEL_PATCH_NAME(500, system_memory_increase)[] = {0x52A3C008}; /* MOV W8, #0x1E000000 */ +static const instruction_t MAKE_KERNEL_PATCH_NAME(600, system_memory_increase)[] = {0x52A3B008}; /* MOV W8, #0x1D800000 */ +static const instruction_t MAKE_KERNEL_PATCH_NAME(700, system_memory_increase)[] = {0x52A3B008}; /* MOV W8, #0x1D800000 */ +static const instruction_t MAKE_KERNEL_PATCH_NAME(800, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */ +static const instruction_t MAKE_KERNEL_PATCH_NAME(900, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */ +static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */ /* Hook Definitions. */ static const kernel_patch_t g_kernel_patches_100[] = { @@ -735,6 +792,35 @@ static const kernel_patch_t g_kernel_patches_900[] = { } }; +static const kernel_patch_t g_kernel_patches_1000[] = { + { /* Send Message Process ID Patch. */ + .pattern_size = 0x1C, + .pattern = MAKE_KERNEL_PATTERN_NAME(1000, proc_id_send), + .pattern_hook_offset = 0x0, + .payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1000, proc_id_send))/sizeof(instruction_t), + .branch_back_offset = 0x10, + .payload = MAKE_KERNEL_PATCH_NAME(1000, proc_id_send) + }, + { /* Receive Message Process ID Patch. */ + .pattern_size = 0x1C, + .pattern = MAKE_KERNEL_PATTERN_NAME(1000, proc_id_recv), + .pattern_hook_offset = 0x0, + .payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1000, proc_id_recv))/sizeof(instruction_t), + .branch_back_offset = 0x10, + .payload = MAKE_KERNEL_PATCH_NAME(1000, proc_id_recv) + }, + { /* svcControlCodeMemory Patch. */ + .payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1000, svc_control_codememory))/sizeof(instruction_t), + .payload = MAKE_KERNEL_PATCH_NAME(1000, svc_control_codememory), + .patch_offset = 0x45DAC, + }, + { /* System Memory Increase Patch. */ + .payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1000, system_memory_increase))/sizeof(instruction_t), + .payload = MAKE_KERNEL_PATCH_NAME(1000, system_memory_increase), + .patch_offset = 0x66950, + } +}; + #define KERNEL_PATCHES(vers) .num_patches = sizeof(g_kernel_patches_##vers)/sizeof(kernel_patch_t), .patches = g_kernel_patches_##vers, /* Kernel Infos. */ @@ -811,6 +897,15 @@ static const kernel_info_t g_kernel_infos[] = { .embedded_ini_ptr = 0x180, .free_code_space_offset = 0x65780, KERNEL_PATCHES(900) + }, + { /* 10.0.0. */ + .hash = {0x59, 0x31, 0xE6, 0x46, 0xF7, 0xAA, 0x15, 0x59, 0x78, 0xC7, 0xB3, 0xA5, 0xFA, 0x80, 0xE2, 0xC0, 0xCA, 0x6F, 0x31, 0x97, 0x3D, 0x86, 0x8A, 0x69, 0xF3, 0xBF, 0xE6, 0xE5, 0x61, 0xA7, 0x1B, 0x5B, }, + .hash_offset = 0x1B8, + .hash_size = 0x93000 - 0x1B8, + .embedded_ini_offset = 0x93000, + .embedded_ini_ptr = 0x178, + .free_code_space_offset = 0x67790, + KERNEL_PATCHES(1000) } }; diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp index 78a25185f..48af48efe 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp @@ -604,6 +604,15 @@ namespace ams::kern::arch::arm64::init { this->state.free_bitmap = ~uintptr_t(); } + ALWAYS_INLINE void InitializeFromState(uintptr_t state_val) { + if (kern::GetTargetFirmware() >= kern::TargetFirmware_10_0_0) { + this->state = *reinterpret_cast(state_val); + } else { + this->state.next_address = state_val; + this->state.free_bitmap = 0; + } + } + ALWAYS_INLINE void GetFinalState(State *out) { *out = this->state; this->state = {}; diff --git a/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp b/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp index e519c4754..56b7f8278 100644 --- a/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp +++ b/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp @@ -318,8 +318,12 @@ namespace ams::svc::aarch64::lp64 { return ::svcQueryPhysicalAddress(reinterpret_cast<::PhysicalMemoryInfo *>(out_info), address); } - ALWAYS_INLINE Result QueryIoMapping(::ams::svc::Address *out_address, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) { - return ::svcQueryIoMapping(reinterpret_cast(out_address), physical_address, size); + ALWAYS_INLINE Result QueryIoMapping(::ams::svc::Address *out_address, ::ams::svc::Size *out_size, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) { + return ::svcQueryIoMapping(reinterpret_cast(out_address), reinterpret_cast(out_size), physical_address, size); + } + + ALWAYS_INLINE Result LegacyQueryIoMapping(::ams::svc::Address *out_address, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) { + return ::svcLegacyQueryIoMapping(reinterpret_cast(out_address), physical_address, size); } ALWAYS_INLINE Result CreateDeviceAddressSpace(::ams::svc::Handle *out_handle, uint64_t das_address, uint64_t das_size) { diff --git a/libraries/libstratosphere/source/dd/dd_io_mappings.cpp b/libraries/libstratosphere/source/dd/dd_io_mappings.cpp index e71f98212..7966defac 100644 --- a/libraries/libstratosphere/source/dd/dd_io_mappings.cpp +++ b/libraries/libstratosphere/source/dd/dd_io_mappings.cpp @@ -22,10 +22,19 @@ namespace ams::dd { const u64 aligned_addr = util::AlignDown(phys_addr, os::MemoryPageSize); const size_t offset = phys_addr - aligned_addr; const u64 aligned_size = size + offset; - R_TRY_CATCH(svcQueryIoMapping(&virtual_addr, aligned_addr, aligned_size)) { - /* Official software handles this by returning 0. */ - R_CATCH(svc::ResultNotFound) { return 0; } - } R_END_TRY_CATCH_WITH_ABORT_UNLESS; + if (hos::GetVersion() >= hos::Version_10_0_0) { + u64 region_size; + R_TRY_CATCH(svcQueryIoMapping(&virtual_addr, ®ion_size, aligned_addr, aligned_size)) { + /* Official software handles this by returning 0. */ + R_CATCH(svc::ResultNotFound) { exosphere::ForceRebootToRcm(); return 0; } + } R_END_TRY_CATCH_WITH_ABORT_UNLESS; + AMS_ASSERT(region_size >= aligned_size); + } else { + R_TRY_CATCH(svcLegacyQueryIoMapping(&virtual_addr, aligned_addr, aligned_size)) { + /* Official software handles this by returning 0. */ + R_CATCH(svc::ResultNotFound) { return 0; } + } R_END_TRY_CATCH_WITH_ABORT_UNLESS; + } return static_cast(virtual_addr + offset); } diff --git a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp index 60c59ea20..60ba8febf 100644 --- a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp +++ b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp @@ -87,7 +87,7 @@ namespace ams::kern::init { cpu::ThreadIdRegisterAccessor(0).Store(); /* Restore the page allocator state setup by kernel loader. */ - g_initial_page_allocator.Initialize(initial_page_allocator_state); + g_initial_page_allocator.InitializeFromState(initial_page_allocator_state); /* Ensure that the T1SZ is correct (and what we expect). */ MESOSPHERE_INIT_ABORT_UNLESS((cpu::TranslationControlRegisterAccessor().GetT1Size() / arch::arm64::L1BlockSize) == arch::arm64::MaxPageTableEntries); @@ -266,7 +266,9 @@ namespace ams::kern::init { SetupCoreLocalRegionMemoryRegions(ttbr1_table, g_initial_page_allocator); /* Finalize the page allocator, we're done allocating at this point. */ - const KPhysicalAddress final_init_page_table_end_address = g_initial_page_allocator.GetFinalNextAddress(); + KInitialPageAllocator::State final_init_page_table_state; + g_initial_page_allocator.GetFinalState(std::addressof(final_init_page_table_state)); + const KPhysicalAddress final_init_page_table_end_address = final_init_page_table_state.next_address; const size_t init_page_table_region_size = GetInteger(final_init_page_table_end_address) - GetInteger(resource_end_phys_addr); /* Insert regions for the initial page table region. */ diff --git a/mesosphere/kernel/source/arch/arm64/init/start.s b/mesosphere/kernel/source/arch/arm64/init/start.s index d8fdbd97c..af91ca038 100644 --- a/mesosphere/kernel/source/arch/arm64/init/start.s +++ b/mesosphere/kernel/source/arch/arm64/init/start.s @@ -42,6 +42,8 @@ __metadata_ini_offset: .quad 0 /* INI1 base address. */ __metadata_kernelldr_offset: .quad 0 /* Kernel Loader base address. */ +__metadata_target_firmware: + .word 0xCCCCCCCC /* Target firmware. */ __metadata_kernel_layout: .word _start - _start /* rx_offset */ .word __rodata_start - _start /* rx_end_offset */ @@ -55,10 +57,17 @@ __metadata_kernel_layout: .word _DYNAMIC - _start /* dynamic_offset */ .word __init_array_start - _start /* init_array_offset */ .word __init_array_end - _start /* init_array_end_offset */ -.if (. - __metadata_begin) != 0x44 +.if (. - __metadata_begin) != 0x48 .error "Incorrect Mesosphere Metadata" .endif +.global _ZN3ams4kern17GetTargetFirmwareEv +.type _ZN3ams4kern17GetTargetFirmwareEv, %function +_ZN3ams4kern17GetTargetFirmwareEv: + adr x0, __metadata_target_firmware + ldr x0, [x0] + ret + /* ams::kern::init::StartCore0(uintptr_t, uintptr_t) */ .section .crt0.text._ZN3ams4kern4init10StartCore0Emm, "ax", %progbits .global _ZN3ams4kern4init10StartCore0Emm diff --git a/mesosphere/kernel_ldr/source/arch/arm64/start.s b/mesosphere/kernel_ldr/source/arch/arm64/start.s index 419b63e18..9862239c9 100644 --- a/mesosphere/kernel_ldr/source/arch/arm64/start.s +++ b/mesosphere/kernel_ldr/source/arch/arm64/start.s @@ -25,9 +25,9 @@ _start: __metadata_begin: .ascii "MLD0" /* Magic */ __metadata_target_firmware: - .dword 0xCCCCCCCC /* Target Firmware. */ + .word 0xCCCCCCCC /* Target Firmware. */ __metadata_reserved: - .dword 0xCCCCCCCC /* Reserved. */ + .word 0xCCCCCCCC /* Reserved. */ _main: /* KernelLdr_Main(uintptr_t kernel_base_address, KernelMap *kernel_map, uintptr_t ini1_base_address); */ adr x18, _start diff --git a/stratosphere/Makefile b/stratosphere/Makefile index d70f63a3a..ecda499cf 100644 --- a/stratosphere/Makefile +++ b/stratosphere/Makefile @@ -1,4 +1,4 @@ -MODULES := loader ncm pm sm boot ams_mitm spl eclct.stub ro creport fatal dmnt boot2 +MODULES := loader ncm pm sm boot ams_mitm spl eclct.stub ro creport fatal dmnt boot2 erpt SUBFOLDERS := $(MODULES)