mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
kern: update for new exception flag semantics
This commit is contained in:
parent
13238fc4fd
commit
bf4fdf6188
4 changed files with 27 additions and 12 deletions
|
@ -38,6 +38,25 @@ namespace ams::kern::arch::arm64::cpu {
|
||||||
ALWAYS_INLINE ~KScopedCoreMigrationDisable() { GetCurrentThread().EnableCoreMigration(); }
|
ALWAYS_INLINE ~KScopedCoreMigrationDisable() { GetCurrentThread().EnableCoreMigration(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class KScopedCacheMaintenance {
|
||||||
|
private:
|
||||||
|
bool m_active;
|
||||||
|
public:
|
||||||
|
ALWAYS_INLINE KScopedCacheMaintenance() {
|
||||||
|
__asm__ __volatile__("" ::: "memory");
|
||||||
|
if (m_active = !GetCurrentThread().IsInCacheMaintenanceOperation(); m_active) {
|
||||||
|
GetCurrentThread().SetInCacheMaintenanceOperation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE ~KScopedCacheMaintenance() {
|
||||||
|
if (m_active) {
|
||||||
|
GetCurrentThread().ClearInCacheMaintenanceOperation();
|
||||||
|
}
|
||||||
|
__asm__ __volatile__("" ::: "memory");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* Nintendo registers a handler for a SGI on thread termination, but does not handle anything. */
|
/* Nintendo registers a handler for a SGI on thread termination, but does not handle anything. */
|
||||||
/* This is sufficient, because post-interrupt scheduling is all they really intend to occur. */
|
/* This is sufficient, because post-interrupt scheduling is all they really intend to occur. */
|
||||||
class KThreadTerminationInterruptHandler : public KInterruptHandler {
|
class KThreadTerminationInterruptHandler : public KInterruptHandler {
|
||||||
|
@ -432,9 +451,7 @@ namespace ams::kern::arch::arm64::cpu {
|
||||||
|
|
||||||
Result InvalidateDataCache(void *addr, size_t size) {
|
Result InvalidateDataCache(void *addr, size_t size) {
|
||||||
/* Mark ourselves as in a cache maintenance operation, and prevent re-ordering. */
|
/* Mark ourselves as in a cache maintenance operation, and prevent re-ordering. */
|
||||||
__asm__ __volatile__("" ::: "memory");
|
KScopedCacheMaintenance cm;
|
||||||
GetCurrentThread().SetInCacheMaintenanceOperation();
|
|
||||||
ON_SCOPE_EXIT { GetCurrentThread().ClearInCacheMaintenanceOperation(); __asm__ __volatile__("" ::: "memory"); };
|
|
||||||
|
|
||||||
const uintptr_t start = reinterpret_cast<uintptr_t>(addr);
|
const uintptr_t start = reinterpret_cast<uintptr_t>(addr);
|
||||||
const uintptr_t end = start + size;
|
const uintptr_t end = start + size;
|
||||||
|
@ -460,9 +477,7 @@ namespace ams::kern::arch::arm64::cpu {
|
||||||
|
|
||||||
Result StoreDataCache(const void *addr, size_t size) {
|
Result StoreDataCache(const void *addr, size_t size) {
|
||||||
/* Mark ourselves as in a cache maintenance operation, and prevent re-ordering. */
|
/* Mark ourselves as in a cache maintenance operation, and prevent re-ordering. */
|
||||||
__asm__ __volatile__("" ::: "memory");
|
KScopedCacheMaintenance cm;
|
||||||
GetCurrentThread().SetInCacheMaintenanceOperation();
|
|
||||||
ON_SCOPE_EXIT { GetCurrentThread().ClearInCacheMaintenanceOperation(); __asm__ __volatile__("" ::: "memory"); };
|
|
||||||
|
|
||||||
const uintptr_t start = util::AlignDown(reinterpret_cast<uintptr_t>(addr), DataCacheLineSize);
|
const uintptr_t start = util::AlignDown(reinterpret_cast<uintptr_t>(addr), DataCacheLineSize);
|
||||||
const uintptr_t end = util::AlignUp( reinterpret_cast<uintptr_t>(addr) + size, DataCacheLineSize);
|
const uintptr_t end = util::AlignUp( reinterpret_cast<uintptr_t>(addr) + size, DataCacheLineSize);
|
||||||
|
@ -472,9 +487,7 @@ namespace ams::kern::arch::arm64::cpu {
|
||||||
|
|
||||||
Result FlushDataCache(const void *addr, size_t size) {
|
Result FlushDataCache(const void *addr, size_t size) {
|
||||||
/* Mark ourselves as in a cache maintenance operation, and prevent re-ordering. */
|
/* Mark ourselves as in a cache maintenance operation, and prevent re-ordering. */
|
||||||
__asm__ __volatile__("" ::: "memory");
|
KScopedCacheMaintenance cm;
|
||||||
GetCurrentThread().SetInCacheMaintenanceOperation();
|
|
||||||
ON_SCOPE_EXIT { GetCurrentThread().ClearInCacheMaintenanceOperation(); __asm__ __volatile__("" ::: "memory"); };
|
|
||||||
|
|
||||||
const uintptr_t start = util::AlignDown(reinterpret_cast<uintptr_t>(addr), DataCacheLineSize);
|
const uintptr_t start = util::AlignDown(reinterpret_cast<uintptr_t>(addr), DataCacheLineSize);
|
||||||
const uintptr_t end = util::AlignUp( reinterpret_cast<uintptr_t>(addr) + size, DataCacheLineSize);
|
const uintptr_t end = util::AlignUp( reinterpret_cast<uintptr_t>(addr) + size, DataCacheLineSize);
|
||||||
|
|
|
@ -86,9 +86,10 @@ _ZN3ams4kern3svc14RestoreContextEm:
|
||||||
/* Get our exception flags. */
|
/* Get our exception flags. */
|
||||||
ldrb w9, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_EXCEPTION_FLAGS)]
|
ldrb w9, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_EXCEPTION_FLAGS)]
|
||||||
|
|
||||||
/* Clear in-svc and needs-fpu-restore flags. */
|
/* Clear in-svc, in-user-exception, and needs-fpu-restore flags. */
|
||||||
and w10, w9, #(~(THREAD_EXCEPTION_FLAG_IS_FPU_CONTEXT_RESTORE_NEEDED))
|
and w10, w9, #(~(THREAD_EXCEPTION_FLAG_IS_FPU_CONTEXT_RESTORE_NEEDED))
|
||||||
and w10, w10, #(~(THREAD_EXCEPTION_FLAG_IS_CALLING_SVC))
|
and w10, w10, #(~(THREAD_EXCEPTION_FLAG_IS_CALLING_SVC))
|
||||||
|
and w10, w10, #(~(THREAD_EXCEPTION_FLAG_IS_IN_USERMODE_EXCEPTION_HANDLER))
|
||||||
strb w10, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_EXCEPTION_FLAGS)]
|
strb w10, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_EXCEPTION_FLAGS)]
|
||||||
|
|
||||||
/* If we don't need to restore the fpu, skip restoring it. */
|
/* If we don't need to restore the fpu, skip restoring it. */
|
||||||
|
|
|
@ -509,7 +509,8 @@ namespace ams::kern {
|
||||||
|
|
||||||
void KThread::OnLeaveUsermodeException() {
|
void KThread::OnLeaveUsermodeException() {
|
||||||
this->ClearUsermodeExceptionSvcPermissions();
|
this->ClearUsermodeExceptionSvcPermissions();
|
||||||
this->ClearInUsermodeExceptionHandler();
|
|
||||||
|
/* NOTE: InUsermodeExceptionHandler will be cleared by RestoreContext. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void KThread::Pin() {
|
void KThread::Pin() {
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace ams::svc {
|
||||||
|
|
||||||
/* This is the highest SVC version supported by Atmosphere, to be updated on new kernel releases. */
|
/* This is the highest SVC version supported by Atmosphere, to be updated on new kernel releases. */
|
||||||
/* NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor. */
|
/* NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor. */
|
||||||
constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(14);
|
constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(15);
|
||||||
constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 3);
|
constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 3);
|
||||||
|
|
||||||
constexpr inline u32 SupportedKernelVersion = EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion);
|
constexpr inline u32 SupportedKernelVersion = EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion);
|
||||||
|
|
Loading…
Reference in a new issue