diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp
new file mode 100644
index 000000000..267cc8ad0
--- /dev/null
+++ b/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp
@@ -0,0 +1,279 @@
+/*
+ * 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 .
+ */
+#pragma once
+#include
+#include
+#include
+
+namespace ams::kern::arch::arm {
+
+ struct GicDistributor {
+ u32 ctlr;
+ u32 typer;
+ u32 iidr;
+ u32 reserved_0x0c;
+ u32 statusr;
+ u32 reserved_0x14[3];
+ u32 impldef_0x20[8];
+ u32 setspi_nsr;
+ u32 reserved_0x44;
+ u32 clrspi_nsr;
+ u32 reserved_0x4c;
+ u32 setspi_sr;
+ u32 reserved_0x54;
+ u32 clrspi_sr;
+ u32 reserved_0x5c[9];
+ u32 igroupr[32];
+ u32 isenabler[32];
+ u32 icenabler[32];
+ u32 ispendr[32];
+ u32 icpendr[32];
+ u32 isactiver[32];
+ u32 icactiver[32];
+ union {
+ u8 bytes[1020];
+ u32 words[255];
+ } ipriorityr;
+ u32 _0x7fc;
+ union {
+ u8 bytes[1020];
+ u32 words[255];
+ } itargetsr;
+ u32 _0xbfc;
+ u32 icfgr[64];
+ u32 igrpmodr[32];
+ u32 _0xd80[32];
+ u32 nsacr[64];
+ u32 sgir;
+ u32 _0xf04[3];
+ u32 cpendsgir[4];
+ u32 spendsgir[4];
+ u32 reserved_0xf30[52];
+
+ static constexpr size_t SgirCpuTargetListShift = 16;
+
+ enum SgirTargetListFilter : u32 {
+ SgirTargetListFilter_CpuTargetList = (0 << 24),
+ SgirTargetListFilter_Others = (1 << 24),
+ SgirTargetListFilter_Self = (2 << 24),
+ SgirTargetListFilter_Reserved = (3 << 24),
+ };
+ };
+ static_assert(util::is_pod::value);
+ static_assert(sizeof(GicDistributor) == 0x1000);
+
+ struct GicCpuInterface {
+ u32 ctlr;
+ u32 pmr;
+ u32 bpr;
+ u32 iar;
+ u32 eoir;
+ u32 rpr;
+ u32 hppir;
+ u32 abpr;
+ u32 aiar;
+ u32 aeoir;
+ u32 ahppir;
+ u32 statusr;
+ u32 reserved_30[4];
+ u32 impldef_40[36];
+ u32 apr[4];
+ u32 nsapr[4];
+ u32 reserved_f0[3];
+ u32 iidr;
+ u32 reserved_100[960];
+ u32 dir;
+ u32 _0x1004[1023];
+ };
+ static_assert(util::is_pod::value);
+ static_assert(sizeof(GicCpuInterface) == 0x2000);
+
+ struct KInterruptController {
+ NON_COPYABLE(KInterruptController);
+ NON_MOVEABLE(KInterruptController);
+ public:
+ static constexpr s32 NumSoftwareInterrupts = 16;
+ static constexpr s32 NumLocalInterrupts = NumSoftwareInterrupts + 16;
+ static constexpr s32 NumGlobalInterrupts = 988;
+ static constexpr s32 NumInterrupts = NumLocalInterrupts + NumGlobalInterrupts;
+ static constexpr s32 NumPriorityLevels = 4;
+ public:
+ struct LocalState {
+ u32 isenabler[NumLocalInterrupts / 32];
+ u32 ipriorityr[NumLocalInterrupts / 4];
+ u32 itargetsr[NumLocalInterrupts / 4];
+ u32 icfgr[NumLocalInterrupts / 16];
+ };
+
+ struct GlobalState {
+ u32 isenabler[NumGlobalInterrupts / 32];
+ u32 ipriorityr[NumGlobalInterrupts / 4];
+ u32 itargetsr[NumGlobalInterrupts / 4];
+ u32 icfgr[NumGlobalInterrupts / 16];
+ };
+
+ enum PriorityLevel : u8 {
+ PriorityLevel_High = 0,
+ PriorityLevel_Low = NumPriorityLevels - 1,
+
+ PriorityLevel_Timer = 1,
+ PriorityLevel_Scheduler = 2,
+ };
+ private:
+ static inline u32 s_mask[cpu::NumCores];
+ private:
+ volatile GicDistributor *gicd;
+ volatile GicCpuInterface *gicc;
+ public:
+ constexpr KInterruptController() : gicd(nullptr), gicc(nullptr) { /* ... */ }
+
+ void Initialize(s32 core_id);
+ void Finalize(s32 core_id);
+
+ void SaveCoreLocal(LocalState *state) const;
+ void SaveGlobal(GlobalState *state) const;
+ void RestoreCoreLocal(const LocalState *state) const;
+ void RestoreGlobal(const GlobalState *state) const;
+ 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)));
+ }
+
+ void Disable(s32 irq) const {
+ this->gicd->icenabler[irq / BITSIZEOF(u32)] = (1u << (irq % BITSIZEOF(u32)));
+ }
+
+ void Clear(s32 irq) const {
+ this->gicd->icpendr[irq / BITSIZEOF(u32)] = (1u << (irq % BITSIZEOF(u32)));
+ }
+
+ void SetTarget(s32 irq, s32 core_id) const {
+ this->gicd->itargetsr.bytes[irq] = this->gicd->itargetsr.bytes[irq] | GetGicMask(core_id);
+ }
+
+ void ClearTarget(s32 irq, s32 core_id) const {
+ this->gicd->itargetsr.bytes[irq] = this->gicd->itargetsr.bytes[irq] & ~GetGicMask(core_id);
+ }
+
+ void SetPriorityLevel(s32 irq, s32 level) const {
+ MESOSPHERE_ASSERT(PriorityLevel_High <= level && level <= PriorityLevel_Low);
+ this->gicd->ipriorityr.bytes[irq] = ToGicPriorityValue(level);
+ }
+
+ s32 GetPriorityLevel(s32 irq) const {
+ return FromGicPriorityValue(this->gicd->ipriorityr.bytes[irq]);
+ }
+
+ void SetPriorityLevel(s32 level) const {
+ MESOSPHERE_ASSERT(PriorityLevel_High <= level && level <= PriorityLevel_Low);
+ this->gicc->pmr = ToGicPriorityValue(level);
+ }
+
+ void SetEdge(s32 irq) const {
+ u32 cfg = this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)];
+ cfg &= ~(0x3 << (2 * (irq % (BITSIZEOF(u32) / 2))));
+ cfg |= (0x2 << (2 * (irq % (BITSIZEOF(u32) / 2))));
+ this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)] = cfg;
+ }
+
+ void SetLevel(s32 irq) const {
+ u32 cfg = this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)];
+ cfg &= ~(0x3 << (2 * (irq % (BITSIZEOF(u32) / 2))));
+ cfg |= (0x0 << (2 * (irq % (BITSIZEOF(u32) / 2))));
+ this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)] = cfg;
+ }
+
+ void SendInterProcessorInterrupt(s32 irq, u64 core_mask) {
+ MESOSPHERE_ASSERT(IsSoftware(irq));
+ this->gicd->sgir = GetCpuTargetListMask(irq, core_mask);
+ }
+
+ void SendInterProcessorInterrupt(s32 irq) {
+ MESOSPHERE_ASSERT(IsSoftware(irq));
+ this->gicd->sgir = GicDistributor::SgirTargetListFilter_Others | irq;
+ }
+
+ void EndOfInterrupt(u32 irq) const {
+ this->gicc->eoir = irq;
+ }
+
+ bool IsInterruptDefined(s32 irq) const {
+ const s32 num_interrupts = std::min(32 + 32 * (this->gicd->typer & 0x1F), static_cast(NumInterrupts));
+ return (0 <= irq && irq < num_interrupts);
+ }
+ public:
+ static constexpr ALWAYS_INLINE bool IsSoftware(s32 id) {
+ MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);
+ return id < NumSoftwareInterrupts;
+ }
+
+ static constexpr ALWAYS_INLINE bool IsLocal(s32 id) {
+ MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);
+ return id < NumLocalInterrupts;
+ }
+
+ static constexpr ALWAYS_INLINE bool IsGlobal(s32 id) {
+ MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);
+ return NumLocalInterrupts <= id;
+ }
+
+ static constexpr size_t GetGlobalInterruptIndex(s32 id) {
+ MESOSPHERE_ASSERT(IsGlobal(id));
+ return id - NumLocalInterrupts;
+ }
+
+ static constexpr size_t GetLocalInterruptIndex(s32 id) {
+ MESOSPHERE_ASSERT(IsLocal(id));
+ return id;
+ }
+ private:
+ static constexpr size_t PriorityShift = BITSIZEOF(u8) - __builtin_ctz(NumPriorityLevels);
+ static_assert(PriorityShift < BITSIZEOF(u8));
+
+ static constexpr ALWAYS_INLINE u8 ToGicPriorityValue(s32 level) {
+ return (level << PriorityShift) | ((1 << PriorityShift) - 1);
+ }
+
+ static constexpr ALWAYS_INLINE s32 FromGicPriorityValue(u8 priority) {
+ return (priority >> PriorityShift) & (NumPriorityLevels - 1);
+ }
+
+ static constexpr ALWAYS_INLINE s32 GetCpuTargetListMask(s32 irq, u64 core_mask) {
+ MESOSPHERE_ASSERT(IsSoftware(irq));
+ MESOSPHERE_ASSERT(core_mask < (1ul << cpu::NumCores));
+ return GicDistributor::SgirTargetListFilter_CpuTargetList | irq | (static_cast(core_mask) << GicDistributor::SgirCpuTargetListShift);
+ }
+
+ static ALWAYS_INLINE s32 GetGicMask(s32 core_id) {
+ return s_mask[core_id];
+ }
+
+ ALWAYS_INLINE void SetGicMask(s32 core_id) const {
+ s_mask[core_id] = this->gicd->itargetsr.bytes[0];
+ }
+
+ NOINLINE void SetupInterruptLines(s32 core_id) const;
+ };
+
+}
diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm/kern_k_interrupt_controller.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm/kern_k_interrupt_controller.hpp
new file mode 100644
index 000000000..3399322ce
--- /dev/null
+++ b/libraries/libmesosphere/include/mesosphere/arch/arm/kern_k_interrupt_controller.hpp
@@ -0,0 +1,29 @@
+/*
+ * 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 .
+ */
+#pragma once
+#include
+#include
+#include
+
+#if 1
+
+ #include
+
+#else
+
+ #error "Unknown board for KInterruptController"
+
+#endif
diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_interrupt_controller.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_interrupt_controller.hpp
index 4051d4c56..3e88b7536 100644
--- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_interrupt_controller.hpp
+++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_interrupt_controller.hpp
@@ -18,261 +18,19 @@
#include
#include
-namespace ams::kern::arch::arm64 {
+#if 1
- struct GicDistributor {
- u32 ctlr;
- u32 typer;
- u32 iidr;
- u32 reserved_0x0c;
- u32 statusr;
- u32 reserved_0x14[3];
- u32 impldef_0x20[8];
- u32 setspi_nsr;
- u32 reserved_0x44;
- u32 clrspi_nsr;
- u32 reserved_0x4c;
- u32 setspi_sr;
- u32 reserved_0x54;
- u32 clrspi_sr;
- u32 reserved_0x5c[9];
- u32 igroupr[32];
- u32 isenabler[32];
- u32 icenabler[32];
- u32 ispendr[32];
- u32 icpendr[32];
- u32 isactiver[32];
- u32 icactiver[32];
- union {
- u8 bytes[1020];
- u32 words[255];
- } ipriorityr;
- u32 _0x7fc;
- union {
- u8 bytes[1020];
- u32 words[255];
- } itargetsr;
- u32 _0xbfc;
- u32 icfgr[64];
- u32 igrpmodr[32];
- u32 _0xd80[32];
- u32 nsacr[64];
- u32 sgir;
- u32 _0xf04[3];
- u32 cpendsgir[4];
- u32 spendsgir[4];
- u32 reserved_0xf30[52];
+ #include
+ namespace ams::kern::arch::arm64 {
- static constexpr size_t SgirCpuTargetListShift = 16;
+ using ams::kern::arch::arm::GicDistributor;
+ using ams::kern::arch::arm::GicCpuInterface;
+ using ams::kern::arch::arm::KInterruptController;
- enum SgirTargetListFilter : u32 {
- SgirTargetListFilter_CpuTargetList = (0 << 24),
- SgirTargetListFilter_Others = (1 << 24),
- SgirTargetListFilter_Self = (2 << 24),
- SgirTargetListFilter_Reserved = (3 << 24),
- };
- };
- static_assert(util::is_pod::value);
- static_assert(sizeof(GicDistributor) == 0x1000);
+ }
- struct GicCpuInterface {
- u32 ctlr;
- u32 pmr;
- u32 bpr;
- u32 iar;
- u32 eoir;
- u32 rpr;
- u32 hppir;
- u32 abpr;
- u32 aiar;
- u32 aeoir;
- u32 ahppir;
- u32 statusr;
- u32 reserved_30[4];
- u32 impldef_40[36];
- u32 apr[4];
- u32 nsapr[4];
- u32 reserved_f0[3];
- u32 iidr;
- u32 reserved_100[960];
- u32 dir;
- u32 _0x1004[1023];
- };
- static_assert(util::is_pod::value);
- static_assert(sizeof(GicCpuInterface) == 0x2000);
+#else
- struct KInterruptController {
- NON_COPYABLE(KInterruptController);
- NON_MOVEABLE(KInterruptController);
- public:
- static constexpr s32 NumSoftwareInterrupts = 16;
- static constexpr s32 NumLocalInterrupts = NumSoftwareInterrupts + 16;
- static constexpr s32 NumGlobalInterrupts = 988;
- static constexpr s32 NumInterrupts = NumLocalInterrupts + NumGlobalInterrupts;
- static constexpr s32 NumPriorityLevels = 4;
- public:
- struct LocalState {
- u32 isenabler[NumLocalInterrupts / 32];
- u32 ipriorityr[NumLocalInterrupts / 4];
- u32 itargetsr[NumLocalInterrupts / 4];
- u32 icfgr[NumLocalInterrupts / 16];
- };
+ #error "Unknown board for KInterruptController"
- struct GlobalState {
- u32 isenabler[NumGlobalInterrupts / 32];
- u32 ipriorityr[NumGlobalInterrupts / 4];
- u32 itargetsr[NumGlobalInterrupts / 4];
- u32 icfgr[NumGlobalInterrupts / 16];
- };
-
- enum PriorityLevel : u8 {
- PriorityLevel_High = 0,
- PriorityLevel_Low = NumPriorityLevels - 1,
-
- PriorityLevel_Timer = 1,
- PriorityLevel_Scheduler = 2,
- };
- private:
- static inline u32 s_mask[cpu::NumCores];
- private:
- volatile GicDistributor *gicd;
- volatile GicCpuInterface *gicc;
- public:
- constexpr KInterruptController() : gicd(nullptr), gicc(nullptr) { /* ... */ }
-
- void Initialize(s32 core_id);
- void Finalize(s32 core_id);
-
- void SaveCoreLocal(LocalState *state) const;
- void SaveGlobal(GlobalState *state) const;
- void RestoreCoreLocal(const LocalState *state) const;
- void RestoreGlobal(const GlobalState *state) const;
- 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)));
- }
-
- void Disable(s32 irq) const {
- this->gicd->icenabler[irq / BITSIZEOF(u32)] = (1u << (irq % BITSIZEOF(u32)));
- }
-
- void Clear(s32 irq) const {
- this->gicd->icpendr[irq / BITSIZEOF(u32)] = (1u << (irq % BITSIZEOF(u32)));
- }
-
- void SetTarget(s32 irq, s32 core_id) const {
- this->gicd->itargetsr.bytes[irq] = this->gicd->itargetsr.bytes[irq] | GetGicMask(core_id);
- }
-
- void ClearTarget(s32 irq, s32 core_id) const {
- this->gicd->itargetsr.bytes[irq] = this->gicd->itargetsr.bytes[irq] & ~GetGicMask(core_id);
- }
-
- void SetPriorityLevel(s32 irq, s32 level) const {
- MESOSPHERE_ASSERT(PriorityLevel_High <= level && level <= PriorityLevel_Low);
- this->gicd->ipriorityr.bytes[irq] = ToGicPriorityValue(level);
- }
-
- s32 GetPriorityLevel(s32 irq) const {
- return FromGicPriorityValue(this->gicd->ipriorityr.bytes[irq]);
- }
-
- void SetPriorityLevel(s32 level) const {
- MESOSPHERE_ASSERT(PriorityLevel_High <= level && level <= PriorityLevel_Low);
- this->gicc->pmr = ToGicPriorityValue(level);
- }
-
- void SetEdge(s32 irq) const {
- u32 cfg = this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)];
- cfg &= ~(0x3 << (2 * (irq % (BITSIZEOF(u32) / 2))));
- cfg |= (0x2 << (2 * (irq % (BITSIZEOF(u32) / 2))));
- this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)] = cfg;
- }
-
- void SetLevel(s32 irq) const {
- u32 cfg = this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)];
- cfg &= ~(0x3 << (2 * (irq % (BITSIZEOF(u32) / 2))));
- cfg |= (0x0 << (2 * (irq % (BITSIZEOF(u32) / 2))));
- this->gicd->icfgr[irq / (BITSIZEOF(u32) / 2)] = cfg;
- }
-
- void SendInterProcessorInterrupt(s32 irq, u64 core_mask) {
- MESOSPHERE_ASSERT(IsSoftware(irq));
- this->gicd->sgir = GetCpuTargetListMask(irq, core_mask);
- }
-
- void SendInterProcessorInterrupt(s32 irq) {
- MESOSPHERE_ASSERT(IsSoftware(irq));
- this->gicd->sgir = GicDistributor::SgirTargetListFilter_Others | irq;
- }
-
- void EndOfInterrupt(u32 irq) const {
- this->gicc->eoir = irq;
- }
-
- bool IsInterruptDefined(s32 irq) const {
- const s32 num_interrupts = std::min(32 + 32 * (this->gicd->typer & 0x1F), static_cast(NumInterrupts));
- return (0 <= irq && irq < num_interrupts);
- }
- public:
- static constexpr ALWAYS_INLINE bool IsSoftware(s32 id) {
- MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);
- return id < NumSoftwareInterrupts;
- }
-
- static constexpr ALWAYS_INLINE bool IsLocal(s32 id) {
- MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);
- return id < NumLocalInterrupts;
- }
-
- static constexpr ALWAYS_INLINE bool IsGlobal(s32 id) {
- MESOSPHERE_ASSERT(0 <= id && id < NumInterrupts);
- return NumLocalInterrupts <= id;
- }
-
- static constexpr size_t GetGlobalInterruptIndex(s32 id) {
- MESOSPHERE_ASSERT(IsGlobal(id));
- return id - NumLocalInterrupts;
- }
-
- static constexpr size_t GetLocalInterruptIndex(s32 id) {
- MESOSPHERE_ASSERT(IsLocal(id));
- return id;
- }
- private:
- static constexpr size_t PriorityShift = BITSIZEOF(u8) - __builtin_ctz(NumPriorityLevels);
- static_assert(PriorityShift < BITSIZEOF(u8));
-
- static constexpr ALWAYS_INLINE u8 ToGicPriorityValue(s32 level) {
- return (level << PriorityShift) | ((1 << PriorityShift) - 1);
- }
-
- static constexpr ALWAYS_INLINE s32 FromGicPriorityValue(u8 priority) {
- return (priority >> PriorityShift) & (NumPriorityLevels - 1);
- }
-
- static constexpr ALWAYS_INLINE s32 GetCpuTargetListMask(s32 irq, u64 core_mask) {
- MESOSPHERE_ASSERT(IsSoftware(irq));
- MESOSPHERE_ASSERT(core_mask < (1ul << cpu::NumCores));
- return GicDistributor::SgirTargetListFilter_CpuTargetList | irq | (static_cast(core_mask) << GicDistributor::SgirCpuTargetListShift);
- }
-
- static ALWAYS_INLINE s32 GetGicMask(s32 core_id) {
- return s_mask[core_id];
- }
-
- ALWAYS_INLINE void SetGicMask(s32 core_id) const {
- s_mask[core_id] = this->gicd->itargetsr.bytes[0];
- }
-
- NOINLINE void SetupInterruptLines(s32 core_id) const;
- };
-}
+#endif
diff --git a/libraries/libmesosphere/include/mesosphere/kern_select_interrupt_controller.hpp b/libraries/libmesosphere/include/mesosphere/kern_select_interrupt_controller.hpp
index 605fa3fcd..7225dc09c 100644
--- a/libraries/libmesosphere/include/mesosphere/kern_select_interrupt_controller.hpp
+++ b/libraries/libmesosphere/include/mesosphere/kern_select_interrupt_controller.hpp
@@ -24,6 +24,13 @@
using ams::kern::arch::arm64::KInterruptController;
}
+#elif defined(ATMOSPHERE_ARCH_ARM)
+
+ #include
+ namespace ams::kern {
+ using ams::kern::arch::arm::KInterruptController;
+ }
+
#else
#error "Unknown architecture for KInterruptController"
diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_interrupt_controller.cpp b/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc
similarity index 99%
rename from libraries/libmesosphere/source/arch/arm64/kern_k_interrupt_controller.cpp
rename to libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc
index 33fef41f7..290701037 100644
--- a/libraries/libmesosphere/source/arch/arm64/kern_k_interrupt_controller.cpp
+++ b/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc
@@ -15,7 +15,7 @@
*/
#include
-namespace ams::kern::arch::arm64 {
+namespace ams::kern::arch::arm {
void KInterruptController::SetupInterruptLines(s32 core_id) const {
const size_t ITLines = (core_id == 0) ? 32 * ((this->gicd->typer & 0x1F) + 1) : NumLocalInterrupts;
diff --git a/libraries/libmesosphere/source/arch/arm/kern_k_interrupt_controller.board.generic.cpp b/libraries/libmesosphere/source/arch/arm/kern_k_interrupt_controller.board.generic.cpp
new file mode 100644
index 000000000..06c132cfb
--- /dev/null
+++ b/libraries/libmesosphere/source/arch/arm/kern_k_interrupt_controller.board.generic.cpp
@@ -0,0 +1,19 @@
+/*
+ * 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 .
+ */
+#include
+
+/* Include the common implementation. */
+#include "../arm/kern_generic_interrupt_controller.inc"
diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_interrupt_controller.board.generic.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_interrupt_controller.board.generic.cpp
new file mode 100644
index 000000000..06c132cfb
--- /dev/null
+++ b/libraries/libmesosphere/source/arch/arm64/kern_k_interrupt_controller.board.generic.cpp
@@ -0,0 +1,19 @@
+/*
+ * 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 .
+ */
+#include
+
+/* Include the common implementation. */
+#include "../arm/kern_generic_interrupt_controller.inc"