mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 14:57:35 +00:00
Kernel/riscv64: Implement initialize_interrupts()
This commit is contained in:
parent
7b7578bc1b
commit
9bbf513c27
2 changed files with 73 additions and 6 deletions
|
@ -37,9 +37,9 @@ void InterruptManagement::find_controllers()
|
||||||
TODO_RISCV64();
|
TODO_RISCV64();
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 InterruptManagement::acquire_mapped_interrupt_number(u8)
|
u8 InterruptManagement::acquire_mapped_interrupt_number(u8 original_irq)
|
||||||
{
|
{
|
||||||
TODO_RISCV64();
|
return original_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<NonnullLockRefPtr<IRQController>> const& InterruptManagement::controllers()
|
Vector<NonnullLockRefPtr<IRQController>> const& InterruptManagement::controllers()
|
||||||
|
|
|
@ -11,9 +11,14 @@
|
||||||
#include <Kernel/Arch/Interrupts.h>
|
#include <Kernel/Arch/Interrupts.h>
|
||||||
#include <Kernel/Arch/TrapFrame.h>
|
#include <Kernel/Arch/TrapFrame.h>
|
||||||
#include <Kernel/Interrupts/GenericInterruptHandler.h>
|
#include <Kernel/Interrupts/GenericInterruptHandler.h>
|
||||||
|
#include <Kernel/Interrupts/SharedIRQHandler.h>
|
||||||
|
#include <Kernel/Interrupts/UnhandledInterruptHandler.h>
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
// FIXME: Share this array with x86_64/aarch64 somehow and consider if this really needs to use raw pointers and not OwnPtrs
|
||||||
|
static Array<GenericInterruptHandler*, 64> s_interrupt_handlers;
|
||||||
|
|
||||||
void dump_registers(RegisterState const&)
|
void dump_registers(RegisterState const&)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -32,18 +37,80 @@ ErrorOr<u8> reserve_interrupt_handlers(u8)
|
||||||
TODO_RISCV64();
|
TODO_RISCV64();
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_generic_interrupt_handler(u8, GenericInterruptHandler&)
|
static void revert_to_unused_handler(u8 interrupt_number)
|
||||||
{
|
{
|
||||||
TODO_RISCV64();
|
auto* handler = new UnhandledInterruptHandler(interrupt_number);
|
||||||
|
handler->register_interrupt_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
void unregister_generic_interrupt_handler(u8, GenericInterruptHandler&)
|
// FIXME: Share the code below with Arch/{x86_64,aarch64}/Interrupts.cpp
|
||||||
|
void register_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHandler& handler)
|
||||||
{
|
{
|
||||||
|
auto*& handler_slot = s_interrupt_handlers[interrupt_number];
|
||||||
|
if (handler_slot == nullptr) {
|
||||||
|
handler_slot = &handler;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (handler_slot->type() == HandlerType::UnhandledInterruptHandler) {
|
||||||
|
auto* unhandled_handler = static_cast<UnhandledInterruptHandler*>(handler_slot);
|
||||||
|
unhandled_handler->unregister_interrupt_handler();
|
||||||
|
delete unhandled_handler;
|
||||||
|
handler_slot = &handler;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (handler_slot->is_shared_handler()) {
|
||||||
|
VERIFY(handler_slot->type() == HandlerType::SharedIRQHandler);
|
||||||
|
static_cast<SharedIRQHandler*>(handler_slot)->register_handler(handler);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!handler_slot->is_shared_handler()) {
|
||||||
|
if (handler_slot->type() == HandlerType::SpuriousInterruptHandler) {
|
||||||
|
// FIXME: Add support for spurious interrupts on riscv64
|
||||||
|
TODO_RISCV64();
|
||||||
|
}
|
||||||
|
VERIFY(handler_slot->type() == HandlerType::IRQHandler);
|
||||||
|
auto& previous_handler = *handler_slot;
|
||||||
|
handler_slot = nullptr;
|
||||||
|
SharedIRQHandler::initialize(interrupt_number);
|
||||||
|
VERIFY(handler_slot);
|
||||||
|
static_cast<SharedIRQHandler*>(handler_slot)->register_handler(previous_handler);
|
||||||
|
static_cast<SharedIRQHandler*>(handler_slot)->register_handler(handler);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Share the code below with Arch/{x86_64,aarch64}/Interrupts.cpp
|
||||||
|
void unregister_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHandler& handler)
|
||||||
|
{
|
||||||
|
auto*& handler_slot = s_interrupt_handlers[interrupt_number];
|
||||||
|
VERIFY(handler_slot != nullptr);
|
||||||
|
if (handler_slot->type() == HandlerType::UnhandledInterruptHandler)
|
||||||
|
return;
|
||||||
|
if (handler_slot->is_shared_handler()) {
|
||||||
|
VERIFY(handler_slot->type() == HandlerType::SharedIRQHandler);
|
||||||
|
auto* shared_handler = static_cast<SharedIRQHandler*>(handler_slot);
|
||||||
|
shared_handler->unregister_handler(handler);
|
||||||
|
if (shared_handler->sharing_devices_count() == 0) {
|
||||||
|
handler_slot = nullptr;
|
||||||
|
revert_to_unused_handler(interrupt_number);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!handler_slot->is_shared_handler()) {
|
||||||
|
VERIFY(handler_slot->type() == HandlerType::IRQHandler);
|
||||||
|
handler_slot = nullptr;
|
||||||
|
revert_to_unused_handler(interrupt_number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize_interrupts()
|
void initialize_interrupts()
|
||||||
{
|
{
|
||||||
TODO_RISCV64();
|
for (size_t i = 0; i < s_interrupt_handlers.size(); ++i) {
|
||||||
|
auto* handler = new UnhandledInterruptHandler(i);
|
||||||
|
handler->register_interrupt_handler();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue