summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/core.cpp4
-rw-r--r--src/core/hle/kernel/session.h10
-rw-r--r--src/core/hle/kernel/thread.cpp11
-rw-r--r--src/core/hle/kernel/thread.h8
4 files changed, 26 insertions, 7 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index bb2ed7a92..b5c258230 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -61,10 +61,6 @@ int Init() {
61 g_sys_core = new ARM_DynCom(USER32MODE); 61 g_sys_core = new ARM_DynCom(USER32MODE);
62 g_app_core = new ARM_DynCom(USER32MODE); 62 g_app_core = new ARM_DynCom(USER32MODE);
63 63
64 // TODO: Whenever TLS is implemented, this should contain
65 // the address of the 0x200-byte TLS
66 g_app_core->SetCP15Register(CP15_THREAD_URO, Memory::TLS_AREA_VADDR);
67
68 LOG_DEBUG(Core, "Initialized OK"); 64 LOG_DEBUG(Core, "Initialized OK");
69 return 0; 65 return 0;
70} 66}
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h
index 0fd18148a..8c3886ffd 100644
--- a/src/core/hle/kernel/session.h
+++ b/src/core/hle/kernel/session.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include "core/hle/kernel/kernel.h" 7#include "core/hle/kernel/kernel.h"
8#include "core/hle/kernel/thread.h"
8#include "core/mem_map.h" 9#include "core/mem_map.h"
9 10
10namespace Kernel { 11namespace Kernel {
@@ -12,12 +13,15 @@ namespace Kernel {
12static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header 13static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header
13 14
14/** 15/**
15 * Returns a pointer to the command buffer in kernel memory 16 * Returns a pointer to the command buffer in the current thread's TLS
17 * TODO(Subv): This is not entirely correct, the command buffer should be copied from
18 * the thread's TLS to an intermediate buffer in kernel memory, and then copied again to
19 * the service handler process' memory.
16 * @param offset Optional offset into command buffer 20 * @param offset Optional offset into command buffer
17 * @return Pointer to command buffer 21 * @return Pointer to command buffer
18 */ 22 */
19inline static u32* GetCommandBuffer(const int offset=0) { 23inline static u32* GetCommandBuffer(const int offset = 0) {
20 return (u32*)Memory::GetPointer(Memory::TLS_AREA_VADDR + kCommandHeaderOffset + offset); 24 return (u32*)Memory::GetPointer(GetCurrentThread()->GetTLSAddress() + kCommandHeaderOffset + offset);
21} 25}
22 26
23/** 27/**
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 0a3fd7cb1..5de8f9a73 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -197,6 +197,7 @@ static void SwitchContext(Thread* new_thread) {
197 new_thread->current_priority = new_thread->nominal_priority; 197 new_thread->current_priority = new_thread->nominal_priority;
198 198
199 Core::g_app_core->LoadContext(new_thread->context); 199 Core::g_app_core->LoadContext(new_thread->context);
200 Core::g_app_core->SetCP15Register(CP15_THREAD_URO, new_thread->GetTLSAddress());
200 } else { 201 } else {
201 current_thread = nullptr; 202 current_thread = nullptr;
202 } 203 }
@@ -402,6 +403,12 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
402 thread->name = std::move(name); 403 thread->name = std::move(name);
403 thread->callback_handle = wakeup_callback_handle_table.Create(thread).MoveFrom(); 404 thread->callback_handle = wakeup_callback_handle_table.Create(thread).MoveFrom();
404 405
406 VAddr tls_address = Memory::TLS_AREA_VADDR + (thread->thread_id - 1) * 0x200;
407
408 ASSERT_MSG(tls_address < Memory::TLS_AREA_VADDR_END, "Too many threads");
409
410 thread->tls_address = tls_address;
411
405 // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used 412 // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used
406 // to initialize the context 413 // to initialize the context
407 Core::g_app_core->ResetContext(thread->context, stack_top, entry_point, arg); 414 Core::g_app_core->ResetContext(thread->context, stack_top, entry_point, arg);
@@ -495,6 +502,10 @@ void Thread::SetWaitSynchronizationOutput(s32 output) {
495 context.cpu_registers[1] = output; 502 context.cpu_registers[1] = output;
496} 503}
497 504
505VAddr Thread::GetTLSAddress() const {
506 return tls_address;
507}
508
498//////////////////////////////////////////////////////////////////////////////////////////////////// 509////////////////////////////////////////////////////////////////////////////////////////////////////
499 510
500void ThreadingInit() { 511void ThreadingInit() {
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 9958b16e6..6891c8c2f 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -135,6 +135,12 @@ public:
135 */ 135 */
136 void Stop(); 136 void Stop();
137 137
138 /*
139 * Returns the Thread Local Storage address of the current thread
140 * @returns VAddr of the thread's TLS
141 */
142 VAddr GetTLSAddress() const;
143
138 Core::ThreadContext context; 144 Core::ThreadContext context;
139 145
140 u32 thread_id; 146 u32 thread_id;
@@ -150,6 +156,8 @@ public:
150 156
151 s32 processor_id; 157 s32 processor_id;
152 158
159 VAddr tls_address; ///< Address of the Thread Local Storage of the thread
160
153 /// Mutexes currently held by this thread, which will be released when it exits. 161 /// Mutexes currently held by this thread, which will be released when it exits.
154 boost::container::flat_set<SharedPtr<Mutex>> held_mutexes; 162 boost::container::flat_set<SharedPtr<Mutex>> held_mutexes;
155 163