summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/arm_interface.h4
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp8
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.h2
-rw-r--r--src/core/arm/unicorn/arm_unicorn.cpp10
-rw-r--r--src/core/arm/unicorn/arm_unicorn.h2
-rw-r--r--src/core/hle/kernel/scheduler.cpp3
-rw-r--r--src/core/hle/kernel/thread.cpp1
-rw-r--r--src/core/hle/kernel/thread.h9
8 files changed, 39 insertions, 0 deletions
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 8416e73b0..28a99defe 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -104,6 +104,10 @@ public:
104 104
105 virtual void SetTlsAddress(VAddr address) = 0; 105 virtual void SetTlsAddress(VAddr address) = 0;
106 106
107 virtual u64 GetTPIDR_EL0() const = 0;
108
109 virtual void SetTPIDR_EL0(u64 value) = 0;
110
107 /** 111 /**
108 * Saves the current CPU context 112 * Saves the current CPU context
109 * @param ctx Thread context to save 113 * @param ctx Thread context to save
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index 3572ee7b9..df47d5ee8 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -196,6 +196,14 @@ void ARM_Dynarmic::SetTlsAddress(u64 address) {
196 cb->tpidrro_el0 = address; 196 cb->tpidrro_el0 = address;
197} 197}
198 198
199u64 ARM_Dynarmic::GetTPIDR_EL0() const {
200 return cb->tpidr_el0;
201}
202
203void ARM_Dynarmic::SetTPIDR_EL0(u64 value) {
204 cb->tpidr_el0 = value;
205}
206
199void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) { 207void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) {
200 ctx.cpu_registers = jit->GetRegisters(); 208 ctx.cpu_registers = jit->GetRegisters();
201 ctx.sp = jit->GetSP(); 209 ctx.sp = jit->GetSP();
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h
index ed724c3f1..a9891ac4f 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.h
+++ b/src/core/arm/dynarmic/arm_dynarmic.h
@@ -34,6 +34,8 @@ public:
34 void SetCPSR(u32 cpsr) override; 34 void SetCPSR(u32 cpsr) override;
35 VAddr GetTlsAddress() const override; 35 VAddr GetTlsAddress() const override;
36 void SetTlsAddress(VAddr address) override; 36 void SetTlsAddress(VAddr address) override;
37 void SetTPIDR_EL0(u64 value) override;
38 u64 GetTPIDR_EL0() const override;
37 39
38 void SaveContext(ThreadContext& ctx) override; 40 void SaveContext(ThreadContext& ctx) override;
39 void LoadContext(const ThreadContext& ctx) override; 41 void LoadContext(const ThreadContext& ctx) override;
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
index d2d699e9b..44a46bf04 100644
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ b/src/core/arm/unicorn/arm_unicorn.cpp
@@ -169,6 +169,16 @@ void ARM_Unicorn::SetTlsAddress(VAddr base) {
169 CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDRRO_EL0, &base)); 169 CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDRRO_EL0, &base));
170} 170}
171 171
172u64 ARM_Unicorn::GetTPIDR_EL0() const {
173 u64 value{};
174 CHECKED(uc_reg_read(uc, UC_ARM64_REG_TPIDR_EL0, &value));
175 return value;
176}
177
178void ARM_Unicorn::SetTPIDR_EL0(u64 value) {
179 CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDR_EL0, &value));
180}
181
172void ARM_Unicorn::Run() { 182void ARM_Unicorn::Run() {
173 if (GDBStub::IsServerEnabled()) { 183 if (GDBStub::IsServerEnabled()) {
174 ExecuteInstructions(std::max(4000000, 0)); 184 ExecuteInstructions(std::max(4000000, 0));
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h
index a78a0acf2..af7943352 100644
--- a/src/core/arm/unicorn/arm_unicorn.h
+++ b/src/core/arm/unicorn/arm_unicorn.h
@@ -28,6 +28,8 @@ public:
28 void SetCPSR(u32 cpsr) override; 28 void SetCPSR(u32 cpsr) override;
29 VAddr GetTlsAddress() const override; 29 VAddr GetTlsAddress() const override;
30 void SetTlsAddress(VAddr address) override; 30 void SetTlsAddress(VAddr address) override;
31 void SetTPIDR_EL0(u64 value) override;
32 u64 GetTPIDR_EL0() const override;
31 void SaveContext(ThreadContext& ctx) override; 33 void SaveContext(ThreadContext& ctx) override;
32 void LoadContext(const ThreadContext& ctx) override; 34 void LoadContext(const ThreadContext& ctx) override;
33 void PrepareReschedule() override; 35 void PrepareReschedule() override;
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index f7e25cbf5..e307eec98 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -56,6 +56,8 @@ void Scheduler::SwitchContext(Thread* new_thread) {
56 if (previous_thread) { 56 if (previous_thread) {
57 previous_thread->last_running_ticks = CoreTiming::GetTicks(); 57 previous_thread->last_running_ticks = CoreTiming::GetTicks();
58 cpu_core->SaveContext(previous_thread->context); 58 cpu_core->SaveContext(previous_thread->context);
59 // Save the TPIDR_EL0 system register in case it was modified.
60 previous_thread->tpidr_el0 = cpu_core->GetTPIDR_EL0();
59 61
60 if (previous_thread->status == ThreadStatus::Running) { 62 if (previous_thread->status == ThreadStatus::Running) {
61 // This is only the case when a reschedule is triggered without the current thread 63 // This is only the case when a reschedule is triggered without the current thread
@@ -87,6 +89,7 @@ void Scheduler::SwitchContext(Thread* new_thread) {
87 89
88 cpu_core->LoadContext(new_thread->context); 90 cpu_core->LoadContext(new_thread->context);
89 cpu_core->SetTlsAddress(new_thread->GetTLSAddress()); 91 cpu_core->SetTlsAddress(new_thread->GetTLSAddress());
92 cpu_core->SetTPIDR_EL0(new_thread->GetTPIDR_EL0());
90 cpu_core->ClearExclusiveState(); 93 cpu_core->ClearExclusiveState();
91 } else { 94 } else {
92 current_thread = nullptr; 95 current_thread = nullptr;
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 53f2e861e..cd85c4b7c 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -312,6 +312,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
312 thread->status = ThreadStatus::Dormant; 312 thread->status = ThreadStatus::Dormant;
313 thread->entry_point = entry_point; 313 thread->entry_point = entry_point;
314 thread->stack_top = stack_top; 314 thread->stack_top = stack_top;
315 thread->tpidr_el0 = 0;
315 thread->nominal_priority = thread->current_priority = priority; 316 thread->nominal_priority = thread->current_priority = priority;
316 thread->last_running_ticks = CoreTiming::GetTicks(); 317 thread->last_running_ticks = CoreTiming::GetTicks();
317 thread->processor_id = processor_id; 318 thread->processor_id = processor_id;
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 47881ec20..6218960d2 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -183,6 +183,14 @@ public:
183 } 183 }
184 184
185 /* 185 /*
186 * Returns the value of the TPIDR_EL0 Read/Write system register for this thread.
187 * @returns The value of the TPIDR_EL0 register.
188 */
189 u64 GetTPIDR_EL0() const {
190 return tpidr_el0;
191 }
192
193 /*
186 * Returns the address of the current thread's command buffer, located in the TLS. 194 * Returns the address of the current thread's command buffer, located in the TLS.
187 * @returns VAddr of the thread's command buffer. 195 * @returns VAddr of the thread's command buffer.
188 */ 196 */
@@ -213,6 +221,7 @@ public:
213 s32 processor_id; 221 s32 processor_id;
214 222
215 VAddr tls_address; ///< Virtual address of the Thread Local Storage of the thread 223 VAddr tls_address; ///< Virtual address of the Thread Local Storage of the thread
224 u64 tpidr_el0; ///< TPIDR_EL0 read/write system register.
216 225
217 SharedPtr<Process> owner_process; ///< Process that owns this thread 226 SharedPtr<Process> owner_process; ///< Process that owns this thread
218 227