mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
Kernel: Introduce PCIIRQHandler
PCIIRQHandler is a generic IRQ handler that the device driver can inherit to use either Pin or MSI(x) based interrupt mechanism. The PCIIRQHandler can do what the existing IRQHandler can do for pin based interrupts but also deal with MSI based interrupts. We can hopefully convert all the PCI based devices to use this handler so that MSI(x) can be used.
This commit is contained in:
parent
82cf0bfb75
commit
feb48cbc7c
Notes:
sideshowbarker
2024-07-16 21:30:46 +09:00
Author: https://github.com/Panky-codes Commit: https://github.com/SerenityOS/serenity/commit/feb48cbc7c Pull-request: https://github.com/SerenityOS/serenity/pull/18580 Reviewed-by: https://github.com/gmta ✅ Reviewed-by: https://github.com/kleinesfilmroellchen Reviewed-by: https://github.com/supercomputer7 ✅
3 changed files with 114 additions and 0 deletions
|
@ -220,6 +220,7 @@ set(KERNEL_SOURCES
|
|||
FutexQueue.cpp
|
||||
Interrupts/GenericInterruptHandler.cpp
|
||||
Interrupts/IRQHandler.cpp
|
||||
Interrupts/PCIIRQHandler.cpp
|
||||
Interrupts/SharedIRQHandler.cpp
|
||||
Interrupts/UnhandledInterruptHandler.cpp
|
||||
KBufferBuilder.cpp
|
||||
|
|
66
Kernel/Interrupts/PCIIRQHandler.cpp
Normal file
66
Kernel/Interrupts/PCIIRQHandler.cpp
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Pankaj R <dev@pankajraghav.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <Kernel/Arch/InterruptManagement.h>
|
||||
#include <Kernel/Arch/PCIMSI.h>
|
||||
#include <Kernel/Debug.h>
|
||||
#include <Kernel/Interrupts/PCIIRQHandler.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
PCIIRQHandler::PCIIRQHandler(PCI::Device& device, u8 irq)
|
||||
: GenericInterruptHandler(irq)
|
||||
, device(device)
|
||||
{
|
||||
auto type = device.get_interrupt_type();
|
||||
|
||||
if (type == PCI::InterruptType::PIN)
|
||||
m_responsible_irq_controller = InterruptManagement::the().get_responsible_irq_controller(irq);
|
||||
|
||||
if (is_registered())
|
||||
disable_irq();
|
||||
}
|
||||
|
||||
bool PCIIRQHandler::eoi()
|
||||
{
|
||||
dbgln_if(IRQ_DEBUG, "EOI IRQ {}", interrupt_number());
|
||||
if (m_shared_with_others)
|
||||
return false;
|
||||
if (!m_responsible_irq_controller.is_null())
|
||||
m_responsible_irq_controller->eoi(*this);
|
||||
else
|
||||
msi_signal_eoi();
|
||||
return true;
|
||||
}
|
||||
|
||||
void PCIIRQHandler::enable_irq()
|
||||
{
|
||||
dbgln_if(IRQ_DEBUG, "Enable IRQ {}", interrupt_number());
|
||||
if (!is_registered())
|
||||
register_interrupt_handler();
|
||||
m_enabled = true;
|
||||
if (m_shared_with_others)
|
||||
return;
|
||||
if (!m_responsible_irq_controller.is_null())
|
||||
m_responsible_irq_controller->enable(*this);
|
||||
else
|
||||
device.enable_interrupt(interrupt_number());
|
||||
}
|
||||
|
||||
void PCIIRQHandler::disable_irq()
|
||||
{
|
||||
dbgln_if(IRQ_DEBUG, "Disable IRQ {}", interrupt_number());
|
||||
m_enabled = false;
|
||||
|
||||
if (m_shared_with_others)
|
||||
return;
|
||||
if (!m_responsible_irq_controller.is_null())
|
||||
m_responsible_irq_controller->disable(*this);
|
||||
else
|
||||
device.disable_interrupt(interrupt_number());
|
||||
}
|
||||
|
||||
}
|
47
Kernel/Interrupts/PCIIRQHandler.h
Normal file
47
Kernel/Interrupts/PCIIRQHandler.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Pankaj R <dev@pankajraghav.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Arch/IRQController.h>
|
||||
#include <Kernel/Bus/PCI/Device.h>
|
||||
#include <Kernel/Interrupts/GenericInterruptHandler.h>
|
||||
#include <Kernel/Library/LockRefPtr.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
class PCIIRQHandler : public GenericInterruptHandler {
|
||||
public:
|
||||
virtual ~PCIIRQHandler() = default;
|
||||
|
||||
virtual bool handle_interrupt(RegisterState const& regs) override { return handle_irq(regs); }
|
||||
virtual bool handle_irq(RegisterState const&) = 0;
|
||||
|
||||
void enable_irq();
|
||||
void disable_irq();
|
||||
|
||||
virtual bool eoi() override;
|
||||
|
||||
virtual HandlerType type() const override { return HandlerType::IRQHandler; }
|
||||
virtual StringView purpose() const override { return "IRQ Handler"sv; }
|
||||
virtual StringView controller() const override { return m_responsible_irq_controller.is_null() ? "PCI-MSI"sv : m_responsible_irq_controller->model(); }
|
||||
|
||||
virtual size_t sharing_devices_count() const override { return 0; }
|
||||
virtual bool is_shared_handler() const override { return false; }
|
||||
void set_shared_with_others(bool status) { m_shared_with_others = status; }
|
||||
|
||||
protected:
|
||||
PCIIRQHandler(PCI::Device& device, u8 irq);
|
||||
|
||||
private:
|
||||
bool m_shared_with_others { false };
|
||||
bool m_enabled { false };
|
||||
LockRefPtr<IRQController> m_responsible_irq_controller { nullptr };
|
||||
PCI::Device& device;
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in a new issue