mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-10 07:06:34 +00:00
kern: optimize and bring into line with N our pstate.i management
This commit is contained in:
parent
e81a1ce5a8
commit
4b7b33809f
3 changed files with 42 additions and 23 deletions
|
@ -105,35 +105,48 @@ namespace ams::kern::arch::arm64 {
|
||||||
Result UnbindLocal(s32 irq);
|
Result UnbindLocal(s32 irq);
|
||||||
Result ClearGlobal(s32 irq);
|
Result ClearGlobal(s32 irq);
|
||||||
Result ClearLocal(s32 irq);
|
Result ClearLocal(s32 irq);
|
||||||
public:
|
private:
|
||||||
static ALWAYS_INLINE u32 DisableInterrupts() {
|
[[nodiscard]] static ALWAYS_INLINE u32 GetInterruptsEnabledState() {
|
||||||
u64 intr_state;
|
u64 intr_state;
|
||||||
__asm__ __volatile__("mrs %[intr_state], daif\n"
|
__asm__ __volatile__("mrs %[intr_state], daif\n"
|
||||||
"msr daifset, #2"
|
"ubfx %[intr_state], %[intr_state], #7, #1"
|
||||||
: [intr_state]"=r"(intr_state)
|
: [intr_state]"=r"(intr_state)
|
||||||
:: "memory");
|
:: "memory");
|
||||||
return intr_state;
|
return intr_state;
|
||||||
}
|
}
|
||||||
|
public:
|
||||||
|
static ALWAYS_INLINE void EnableInterrupts() {
|
||||||
|
__asm__ __volatile__("msr daifclr, #2" ::: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE u32 EnableInterrupts() {
|
static ALWAYS_INLINE void DisableInterrupts() {
|
||||||
u64 intr_state;
|
__asm__ __volatile__("msr daifset, #2" ::: "memory");
|
||||||
__asm__ __volatile__("mrs %[intr_state], daif\n"
|
}
|
||||||
"msr daifclr, #2"
|
|
||||||
: [intr_state]"=r"(intr_state)
|
[[nodiscard]] static ALWAYS_INLINE u32 GetInterruptsEnabledStateAndDisableInterrupts() {
|
||||||
:: "memory");
|
const auto intr_state = GetInterruptsEnabledState();
|
||||||
|
DisableInterrupts();
|
||||||
|
return intr_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static ALWAYS_INLINE u32 GetInterruptsEnabledStateAndEnableInterrupts() {
|
||||||
|
const auto intr_state = GetInterruptsEnabledState();
|
||||||
|
EnableInterrupts();
|
||||||
return intr_state;
|
return intr_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE void RestoreInterrupts(u32 intr_state) {
|
static ALWAYS_INLINE void RestoreInterrupts(u32 intr_state) {
|
||||||
u64 cur_state;
|
u64 tmp;
|
||||||
__asm__ __volatile__("mrs %[cur_state], daif" : [cur_state]"=r"(cur_state));
|
__asm__ __volatile__("mrs %[tmp], daif\n"
|
||||||
__asm__ __volatile__("msr daif, %[intr_state]" :: [intr_state]"r"((cur_state & ~0x80ul) | (intr_state & 0x80)));
|
"bfi %[tmp], %[intr_state], #7, #1\n"
|
||||||
|
"msr daif, %[tmp]"
|
||||||
|
: [tmp]"=&r"(tmp)
|
||||||
|
: [intr_state]"r"(intr_state)
|
||||||
|
: "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE bool AreInterruptsEnabled() {
|
static ALWAYS_INLINE bool AreInterruptsEnabled() {
|
||||||
u64 intr_state;
|
return GetInterruptsEnabledState() == 0;
|
||||||
__asm__ __volatile__("mrs %[intr_state], daif" : [intr_state]"=r"(intr_state));
|
|
||||||
return (intr_state & 0x80) == 0;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace ams::kern {
|
||||||
private:
|
private:
|
||||||
u32 m_prev_intr_state;
|
u32 m_prev_intr_state;
|
||||||
public:
|
public:
|
||||||
ALWAYS_INLINE KScopedInterruptDisable() : m_prev_intr_state(KInterruptManager::DisableInterrupts()) { /* ... */ }
|
ALWAYS_INLINE KScopedInterruptDisable() : m_prev_intr_state(KInterruptManager::GetInterruptsEnabledStateAndDisableInterrupts()) { /* ... */ }
|
||||||
ALWAYS_INLINE ~KScopedInterruptDisable() { KInterruptManager::RestoreInterrupts(m_prev_intr_state); }
|
ALWAYS_INLINE ~KScopedInterruptDisable() { KInterruptManager::RestoreInterrupts(m_prev_intr_state); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ namespace ams::kern {
|
||||||
private:
|
private:
|
||||||
u32 m_prev_intr_state;
|
u32 m_prev_intr_state;
|
||||||
public:
|
public:
|
||||||
ALWAYS_INLINE KScopedInterruptEnable() : m_prev_intr_state(KInterruptManager::EnableInterrupts()) { /* ... */ }
|
ALWAYS_INLINE KScopedInterruptEnable() : m_prev_intr_state(KInterruptManager::GetInterruptsEnabledStateAndEnableInterrupts()) { /* ... */ }
|
||||||
ALWAYS_INLINE ~KScopedInterruptEnable() { KInterruptManager::RestoreInterrupts(m_prev_intr_state); }
|
ALWAYS_INLINE ~KScopedInterruptEnable() { KInterruptManager::RestoreInterrupts(m_prev_intr_state); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -201,7 +201,7 @@ namespace ams::kern::arch::arm64 {
|
||||||
if (user_mode) {
|
if (user_mode) {
|
||||||
KThread *cur_thread = GetCurrentThreadPointer();
|
KThread *cur_thread = GetCurrentThreadPointer();
|
||||||
if (cur_thread->IsTerminationRequested()) {
|
if (cur_thread->IsTerminationRequested()) {
|
||||||
KScopedInterruptEnable ei;
|
EnableInterrupts();
|
||||||
cur_thread->Exit();
|
cur_thread->Exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,13 +212,14 @@ namespace ams::kern::arch::arm64 {
|
||||||
|
|
||||||
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange());
|
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange());
|
||||||
|
|
||||||
KScopedInterruptDisable di;
|
|
||||||
|
|
||||||
if (KInterruptController::IsGlobal(irq)) {
|
if (KInterruptController::IsGlobal(irq)) {
|
||||||
|
KScopedInterruptDisable di;
|
||||||
KScopedSpinLock lk(this->GetGlobalInterruptLock());
|
KScopedSpinLock lk(this->GetGlobalInterruptLock());
|
||||||
return this->BindGlobal(handler, irq, core_id, priority, manual_clear, level);
|
return this->BindGlobal(handler, irq, core_id, priority, manual_clear, level);
|
||||||
} else {
|
} else {
|
||||||
MESOSPHERE_ASSERT(core_id == GetCurrentCoreId());
|
MESOSPHERE_ASSERT(core_id == GetCurrentCoreId());
|
||||||
|
|
||||||
|
KScopedInterruptDisable di;
|
||||||
return this->BindLocal(handler, irq, priority, manual_clear);
|
return this->BindLocal(handler, irq, priority, manual_clear);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,13 +229,16 @@ namespace ams::kern::arch::arm64 {
|
||||||
|
|
||||||
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange());
|
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange());
|
||||||
|
|
||||||
KScopedInterruptDisable di;
|
|
||||||
|
|
||||||
if (KInterruptController::IsGlobal(irq)) {
|
if (KInterruptController::IsGlobal(irq)) {
|
||||||
|
KScopedInterruptDisable di;
|
||||||
|
|
||||||
KScopedSpinLock lk(this->GetGlobalInterruptLock());
|
KScopedSpinLock lk(this->GetGlobalInterruptLock());
|
||||||
return this->UnbindGlobal(irq);
|
return this->UnbindGlobal(irq);
|
||||||
} else {
|
} else {
|
||||||
MESOSPHERE_ASSERT(core_id == GetCurrentCoreId());
|
MESOSPHERE_ASSERT(core_id == GetCurrentCoreId());
|
||||||
|
|
||||||
|
KScopedInterruptDisable di;
|
||||||
return this->UnbindLocal(irq);
|
return this->UnbindLocal(irq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,13 +248,15 @@ namespace ams::kern::arch::arm64 {
|
||||||
|
|
||||||
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange());
|
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange());
|
||||||
|
|
||||||
KScopedInterruptDisable di;
|
|
||||||
|
|
||||||
if (KInterruptController::IsGlobal(irq)) {
|
if (KInterruptController::IsGlobal(irq)) {
|
||||||
|
KScopedInterruptDisable di;
|
||||||
KScopedSpinLock lk(this->GetGlobalInterruptLock());
|
KScopedSpinLock lk(this->GetGlobalInterruptLock());
|
||||||
return this->ClearGlobal(irq);
|
return this->ClearGlobal(irq);
|
||||||
} else {
|
} else {
|
||||||
MESOSPHERE_ASSERT(core_id == GetCurrentCoreId());
|
MESOSPHERE_ASSERT(core_id == GetCurrentCoreId());
|
||||||
|
|
||||||
|
KScopedInterruptDisable di;
|
||||||
return this->ClearLocal(irq);
|
return this->ClearLocal(irq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue