kern: Implement exception vector ASM

This commit is contained in:
Michael Scire
2020-02-08 02:49:32 -08:00
parent e330b6187f
commit 919b8124dc
26 changed files with 1497 additions and 60 deletions

View File

@@ -43,6 +43,7 @@ namespace ams::kern::arm64::cpu {
MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(VbarEl1, vbar_el1)
MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(FarEl1, far_el1)
MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(ParEl1, par_el1)
MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(SctlrEl1, sctlr_el1)
@@ -56,6 +57,10 @@ namespace ams::kern::arm64::cpu {
MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(TpidrRoEl0, tpidrro_el0)
MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(EsrEl1, esr_el1)
MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(Afsr0El1, afsr0_el1)
MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(Afsr1El1, afsr1_el1)
#define FOR_I_IN_0_TO_15(HANDLER, ...) \
HANDLER(0, ## __VA_ARGS__) HANDLER(1, ## __VA_ARGS__) HANDLER(2, ## __VA_ARGS__) HANDLER(3, ## __VA_ARGS__) \
HANDLER(4, ## __VA_ARGS__) HANDLER(5, ## __VA_ARGS__) HANDLER(6, ## __VA_ARGS__) HANDLER(7, ## __VA_ARGS__) \
@@ -139,6 +144,24 @@ namespace ams::kern::arm64::cpu {
}
};
MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS(ArchitecturalFeatureAccessControl) {
public:
MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS_FUNCTIONS(ArchitecturalFeatureAccessControl, cpacr_el1)
constexpr ALWAYS_INLINE decltype(auto) SetFpEnabled(bool en) {
if (en) {
this->SetBits(20, 2, 0x3);
} else {
this->SetBits(20, 2, 0x0);
}
return *this;
}
constexpr ALWAYS_INLINE bool IsFpEnabled() {
return this->GetBits(20, 2) != 0;
}
};
MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS(DebugFeature) {
public:
MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS_FUNCTIONS(DebugFeature, id_aa64dfr0_el1)

View File

@@ -143,6 +143,14 @@ namespace ams::kern::arm64 {
void Initialize(s32 core_id);
void Finalize(s32 core_id);
public:
u32 GetIrq() const {
return this->gicc->iar;
}
static constexpr s32 ConvertRawIrq(u32 irq) {
return (irq == 0x3FF) ? -1 : (irq & 0x3FF);
}
void Enable(s32 irq) const {
this->gicd->isenabler[irq / BITSIZEOF(u32)] = (1u << (irq % BITSIZEOF(u32)));
}

View File

@@ -60,6 +60,8 @@ namespace ams::kern::arm64 {
static ALWAYS_INLINE KSpinLock &GetLock() { return s_lock; }
static ALWAYS_INLINE KGlobalInterruptEntry &GetGlobalInterruptEntry(s32 irq) { return s_global_interrupts[KInterruptController::GetGlobalInterruptIndex(irq)]; }
ALWAYS_INLINE KCoreLocalInterruptEntry &GetLocalInterruptEntry(s32 irq) { return this->core_local_interrupts[KInterruptController::GetLocalInterruptIndex(irq)]; }
bool OnHandleInterrupt();
public:
constexpr KInterruptManager() : core_local_interrupts(), interrupt_controller(), local_state(), local_state_saved(false) { /* ... */ }
NOINLINE void Initialize(s32 core_id);
@@ -79,6 +81,8 @@ namespace ams::kern::arm64 {
this->interrupt_controller.SendInterProcessorInterrupt(irq);
}
static void HandleInterrupt(bool user_mode);
/* Implement more KInterruptManager functionality. */
private:
Result BindGlobal(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level);

View File

@@ -62,6 +62,8 @@ namespace ams::kern::arm64 {
Result Initialize(KVirtualAddress u_pc, KVirtualAddress k_sp, KVirtualAddress u_sp, uintptr_t arg, bool is_user, bool is_64_bit, bool is_main);
Result Finalize();
static void FpuContextSwitchHandler(KThread *thread);
/* TODO: More methods (especially FPU management) */
};

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <mesosphere/kern_common.hpp>
namespace ams::kern::arm64 {
void UserspaceMemoryAccessFunctionAreaBegin();
void UserspaceMemoryAccessFunctionAreaEnd();
}