kern: implement SvcCreateInterruptEvent

This commit is contained in:
Michael Scire 2020-07-14 03:26:02 -07:00 committed by SciresM
parent b35380a942
commit 04f325cf5a
8 changed files with 239 additions and 8 deletions

View file

@ -213,7 +213,7 @@ namespace ams::kern::arch::arm64 {
this->gicc->eoir = irq;
}
bool IsInterruptDefined(s32 irq) {
bool IsInterruptDefined(s32 irq) const {
const s32 num_interrupts = std::min(32 + 32 * (this->gicd->typer & 0x1F), static_cast<u32>(NumInterrupts));
return (0 <= irq && irq < num_interrupts);
}

View file

@ -67,10 +67,18 @@ namespace ams::kern::arch::arm64 {
NOINLINE void Initialize(s32 core_id);
NOINLINE void Finalize(s32 core_id);
bool IsInterruptDefined(s32 irq) {
bool IsInterruptDefined(s32 irq) const {
return this->interrupt_controller.IsInterruptDefined(irq);
}
bool IsGlobal(s32 irq) const {
return this->interrupt_controller.IsGlobal(irq);
}
bool IsLocal(s32 irq) const {
return this->interrupt_controller.IsLocal(irq);
}
NOINLINE Result BindHandler(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level);
NOINLINE Result UnbindHandler(s32 irq, s32 core);

View file

@ -230,7 +230,7 @@ namespace ams::kern {
}
}
bool SetInterruptAllowed(u32 id) {
bool SetInterruptPermitted(u32 id) {
constexpr size_t BitsPerWord = BITSIZEOF(this->irq_access_flags[0]);
if (id < BITSIZEOF(this->irq_access_flags)) {
this->irq_access_flags[id / BitsPerWord] = (1ul << (id % BitsPerWord));
@ -274,6 +274,15 @@ namespace ams::kern {
}
}
constexpr bool IsPermittedInterrupt(u32 id) const {
constexpr size_t BitsPerWord = BITSIZEOF(this->irq_access_flags[0]);
if (id < BITSIZEOF(this->irq_access_flags)) {
return (this->irq_access_flags[id / BitsPerWord] & (1ul << (id % BitsPerWord))) != 0;
} else {
return false;
}
}
/* TODO: Member functions. */
};

View file

@ -26,13 +26,40 @@ namespace ams::kern {
class KInterruptEvent final : public KAutoObjectWithSlabHeapAndContainer<KInterruptEvent, KReadableEvent> {
MESOSPHERE_AUTOOBJECT_TRAITS(KInterruptEvent, KReadableEvent);
private:
KInterruptEventTask *task;
s32 interrupt_id;
bool is_initialized;
public:
/* TODO: This is a placeholder definition. */
constexpr KInterruptEvent() : task(nullptr), interrupt_id(-1), is_initialized(false) { /* ... */ }
virtual ~KInterruptEvent() { /* ... */ }
Result Initialize(int32_t interrupt_name, ams::svc::InterruptType type);
virtual void Finalize() override;
virtual Result Reset() override;
virtual bool IsInitialized() const override { return this->is_initialized; }
static void PostDestroy(uintptr_t arg) { /* ... */ }
constexpr s32 GetInterruptId() const { return this->interrupt_id; }
};
class KInterruptEventTask : public KSlabAllocated<KInterruptEventTask>, public KInterruptTask {
private:
KInterruptEvent *event;
s32 interrupt_id;
public:
/* TODO: This is a placeholder definition. */
constexpr KInterruptEventTask() : event(nullptr), interrupt_id(-1) { /* ... */ }
~KInterruptEventTask() { /* ... */ }
virtual KInterruptTask *OnInterrupt(s32 interrupt_id) override;
virtual void DoTask() override;
void Unregister();
public:
static Result Register(KInterruptEventTask **out, s32 interrupt_id, bool level, KInterruptEvent *event);
};
}

View file

@ -147,6 +147,10 @@ namespace ams::kern {
return this->is_suspended;
}
constexpr bool IsPermittedInterrupt(int32_t interrupt_id) const {
return this->capabilities.IsPermittedInterrupt(interrupt_id);
}
bool EnterUserException();
bool LeaveUserException();
bool ReleaseUserException(KThread *thread);