summaryrefslogtreecommitdiffstats
path: root/src/core/hle
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2015-05-09 03:20:37 +0200
committerbunnei <bunneidev@gmail.com>2015-05-09 03:20:37 +0200
commit917ac23dfcab37c65e11e3413e397863bd4bc000 (patch)
tree956ca5d1a4aad3383c4a3bfc9103476abe3f1987 /src/core/hle
parentMerge pull request #728 from lioncash/vars (diff)
parentKernel: Remove unused g_main_thread variable (diff)
downloadyuzu-917ac23dfcab37c65e11e3413e397863bd4bc000.tar
yuzu-917ac23dfcab37c65e11e3413e397863bd4bc000.tar.gz
yuzu-917ac23dfcab37c65e11e3413e397863bd4bc000.tar.bz2
yuzu-917ac23dfcab37c65e11e3413e397863bd4bc000.tar.lz
yuzu-917ac23dfcab37c65e11e3413e397863bd4bc000.tar.xz
yuzu-917ac23dfcab37c65e11e3413e397863bd4bc000.tar.zst
yuzu-917ac23dfcab37c65e11e3413e397863bd4bc000.zip
Diffstat (limited to 'src/core/hle')
-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 @@
#include "core/arm/arm_interface.h"
#include "core/core.h"
#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/process.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/timer.h"
namespace Kernel {
unsigned int Object::next_object_id;
-SharedPtr<Thread> g_main_thread;
HandleTable g_handle_table;
-u64 g_program_id;
void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) {
auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
@@ -140,8 +139,6 @@ void Init() {
Kernel::TimersInit();
Object::next_object_id = 0;
- g_program_id = 0;
- g_main_thread = nullptr;
}
/// Shutdown the kernel
@@ -149,18 +146,7 @@ void Shutdown() {
Kernel::ThreadingShutdown();
Kernel::TimersShutdown();
g_handle_table.Clear(); // Free all kernel objects
-}
-
-/**
- * Loads executable stored at specified address
- * @entry_point Entry point in memory of loaded executable
- * @return True on success, otherwise false
- */
-bool LoadExec(u32 entry_point) {
- // 0x30 is the typical main thread priority I've seen used so far
- g_main_thread = Kernel::SetupMainThread(Kernel::DEFAULT_STACK_SIZE, entry_point, THREADPRIO_DEFAULT);
-
- return true;
+ g_current_process = nullptr;
}
} // 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 @@
#include <boost/intrusive_ptr.hpp>
#include <array>
+#include <memory>
#include <string>
#include <vector>
@@ -15,6 +16,8 @@
#include "core/hle/hle.h"
#include "core/hle/result.h"
+struct ApplicationInfo;
+
namespace Kernel {
class Thread;
@@ -270,23 +273,10 @@ private:
extern HandleTable g_handle_table;
-/// The ID code of the currently running game
-/// TODO(Subv): This variable should not be here,
-/// we need a way to store information about the currently loaded application
-/// for later query during runtime, maybe using the LDR service?
-extern u64 g_program_id;
-
/// Initialize the kernel
void Init();
/// Shutdown the kernel
void Shutdown();
-/**
- * Loads executable stored at specified address
- * @entry_point Entry point in memory of loaded executable
- * @return True on success, otherwise false
- */
-bool LoadExec(u32 entry_point);
-
} // 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 @@
+// Copyright 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/assert.h"
+#include "common/common_funcs.h"
+#include "common/logging/log.h"
+
+#include "core/hle/kernel/process.h"
+#include "core/hle/kernel/thread.h"
+#include "core/mem_map.h"
+
+namespace Kernel {
+
+SharedPtr<Process> Process::Create(std::string name, u64 program_id) {
+ SharedPtr<Process> process(new Process);
+
+ process->name = std::move(name);
+ process->program_id = program_id;
+
+ process->flags.raw = 0;
+ process->flags.memory_region = MemoryRegion::APPLICATION;
+
+ return process;
+}
+
+void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
+ for (int i = 0; i < len; ++i) {
+ u32 descriptor = kernel_caps[i];
+ u32 type = descriptor >> 20;
+
+ if (descriptor == 0xFFFFFFFF) {
+ // Unused descriptor entry
+ continue;
+ } else if ((type & 0xF00) == 0xE00) { // 0x0FFF
+ // Allowed interrupts list
+ LOG_WARNING(Loader, "ExHeader allowed interrupts list ignored");
+ } else if ((type & 0xF80) == 0xF00) { // 0x07FF
+ // Allowed syscalls mask
+ unsigned int index = ((descriptor >> 24) & 7) * 24;
+ u32 bits = descriptor & 0xFFFFFF;
+
+ while (bits && index < svc_access_mask.size()) {
+ svc_access_mask.set(index, bits & 1);
+ ++index; bits >>= 1;
+ }
+ } else if ((type & 0xFF0) == 0xFE0) { // 0x00FF
+ // Handle table size
+ handle_table_size = descriptor & 0x3FF;
+ } else if ((type & 0xFF8) == 0xFF0) { // 0x007F
+ // Misc. flags
+ flags.raw = descriptor & 0xFFFF;
+ } else if ((type & 0xFFE) == 0xFF8) { // 0x001F
+ // Mapped memory range
+ if (i+1 >= len || ((kernel_caps[i+1] >> 20) & 0xFFE) != 0xFF8) {
+ LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored.");
+ continue;
+ }
+ u32 end_desc = kernel_caps[i+1];
+ ++i; // Skip over the second descriptor on the next iteration
+
+ AddressMapping mapping;
+ mapping.address = descriptor << 12;
+ mapping.size = (end_desc << 12) - mapping.address;
+ mapping.writable = descriptor & BIT(20);
+ mapping.unk_flag = end_desc & BIT(20);
+
+ address_mappings.push_back(mapping);
+ } else if ((type & 0xFFF) == 0xFFE) { // 0x000F
+ // Mapped memory page
+ AddressMapping mapping;
+ mapping.address = descriptor << 12;
+ mapping.size = Memory::PAGE_SIZE;
+ mapping.writable = true; // TODO: Not sure if correct
+ mapping.unk_flag = false;
+ } else if ((type & 0xFE0) == 0xFC0) { // 0x01FF
+ // Kernel version
+ int minor = descriptor & 0xFF;
+ int major = (descriptor >> 8) & 0xFF;
+ LOG_INFO(Loader, "ExHeader kernel version ignored: %d.%d", major, minor);
+ } else {
+ LOG_ERROR(Loader, "Unhandled kernel caps descriptor: 0x%08X", descriptor);
+ }
+ }
+}
+
+void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
+ Kernel::SetupMainThread(stack_size, entry_point, main_thread_priority);
+}
+
+Kernel::Process::Process() {}
+Kernel::Process::~Process() {}
+
+SharedPtr<Process> g_current_process;
+
+}
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 @@
+// Copyright 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <bitset>
+
+#include <boost/container/static_vector.hpp>
+
+#include "common/bit_field.h"
+#include "common/common_types.h"
+
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/result.h"
+
+namespace Kernel {
+
+struct AddressMapping {
+ // Address and size must be page-aligned
+ VAddr address;
+ u32 size;
+ bool writable;
+ bool unk_flag;
+};
+
+enum class MemoryRegion : u16 {
+ APPLICATION = 1,
+ SYSTEM = 2,
+ BASE = 3,
+};
+
+union ProcessFlags {
+ u16 raw;
+
+ BitField< 0, 1, u16> allow_debug; ///< Allows other processes to attach to and debug this process.
+ BitField< 1, 1, u16> force_debug; ///< Allows this process to attach to processes even if they don't have allow_debug set.
+ BitField< 2, 1, u16> allow_nonalphanum;
+ BitField< 3, 1, u16> shared_page_writable; ///< Shared page is mapped with write permissions.
+ BitField< 4, 1, u16> privileged_priority; ///< Can use priority levels higher than 24.
+ BitField< 5, 1, u16> allow_main_args;
+ BitField< 6, 1, u16> shared_device_mem;
+ BitField< 7, 1, u16> runnable_on_sleep;
+ BitField< 8, 4, MemoryRegion> memory_region; ///< Default region for memory allocations for this process
+ BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000).
+};
+
+class Process final : public Object {
+public:
+ static SharedPtr<Process> Create(std::string name, u64 program_id);
+
+ std::string GetTypeName() const override { return "Process"; }
+ std::string GetName() const override { return name; }
+
+ static const HandleType HANDLE_TYPE = HandleType::Process;
+ HandleType GetHandleType() const override { return HANDLE_TYPE; }
+
+ /// Name of the process
+ std::string name;
+ /// Title ID corresponding to the process
+ u64 program_id;
+
+ /// The process may only call SVCs which have the corresponding bit set.
+ std::bitset<0x80> svc_access_mask;
+ /// Maximum size of the handle table for the process.
+ unsigned int handle_table_size = 0x200;
+ /// Special memory ranges mapped into this processes address space. This is used to give
+ /// processes access to specific I/O regions and device memory.
+ boost::container::static_vector<AddressMapping, 8> address_mappings;
+ ProcessFlags flags;
+
+ /**
+ * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them
+ * to this process.
+ */
+ void ParseKernelCaps(const u32* kernel_caps, size_t len);
+
+ /**
+ * Applies address space changes and launches the process main thread.
+ */
+ void Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size);
+
+private:
+ Process();
+ ~Process() override;
+};
+
+extern SharedPtr<Process> g_current_process;
+
+}
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:
Handle callback_handle;
};
-extern SharedPtr<Thread> g_main_thread;
-
/**
* Sets up the primary application thread
* @param stack_size The size of the thread's stack