diff options
| author | 2018-07-21 10:48:30 -0700 | |
|---|---|---|
| committer | 2018-07-21 10:48:30 -0700 | |
| commit | fe2498a65038bdea6ac5e4a2fad4fc992d4ff4ba (patch) | |
| tree | e4d5cfdca67efdf79956f275f346f68292629ade /src/core/hle/kernel | |
| parent | Merge pull request #753 from lioncash/const (diff) | |
| parent | CPU: Save and restore the TPIDR_EL0 system register on every context switch. (diff) | |
| download | yuzu-fe2498a65038bdea6ac5e4a2fad4fc992d4ff4ba.tar.gz yuzu-fe2498a65038bdea6ac5e4a2fad4fc992d4ff4ba.tar.xz yuzu-fe2498a65038bdea6ac5e4a2fad4fc992d4ff4ba.zip | |
Merge pull request #751 from Subv/tpidr_el0
CPU: Save and restore the TPIDR_EL0 system register on every context switch
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 9 |
3 files changed, 13 insertions, 0 deletions
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 | ||