summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar bunnei2015-05-08 21:20:37 -0400
committerGravatar bunnei2015-05-08 21:20:37 -0400
commit917ac23dfcab37c65e11e3413e397863bd4bc000 (patch)
tree956ca5d1a4aad3383c4a3bfc9103476abe3f1987 /src/core/hle/kernel
parentMerge pull request #728 from lioncash/vars (diff)
parentKernel: Remove unused g_main_thread variable (diff)
downloadyuzu-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/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/kernel.cpp18
-rw-r--r--src/core/hle/kernel/kernel.h16
-rw-r--r--src/core/hle/kernel/process.cpp96
-rw-r--r--src/core/hle/kernel/process.h90
-rw-r--r--src/core/hle/kernel/thread.h2
5 files changed, 191 insertions, 31 deletions
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
16namespace Kernel { 17namespace Kernel {
17 18
18unsigned int Object::next_object_id; 19unsigned int Object::next_object_id;
19SharedPtr<Thread> g_main_thread;
20HandleTable g_handle_table; 20HandleTable g_handle_table;
21u64 g_program_id;
22 21
23void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) { 22void 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 */
159bool 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
19struct ApplicationInfo;
20
18namespace Kernel { 21namespace Kernel {
19 22
20class Thread; 23class Thread;
@@ -270,23 +273,10 @@ private:
270 273
271extern HandleTable g_handle_table; 274extern 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?
277extern u64 g_program_id;
278
279/// Initialize the kernel 276/// Initialize the kernel
280void Init(); 277void Init();
281 278
282/// Shutdown the kernel 279/// Shutdown the kernel
283void Shutdown(); 280void 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 */
290bool 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
13namespace Kernel {
14
15SharedPtr<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
27void 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
87void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
88 Kernel::SetupMainThread(stack_size, entry_point, main_thread_priority);
89}
90
91Kernel::Process::Process() {}
92Kernel::Process::~Process() {}
93
94SharedPtr<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
17namespace Kernel {
18
19struct AddressMapping {
20 // Address and size must be page-aligned
21 VAddr address;
22 u32 size;
23 bool writable;
24 bool unk_flag;
25};
26
27enum class MemoryRegion : u16 {
28 APPLICATION = 1,
29 SYSTEM = 2,
30 BASE = 3,
31};
32
33union 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
48class Process final : public Object {
49public:
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
83private:
84 Process();
85 ~Process() override;
86};
87
88extern 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
174extern 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