diff options
| author | 2018-07-20 19:57:45 -0500 | |
|---|---|---|
| committer | 2018-07-20 19:57:45 -0500 | |
| commit | d84eb9dac64f314adcef2c374de245012f658b1d (patch) | |
| tree | 56720a5bce5d1a285dda01c16bfcb1dd57e53054 /src/core/hle/kernel | |
| parent | Merge pull request #730 from lioncash/string (diff) | |
| download | yuzu-d84eb9dac64f314adcef2c374de245012f658b1d.tar.gz yuzu-d84eb9dac64f314adcef2c374de245012f658b1d.tar.xz yuzu-d84eb9dac64f314adcef2c374de245012f658b1d.zip | |
CPU: Save and restore the TPIDR_EL0 system register on every context switch.
Note that there's currently a dynarmic bug preventing this register from being written.
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 1f4abfbe8..82829f6bb 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 e7fd6c842..7f1e18831 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -313,6 +313,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 313 | thread->status = THREADSTATUS_DORMANT; | 313 | thread->status = THREADSTATUS_DORMANT; |
| 314 | thread->entry_point = entry_point; | 314 | thread->entry_point = entry_point; |
| 315 | thread->stack_top = stack_top; | 315 | thread->stack_top = stack_top; |
| 316 | thread->tpidr_el0 = 0; | ||
| 316 | thread->nominal_priority = thread->current_priority = priority; | 317 | thread->nominal_priority = thread->current_priority = priority; |
| 317 | thread->last_running_ticks = CoreTiming::GetTicks(); | 318 | thread->last_running_ticks = CoreTiming::GetTicks(); |
| 318 | thread->processor_id = processor_id; | 319 | thread->processor_id = processor_id; |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index f1e759802..5fe72c55c 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 | ||