diff --git a/libraries/libmesosphere/include/mesosphere/kern_debug_log.hpp b/libraries/libmesosphere/include/mesosphere/kern_debug_log.hpp index 1611e68a3..bb4d4e988 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_debug_log.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_debug_log.hpp @@ -33,7 +33,7 @@ namespace ams::kern { #ifndef MESOSPHERE_DEBUG_LOG_SELECTED #ifdef ATMOSPHERE_BOARD_NINTENDO_SWITCH - #define MESOSPHERE_DEBUG_LOG_USE_UART_A + #define MESOSPHERE_DEBUG_LOG_USE_UART_C #else #error "Unknown board for Default Debug Log Source" #endif diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp index 1f5f42ead..4903b4f72 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp @@ -50,9 +50,9 @@ namespace ams::kern { private: friend class KScopedSchedulerLock; friend class KScopedSchedulerLockAndSleep; - static inline bool s_scheduler_update_needed; - static inline LockType s_scheduler_lock; - static inline KSchedulerPriorityQueue s_priority_queue; + static bool s_scheduler_update_needed; + static LockType s_scheduler_lock; + static KSchedulerPriorityQueue s_priority_queue; private: SchedulingState state; bool is_active; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp index c720d7ff2..16b0c91fd 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp @@ -173,7 +173,21 @@ namespace ams::kern { s8 priority_inheritance_count; bool resource_limit_release_hint; public: - explicit KThread() /* TODO: : ? */ { MESOSPHERE_ASSERT_THIS(); } + constexpr KThread() : + thread_context(), affinity_mask(), thread_id(), cpu_time(), synced_object(), waiting_lock(), + condvar_key(), entrypoint(), arbiter_key(), parent(), kernel_stack_top(), light_ipc_data(), + tls_address(), tls_heap_address(), activity_pause_lock(), sync_object_buffer(), schedule_count(), + last_scheduled_tick(), per_core_priority_queue_entry(), sleeping_queue_entry(), sleeping_queue(), waiter_list_node(), + condvar_arbiter_tree_node(), process_list_node(), waiter_list(), paused_waiter_list(), lock_owner(), + cond_var_tree(), debug_params(), arbiter_value(), suspend_request_flags(), suspend_allowed_flags(), + wait_result(ResultSuccess()), debug_exception_result(ResultSuccess()), priority(), core_id(), base_priority(), + ideal_core_id(), num_kernel_waiters(), original_affinity_mask(), original_ideal_core_id(), num_core_migration_disables(), + thread_state(), termination_requested(), ipc_cancelled(), wait_cancelled(), cancellable(), + registered(), signaled(), initialized(), debug_attached(), priority_inheritance_count(), + resource_limit_release_hint() + { + /* ... */ + } virtual ~KThread() { /* ... */ } /* TODO: Is a constexpr KThread() possible? */ diff --git a/libraries/libmesosphere/include/mesosphere/kern_kernel.hpp b/libraries/libmesosphere/include/mesosphere/kern_kernel.hpp index 459252910..2ba8599f1 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_kernel.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_kernel.hpp @@ -62,8 +62,6 @@ namespace ams::kern { static constexpr size_t BlockInfoSlabHeapSize = 4000; private: static State s_state; - static KThread s_main_threads[cpu::NumCores]; - static KThread s_idle_threads[cpu::NumCores]; static KResourceLimit s_system_resource_limit; static KMemoryManager s_memory_manager; static KPageTableManager s_page_table_manager; @@ -87,13 +85,8 @@ namespace ams::kern { static ALWAYS_INLINE State GetState() { return s_state; } static ALWAYS_INLINE void SetState(State state) { s_state = state; } - static ALWAYS_INLINE KThread &GetMainThread(s32 core_id) { - return s_main_threads[core_id]; - } - - static ALWAYS_INLINE KThread &GetIdleThread(s32 core_id) { - return s_idle_threads[core_id]; - } + static KThread &GetMainThread(s32 core_id); + static KThread &GetIdleThread(s32 core_id); static ALWAYS_INLINE KScheduler &GetScheduler() { return GetCoreLocalContext().scheduler; diff --git a/libraries/libmesosphere/include/mesosphere/kern_panic.hpp b/libraries/libmesosphere/include/mesosphere/kern_panic.hpp index 2402b7d21..4e1717c11 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_panic.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_panic.hpp @@ -42,8 +42,8 @@ namespace ams::kern { #define MESOSPHERE_ASSERT_IMPL(expr, ...) do { static_cast(expr); } while (0) #endif -#define MESOSPHERE_ASSERT(expr) MESOSPHERE_ASSERT_IMPL(expr, "Assertion failed: %s", #expr) -#define MESOSPHERE_R_ASSERT(expr) MESOSPHERE_ASSERT_IMPL(R_SUCCEEDED(expr), "Result assertion failed: %s", #expr) +#define MESOSPHERE_ASSERT(expr) MESOSPHERE_ASSERT_IMPL(expr, "Assertion failed: %s\n", #expr) +#define MESOSPHERE_R_ASSERT(expr) MESOSPHERE_ASSERT_IMPL(R_SUCCEEDED(expr), "Result assertion failed: %s\n", #expr) #define MESOSPHERE_UNREACHABLE_DEFAULT_CASE() default: MESOSPHERE_PANIC("Unreachable default case entered") #ifdef MESOSPHERE_ENABLE_THIS_ASSERT @@ -58,10 +58,10 @@ namespace ams::kern { #define MESOSPHERE_AUDIT(expr) do { static_cast(expr); } while (0) #endif -#define MESOSPHERE_TODO(arg) ({ constexpr const char *__mesosphere_todo = arg; MESOSPHERE_PANIC("TODO (%s): %s", __PRETTY_FUNCTION__, __mesosphere_todo); }) +#define MESOSPHERE_TODO(arg) ({ constexpr const char *__mesosphere_todo = arg; MESOSPHERE_PANIC("TODO (%s): %s\n", __PRETTY_FUNCTION__, __mesosphere_todo); }) #define MESOSPHERE_TODO_IMPLEMENT() MESOSPHERE_TODO("Implement") -#define MESOSPHERE_ABORT() MESOSPHERE_PANIC("Abort()"); +#define MESOSPHERE_ABORT() MESOSPHERE_PANIC("Abort()\n"); #define MESOSPHERE_INIT_ABORT() do { /* ... */ } while (true) #define MESOSPHERE_ABORT_UNLESS(expr) \ @@ -80,10 +80,10 @@ namespace ams::kern { } \ }) -#define MESOSPHERE_R_ABORT_UNLESS(expr) \ - ({ \ - const ::ams::Result _tmp_meso_r_abort_res = static_cast<::ams::Result>((expr)); \ - if (AMS_UNLIKELY((R_FAILED(_tmp_meso_r_abort_res)))) { \ - MESOSPHERE_PANIC("Result Abort(): %s 2%03d-%04d", #expr, _tmp_meso_r_abort_res.GetModule(), _tmp_meso_r_abort_res.GetDescription()); \ - } \ +#define MESOSPHERE_R_ABORT_UNLESS(expr) \ + ({ \ + const ::ams::Result _tmp_meso_r_abort_res = static_cast<::ams::Result>((expr)); \ + if (AMS_UNLIKELY((R_FAILED(_tmp_meso_r_abort_res)))) { \ + MESOSPHERE_PANIC("Result Abort(): %s 2%03d-%04d\n", #expr, _tmp_meso_r_abort_res.GetModule(), _tmp_meso_r_abort_res.GetDescription()); \ + } \ }) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index d2bd5e1f0..5add50a5c 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -181,7 +181,6 @@ namespace ams::kern::arm64 { Result KPageTable::MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - MESOSPHERE_LOG("KPageTable::MapContiguous(%016lx, %016lx, %zu)\n", GetInteger(virt_addr), GetInteger(phys_addr), num_pages); /* Cache initial addresses for use on cleanup. */ const KProcessAddress orig_virt_addr = virt_addr; diff --git a/libraries/libmesosphere/source/board/nintendo/switch/kern_debug_log_impl.cpp b/libraries/libmesosphere/source/board/nintendo/switch/kern_debug_log_impl.cpp index 662377939..8985447cf 100644 --- a/libraries/libmesosphere/source/board/nintendo/switch/kern_debug_log_impl.cpp +++ b/libraries/libmesosphere/source/board/nintendo/switch/kern_debug_log_impl.cpp @@ -28,6 +28,8 @@ namespace ams::kern { UartRegister_LSR = 5, + UartRegister_IRSA_CSR = 8, + UartRegister_DLL = 0, UartRegister_DLH = 1, }; @@ -71,8 +73,9 @@ namespace ams::kern { /* Disable UART interrupts. */ WriteUartRegister(UartRegister_IER, 0x00); - /* Configure the FIFOO to be enabled and clear receive. */ + /* Configure the FIFO to be enabled and clear receive. */ WriteUartRegister(UartRegister_FCR, 0x03); + WriteUartRegister(UartRegister_IRSA_CSR, 0x02); ReadUartRegister(UartRegister_FCR); return true; diff --git a/libraries/libmesosphere/source/board/nintendo/switch/kern_k_system_control.cpp b/libraries/libmesosphere/source/board/nintendo/switch/kern_k_system_control.cpp index 4d37cb552..358645e7d 100644 --- a/libraries/libmesosphere/source/board/nintendo/switch/kern_k_system_control.cpp +++ b/libraries/libmesosphere/source/board/nintendo/switch/kern_k_system_control.cpp @@ -260,7 +260,7 @@ namespace ams::kern { void KSystemControl::StopSystem() { if (g_call_smc_on_panic) { /* Display a panic screen via secure monitor. */ - smc::Panic(0xF00); + /* TODO: Enable in release: smc::Panic(0xF00); */ } while (true) { /* ... */ } } diff --git a/libraries/libmesosphere/source/board/nintendo/switch/kern_secure_monitor.cpp b/libraries/libmesosphere/source/board/nintendo/switch/kern_secure_monitor.cpp index 1aac226a7..7c49443d6 100644 --- a/libraries/libmesosphere/source/board/nintendo/switch/kern_secure_monitor.cpp +++ b/libraries/libmesosphere/source/board/nintendo/switch/kern_secure_monitor.cpp @@ -116,7 +116,7 @@ namespace ams::kern::smc { void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) { SecureMonitorArguments args = { FunctionId_GetConfig, static_cast(config_item) }; CallPrivilegedSecureMonitorFunctionForInit(args); - MESOSPHERE_ABORT_UNLESS((static_cast(args.x[0]) == SmcResult::Success)); + MESOSPHERE_INIT_ABORT_UNLESS((static_cast(args.x[0]) == SmcResult::Success)); for (size_t i = 0; i < num_qwords && i < 7; i++) { out[i] = args.x[1 + i]; } @@ -125,10 +125,10 @@ namespace ams::kern::smc { void GenerateRandomBytes(void *dst, size_t size) { /* Call SmcGenerateRandomBytes() */ SecureMonitorArguments args = { FunctionId_GenerateRandomBytes, size }; - MESOSPHERE_ABORT_UNLESS(size <= sizeof(args) - sizeof(args.x[0])); + MESOSPHERE_INIT_ABORT_UNLESS(size <= sizeof(args) - sizeof(args.x[0])); CallPrivilegedSecureMonitorFunctionForInit(args); - MESOSPHERE_ABORT_UNLESS((static_cast(args.x[0]) == SmcResult::Success)); + MESOSPHERE_INIT_ABORT_UNLESS((static_cast(args.x[0]) == SmcResult::Success)); /* Copy output. */ std::memcpy(dst, &args.x[1], size); diff --git a/libraries/libmesosphere/source/kern_k_scheduler.cpp b/libraries/libmesosphere/source/kern_k_scheduler.cpp index 4bd37ed57..50e778c6e 100644 --- a/libraries/libmesosphere/source/kern_k_scheduler.cpp +++ b/libraries/libmesosphere/source/kern_k_scheduler.cpp @@ -17,6 +17,10 @@ namespace ams::kern { + bool KScheduler::s_scheduler_update_needed; + KScheduler::LockType KScheduler::s_scheduler_lock; + KSchedulerPriorityQueue KScheduler::s_priority_queue; + namespace { class KSchedulerInterruptTask : public KInterruptTask { diff --git a/libraries/libmesosphere/source/kern_kernel.cpp b/libraries/libmesosphere/source/kern_kernel.cpp index 09bc065c2..d312d270d 100644 --- a/libraries/libmesosphere/source/kern_kernel.cpp +++ b/libraries/libmesosphere/source/kern_kernel.cpp @@ -17,18 +17,6 @@ namespace ams::kern { - /* Declare kernel data members in kernel TU. */ - Kernel::State Kernel::s_state = Kernel::State::Invalid; - KThread Kernel::s_main_threads[cpu::NumCores]; - KThread Kernel::s_idle_threads[cpu::NumCores]; - KResourceLimit Kernel::s_system_resource_limit; - KMemoryManager Kernel::s_memory_manager; - KPageTableManager Kernel::s_page_table_manager; - KMemoryBlockSlabManager Kernel::s_app_memory_block_manager; - KMemoryBlockSlabManager Kernel::s_sys_memory_block_manager; - KBlockInfoManager Kernel::s_block_info_manager; - KSupervisorPageTable Kernel::s_supervisor_page_table; - namespace { template diff --git a/libraries/libvapours/include/vapours/util/util_intrusive_list.hpp b/libraries/libvapours/include/vapours/util/util_intrusive_list.hpp index c7d52e7c5..771aa3843 100644 --- a/libraries/libvapours/include/vapours/util/util_intrusive_list.hpp +++ b/libraries/libvapours/include/vapours/util/util_intrusive_list.hpp @@ -405,7 +405,7 @@ namespace ams::util { return Traits::GetParent(node); } public: - IntrusiveList() : impl() { /* ... */ } + constexpr IntrusiveList() : impl() { /* ... */ } /* Iterator accessors. */ iterator begin() { diff --git a/mesosphere/build_mesosphere.py b/mesosphere/build_mesosphere.py index e5fc15d58..eb53e7ee6 100644 --- a/mesosphere/build_mesosphere.py +++ b/mesosphere/build_mesosphere.py @@ -22,11 +22,17 @@ def main(argc, argv): assert (kernel_end >= len(kernel)) embedded_ini = b'' + try: + with open('ini.bin', 'rb') as f: + embedded_ini = f.read() + except: + pass embedded_ini_offset = align_up(kernel_end, 0x1000) + 0x1000 - embedded_ini_end = embedded_ini_offset + 0 # TODO: Create and embed an INI, eventually. + embedded_ini_end = embedded_ini_offset + len(embedded_ini) # TODO: Create and embed an INI, eventually. kernel_ldr_offset = align_up(embedded_ini_end, 0x1000) + 0x1000 kernel_ldr_end = kernel_ldr_offset + len(kernel_ldr) + mesosphere_end = align_up(kernel_ldr_end, 0x1000) with open('mesosphere.bin', 'wb') as f: f.write(kernel[:kernel_metadata_offset + 4]) @@ -37,7 +43,8 @@ def main(argc, argv): f.seek(embedded_ini_end) f.seek(kernel_ldr_offset) f.write(kernel_ldr) - f.seek(kernel_ldr_end) + f.seek(mesosphere_end) + f.write(b'\x00'*0x1000) return 0 diff --git a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers_asm.s b/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s similarity index 100% rename from libraries/libmesosphere/source/arch/arm64/kern_exception_handlers_asm.s rename to mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_scheduler_asm.s b/mesosphere/kernel/source/arch/arm64/kern_k_scheduler_asm.s similarity index 100% rename from libraries/libmesosphere/source/arch/arm64/kern_k_scheduler_asm.s rename to mesosphere/kernel/source/arch/arm64/kern_k_scheduler_asm.s diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context_asm.s b/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s similarity index 100% rename from libraries/libmesosphere/source/arch/arm64/kern_k_thread_context_asm.s rename to mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s diff --git a/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s b/mesosphere/kernel/source/arch/arm64/kern_userspace_memory_access_asm.s similarity index 100% rename from libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s rename to mesosphere/kernel/source/arch/arm64/kern_userspace_memory_access_asm.s diff --git a/mesosphere/kernel/source/kern_kernel_instantiations.cpp b/mesosphere/kernel/source/kern_kernel_instantiations.cpp new file mode 100644 index 000000000..6167c2726 --- /dev/null +++ b/mesosphere/kernel/source/kern_kernel_instantiations.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018-2020 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 . + */ +#include + +namespace ams::kern { + + /* Declare kernel data members in kernel TU. */ + Kernel::State Kernel::s_state = Kernel::State::Invalid; + KResourceLimit Kernel::s_system_resource_limit; + KMemoryManager Kernel::s_memory_manager; + KPageTableManager Kernel::s_page_table_manager; + KMemoryBlockSlabManager Kernel::s_app_memory_block_manager; + KMemoryBlockSlabManager Kernel::s_sys_memory_block_manager; + KBlockInfoManager Kernel::s_block_info_manager; + KSupervisorPageTable Kernel::s_supervisor_page_table; + + namespace { + + KThread g_main_threads[cpu::NumCores]; + KThread g_idle_threads[cpu::NumCores]; + } + + KThread &Kernel::GetMainThread(s32 core_id) { return g_main_threads[core_id]; } + KThread &Kernel::GetIdleThread(s32 core_id) { return g_idle_threads[core_id]; } + +} diff --git a/mesosphere/kernel_ldr/source/arch/arm64/start.s b/mesosphere/kernel_ldr/source/arch/arm64/start.s index 2d9c3dffd..18412f500 100644 --- a/mesosphere/kernel_ldr/source/arch/arm64/start.s +++ b/mesosphere/kernel_ldr/source/arch/arm64/start.s @@ -73,6 +73,7 @@ _start: /* Call ams::kern::init::loader::Main(uintptr_t, ams::kern::init::KernelLayout *, uintptr_t) */ ldp x0, x1, [sp, #0x00] ldr x2, [sp, #0x10] + bl _ZN3ams4kern4init6loader4MainEmPNS1_12KernelLayoutEm str x0, [sp, #0x00] diff --git a/mesosphere/kernel_ldr/source/kern_init_loader.cpp b/mesosphere/kernel_ldr/source/kern_init_loader.cpp index 004259a4c..226e20de2 100644 --- a/mesosphere/kernel_ldr/source/kern_init_loader.cpp +++ b/mesosphere/kernel_ldr/source/kern_init_loader.cpp @@ -218,7 +218,6 @@ namespace ams::kern::init::loader { } - uintptr_t Main(uintptr_t base_address, KernelLayout *layout, uintptr_t ini_base_address) { /* Relocate the kernel to the correct physical base address. */ /* Base address and layout are passed by reference and modified. */ @@ -235,12 +234,12 @@ namespace ams::kern::init::loader { const uintptr_t rw_offset = layout->rw_offset; /* UNUSED: const uintptr_t rw_end_offset = layout->rw_end_offset; */ const uintptr_t bss_end_offset = layout->bss_end_offset; - MESOSPHERE_ABORT_UNLESS(util::IsAligned(rx_offset, 0x1000)); - MESOSPHERE_ABORT_UNLESS(util::IsAligned(rx_end_offset, 0x1000)); - MESOSPHERE_ABORT_UNLESS(util::IsAligned(ro_offset, 0x1000)); - MESOSPHERE_ABORT_UNLESS(util::IsAligned(ro_end_offset, 0x1000)); - MESOSPHERE_ABORT_UNLESS(util::IsAligned(rw_offset, 0x1000)); - MESOSPHERE_ABORT_UNLESS(util::IsAligned(bss_end_offset, 0x1000)); + MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(rx_offset, 0x1000)); + MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(rx_end_offset, 0x1000)); + MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(ro_offset, 0x1000)); + MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(ro_end_offset, 0x1000)); + MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(rw_offset, 0x1000)); + MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(bss_end_offset, 0x1000)); const uintptr_t bss_offset = layout->bss_offset; const uintptr_t ini_load_offset = layout->ini_load_offset; const uintptr_t dynamic_offset = layout->dynamic_offset; diff --git a/stratosphere/ro/source/impl/ro_nro_utils.cpp b/stratosphere/ro/source/impl/ro_nro_utils.cpp index 181512e58..90de057e9 100644 --- a/stratosphere/ro/source/impl/ro_nro_utils.cpp +++ b/stratosphere/ro/source/impl/ro_nro_utils.cpp @@ -38,7 +38,7 @@ namespace ams::ro::impl { if (bss_heap_size > 0) { map::MappedCodeMemory tmp_bss_mcm(process_handle, base_address + nro_heap_size, bss_heap_address, bss_heap_size); R_TRY_CATCH(tmp_bss_mcm.GetResult()) { - R_CATCH(svc::ResultInvalidCurrentMemoryState) { + R_CATCH(svc::ResultInvalidCurrentMemory) { continue; } } R_END_TRY_CATCH;