diff options
| author | 2015-05-08 21:20:37 -0400 | |
|---|---|---|
| committer | 2015-05-08 21:20:37 -0400 | |
| commit | 917ac23dfcab37c65e11e3413e397863bd4bc000 (patch) | |
| tree | 956ca5d1a4aad3383c4a3bfc9103476abe3f1987 /src | |
| parent | Merge pull request #728 from lioncash/vars (diff) | |
| parent | Kernel: Remove unused g_main_thread variable (diff) | |
| download | yuzu-917ac23dfcab37c65e11e3413e397863bd4bc000.tar.gz yuzu-917ac23dfcab37c65e11e3413e397863bd4bc000.tar.xz yuzu-917ac23dfcab37c65e11e3413e397863bd4bc000.zip | |
Merge pull request #731 from yuriks/app-info
Kernel: Process class and ExHeader caps parsing
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/common_funcs.h | 2 | ||||
| -rw-r--r-- | src/common/string_util.cpp | 8 | ||||
| -rw-r--r-- | src/common/string_util.h | 6 | ||||
| -rw-r--r-- | src/core/CMakeLists.txt | 44 | ||||
| -rw-r--r-- | src/core/file_sys/archive_savedata.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 18 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 16 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 96 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.h | 90 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 2 | ||||
| -rw-r--r-- | src/core/loader/3dsx.cpp | 12 | ||||
| -rw-r--r-- | src/core/loader/3dsx.h | 8 | ||||
| -rw-r--r-- | src/core/loader/elf.cpp | 14 | ||||
| -rw-r--r-- | src/core/loader/elf.h | 8 | ||||
| -rw-r--r-- | src/core/loader/loader.cpp | 39 | ||||
| -rw-r--r-- | src/core/loader/loader.h | 8 | ||||
| -rw-r--r-- | src/core/loader/ncch.cpp | 24 | ||||
| -rw-r--r-- | src/core/loader/ncch.h | 36 | ||||
| -rw-r--r-- | src/core/mem_map.h | 2 |
19 files changed, 335 insertions, 103 deletions
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index 91b74c6bc..fde0f3a59 100644 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | #define b32(x) (b16(x) | (b16(x) >>16) ) | 15 | #define b32(x) (b16(x) | (b16(x) >>16) ) |
| 16 | #define ROUND_UP_POW2(x) (b32(x - 1) + 1) | 16 | #define ROUND_UP_POW2(x) (b32(x - 1) + 1) |
| 17 | 17 | ||
| 18 | #define BIT(x) (1U << (x)) | ||
| 19 | |||
| 18 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) | 20 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) |
| 19 | 21 | ||
| 20 | /// Textually concatenates two tokens. The double-expansion is required by the C preprocessor. | 22 | /// Textually concatenates two tokens. The double-expansion is required by the C preprocessor. |
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index 3a6e51daa..7dc0ba7ba 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp | |||
| @@ -477,4 +477,12 @@ std::string SHIFTJISToUTF8(const std::string& input) | |||
| 477 | 477 | ||
| 478 | #endif | 478 | #endif |
| 479 | 479 | ||
| 480 | std::string StringFromFixedZeroTerminatedBuffer(const char * buffer, size_t max_len) { | ||
| 481 | size_t len = 0; | ||
| 482 | while (len < max_len && buffer[len] != '\0') | ||
| 483 | ++len; | ||
| 484 | |||
| 485 | return std::string(buffer, len); | ||
| 486 | } | ||
| 487 | |||
| 480 | } | 488 | } |
diff --git a/src/common/string_util.h b/src/common/string_util.h index 356da5b60..fdc410499 100644 --- a/src/common/string_util.h +++ b/src/common/string_util.h | |||
| @@ -128,4 +128,10 @@ bool ComparePartialString(InIt begin, InIt end, const char* other) { | |||
| 128 | return (begin == end) == (*other == '\0'); | 128 | return (begin == end) == (*other == '\0'); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | /** | ||
| 132 | * Creates a std::string from a fixed-size NUL-terminated char buffer. If the buffer isn't | ||
| 133 | * NUL-terminated then the string ends at max_len characters. | ||
| 134 | */ | ||
| 135 | std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_len); | ||
| 136 | |||
| 131 | } | 137 | } |
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index aaa6d87f3..ebedcb710 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -12,6 +12,8 @@ set(SRCS | |||
| 12 | arm/skyeye_common/vfp/vfpdouble.cpp | 12 | arm/skyeye_common/vfp/vfpdouble.cpp |
| 13 | arm/skyeye_common/vfp/vfpinstr.cpp | 13 | arm/skyeye_common/vfp/vfpinstr.cpp |
| 14 | arm/skyeye_common/vfp/vfpsingle.cpp | 14 | arm/skyeye_common/vfp/vfpsingle.cpp |
| 15 | core.cpp | ||
| 16 | core_timing.cpp | ||
| 15 | file_sys/archive_backend.cpp | 17 | file_sys/archive_backend.cpp |
| 16 | file_sys/archive_extsavedata.cpp | 18 | file_sys/archive_extsavedata.cpp |
| 17 | file_sys/archive_romfs.cpp | 19 | file_sys/archive_romfs.cpp |
| @@ -21,15 +23,18 @@ set(SRCS | |||
| 21 | file_sys/archive_systemsavedata.cpp | 23 | file_sys/archive_systemsavedata.cpp |
| 22 | file_sys/disk_archive.cpp | 24 | file_sys/disk_archive.cpp |
| 23 | file_sys/ivfc_archive.cpp | 25 | file_sys/ivfc_archive.cpp |
| 26 | hle/config_mem.cpp | ||
| 27 | hle/hle.cpp | ||
| 24 | hle/kernel/address_arbiter.cpp | 28 | hle/kernel/address_arbiter.cpp |
| 25 | hle/kernel/event.cpp | 29 | hle/kernel/event.cpp |
| 26 | hle/kernel/kernel.cpp | 30 | hle/kernel/kernel.cpp |
| 27 | hle/kernel/mutex.cpp | 31 | hle/kernel/mutex.cpp |
| 32 | hle/kernel/process.cpp | ||
| 28 | hle/kernel/semaphore.cpp | 33 | hle/kernel/semaphore.cpp |
| 29 | hle/kernel/session.cpp | 34 | hle/kernel/session.cpp |
| 30 | hle/kernel/shared_memory.cpp | 35 | hle/kernel/shared_memory.cpp |
| 31 | hle/kernel/timer.cpp | ||
| 32 | hle/kernel/thread.cpp | 36 | hle/kernel/thread.cpp |
| 37 | hle/kernel/timer.cpp | ||
| 33 | hle/service/ac_u.cpp | 38 | hle/service/ac_u.cpp |
| 34 | hle/service/act_u.cpp | 39 | hle/service/act_u.cpp |
| 35 | hle/service/am_app.cpp | 40 | hle/service/am_app.cpp |
| @@ -56,10 +61,10 @@ set(SRCS | |||
| 56 | hle/service/fs/archive.cpp | 61 | hle/service/fs/archive.cpp |
| 57 | hle/service/fs/fs_user.cpp | 62 | hle/service/fs/fs_user.cpp |
| 58 | hle/service/gsp_gpu.cpp | 63 | hle/service/gsp_gpu.cpp |
| 64 | hle/service/gsp_lcd.cpp | ||
| 59 | hle/service/hid/hid.cpp | 65 | hle/service/hid/hid.cpp |
| 60 | hle/service/hid/hid_user.cpp | ||
| 61 | hle/service/hid/hid_spvr.cpp | 66 | hle/service/hid/hid_spvr.cpp |
| 62 | hle/service/gsp_lcd.cpp | 67 | hle/service/hid/hid_user.cpp |
| 63 | hle/service/http_c.cpp | 68 | hle/service/http_c.cpp |
| 64 | hle/service/ir/ir.cpp | 69 | hle/service/ir/ir.cpp |
| 65 | hle/service/ir/ir_rst.cpp | 70 | hle/service/ir/ir_rst.cpp |
| @@ -77,26 +82,22 @@ set(SRCS | |||
| 77 | hle/service/pm_app.cpp | 82 | hle/service/pm_app.cpp |
| 78 | hle/service/ptm/ptm.cpp | 83 | hle/service/ptm/ptm.cpp |
| 79 | hle/service/ptm/ptm_play.cpp | 84 | hle/service/ptm/ptm_play.cpp |
| 80 | hle/service/ptm/ptm_u.cpp | ||
| 81 | hle/service/ptm/ptm_sysm.cpp | 85 | hle/service/ptm/ptm_sysm.cpp |
| 86 | hle/service/ptm/ptm_u.cpp | ||
| 82 | hle/service/service.cpp | 87 | hle/service/service.cpp |
| 83 | hle/service/soc_u.cpp | 88 | hle/service/soc_u.cpp |
| 84 | hle/service/srv.cpp | 89 | hle/service/srv.cpp |
| 85 | hle/service/ssl_c.cpp | 90 | hle/service/ssl_c.cpp |
| 86 | hle/service/y2r_u.cpp | 91 | hle/service/y2r_u.cpp |
| 87 | hle/config_mem.cpp | ||
| 88 | hle/hle.cpp | ||
| 89 | hle/shared_page.cpp | 92 | hle/shared_page.cpp |
| 90 | hle/svc.cpp | 93 | hle/svc.cpp |
| 91 | hw/gpu.cpp | 94 | hw/gpu.cpp |
| 92 | hw/hw.cpp | 95 | hw/hw.cpp |
| 93 | hw/lcd.cpp | 96 | hw/lcd.cpp |
| 97 | loader/3dsx.cpp | ||
| 94 | loader/elf.cpp | 98 | loader/elf.cpp |
| 95 | loader/loader.cpp | 99 | loader/loader.cpp |
| 96 | loader/ncch.cpp | 100 | loader/ncch.cpp |
| 97 | loader/3dsx.cpp | ||
| 98 | core.cpp | ||
| 99 | core_timing.cpp | ||
| 100 | mem_map.cpp | 101 | mem_map.cpp |
| 101 | mem_map_funcs.cpp | 102 | mem_map_funcs.cpp |
| 102 | settings.cpp | 103 | settings.cpp |
| @@ -104,6 +105,7 @@ set(SRCS | |||
| 104 | ) | 105 | ) |
| 105 | 106 | ||
| 106 | set(HEADERS | 107 | set(HEADERS |
| 108 | arm/arm_interface.h | ||
| 107 | arm/disassembler/arm_disasm.h | 109 | arm/disassembler/arm_disasm.h |
| 108 | arm/disassembler/load_symbol_map.h | 110 | arm/disassembler/load_symbol_map.h |
| 109 | arm/dyncom/arm_dyncom.h | 111 | arm/dyncom/arm_dyncom.h |
| @@ -118,7 +120,8 @@ set(HEADERS | |||
| 118 | arm/skyeye_common/vfp/asm_vfp.h | 120 | arm/skyeye_common/vfp/asm_vfp.h |
| 119 | arm/skyeye_common/vfp/vfp.h | 121 | arm/skyeye_common/vfp/vfp.h |
| 120 | arm/skyeye_common/vfp/vfp_helper.h | 122 | arm/skyeye_common/vfp/vfp_helper.h |
| 121 | arm/arm_interface.h | 123 | core.h |
| 124 | core_timing.h | ||
| 122 | file_sys/archive_backend.h | 125 | file_sys/archive_backend.h |
| 123 | file_sys/archive_extsavedata.h | 126 | file_sys/archive_extsavedata.h |
| 124 | file_sys/archive_romfs.h | 127 | file_sys/archive_romfs.h |
| @@ -126,19 +129,24 @@ set(HEADERS | |||
| 126 | file_sys/archive_savedatacheck.h | 129 | file_sys/archive_savedatacheck.h |
| 127 | file_sys/archive_sdmc.h | 130 | file_sys/archive_sdmc.h |
| 128 | file_sys/archive_systemsavedata.h | 131 | file_sys/archive_systemsavedata.h |
| 132 | file_sys/directory_backend.h | ||
| 129 | file_sys/disk_archive.h | 133 | file_sys/disk_archive.h |
| 130 | file_sys/file_backend.h | 134 | file_sys/file_backend.h |
| 131 | file_sys/ivfc_archive.h | 135 | file_sys/ivfc_archive.h |
| 132 | file_sys/directory_backend.h | 136 | hle/config_mem.h |
| 137 | hle/function_wrappers.h | ||
| 138 | hle/hle.h | ||
| 133 | hle/kernel/address_arbiter.h | 139 | hle/kernel/address_arbiter.h |
| 134 | hle/kernel/event.h | 140 | hle/kernel/event.h |
| 135 | hle/kernel/kernel.h | 141 | hle/kernel/kernel.h |
| 136 | hle/kernel/mutex.h | 142 | hle/kernel/mutex.h |
| 143 | hle/kernel/process.h | ||
| 137 | hle/kernel/semaphore.h | 144 | hle/kernel/semaphore.h |
| 138 | hle/kernel/session.h | 145 | hle/kernel/session.h |
| 139 | hle/kernel/shared_memory.h | 146 | hle/kernel/shared_memory.h |
| 140 | hle/kernel/timer.h | ||
| 141 | hle/kernel/thread.h | 147 | hle/kernel/thread.h |
| 148 | hle/kernel/timer.h | ||
| 149 | hle/result.h | ||
| 142 | hle/service/ac_u.h | 150 | hle/service/ac_u.h |
| 143 | hle/service/act_u.h | 151 | hle/service/act_u.h |
| 144 | hle/service/am_app.h | 152 | hle/service/am_app.h |
| @@ -165,10 +173,10 @@ set(HEADERS | |||
| 165 | hle/service/fs/archive.h | 173 | hle/service/fs/archive.h |
| 166 | hle/service/fs/fs_user.h | 174 | hle/service/fs/fs_user.h |
| 167 | hle/service/gsp_gpu.h | 175 | hle/service/gsp_gpu.h |
| 176 | hle/service/gsp_lcd.h | ||
| 168 | hle/service/hid/hid.h | 177 | hle/service/hid/hid.h |
| 169 | hle/service/hid/hid_spvr.h | 178 | hle/service/hid/hid_spvr.h |
| 170 | hle/service/hid/hid_user.h | 179 | hle/service/hid/hid_user.h |
| 171 | hle/service/gsp_lcd.h | ||
| 172 | hle/service/http_c.h | 180 | hle/service/http_c.h |
| 173 | hle/service/ir/ir.h | 181 | hle/service/ir/ir.h |
| 174 | hle/service/ir/ir_rst.h | 182 | hle/service/ir/ir_rst.h |
| @@ -186,28 +194,22 @@ set(HEADERS | |||
| 186 | hle/service/pm_app.h | 194 | hle/service/pm_app.h |
| 187 | hle/service/ptm/ptm.h | 195 | hle/service/ptm/ptm.h |
| 188 | hle/service/ptm/ptm_play.h | 196 | hle/service/ptm/ptm_play.h |
| 189 | hle/service/ptm/ptm_u.h | ||
| 190 | hle/service/ptm/ptm_sysm.h | 197 | hle/service/ptm/ptm_sysm.h |
| 198 | hle/service/ptm/ptm_u.h | ||
| 191 | hle/service/service.h | 199 | hle/service/service.h |
| 192 | hle/service/soc_u.h | 200 | hle/service/soc_u.h |
| 193 | hle/service/srv.h | 201 | hle/service/srv.h |
| 194 | hle/service/ssl_c.h | 202 | hle/service/ssl_c.h |
| 195 | hle/service/y2r_u.h | 203 | hle/service/y2r_u.h |
| 196 | hle/config_mem.h | ||
| 197 | hle/result.h | ||
| 198 | hle/function_wrappers.h | ||
| 199 | hle/hle.h | ||
| 200 | hle/shared_page.h | 204 | hle/shared_page.h |
| 201 | hle/svc.h | 205 | hle/svc.h |
| 202 | hw/gpu.h | 206 | hw/gpu.h |
| 203 | hw/hw.h | 207 | hw/hw.h |
| 204 | hw/lcd.h | 208 | hw/lcd.h |
| 209 | loader/3dsx.h | ||
| 205 | loader/elf.h | 210 | loader/elf.h |
| 206 | loader/loader.h | 211 | loader/loader.h |
| 207 | loader/ncch.h | 212 | loader/ncch.h |
| 208 | loader/3dsx.h | ||
| 209 | core.h | ||
| 210 | core_timing.h | ||
| 211 | mem_map.h | 213 | mem_map.h |
| 212 | settings.h | 214 | settings.h |
| 213 | system.h | 215 | system.h |
diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp index 12624fa31..8dff51966 100644 --- a/src/core/file_sys/archive_savedata.cpp +++ b/src/core/file_sys/archive_savedata.cpp | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | #include "core/file_sys/archive_savedata.h" | 12 | #include "core/file_sys/archive_savedata.h" |
| 13 | #include "core/file_sys/disk_archive.h" | 13 | #include "core/file_sys/disk_archive.h" |
| 14 | #include "core/hle/kernel/process.h" | ||
| 14 | #include "core/hle/service/fs/archive.h" | 15 | #include "core/hle/service/fs/archive.h" |
| 15 | #include "core/settings.h" | 16 | #include "core/settings.h" |
| 16 | 17 | ||
| @@ -36,7 +37,7 @@ ArchiveFactory_SaveData::ArchiveFactory_SaveData(const std::string& sdmc_directo | |||
| 36 | } | 37 | } |
| 37 | 38 | ||
| 38 | ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveData::Open(const Path& path) { | 39 | ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveData::Open(const Path& path) { |
| 39 | std::string concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_program_id); | 40 | std::string concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_current_process->program_id); |
| 40 | if (!FileUtil::Exists(concrete_mount_point)) { | 41 | if (!FileUtil::Exists(concrete_mount_point)) { |
| 41 | // When a SaveData archive is created for the first time, it is not yet formatted | 42 | // When a SaveData archive is created for the first time, it is not yet formatted |
| 42 | // and the save file/directory structure expected by the game has not yet been initialized. | 43 | // and the save file/directory structure expected by the game has not yet been initialized. |
| @@ -51,7 +52,7 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveData::Open(const P | |||
| 51 | } | 52 | } |
| 52 | 53 | ||
| 53 | ResultCode ArchiveFactory_SaveData::Format(const Path& path) { | 54 | ResultCode ArchiveFactory_SaveData::Format(const Path& path) { |
| 54 | std::string concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_program_id); | 55 | std::string concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_current_process->program_id); |
| 55 | FileUtil::DeleteDirRecursively(concrete_mount_point); | 56 | FileUtil::DeleteDirRecursively(concrete_mount_point); |
| 56 | FileUtil::CreateFullPath(concrete_mount_point); | 57 | FileUtil::CreateFullPath(concrete_mount_point); |
| 57 | return RESULT_SUCCESS; | 58 | return RESULT_SUCCESS; |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 533fe65fd..a3715e555 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -10,15 +10,14 @@ | |||
| 10 | #include "core/arm/arm_interface.h" | 10 | #include "core/arm/arm_interface.h" |
| 11 | #include "core/core.h" | 11 | #include "core/core.h" |
| 12 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/kernel.h" |
| 13 | #include "core/hle/kernel/process.h" | ||
| 13 | #include "core/hle/kernel/thread.h" | 14 | #include "core/hle/kernel/thread.h" |
| 14 | #include "core/hle/kernel/timer.h" | 15 | #include "core/hle/kernel/timer.h" |
| 15 | 16 | ||
| 16 | namespace Kernel { | 17 | namespace Kernel { |
| 17 | 18 | ||
| 18 | unsigned int Object::next_object_id; | 19 | unsigned int Object::next_object_id; |
| 19 | SharedPtr<Thread> g_main_thread; | ||
| 20 | HandleTable g_handle_table; | 20 | HandleTable g_handle_table; |
| 21 | u64 g_program_id; | ||
| 22 | 21 | ||
| 23 | void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) { | 22 | void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) { |
| 24 | auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); | 23 | auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); |
| @@ -140,8 +139,6 @@ void Init() { | |||
| 140 | Kernel::TimersInit(); | 139 | Kernel::TimersInit(); |
| 141 | 140 | ||
| 142 | Object::next_object_id = 0; | 141 | Object::next_object_id = 0; |
| 143 | g_program_id = 0; | ||
| 144 | g_main_thread = nullptr; | ||
| 145 | } | 142 | } |
| 146 | 143 | ||
| 147 | /// Shutdown the kernel | 144 | /// Shutdown the kernel |
| @@ -149,18 +146,7 @@ void Shutdown() { | |||
| 149 | Kernel::ThreadingShutdown(); | 146 | Kernel::ThreadingShutdown(); |
| 150 | Kernel::TimersShutdown(); | 147 | Kernel::TimersShutdown(); |
| 151 | g_handle_table.Clear(); // Free all kernel objects | 148 | g_handle_table.Clear(); // Free all kernel objects |
| 152 | } | 149 | g_current_process = nullptr; |
| 153 | |||
| 154 | /** | ||
| 155 | * Loads executable stored at specified address | ||
| 156 | * @entry_point Entry point in memory of loaded executable | ||
| 157 | * @return True on success, otherwise false | ||
| 158 | */ | ||
| 159 | bool LoadExec(u32 entry_point) { | ||
| 160 | // 0x30 is the typical main thread priority I've seen used so far | ||
| 161 | g_main_thread = Kernel::SetupMainThread(Kernel::DEFAULT_STACK_SIZE, entry_point, THREADPRIO_DEFAULT); | ||
| 162 | |||
| 163 | return true; | ||
| 164 | } | 150 | } |
| 165 | 151 | ||
| 166 | } // namespace | 152 | } // namespace |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index a7bc6b71a..7c106d37c 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <boost/intrusive_ptr.hpp> | 7 | #include <boost/intrusive_ptr.hpp> |
| 8 | 8 | ||
| 9 | #include <array> | 9 | #include <array> |
| 10 | #include <memory> | ||
| 10 | #include <string> | 11 | #include <string> |
| 11 | #include <vector> | 12 | #include <vector> |
| 12 | 13 | ||
| @@ -15,6 +16,8 @@ | |||
| 15 | #include "core/hle/hle.h" | 16 | #include "core/hle/hle.h" |
| 16 | #include "core/hle/result.h" | 17 | #include "core/hle/result.h" |
| 17 | 18 | ||
| 19 | struct ApplicationInfo; | ||
| 20 | |||
| 18 | namespace Kernel { | 21 | namespace Kernel { |
| 19 | 22 | ||
| 20 | class Thread; | 23 | class Thread; |
| @@ -270,23 +273,10 @@ private: | |||
| 270 | 273 | ||
| 271 | extern HandleTable g_handle_table; | 274 | extern HandleTable g_handle_table; |
| 272 | 275 | ||
| 273 | /// The ID code of the currently running game | ||
| 274 | /// TODO(Subv): This variable should not be here, | ||
| 275 | /// we need a way to store information about the currently loaded application | ||
| 276 | /// for later query during runtime, maybe using the LDR service? | ||
| 277 | extern u64 g_program_id; | ||
| 278 | |||
| 279 | /// Initialize the kernel | 276 | /// Initialize the kernel |
| 280 | void Init(); | 277 | void Init(); |
| 281 | 278 | ||
| 282 | /// Shutdown the kernel | 279 | /// Shutdown the kernel |
| 283 | void Shutdown(); | 280 | void Shutdown(); |
| 284 | 281 | ||
| 285 | /** | ||
| 286 | * Loads executable stored at specified address | ||
| 287 | * @entry_point Entry point in memory of loaded executable | ||
| 288 | * @return True on success, otherwise false | ||
| 289 | */ | ||
| 290 | bool LoadExec(u32 entry_point); | ||
| 291 | |||
| 292 | } // namespace | 282 | } // namespace |
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp new file mode 100644 index 000000000..a444e22e5 --- /dev/null +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | // Copyright 2015 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/assert.h" | ||
| 6 | #include "common/common_funcs.h" | ||
| 7 | #include "common/logging/log.h" | ||
| 8 | |||
| 9 | #include "core/hle/kernel/process.h" | ||
| 10 | #include "core/hle/kernel/thread.h" | ||
| 11 | #include "core/mem_map.h" | ||
| 12 | |||
| 13 | namespace Kernel { | ||
| 14 | |||
| 15 | SharedPtr<Process> Process::Create(std::string name, u64 program_id) { | ||
| 16 | SharedPtr<Process> process(new Process); | ||
| 17 | |||
| 18 | process->name = std::move(name); | ||
| 19 | process->program_id = program_id; | ||
| 20 | |||
| 21 | process->flags.raw = 0; | ||
| 22 | process->flags.memory_region = MemoryRegion::APPLICATION; | ||
| 23 | |||
| 24 | return process; | ||
| 25 | } | ||
| 26 | |||
| 27 | void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { | ||
| 28 | for (int i = 0; i < len; ++i) { | ||
| 29 | u32 descriptor = kernel_caps[i]; | ||
| 30 | u32 type = descriptor >> 20; | ||
| 31 | |||
| 32 | if (descriptor == 0xFFFFFFFF) { | ||
| 33 | // Unused descriptor entry | ||
| 34 | continue; | ||
| 35 | } else if ((type & 0xF00) == 0xE00) { // 0x0FFF | ||
| 36 | // Allowed interrupts list | ||
| 37 | LOG_WARNING(Loader, "ExHeader allowed interrupts list ignored"); | ||
| 38 | } else if ((type & 0xF80) == 0xF00) { // 0x07FF | ||
| 39 | // Allowed syscalls mask | ||
| 40 | unsigned int index = ((descriptor >> 24) & 7) * 24; | ||
| 41 | u32 bits = descriptor & 0xFFFFFF; | ||
| 42 | |||
| 43 | while (bits && index < svc_access_mask.size()) { | ||
| 44 | svc_access_mask.set(index, bits & 1); | ||
| 45 | ++index; bits >>= 1; | ||
| 46 | } | ||
| 47 | } else if ((type & 0xFF0) == 0xFE0) { // 0x00FF | ||
| 48 | // Handle table size | ||
| 49 | handle_table_size = descriptor & 0x3FF; | ||
| 50 | } else if ((type & 0xFF8) == 0xFF0) { // 0x007F | ||
| 51 | // Misc. flags | ||
| 52 | flags.raw = descriptor & 0xFFFF; | ||
| 53 | } else if ((type & 0xFFE) == 0xFF8) { // 0x001F | ||
| 54 | // Mapped memory range | ||
| 55 | if (i+1 >= len || ((kernel_caps[i+1] >> 20) & 0xFFE) != 0xFF8) { | ||
| 56 | LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored."); | ||
| 57 | continue; | ||
| 58 | } | ||
| 59 | u32 end_desc = kernel_caps[i+1]; | ||
| 60 | ++i; // Skip over the second descriptor on the next iteration | ||
| 61 | |||
| 62 | AddressMapping mapping; | ||
| 63 | mapping.address = descriptor << 12; | ||
| 64 | mapping.size = (end_desc << 12) - mapping.address; | ||
| 65 | mapping.writable = descriptor & BIT(20); | ||
| 66 | mapping.unk_flag = end_desc & BIT(20); | ||
| 67 | |||
| 68 | address_mappings.push_back(mapping); | ||
| 69 | } else if ((type & 0xFFF) == 0xFFE) { // 0x000F | ||
| 70 | // Mapped memory page | ||
| 71 | AddressMapping mapping; | ||
| 72 | mapping.address = descriptor << 12; | ||
| 73 | mapping.size = Memory::PAGE_SIZE; | ||
| 74 | mapping.writable = true; // TODO: Not sure if correct | ||
| 75 | mapping.unk_flag = false; | ||
| 76 | } else if ((type & 0xFE0) == 0xFC0) { // 0x01FF | ||
| 77 | // Kernel version | ||
| 78 | int minor = descriptor & 0xFF; | ||
| 79 | int major = (descriptor >> 8) & 0xFF; | ||
| 80 | LOG_INFO(Loader, "ExHeader kernel version ignored: %d.%d", major, minor); | ||
| 81 | } else { | ||
| 82 | LOG_ERROR(Loader, "Unhandled kernel caps descriptor: 0x%08X", descriptor); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | ||
| 88 | Kernel::SetupMainThread(stack_size, entry_point, main_thread_priority); | ||
| 89 | } | ||
| 90 | |||
| 91 | Kernel::Process::Process() {} | ||
| 92 | Kernel::Process::~Process() {} | ||
| 93 | |||
| 94 | SharedPtr<Process> g_current_process; | ||
| 95 | |||
| 96 | } | ||
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h new file mode 100644 index 000000000..88ed9a5a5 --- /dev/null +++ b/src/core/hle/kernel/process.h | |||
| @@ -0,0 +1,90 @@ | |||
| 1 | // Copyright 2015 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <bitset> | ||
| 8 | |||
| 9 | #include <boost/container/static_vector.hpp> | ||
| 10 | |||
| 11 | #include "common/bit_field.h" | ||
| 12 | #include "common/common_types.h" | ||
| 13 | |||
| 14 | #include "core/hle/kernel/kernel.h" | ||
| 15 | #include "core/hle/result.h" | ||
| 16 | |||
| 17 | namespace Kernel { | ||
| 18 | |||
| 19 | struct AddressMapping { | ||
| 20 | // Address and size must be page-aligned | ||
| 21 | VAddr address; | ||
| 22 | u32 size; | ||
| 23 | bool writable; | ||
| 24 | bool unk_flag; | ||
| 25 | }; | ||
| 26 | |||
| 27 | enum class MemoryRegion : u16 { | ||
| 28 | APPLICATION = 1, | ||
| 29 | SYSTEM = 2, | ||
| 30 | BASE = 3, | ||
| 31 | }; | ||
| 32 | |||
| 33 | union ProcessFlags { | ||
| 34 | u16 raw; | ||
| 35 | |||
| 36 | BitField< 0, 1, u16> allow_debug; ///< Allows other processes to attach to and debug this process. | ||
| 37 | BitField< 1, 1, u16> force_debug; ///< Allows this process to attach to processes even if they don't have allow_debug set. | ||
| 38 | BitField< 2, 1, u16> allow_nonalphanum; | ||
| 39 | BitField< 3, 1, u16> shared_page_writable; ///< Shared page is mapped with write permissions. | ||
| 40 | BitField< 4, 1, u16> privileged_priority; ///< Can use priority levels higher than 24. | ||
| 41 | BitField< 5, 1, u16> allow_main_args; | ||
| 42 | BitField< 6, 1, u16> shared_device_mem; | ||
| 43 | BitField< 7, 1, u16> runnable_on_sleep; | ||
| 44 | BitField< 8, 4, MemoryRegion> memory_region; ///< Default region for memory allocations for this process | ||
| 45 | BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000). | ||
| 46 | }; | ||
| 47 | |||
| 48 | class Process final : public Object { | ||
| 49 | public: | ||
| 50 | static SharedPtr<Process> Create(std::string name, u64 program_id); | ||
| 51 | |||
| 52 | std::string GetTypeName() const override { return "Process"; } | ||
| 53 | std::string GetName() const override { return name; } | ||
| 54 | |||
| 55 | static const HandleType HANDLE_TYPE = HandleType::Process; | ||
| 56 | HandleType GetHandleType() const override { return HANDLE_TYPE; } | ||
| 57 | |||
| 58 | /// Name of the process | ||
| 59 | std::string name; | ||
| 60 | /// Title ID corresponding to the process | ||
| 61 | u64 program_id; | ||
| 62 | |||
| 63 | /// The process may only call SVCs which have the corresponding bit set. | ||
| 64 | std::bitset<0x80> svc_access_mask; | ||
| 65 | /// Maximum size of the handle table for the process. | ||
| 66 | unsigned int handle_table_size = 0x200; | ||
| 67 | /// Special memory ranges mapped into this processes address space. This is used to give | ||
| 68 | /// processes access to specific I/O regions and device memory. | ||
| 69 | boost::container::static_vector<AddressMapping, 8> address_mappings; | ||
| 70 | ProcessFlags flags; | ||
| 71 | |||
| 72 | /** | ||
| 73 | * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them | ||
| 74 | * to this process. | ||
| 75 | */ | ||
| 76 | void ParseKernelCaps(const u32* kernel_caps, size_t len); | ||
| 77 | |||
| 78 | /** | ||
| 79 | * Applies address space changes and launches the process main thread. | ||
| 80 | */ | ||
| 81 | void Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size); | ||
| 82 | |||
| 83 | private: | ||
| 84 | Process(); | ||
| 85 | ~Process() override; | ||
| 86 | }; | ||
| 87 | |||
| 88 | extern SharedPtr<Process> g_current_process; | ||
| 89 | |||
| 90 | } | ||
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 233bcbdbd..9958b16e6 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -171,8 +171,6 @@ private: | |||
| 171 | Handle callback_handle; | 171 | Handle callback_handle; |
| 172 | }; | 172 | }; |
| 173 | 173 | ||
| 174 | extern SharedPtr<Thread> g_main_thread; | ||
| 175 | |||
| 176 | /** | 174 | /** |
| 177 | * Sets up the primary application thread | 175 | * Sets up the primary application thread |
| 178 | * @param stack_size The size of the thread's stack | 176 | * @param stack_size The size of the thread's stack |
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index 5d806c5d0..15527c5a6 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp | |||
| @@ -8,9 +8,10 @@ | |||
| 8 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 9 | 9 | ||
| 10 | #include "core/file_sys/archive_romfs.h" | 10 | #include "core/file_sys/archive_romfs.h" |
| 11 | #include "core/hle/kernel/process.h" | ||
| 12 | #include "core/hle/service/fs/archive.h" | ||
| 11 | #include "core/loader/elf.h" | 13 | #include "core/loader/elf.h" |
| 12 | #include "core/loader/ncch.h" | 14 | #include "core/loader/ncch.h" |
| 13 | #include "core/hle/service/fs/archive.h" | ||
| 14 | #include "core/mem_map.h" | 15 | #include "core/mem_map.h" |
| 15 | 16 | ||
| 16 | #include "3dsx.h" | 17 | #include "3dsx.h" |
| @@ -229,8 +230,13 @@ ResultStatus AppLoader_THREEDSX::Load() { | |||
| 229 | if (!file->IsOpen()) | 230 | if (!file->IsOpen()) |
| 230 | return ResultStatus::Error; | 231 | return ResultStatus::Error; |
| 231 | 232 | ||
| 232 | Load3DSXFile(*file, 0x00100000); | 233 | Kernel::g_current_process = Kernel::Process::Create(filename, 0); |
| 233 | Kernel::LoadExec(0x00100000); | 234 | Kernel::g_current_process->svc_access_mask.set(); |
| 235 | Kernel::g_current_process->address_mappings = default_address_mappings; | ||
| 236 | |||
| 237 | Load3DSXFile(*file, Memory::EXEFS_CODE_VADDR); | ||
| 238 | |||
| 239 | Kernel::g_current_process->Run(Memory::EXEFS_CODE_VADDR, 48, Kernel::DEFAULT_STACK_SIZE); | ||
| 234 | 240 | ||
| 235 | is_loaded = true; | 241 | is_loaded = true; |
| 236 | return ResultStatus::Success; | 242 | return ResultStatus::Success; |
diff --git a/src/core/loader/3dsx.h b/src/core/loader/3dsx.h index a11667400..096b3ec20 100644 --- a/src/core/loader/3dsx.h +++ b/src/core/loader/3dsx.h | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <string> | ||
| 8 | |||
| 7 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 8 | #include "core/loader/loader.h" | 10 | #include "core/loader/loader.h" |
| 9 | 11 | ||
| @@ -15,7 +17,8 @@ namespace Loader { | |||
| 15 | /// Loads an 3DSX file | 17 | /// Loads an 3DSX file |
| 16 | class AppLoader_THREEDSX final : public AppLoader { | 18 | class AppLoader_THREEDSX final : public AppLoader { |
| 17 | public: | 19 | public: |
| 18 | AppLoader_THREEDSX(std::unique_ptr<FileUtil::IOFile>&& file) : AppLoader(std::move(file)) { } | 20 | AppLoader_THREEDSX(std::unique_ptr<FileUtil::IOFile>&& file, std::string filename) |
| 21 | : AppLoader(std::move(file)), filename(std::move(filename)) {} | ||
| 19 | 22 | ||
| 20 | /** | 23 | /** |
| 21 | * Returns the type of the file | 24 | * Returns the type of the file |
| @@ -29,6 +32,9 @@ public: | |||
| 29 | * @return ResultStatus result of function | 32 | * @return ResultStatus result of function |
| 30 | */ | 33 | */ |
| 31 | ResultStatus Load() override; | 34 | ResultStatus Load() override; |
| 35 | |||
| 36 | private: | ||
| 37 | std::string filename; | ||
| 32 | }; | 38 | }; |
| 33 | 39 | ||
| 34 | } // namespace Loader | 40 | } // namespace Loader |
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 467e91924..f86a98b8c 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp | |||
| @@ -10,9 +10,9 @@ | |||
| 10 | #include "common/logging/log.h" | 10 | #include "common/logging/log.h" |
| 11 | #include "common/symbols.h" | 11 | #include "common/symbols.h" |
| 12 | 12 | ||
| 13 | #include "core/mem_map.h" | ||
| 14 | #include "core/loader/elf.h" | ||
| 15 | #include "core/hle/kernel/kernel.h" | 13 | #include "core/hle/kernel/kernel.h" |
| 14 | #include "core/loader/elf.h" | ||
| 15 | #include "core/mem_map.h" | ||
| 16 | 16 | ||
| 17 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 17 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 18 | // ELF Header Constants | 18 | // ELF Header Constants |
| @@ -350,9 +350,15 @@ ResultStatus AppLoader_ELF::Load() { | |||
| 350 | if (file->ReadBytes(&buffer[0], size) != size) | 350 | if (file->ReadBytes(&buffer[0], size) != size) |
| 351 | return ResultStatus::Error; | 351 | return ResultStatus::Error; |
| 352 | 352 | ||
| 353 | Kernel::g_current_process = Kernel::Process::Create(filename, 0); | ||
| 354 | Kernel::g_current_process->svc_access_mask.set(); | ||
| 355 | Kernel::g_current_process->address_mappings = default_address_mappings; | ||
| 356 | |||
| 353 | ElfReader elf_reader(&buffer[0]); | 357 | ElfReader elf_reader(&buffer[0]); |
| 354 | elf_reader.LoadInto(0x00100000); | 358 | elf_reader.LoadInto(Memory::EXEFS_CODE_VADDR); |
| 355 | Kernel::LoadExec(elf_reader.GetEntryPoint()); | 359 | // TODO: Fill application title |
| 360 | |||
| 361 | Kernel::g_current_process->Run(elf_reader.GetEntryPoint(), 48, Kernel::DEFAULT_STACK_SIZE); | ||
| 356 | 362 | ||
| 357 | is_loaded = true; | 363 | is_loaded = true; |
| 358 | return ResultStatus::Success; | 364 | return ResultStatus::Success; |
diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h index b6e6651f5..32841606a 100644 --- a/src/core/loader/elf.h +++ b/src/core/loader/elf.h | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <string> | ||
| 8 | |||
| 7 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 8 | #include "core/loader/loader.h" | 10 | #include "core/loader/loader.h" |
| 9 | 11 | ||
| @@ -15,7 +17,8 @@ namespace Loader { | |||
| 15 | /// Loads an ELF/AXF file | 17 | /// Loads an ELF/AXF file |
| 16 | class AppLoader_ELF final : public AppLoader { | 18 | class AppLoader_ELF final : public AppLoader { |
| 17 | public: | 19 | public: |
| 18 | AppLoader_ELF(std::unique_ptr<FileUtil::IOFile>&& file) : AppLoader(std::move(file)) { } | 20 | AppLoader_ELF(std::unique_ptr<FileUtil::IOFile>&& file, std::string filename) |
| 21 | : AppLoader(std::move(file)), filename(std::move(filename)) { } | ||
| 19 | 22 | ||
| 20 | /** | 23 | /** |
| 21 | * Returns the type of the file | 24 | * Returns the type of the file |
| @@ -29,6 +32,9 @@ public: | |||
| 29 | * @return ResultStatus result of function | 32 | * @return ResultStatus result of function |
| 30 | */ | 33 | */ |
| 31 | ResultStatus Load() override; | 34 | ResultStatus Load() override; |
| 35 | |||
| 36 | private: | ||
| 37 | std::string filename; | ||
| 32 | }; | 38 | }; |
| 33 | 39 | ||
| 34 | } // namespace Loader | 40 | } // namespace Loader |
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index de0ab540a..505e2d280 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp | |||
| @@ -8,16 +8,23 @@ | |||
| 8 | #include "common/make_unique.h" | 8 | #include "common/make_unique.h" |
| 9 | 9 | ||
| 10 | #include "core/file_sys/archive_romfs.h" | 10 | #include "core/file_sys/archive_romfs.h" |
| 11 | #include "core/hle/kernel/process.h" | ||
| 12 | #include "core/hle/service/fs/archive.h" | ||
| 11 | #include "core/loader/3dsx.h" | 13 | #include "core/loader/3dsx.h" |
| 12 | #include "core/loader/elf.h" | 14 | #include "core/loader/elf.h" |
| 13 | #include "core/loader/ncch.h" | 15 | #include "core/loader/ncch.h" |
| 14 | #include "core/hle/service/fs/archive.h" | ||
| 15 | #include "core/mem_map.h" | 16 | #include "core/mem_map.h" |
| 16 | 17 | ||
| 17 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 18 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 18 | 19 | ||
| 19 | namespace Loader { | 20 | namespace Loader { |
| 20 | 21 | ||
| 22 | const std::initializer_list<Kernel::AddressMapping> default_address_mappings = { | ||
| 23 | { 0x1FF50000, 0x8000, true }, // part of DSP RAM | ||
| 24 | { 0x1FF70000, 0x8000, true }, // part of DSP RAM | ||
| 25 | { 0x1F000000, 0x600000, false }, // entire VRAM | ||
| 26 | }; | ||
| 27 | |||
| 21 | /** | 28 | /** |
| 22 | * Identifies the type of a bootable file | 29 | * Identifies the type of a bootable file |
| 23 | * @param file open file | 30 | * @param file open file |
| @@ -42,19 +49,11 @@ static FileType IdentifyFile(FileUtil::IOFile& file) { | |||
| 42 | 49 | ||
| 43 | /** | 50 | /** |
| 44 | * Guess the type of a bootable file from its extension | 51 | * Guess the type of a bootable file from its extension |
| 45 | * @param filename String filename of bootable file | 52 | * @param extension String extension of bootable file |
| 46 | * @return FileType of file | 53 | * @return FileType of file |
| 47 | */ | 54 | */ |
| 48 | static FileType GuessFromFilename(const std::string& filename) { | 55 | static FileType GuessFromExtension(const std::string& extension_) { |
| 49 | if (filename.size() == 0) { | 56 | std::string extension = Common::ToLower(extension_); |
| 50 | LOG_ERROR(Loader, "invalid filename %s", filename.c_str()); | ||
| 51 | return FileType::Error; | ||
| 52 | } | ||
| 53 | |||
| 54 | size_t extension_loc = filename.find_last_of('.'); | ||
| 55 | if (extension_loc == std::string::npos) | ||
| 56 | return FileType::Unknown; | ||
| 57 | std::string extension = Common::ToLower(filename.substr(extension_loc)); | ||
| 58 | 57 | ||
| 59 | if (extension == ".elf") | 58 | if (extension == ".elf") |
| 60 | return FileType::ELF; | 59 | return FileType::ELF; |
| @@ -100,8 +99,11 @@ ResultStatus LoadFile(const std::string& filename) { | |||
| 100 | return ResultStatus::Error; | 99 | return ResultStatus::Error; |
| 101 | } | 100 | } |
| 102 | 101 | ||
| 102 | std::string filename_filename, filename_extension; | ||
| 103 | Common::SplitPath(filename, nullptr, &filename_filename, &filename_extension); | ||
| 104 | |||
| 103 | FileType type = IdentifyFile(*file); | 105 | FileType type = IdentifyFile(*file); |
| 104 | FileType filename_type = GuessFromFilename(filename); | 106 | FileType filename_type = GuessFromExtension(filename_extension); |
| 105 | 107 | ||
| 106 | if (type != filename_type) { | 108 | if (type != filename_type) { |
| 107 | LOG_WARNING(Loader, "File %s has a different type than its extension.", filename.c_str()); | 109 | LOG_WARNING(Loader, "File %s has a different type than its extension.", filename.c_str()); |
| @@ -115,11 +117,11 @@ ResultStatus LoadFile(const std::string& filename) { | |||
| 115 | 117 | ||
| 116 | //3DSX file format... | 118 | //3DSX file format... |
| 117 | case FileType::THREEDSX: | 119 | case FileType::THREEDSX: |
| 118 | return AppLoader_THREEDSX(std::move(file)).Load(); | 120 | return AppLoader_THREEDSX(std::move(file), filename_filename).Load(); |
| 119 | 121 | ||
| 120 | // Standard ELF file format... | 122 | // Standard ELF file format... |
| 121 | case FileType::ELF: | 123 | case FileType::ELF: |
| 122 | return AppLoader_ELF(std::move(file)).Load(); | 124 | return AppLoader_ELF(std::move(file), filename_filename).Load(); |
| 123 | 125 | ||
| 124 | // NCCH/NCSD container formats... | 126 | // NCCH/NCSD container formats... |
| 125 | case FileType::CXI: | 127 | case FileType::CXI: |
| @@ -129,7 +131,6 @@ ResultStatus LoadFile(const std::string& filename) { | |||
| 129 | 131 | ||
| 130 | // Load application and RomFS | 132 | // Load application and RomFS |
| 131 | if (ResultStatus::Success == app_loader.Load()) { | 133 | if (ResultStatus::Success == app_loader.Load()) { |
| 132 | Kernel::g_program_id = app_loader.GetProgramId(); | ||
| 133 | Service::FS::RegisterArchiveType(Common::make_unique<FileSys::ArchiveFactory_RomFS>(app_loader), Service::FS::ArchiveIdCode::RomFS); | 134 | Service::FS::RegisterArchiveType(Common::make_unique<FileSys::ArchiveFactory_RomFS>(app_loader), Service::FS::ArchiveIdCode::RomFS); |
| 134 | return ResultStatus::Success; | 135 | return ResultStatus::Success; |
| 135 | } | 136 | } |
| @@ -139,11 +140,15 @@ ResultStatus LoadFile(const std::string& filename) { | |||
| 139 | // Raw BIN file format... | 140 | // Raw BIN file format... |
| 140 | case FileType::BIN: | 141 | case FileType::BIN: |
| 141 | { | 142 | { |
| 143 | Kernel::g_current_process = Kernel::Process::Create(filename_filename, 0); | ||
| 144 | Kernel::g_current_process->svc_access_mask.set(); | ||
| 145 | Kernel::g_current_process->address_mappings = default_address_mappings; | ||
| 146 | |||
| 142 | size_t size = (size_t)file->GetSize(); | 147 | size_t size = (size_t)file->GetSize(); |
| 143 | if (file->ReadBytes(Memory::GetPointer(Memory::EXEFS_CODE_VADDR), size) != size) | 148 | if (file->ReadBytes(Memory::GetPointer(Memory::EXEFS_CODE_VADDR), size) != size) |
| 144 | return ResultStatus::Error; | 149 | return ResultStatus::Error; |
| 145 | 150 | ||
| 146 | Kernel::LoadExec(Memory::EXEFS_CODE_VADDR); | 151 | Kernel::g_current_process->Run(Memory::EXEFS_CODE_VADDR, 0x30, Kernel::DEFAULT_STACK_SIZE); |
| 147 | return ResultStatus::Success; | 152 | return ResultStatus::Success; |
| 148 | } | 153 | } |
| 149 | 154 | ||
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 2b87239cf..a56f67205 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h | |||
| @@ -9,6 +9,8 @@ | |||
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "common/file_util.h" | 10 | #include "common/file_util.h" |
| 11 | 11 | ||
| 12 | #include "core/hle/kernel/process.h" | ||
| 13 | |||
| 12 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 14 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 13 | // Loader namespace | 15 | // Loader namespace |
| 14 | 16 | ||
| @@ -105,6 +107,12 @@ protected: | |||
| 105 | }; | 107 | }; |
| 106 | 108 | ||
| 107 | /** | 109 | /** |
| 110 | * Common address mappings found in most games, used for binary formats that don't have this | ||
| 111 | * information. | ||
| 112 | */ | ||
| 113 | extern const std::initializer_list<Kernel::AddressMapping> default_address_mappings; | ||
| 114 | |||
| 115 | /** | ||
| 108 | * Identifies and loads a bootable file | 116 | * Identifies and loads a bootable file |
| 109 | * @param filename String filename of bootable file | 117 | * @param filename String filename of bootable file |
| 110 | * @return ResultStatus result of function | 118 | * @return ResultStatus result of function |
diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index 9bce2b79d..0e2db2fbb 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp | |||
| @@ -5,9 +5,12 @@ | |||
| 5 | #include <memory> | 5 | #include <memory> |
| 6 | 6 | ||
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "common/make_unique.h" | ||
| 9 | #include "common/string_util.h" | ||
| 10 | #include "common/swap.h" | ||
| 8 | 11 | ||
| 9 | #include "core/loader/ncch.h" | ||
| 10 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/kernel.h" |
| 13 | #include "core/loader/ncch.h" | ||
| 11 | #include "core/mem_map.h" | 14 | #include "core/mem_map.h" |
| 12 | 15 | ||
| 13 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 16 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| @@ -117,8 +120,21 @@ ResultStatus AppLoader_NCCH::LoadExec() const { | |||
| 117 | 120 | ||
| 118 | std::vector<u8> code; | 121 | std::vector<u8> code; |
| 119 | if (ResultStatus::Success == ReadCode(code)) { | 122 | if (ResultStatus::Success == ReadCode(code)) { |
| 123 | std::string process_name = Common::StringFromFixedZeroTerminatedBuffer( | ||
| 124 | (const char*)exheader_header.codeset_info.name, 8); | ||
| 125 | u64 program_id = *reinterpret_cast<u64_le const*>(&ncch_header.program_id[0]); | ||
| 126 | Kernel::g_current_process = Kernel::Process::Create(process_name, program_id); | ||
| 127 | |||
| 128 | // Copy data while converting endianess | ||
| 129 | std::array<u32, ARRAY_SIZE(exheader_header.arm11_kernel_caps.descriptors)> kernel_caps; | ||
| 130 | std::copy_n(exheader_header.arm11_kernel_caps.descriptors, kernel_caps.size(), begin(kernel_caps)); | ||
| 131 | Kernel::g_current_process->ParseKernelCaps(kernel_caps.data(), kernel_caps.size()); | ||
| 132 | |||
| 120 | Memory::WriteBlock(entry_point, &code[0], code.size()); | 133 | Memory::WriteBlock(entry_point, &code[0], code.size()); |
| 121 | Kernel::LoadExec(entry_point); | 134 | |
| 135 | s32 priority = exheader_header.arm11_system_local_caps.priority; | ||
| 136 | u32 stack_size = exheader_header.codeset_info.stack_size; | ||
| 137 | Kernel::g_current_process->Run(entry_point, priority, stack_size); | ||
| 122 | return ResultStatus::Success; | 138 | return ResultStatus::Success; |
| 123 | } | 139 | } |
| 124 | return ResultStatus::Error; | 140 | return ResultStatus::Error; |
| @@ -277,8 +293,4 @@ ResultStatus AppLoader_NCCH::ReadRomFS(std::vector<u8>& buffer) const { | |||
| 277 | return ResultStatus::ErrorNotUsed; | 293 | return ResultStatus::ErrorNotUsed; |
| 278 | } | 294 | } |
| 279 | 295 | ||
| 280 | u64 AppLoader_NCCH::GetProgramId() const { | ||
| 281 | return *reinterpret_cast<u64 const*>(&ncch_header.program_id[0]); | ||
| 282 | } | ||
| 283 | |||
| 284 | } // namespace Loader | 296 | } // namespace Loader |
diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h index 44c72a4e2..29e39d2c0 100644 --- a/src/core/loader/ncch.h +++ b/src/core/loader/ncch.h | |||
| @@ -6,7 +6,9 @@ | |||
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | 8 | ||
| 9 | #include "common/bit_field.h" | ||
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "common/swap.h" | ||
| 10 | 12 | ||
| 11 | #include "core/loader/loader.h" | 13 | #include "core/loader/loader.h" |
| 12 | 14 | ||
| @@ -65,13 +67,13 @@ struct ExeFs_Header { | |||
| 65 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 67 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 66 | // ExHeader (executable file system header) headers | 68 | // ExHeader (executable file system header) headers |
| 67 | 69 | ||
| 68 | struct ExHeader_SystemInfoFlags{ | 70 | struct ExHeader_SystemInfoFlags { |
| 69 | u8 reserved[5]; | 71 | u8 reserved[5]; |
| 70 | u8 flag; | 72 | u8 flag; |
| 71 | u8 remaster_version[2]; | 73 | u8 remaster_version[2]; |
| 72 | }; | 74 | }; |
| 73 | 75 | ||
| 74 | struct ExHeader_CodeSegmentInfo{ | 76 | struct ExHeader_CodeSegmentInfo { |
| 75 | u32 address; | 77 | u32 address; |
| 76 | u32 num_max_pages; | 78 | u32 num_max_pages; |
| 77 | u32 code_size; | 79 | u32 code_size; |
| @@ -88,17 +90,17 @@ struct ExHeader_CodeSetInfo { | |||
| 88 | u32 bss_size; | 90 | u32 bss_size; |
| 89 | }; | 91 | }; |
| 90 | 92 | ||
| 91 | struct ExHeader_DependencyList{ | 93 | struct ExHeader_DependencyList { |
| 92 | u8 program_id[0x30][8]; | 94 | u8 program_id[0x30][8]; |
| 93 | }; | 95 | }; |
| 94 | 96 | ||
| 95 | struct ExHeader_SystemInfo{ | 97 | struct ExHeader_SystemInfo { |
| 96 | u64 save_data_size; | 98 | u64 save_data_size; |
| 97 | u8 jump_id[8]; | 99 | u8 jump_id[8]; |
| 98 | u8 reserved_2[0x30]; | 100 | u8 reserved_2[0x30]; |
| 99 | }; | 101 | }; |
| 100 | 102 | ||
| 101 | struct ExHeader_StorageInfo{ | 103 | struct ExHeader_StorageInfo { |
| 102 | u8 ext_save_data_id[8]; | 104 | u8 ext_save_data_id[8]; |
| 103 | u8 system_save_data_id[8]; | 105 | u8 system_save_data_id[8]; |
| 104 | u8 reserved[8]; | 106 | u8 reserved[8]; |
| @@ -106,10 +108,16 @@ struct ExHeader_StorageInfo{ | |||
| 106 | u8 other_attributes; | 108 | u8 other_attributes; |
| 107 | }; | 109 | }; |
| 108 | 110 | ||
| 109 | struct ExHeader_ARM11_SystemLocalCaps{ | 111 | struct ExHeader_ARM11_SystemLocalCaps { |
| 110 | u8 program_id[8]; | 112 | u8 program_id[8]; |
| 111 | u32 core_version; | 113 | u32 core_version; |
| 112 | u8 flags[3]; | 114 | u8 reserved_flags[2]; |
| 115 | union { | ||
| 116 | u8 flags0; | ||
| 117 | BitField<0, 2, u8> ideal_processor; | ||
| 118 | BitField<2, 2, u8> affinity_mask; | ||
| 119 | BitField<4, 4, u8> system_mode; | ||
| 120 | }; | ||
| 113 | u8 priority; | 121 | u8 priority; |
| 114 | u8 resource_limit_descriptor[0x10][2]; | 122 | u8 resource_limit_descriptor[0x10][2]; |
| 115 | ExHeader_StorageInfo storage_info; | 123 | ExHeader_StorageInfo storage_info; |
| @@ -119,17 +127,17 @@ struct ExHeader_ARM11_SystemLocalCaps{ | |||
| 119 | u8 resource_limit_category; | 127 | u8 resource_limit_category; |
| 120 | }; | 128 | }; |
| 121 | 129 | ||
| 122 | struct ExHeader_ARM11_KernelCaps{ | 130 | struct ExHeader_ARM11_KernelCaps { |
| 123 | u8 descriptors[28][4]; | 131 | u32_le descriptors[28]; |
| 124 | u8 reserved[0x10]; | 132 | u8 reserved[0x10]; |
| 125 | }; | 133 | }; |
| 126 | 134 | ||
| 127 | struct ExHeader_ARM9_AccessControl{ | 135 | struct ExHeader_ARM9_AccessControl { |
| 128 | u8 descriptors[15]; | 136 | u8 descriptors[15]; |
| 129 | u8 descversion; | 137 | u8 descversion; |
| 130 | }; | 138 | }; |
| 131 | 139 | ||
| 132 | struct ExHeader_Header{ | 140 | struct ExHeader_Header { |
| 133 | ExHeader_CodeSetInfo codeset_info; | 141 | ExHeader_CodeSetInfo codeset_info; |
| 134 | ExHeader_DependencyList dependency_list; | 142 | ExHeader_DependencyList dependency_list; |
| 135 | ExHeader_SystemInfo system_info; | 143 | ExHeader_SystemInfo system_info; |
| @@ -205,12 +213,6 @@ public: | |||
| 205 | */ | 213 | */ |
| 206 | ResultStatus ReadRomFS(std::vector<u8>& buffer) const override; | 214 | ResultStatus ReadRomFS(std::vector<u8>& buffer) const override; |
| 207 | 215 | ||
| 208 | /* | ||
| 209 | * Gets the program id from the NCCH header | ||
| 210 | * @return u64 Program id | ||
| 211 | */ | ||
| 212 | u64 GetProgramId() const; | ||
| 213 | |||
| 214 | private: | 216 | private: |
| 215 | 217 | ||
| 216 | /** | 218 | /** |
diff --git a/src/core/mem_map.h b/src/core/mem_map.h index 1fb77c94a..fb582d65a 100644 --- a/src/core/mem_map.h +++ b/src/core/mem_map.h | |||
| @@ -10,6 +10,8 @@ namespace Memory { | |||
| 10 | 10 | ||
| 11 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 11 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 12 | 12 | ||
| 13 | const u32 PAGE_SIZE = 0x1000; | ||
| 14 | |||
| 13 | enum : u32 { | 15 | enum : u32 { |
| 14 | BOOTROM_SIZE = 0x00010000, ///< Bootrom (super secret code/data @ 0x8000) size | 16 | BOOTROM_SIZE = 0x00010000, ///< Bootrom (super secret code/data @ 0x8000) size |
| 15 | BOOTROM_PADDR = 0x00000000, ///< Bootrom physical address | 17 | BOOTROM_PADDR = 0x00000000, ///< Bootrom physical address |