mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
Kernel+lsirq: Stop using u8s for interrupt numbers
Architectures other than x86 support more than 256 interrupt sources, so using `u8`s for interrupt numbers is not appropriate. Instead, introduce a new `DistinctNumeric` "InterruptNumber" with an underlying type of `size_t`. Using a DistinctNumeric ensures that we don't accidentally convert interrupt numbers to `u8`s (again). Some places previously used `size_t`s for interrupts numbers, convert them to `InteruptNumber`s as well. Additionally, change the iteration variable of two for loops to avoid '-Werror=sign-compare' errors.
This commit is contained in:
1 parent
5efef0392e
commit
f8f25770d1
90 files changed
+301
-278
No files matched your search
@@ -9,6 +9,7 @@
|
||||
#include <AK/Error.h>
|
||||
#include <AK/Platform.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Interrupts/Interrupts.h>
|
||||
|
||||
#if ARCH(X86_64)
|
||||
# include <Kernel/Arch/x86_64/Interrupts.h>
|
||||
@@ -20,10 +21,10 @@ namespace Kernel {
|
||||
|
||||
class GenericInterruptHandler;
|
||||
|
||||
GenericInterruptHandler& get_interrupt_handler(u8 interrupt_number);
|
||||
void register_generic_interrupt_handler(u8 number, GenericInterruptHandler&);
|
||||
void unregister_generic_interrupt_handler(u8 number, GenericInterruptHandler&);
|
||||
ErrorOr<u8> reserve_interrupt_handlers(u8 number_of_irqs);
|
||||
GenericInterruptHandler& get_interrupt_handler(InterruptNumber);
|
||||
void register_generic_interrupt_handler(InterruptNumber, GenericInterruptHandler&);
|
||||
void unregister_generic_interrupt_handler(InterruptNumber, GenericInterruptHandler&);
|
||||
ErrorOr<InterruptNumber> reserve_interrupt_handlers(size_t number_of_irqs);
|
||||
|
||||
void initialize_interrupts();
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AK/AtomicRefCounted.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Interrupts/Interrupts.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
@@ -22,7 +23,7 @@ public:
|
||||
|
||||
virtual void eoi(GenericInterruptHandler const&) = 0;
|
||||
|
||||
virtual Optional<size_t> pending_interrupt() const = 0;
|
||||
virtual Optional<InterruptNumber> pending_interrupt() const = 0;
|
||||
|
||||
virtual StringView model() const = 0;
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ ErrorOr<void> InterruptManagement::register_interrupt_controller(NonnullLockRefP
|
||||
return s_interrupt_controllers->try_append(move(interrupt_controller));
|
||||
}
|
||||
|
||||
u8 InterruptManagement::acquire_mapped_interrupt_number(u8 interrupt_number)
|
||||
InterruptNumber InterruptManagement::acquire_mapped_interrupt_number(InterruptNumber interrupt_number)
|
||||
{
|
||||
return interrupt_number;
|
||||
}
|
||||
@@ -53,7 +53,7 @@ Vector<NonnullLockRefPtr<IRQController>> const& InterruptManagement::controllers
|
||||
return *s_interrupt_controllers;
|
||||
}
|
||||
|
||||
NonnullLockRefPtr<IRQController> InterruptManagement::get_responsible_irq_controller(u8)
|
||||
NonnullLockRefPtr<IRQController> InterruptManagement::get_responsible_irq_controller(InterruptNumber)
|
||||
{
|
||||
// TODO: Support more interrupt controllers
|
||||
VERIFY(s_interrupt_controllers->size() == 1);
|
||||
|
||||
@@ -20,10 +20,10 @@ public:
|
||||
|
||||
static ErrorOr<void> register_interrupt_controller(NonnullLockRefPtr<IRQController>);
|
||||
|
||||
static u8 acquire_mapped_interrupt_number(u8 original_irq);
|
||||
static InterruptNumber acquire_mapped_interrupt_number(InterruptNumber original_irq);
|
||||
|
||||
Vector<NonnullLockRefPtr<IRQController>> const& controllers();
|
||||
NonnullLockRefPtr<IRQController> get_responsible_irq_controller(u8 interrupt_vector);
|
||||
NonnullLockRefPtr<IRQController> get_responsible_irq_controller(InterruptNumber interrupt_vector);
|
||||
|
||||
void enumerate_interrupt_handlers(Function<void(GenericInterruptHandler&)>);
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ extern "C" void handle_interrupt(TrapFrame& trap_frame)
|
||||
if (!maybe_irq.has_value())
|
||||
break;
|
||||
|
||||
auto* handler = s_interrupt_handlers[maybe_irq.value()];
|
||||
auto* handler = s_interrupt_handlers[maybe_irq.value().value()];
|
||||
VERIFY(handler);
|
||||
handler->increment_call_count();
|
||||
handler->handle_interrupt();
|
||||
@@ -175,22 +175,22 @@ extern "C" void handle_interrupt(TrapFrame& trap_frame)
|
||||
|
||||
// FIXME: Share the code below with Arch/x86_64/Interrupts.cpp
|
||||
// While refactoring, the interrupt handlers can also be moved into the InterruptManagement class.
|
||||
GenericInterruptHandler& get_interrupt_handler(u8 interrupt_number)
|
||||
GenericInterruptHandler& get_interrupt_handler(InterruptNumber interrupt_number)
|
||||
{
|
||||
auto*& handler_slot = s_interrupt_handlers[interrupt_number];
|
||||
auto*& handler_slot = s_interrupt_handlers[interrupt_number.value()];
|
||||
VERIFY(handler_slot != nullptr);
|
||||
return *handler_slot;
|
||||
}
|
||||
|
||||
static void revert_to_unused_handler(u8 interrupt_number)
|
||||
static void revert_to_unused_handler(InterruptNumber interrupt_number)
|
||||
{
|
||||
auto handler = new UnhandledInterruptHandler(interrupt_number);
|
||||
handler->register_interrupt_handler();
|
||||
}
|
||||
|
||||
void register_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHandler& handler)
|
||||
void register_generic_interrupt_handler(InterruptNumber interrupt_number, GenericInterruptHandler& handler)
|
||||
{
|
||||
auto*& handler_slot = s_interrupt_handlers[interrupt_number];
|
||||
auto*& handler_slot = s_interrupt_handlers[interrupt_number.value()];
|
||||
if (handler_slot == nullptr) {
|
||||
handler_slot = &handler;
|
||||
return;
|
||||
@@ -224,9 +224,9 @@ void register_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHan
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
void unregister_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHandler& handler)
|
||||
void unregister_generic_interrupt_handler(InterruptNumber interrupt_number, GenericInterruptHandler& handler)
|
||||
{
|
||||
auto*& handler_slot = s_interrupt_handlers[interrupt_number];
|
||||
auto*& handler_slot = s_interrupt_handlers[interrupt_number.value()];
|
||||
VERIFY(handler_slot != nullptr);
|
||||
if (handler_slot->type() == HandlerType::UnhandledInterruptHandler)
|
||||
return;
|
||||
@@ -259,10 +259,10 @@ void initialize_interrupts()
|
||||
// Sets the reserved flag on `number_of_irqs` if it finds unused interrupt handler on
|
||||
// a contiguous range.
|
||||
// FIXME: Share the code below with Arch/x86_64/Interrupts.cpp.
|
||||
ErrorOr<u8> reserve_interrupt_handlers(u8 number_of_irqs)
|
||||
ErrorOr<InterruptNumber> reserve_interrupt_handlers(size_t number_of_irqs)
|
||||
{
|
||||
bool found_range = false;
|
||||
u8 first_irq = 0;
|
||||
InterruptNumber first_irq = 0;
|
||||
SpinlockLocker locker(s_interrupt_handler_lock);
|
||||
for (size_t start_irq = 0; start_irq < s_interrupt_handlers.size(); start_irq++) {
|
||||
auto*& handler_slot = s_interrupt_handlers[start_irq];
|
||||
@@ -272,7 +272,7 @@ ErrorOr<u8> reserve_interrupt_handlers(u8 number_of_irqs)
|
||||
continue;
|
||||
|
||||
found_range = true;
|
||||
for (auto off = 1; off < number_of_irqs; off++) {
|
||||
for (size_t off = 1; off < number_of_irqs; off++) {
|
||||
auto*& handler = s_interrupt_handlers[start_irq + off];
|
||||
VERIFY(handler_slot != nullptr);
|
||||
|
||||
@@ -292,7 +292,7 @@ ErrorOr<u8> reserve_interrupt_handlers(u8 number_of_irqs)
|
||||
return Error::from_errno(EAGAIN);
|
||||
|
||||
for (auto irq = first_irq; irq < number_of_irqs; irq++) {
|
||||
auto*& handler_slot = s_interrupt_handlers[irq];
|
||||
auto*& handler_slot = s_interrupt_handlers[irq.value()];
|
||||
handler_slot->set_reserved();
|
||||
}
|
||||
|
||||
|
||||
@@ -106,22 +106,22 @@ void GICv2::enable(GenericInterruptHandler const& handler)
|
||||
// FIXME: Set the trigger mode in DistributorRegisters::interrupt_configuration (GICD_ICFGRn) to level-triggered or edge-triggered.
|
||||
|
||||
auto interrupt_number = handler.interrupt_number();
|
||||
m_distributor_registers->interrupt_set_enable[interrupt_number / 32] = 1 << (interrupt_number % 32);
|
||||
m_distributor_registers->interrupt_set_enable[interrupt_number.value() / 32] = 1 << (interrupt_number.value() % 32);
|
||||
}
|
||||
|
||||
void GICv2::disable(GenericInterruptHandler const& handler)
|
||||
{
|
||||
auto interrupt_number = handler.interrupt_number();
|
||||
m_distributor_registers->interrupt_clear_enable[interrupt_number / 32] = 1 << (interrupt_number % 32);
|
||||
m_distributor_registers->interrupt_clear_enable[interrupt_number.value() / 32] = 1 << (interrupt_number.value() % 32);
|
||||
}
|
||||
|
||||
void GICv2::eoi(GenericInterruptHandler const& handler)
|
||||
{
|
||||
auto interrupt_number = handler.interrupt_number();
|
||||
m_cpu_interface_registers->end_of_interrupt = interrupt_number;
|
||||
m_cpu_interface_registers->end_of_interrupt = interrupt_number.value();
|
||||
}
|
||||
|
||||
Optional<size_t> GICv2::pending_interrupt() const
|
||||
Optional<InterruptNumber> GICv2::pending_interrupt() const
|
||||
{
|
||||
auto interrupt_number = m_cpu_interface_registers->interrupt_acknowledge;
|
||||
|
||||
@@ -132,7 +132,7 @@ Optional<size_t> GICv2::pending_interrupt() const
|
||||
return interrupt_number;
|
||||
}
|
||||
|
||||
ErrorOr<size_t> GICv2::translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes interrupt_specifier) const
|
||||
ErrorOr<InterruptNumber> GICv2::translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes interrupt_specifier) const
|
||||
{
|
||||
// https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
|
||||
|
||||
|
||||
@@ -27,12 +27,12 @@ public:
|
||||
|
||||
virtual void eoi(GenericInterruptHandler const&) override;
|
||||
|
||||
virtual Optional<size_t> pending_interrupt() const override;
|
||||
virtual Optional<InterruptNumber> pending_interrupt() const override;
|
||||
|
||||
virtual StringView model() const override { return "GICv2"sv; }
|
||||
|
||||
// ^DeviceTree::InterruptController
|
||||
virtual ErrorOr<size_t> translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes) const override;
|
||||
virtual ErrorOr<InterruptNumber> translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes) const override;
|
||||
|
||||
struct DistributorRegisters;
|
||||
struct CPUInterfaceRegisters;
|
||||
|
||||
@@ -106,9 +106,9 @@ void GICv3::enable(GenericInterruptHandler const& handler)
|
||||
auto interrupt_number = handler.interrupt_number();
|
||||
|
||||
if (interrupt_number < SHARED_PERIPHERAL_INTERRUPT_RANGE_START)
|
||||
m_redistributor_registers[m_boot_cpu_redistributor_index]->sgis_and_ppis.interrupt_set_enable[interrupt_number / 32] = 1 << (interrupt_number % 32);
|
||||
m_redistributor_registers[m_boot_cpu_redistributor_index]->sgis_and_ppis.interrupt_set_enable[interrupt_number.value() / 32] = 1 << (interrupt_number.value() % 32);
|
||||
else
|
||||
m_distributor_registers->interrupt_set_enable[interrupt_number / 32] = 1 << (interrupt_number % 32);
|
||||
m_distributor_registers->interrupt_set_enable[interrupt_number.value() / 32] = 1 << (interrupt_number.value() % 32);
|
||||
}
|
||||
|
||||
void GICv3::disable(GenericInterruptHandler const& handler)
|
||||
@@ -116,18 +116,18 @@ void GICv3::disable(GenericInterruptHandler const& handler)
|
||||
auto interrupt_number = handler.interrupt_number();
|
||||
|
||||
if (interrupt_number < SHARED_PERIPHERAL_INTERRUPT_RANGE_START)
|
||||
m_redistributor_registers[m_boot_cpu_redistributor_index]->sgis_and_ppis.interrupt_clear_enable[interrupt_number / 32] = 1 << (interrupt_number % 32);
|
||||
m_redistributor_registers[m_boot_cpu_redistributor_index]->sgis_and_ppis.interrupt_clear_enable[interrupt_number.value() / 32] = 1 << (interrupt_number.value() % 32);
|
||||
else
|
||||
m_distributor_registers->interrupt_clear_enable[interrupt_number / 32] = 1 << (interrupt_number % 32);
|
||||
m_distributor_registers->interrupt_clear_enable[interrupt_number.value() / 32] = 1 << (interrupt_number.value() % 32);
|
||||
}
|
||||
|
||||
void GICv3::eoi(GenericInterruptHandler const& handler)
|
||||
{
|
||||
auto interrupt_number = handler.interrupt_number();
|
||||
Aarch64::ICC_EOIR1_EL1::write({ .INTID = interrupt_number });
|
||||
Aarch64::ICC_EOIR1_EL1::write({ .INTID = interrupt_number.value() });
|
||||
}
|
||||
|
||||
Optional<size_t> GICv3::pending_interrupt() const
|
||||
Optional<InterruptNumber> GICv3::pending_interrupt() const
|
||||
{
|
||||
auto interrupt_number = Aarch64::ICC_IAR1_EL1::read().INTID;
|
||||
|
||||
@@ -143,7 +143,7 @@ Optional<size_t> GICv3::pending_interrupt() const
|
||||
return interrupt_number;
|
||||
}
|
||||
|
||||
ErrorOr<size_t> GICv3::translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes interrupt_specifier) const
|
||||
ErrorOr<InterruptNumber> GICv3::translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes interrupt_specifier) const
|
||||
{
|
||||
// https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
|
||||
|
||||
|
||||
@@ -28,12 +28,12 @@ public:
|
||||
|
||||
virtual void eoi(GenericInterruptHandler const&) override;
|
||||
|
||||
virtual Optional<size_t> pending_interrupt() const override;
|
||||
virtual Optional<InterruptNumber> pending_interrupt() const override;
|
||||
|
||||
virtual StringView model() const override { return "GICv3"sv; }
|
||||
|
||||
// ^DeviceTree::InterruptController
|
||||
virtual ErrorOr<size_t> translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes) const override;
|
||||
virtual ErrorOr<InterruptNumber> translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes) const override;
|
||||
|
||||
struct DistributorRegisters;
|
||||
struct RedistributorRegisters;
|
||||
|
||||
@@ -38,24 +38,24 @@ InterruptController::InterruptController(Memory::TypedMapping<InterruptControlle
|
||||
|
||||
void InterruptController::enable(GenericInterruptHandler const& handler)
|
||||
{
|
||||
u8 interrupt_number = handler.interrupt_number();
|
||||
InterruptNumber interrupt_number = handler.interrupt_number();
|
||||
VERIFY(interrupt_number < 64);
|
||||
|
||||
if (interrupt_number < 32)
|
||||
m_registers->enable_irqs_1 = m_registers->enable_irqs_1 | (1 << interrupt_number);
|
||||
m_registers->enable_irqs_1 = m_registers->enable_irqs_1 | (1 << interrupt_number.value());
|
||||
else
|
||||
m_registers->enable_irqs_2 = m_registers->enable_irqs_2 | (1 << (interrupt_number - 32));
|
||||
m_registers->enable_irqs_2 = m_registers->enable_irqs_2 | (1 << (interrupt_number.value() - 32));
|
||||
}
|
||||
|
||||
void InterruptController::disable(GenericInterruptHandler const& handler)
|
||||
{
|
||||
u8 interrupt_number = handler.interrupt_number();
|
||||
InterruptNumber interrupt_number = handler.interrupt_number();
|
||||
VERIFY(interrupt_number < 64);
|
||||
|
||||
if (interrupt_number < 32)
|
||||
m_registers->disable_irqs_1 = m_registers->disable_irqs_1 | (1 << interrupt_number);
|
||||
m_registers->disable_irqs_1 = m_registers->disable_irqs_1 | (1 << interrupt_number.value());
|
||||
else
|
||||
m_registers->disable_irqs_2 = m_registers->disable_irqs_2 | (1 << (interrupt_number - 32));
|
||||
m_registers->disable_irqs_2 = m_registers->disable_irqs_2 | (1 << (interrupt_number.value() - 32));
|
||||
}
|
||||
|
||||
void InterruptController::eoi(GenericInterruptHandler const&)
|
||||
@@ -64,7 +64,7 @@ void InterruptController::eoi(GenericInterruptHandler const&)
|
||||
// The interrupt should be cleared by the corresponding device driver, such as a timer or uart.
|
||||
}
|
||||
|
||||
Optional<size_t> InterruptController::pending_interrupt() const
|
||||
Optional<InterruptNumber> InterruptController::pending_interrupt() const
|
||||
{
|
||||
auto irq_number_plus_one = bit_scan_forward(((u64)m_registers->irq_pending_2 << 32) | (u64)m_registers->irq_pending_1);
|
||||
if (irq_number_plus_one == 0)
|
||||
@@ -72,7 +72,7 @@ Optional<size_t> InterruptController::pending_interrupt() const
|
||||
return irq_number_plus_one - 1;
|
||||
}
|
||||
|
||||
ErrorOr<size_t> InterruptController::translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes interrupt_specifier) const
|
||||
ErrorOr<InterruptNumber> InterruptController::translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes interrupt_specifier) const
|
||||
{
|
||||
// https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ private:
|
||||
|
||||
virtual void eoi(GenericInterruptHandler const&) override;
|
||||
|
||||
virtual Optional<size_t> pending_interrupt() const override;
|
||||
virtual Optional<InterruptNumber> pending_interrupt() const override;
|
||||
|
||||
virtual StringView model() const override
|
||||
{
|
||||
@@ -39,7 +39,7 @@ private:
|
||||
}
|
||||
|
||||
// ^DeviceTree::InterruptController
|
||||
virtual ErrorOr<size_t> translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes) const override;
|
||||
virtual ErrorOr<InterruptNumber> translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes) const override;
|
||||
|
||||
Memory::TypedMapping<InterruptControllerRegisters volatile> m_registers;
|
||||
};
|
||||
|
||||
@@ -17,10 +17,10 @@ namespace Kernel::RPi {
|
||||
|
||||
class RP1xHCIController final : public USB::xHCI::xHCIController {
|
||||
public:
|
||||
static ErrorOr<NonnullLockRefPtr<RP1xHCIController>> try_to_initialize(PhysicalAddress, size_t index, size_t interrupt_number);
|
||||
static ErrorOr<NonnullLockRefPtr<RP1xHCIController>> try_to_initialize(PhysicalAddress, size_t index, InterruptNumber interrupt_number);
|
||||
|
||||
private:
|
||||
RP1xHCIController(Memory::TypedMapping<u8> registers_mapping, size_t index, size_t interrupt_number);
|
||||
RP1xHCIController(Memory::TypedMapping<u8> registers_mapping, size_t index, InterruptNumber interrupt_number);
|
||||
|
||||
// ^xHCIController
|
||||
virtual bool using_message_signalled_interrupts() const override { return m_using_message_signalled_interrupts; }
|
||||
@@ -32,11 +32,11 @@ private:
|
||||
}
|
||||
|
||||
size_t m_index { 0 };
|
||||
size_t m_interrupt_number { 0 };
|
||||
InterruptNumber m_interrupt_number { 0 };
|
||||
bool m_using_message_signalled_interrupts { false };
|
||||
};
|
||||
|
||||
ErrorOr<NonnullLockRefPtr<RP1xHCIController>> RP1xHCIController::try_to_initialize(PhysicalAddress paddr, size_t index, size_t interrupt_number)
|
||||
ErrorOr<NonnullLockRefPtr<RP1xHCIController>> RP1xHCIController::try_to_initialize(PhysicalAddress paddr, size_t index, InterruptNumber interrupt_number)
|
||||
{
|
||||
auto registers_mapping = TRY(Memory::map_typed_writable<u8>(paddr));
|
||||
|
||||
@@ -45,7 +45,7 @@ ErrorOr<NonnullLockRefPtr<RP1xHCIController>> RP1xHCIController::try_to_initiali
|
||||
return controller;
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT RP1xHCIController::RP1xHCIController(Memory::TypedMapping<u8> registers_mapping, size_t index, size_t interrupt_number)
|
||||
UNMAP_AFTER_INIT RP1xHCIController::RP1xHCIController(Memory::TypedMapping<u8> registers_mapping, size_t index, InterruptNumber interrupt_number)
|
||||
: xHCIController(move(registers_mapping))
|
||||
, m_index(index)
|
||||
, m_interrupt_number(interrupt_number)
|
||||
|
||||
@@ -33,7 +33,7 @@ enum FlagBits {
|
||||
SystemTimerMatch3 = 1 << 3,
|
||||
};
|
||||
|
||||
Timer::Timer(Memory::TypedMapping<TimerRegisters volatile> registers_mapping, size_t interrupt_number)
|
||||
Timer::Timer(Memory::TypedMapping<TimerRegisters volatile> registers_mapping, InterruptNumber interrupt_number)
|
||||
: HardwareTimer(interrupt_number)
|
||||
, m_registers(move(registers_mapping))
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ struct TimerRegisters;
|
||||
|
||||
class Timer final : public HardwareTimer<IRQHandler> {
|
||||
public:
|
||||
Timer(Memory::TypedMapping<TimerRegisters volatile>, size_t interrupt_number);
|
||||
Timer(Memory::TypedMapping<TimerRegisters volatile>, InterruptNumber interrupt_number);
|
||||
virtual ~Timer();
|
||||
|
||||
virtual HardwareTimerType timer_type() const override { return HardwareTimerType::RPiTimer; }
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Kernel {
|
||||
|
||||
static ARMv8Timer* s_the = nullptr;
|
||||
|
||||
ARMv8Timer::ARMv8Timer(u8 interrupt_number, u32 frequency)
|
||||
ARMv8Timer::ARMv8Timer(InterruptNumber interrupt_number, u32 frequency)
|
||||
: HardwareTimer(interrupt_number)
|
||||
, m_frequency(frequency)
|
||||
{
|
||||
@@ -23,7 +23,7 @@ ARMv8Timer::ARMv8Timer(u8 interrupt_number, u32 frequency)
|
||||
start_timer(m_interrupt_interval);
|
||||
}
|
||||
|
||||
ErrorOr<NonnullLockRefPtr<ARMv8Timer>> ARMv8Timer::initialize(u8 interrupt_number, u32 frequency)
|
||||
ErrorOr<NonnullLockRefPtr<ARMv8Timer>> ARMv8Timer::initialize(InterruptNumber interrupt_number, u32 frequency)
|
||||
{
|
||||
auto timer = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) ARMv8Timer(interrupt_number, frequency)));
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Kernel {
|
||||
|
||||
class ARMv8Timer final : public HardwareTimer<IRQHandler> {
|
||||
public:
|
||||
static ErrorOr<NonnullLockRefPtr<ARMv8Timer>> initialize(u8 interrupt_number, u32 frequency);
|
||||
static ErrorOr<NonnullLockRefPtr<ARMv8Timer>> initialize(InterruptNumber interrupt_number, u32 frequency);
|
||||
|
||||
static bool is_initialized();
|
||||
static ARMv8Timer& the();
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
u64 update_time(u64& seconds_since_boot, u32& ticks_this_second, bool query_only);
|
||||
|
||||
private:
|
||||
ARMv8Timer(u8 interrupt_number, u32 frequency);
|
||||
ARMv8Timer(InterruptNumber interrupt_number, u32 frequency);
|
||||
|
||||
static u64 current_ticks();
|
||||
static void start_timer(u32 delta);
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
|
||||
virtual void eoi(GenericInterruptHandler const&) = 0;
|
||||
|
||||
virtual Optional<u8> pending_interrupt() const = 0;
|
||||
virtual Optional<InterruptNumber> pending_interrupt() const = 0;
|
||||
|
||||
virtual StringView model() const = 0;
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ ErrorOr<void> InterruptManagement::register_interrupt_controller(NonnullLockRefP
|
||||
return s_interrupt_controllers->try_append(move(interrupt_controller));
|
||||
}
|
||||
|
||||
u8 InterruptManagement::acquire_mapped_interrupt_number(u8 original_irq)
|
||||
InterruptNumber InterruptManagement::acquire_mapped_interrupt_number(InterruptNumber original_irq)
|
||||
{
|
||||
return original_irq;
|
||||
}
|
||||
@@ -54,7 +54,7 @@ Vector<NonnullLockRefPtr<IRQController>> const& InterruptManagement::controllers
|
||||
return *s_interrupt_controllers;
|
||||
}
|
||||
|
||||
NonnullLockRefPtr<IRQController> InterruptManagement::get_responsible_irq_controller(size_t)
|
||||
NonnullLockRefPtr<IRQController> InterruptManagement::get_responsible_irq_controller(InterruptNumber)
|
||||
{
|
||||
// TODO: Support more interrupt controllers
|
||||
VERIFY(s_interrupt_controllers->size() == 1);
|
||||
|
||||
@@ -23,10 +23,10 @@ public:
|
||||
|
||||
static ErrorOr<void> register_interrupt_controller(NonnullLockRefPtr<IRQController>);
|
||||
|
||||
static u8 acquire_mapped_interrupt_number(u8 original_irq);
|
||||
static InterruptNumber acquire_mapped_interrupt_number(InterruptNumber original_irq);
|
||||
|
||||
Vector<NonnullLockRefPtr<IRQController>> const& controllers();
|
||||
NonnullLockRefPtr<IRQController> get_responsible_irq_controller(size_t irq_number);
|
||||
NonnullLockRefPtr<IRQController> get_responsible_irq_controller(InterruptNumber irq_number);
|
||||
|
||||
void enumerate_interrupt_handlers(Function<void(GenericInterruptHandler&)>);
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ extern "C" void trap_handler(TrapFrame& trap_frame)
|
||||
if (!maybe_interrupt_number.has_value())
|
||||
break;
|
||||
|
||||
auto* handler = s_interrupt_handlers[maybe_interrupt_number.value()];
|
||||
auto* handler = s_interrupt_handlers[maybe_interrupt_number.value().value()];
|
||||
VERIFY(handler);
|
||||
handler->increment_call_count();
|
||||
handler->handle_interrupt();
|
||||
@@ -169,30 +169,30 @@ extern "C" void trap_handler(TrapFrame& trap_frame)
|
||||
|
||||
// FIXME: Share the code below with Arch/x86_64/Interrupts.cpp
|
||||
// While refactoring, the interrupt handlers can also be moved into the InterruptManagement class.
|
||||
GenericInterruptHandler& get_interrupt_handler(u8 interrupt_number)
|
||||
GenericInterruptHandler& get_interrupt_handler(InterruptNumber interrupt_number)
|
||||
{
|
||||
auto*& handler_slot = s_interrupt_handlers[interrupt_number];
|
||||
auto*& handler_slot = s_interrupt_handlers[interrupt_number.value()];
|
||||
VERIFY(handler_slot != nullptr);
|
||||
return *handler_slot;
|
||||
}
|
||||
|
||||
// Sets the reserved flag on `number_of_irqs` if it finds unused interrupt handler on
|
||||
// a contiguous range.
|
||||
ErrorOr<u8> reserve_interrupt_handlers(u8)
|
||||
ErrorOr<InterruptNumber> reserve_interrupt_handlers(size_t)
|
||||
{
|
||||
TODO_RISCV64();
|
||||
}
|
||||
|
||||
static void revert_to_unused_handler(u8 interrupt_number)
|
||||
static void revert_to_unused_handler(InterruptNumber interrupt_number)
|
||||
{
|
||||
auto* handler = new UnhandledInterruptHandler(interrupt_number);
|
||||
handler->register_interrupt_handler();
|
||||
}
|
||||
|
||||
// FIXME: Share the code below with Arch/{x86_64,aarch64}/Interrupts.cpp
|
||||
void register_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHandler& handler)
|
||||
void register_generic_interrupt_handler(InterruptNumber interrupt_number, GenericInterruptHandler& handler)
|
||||
{
|
||||
auto*& handler_slot = s_interrupt_handlers[interrupt_number];
|
||||
auto*& handler_slot = s_interrupt_handlers[interrupt_number.value()];
|
||||
if (handler_slot == nullptr) {
|
||||
handler_slot = &handler;
|
||||
return;
|
||||
@@ -227,9 +227,9 @@ void register_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHan
|
||||
}
|
||||
|
||||
// FIXME: Share the code below with Arch/{x86_64,aarch64}/Interrupts.cpp
|
||||
void unregister_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHandler& handler)
|
||||
void unregister_generic_interrupt_handler(InterruptNumber interrupt_number, GenericInterruptHandler& handler)
|
||||
{
|
||||
auto*& handler_slot = s_interrupt_handlers[interrupt_number];
|
||||
auto*& handler_slot = s_interrupt_handlers[interrupt_number.value()];
|
||||
VERIFY(handler_slot != nullptr);
|
||||
if (handler_slot->type() == HandlerType::UnhandledInterruptHandler)
|
||||
return;
|
||||
|
||||
@@ -18,7 +18,6 @@ UNMAP_AFTER_INIT PLIC::PLIC(Memory::TypedMapping<RegisterMap volatile> registers
|
||||
, m_interrupt_count(interrupt_count)
|
||||
, m_boot_hart_supervisor_mode_context_id(boot_hart_supervisor_mode_context_id)
|
||||
{
|
||||
VERIFY(m_interrupt_count < 256); // TODO: Serenity currently only supports up to 256 unique interrupts, but the PLIC supports up to 1024
|
||||
initialize();
|
||||
}
|
||||
|
||||
@@ -42,22 +41,22 @@ void PLIC::enable(GenericInterruptHandler const& handler)
|
||||
{
|
||||
auto interrupt_number = handler.interrupt_number();
|
||||
VERIFY(interrupt_number > 0); // Interrupt number 0 is reserved to mean no-interrupt
|
||||
m_registers->interrupt_enable_bitmap[m_boot_hart_supervisor_mode_context_id][interrupt_number >> 5] |= 1u << (interrupt_number & 0x1F);
|
||||
m_registers->interrupt_enable_bitmap[m_boot_hart_supervisor_mode_context_id][interrupt_number.value() >> 5] |= 1u << (interrupt_number.value() & 0x1F);
|
||||
}
|
||||
|
||||
void PLIC::disable(GenericInterruptHandler const& handler)
|
||||
{
|
||||
auto interrupt_number = handler.interrupt_number();
|
||||
VERIFY(interrupt_number > 0); // Interrupt number 0 is reserved to mean no-interrupt
|
||||
m_registers->interrupt_enable_bitmap[m_boot_hart_supervisor_mode_context_id][interrupt_number >> 5] &= ~(1u << (interrupt_number & 0x1F));
|
||||
m_registers->interrupt_enable_bitmap[m_boot_hart_supervisor_mode_context_id][interrupt_number.value() >> 5] &= ~(1u << (interrupt_number.value() & 0x1F));
|
||||
}
|
||||
|
||||
void PLIC::eoi(GenericInterruptHandler const& handler)
|
||||
{
|
||||
m_registers->contexts[m_boot_hart_supervisor_mode_context_id].claim_complete = handler.interrupt_number();
|
||||
m_registers->contexts[m_boot_hart_supervisor_mode_context_id].claim_complete = handler.interrupt_number().value();
|
||||
}
|
||||
|
||||
Optional<u8> PLIC::pending_interrupt() const
|
||||
Optional<InterruptNumber> PLIC::pending_interrupt() const
|
||||
{
|
||||
auto interrupt_number = m_registers->contexts[m_boot_hart_supervisor_mode_context_id].claim_complete;
|
||||
|
||||
@@ -68,7 +67,7 @@ Optional<u8> PLIC::pending_interrupt() const
|
||||
return interrupt_number;
|
||||
}
|
||||
|
||||
ErrorOr<size_t> PLIC::translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes interrupt_specifier) const
|
||||
ErrorOr<InterruptNumber> PLIC::translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes interrupt_specifier) const
|
||||
{
|
||||
// https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
|
||||
// For generic PLICs the #interrupt-cells property should be 1 and the interrupt specifier should simply be the interrupt number.
|
||||
|
||||
@@ -37,12 +37,12 @@ public:
|
||||
|
||||
virtual void eoi(GenericInterruptHandler const&) override;
|
||||
|
||||
virtual Optional<u8> pending_interrupt() const override;
|
||||
virtual Optional<InterruptNumber> pending_interrupt() const override;
|
||||
|
||||
virtual StringView model() const override { return "PLIC"sv; }
|
||||
|
||||
// ^DeviceTree::InterruptController
|
||||
virtual ErrorOr<size_t> translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes) const override;
|
||||
virtual ErrorOr<InterruptNumber> translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes) const override;
|
||||
|
||||
private:
|
||||
void initialize();
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <AK/AtomicRefCounted.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Interrupts/GenericInterruptHandler.h>
|
||||
#include <Kernel/Interrupts/Interrupts.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
@@ -26,7 +27,7 @@ public:
|
||||
virtual void enable(GenericInterruptHandler const&) = 0;
|
||||
virtual void disable(GenericInterruptHandler const&) = 0;
|
||||
virtual void hard_disable() { m_hard_disabled = true; }
|
||||
virtual bool is_vector_enabled(u8 number) const = 0;
|
||||
virtual bool is_vector_enabled(InterruptNumber) const = 0;
|
||||
virtual bool is_enabled() const = 0;
|
||||
bool is_hard_disabled() const { return m_hard_disabled; }
|
||||
virtual void eoi(GenericInterruptHandler const&) const = 0;
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Kernel {
|
||||
#define IRQ_FIRST_PORT 1
|
||||
#define IRQ_SECOND_PORT 12
|
||||
|
||||
UNMAP_AFTER_INIT ErrorOr<NonnullOwnPtr<I8042ControllerIRQHandler>> I8042ControllerIRQHandler::try_create(I8042Controller const& controller, u8 irq_number)
|
||||
UNMAP_AFTER_INIT ErrorOr<NonnullOwnPtr<I8042ControllerIRQHandler>> I8042ControllerIRQHandler::try_create(I8042Controller const& controller, InterruptNumber irq_number)
|
||||
{
|
||||
return adopt_nonnull_own_or_enomem(new I8042ControllerIRQHandler(controller, irq_number));
|
||||
}
|
||||
@@ -32,7 +32,7 @@ bool I8042ControllerIRQHandler::handle_irq()
|
||||
return m_controller->handle_irq({}, interrupt_number());
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT I8042ControllerIRQHandler::I8042ControllerIRQHandler(I8042Controller const& controller, u8 irq_number)
|
||||
UNMAP_AFTER_INIT I8042ControllerIRQHandler::I8042ControllerIRQHandler(I8042Controller const& controller, InterruptNumber irq_number)
|
||||
: IRQHandler(irq_number)
|
||||
, m_controller(controller)
|
||||
{
|
||||
@@ -47,7 +47,7 @@ UNMAP_AFTER_INIT I8042Controller::I8042Controller()
|
||||
{
|
||||
}
|
||||
|
||||
bool I8042Controller::handle_irq(Badge<I8042ControllerIRQHandler>, u8 irq_number)
|
||||
bool I8042Controller::handle_irq(Badge<I8042ControllerIRQHandler>, InterruptNumber irq_number)
|
||||
{
|
||||
// NOTE: The controller will read the data and call handle_byte_read_from_serial_input
|
||||
// for the appropriate device.
|
||||
|
||||
@@ -74,10 +74,10 @@ class I8042Controller;
|
||||
class I8042ControllerIRQHandler final
|
||||
: public IRQHandler {
|
||||
public:
|
||||
static ErrorOr<NonnullOwnPtr<I8042ControllerIRQHandler>> try_create(I8042Controller const&, u8 irq_number);
|
||||
static ErrorOr<NonnullOwnPtr<I8042ControllerIRQHandler>> try_create(I8042Controller const&, InterruptNumber irq_number);
|
||||
|
||||
private:
|
||||
I8042ControllerIRQHandler(I8042Controller const& controller, u8 irq_number);
|
||||
I8042ControllerIRQHandler(I8042Controller const& controller, InterruptNumber irq_number);
|
||||
|
||||
// ^IRQHandler
|
||||
virtual bool handle_irq() override;
|
||||
@@ -118,7 +118,7 @@ public:
|
||||
// Note: This function exists only for the initialization process of the controller
|
||||
bool check_existence_via_probing(Badge<InputManagement>);
|
||||
|
||||
bool handle_irq(Badge<I8042ControllerIRQHandler>, u8 irq_number);
|
||||
bool handle_irq(Badge<I8042ControllerIRQHandler>, InterruptNumber irq_number);
|
||||
|
||||
private:
|
||||
I8042Controller();
|
||||
|
||||
@@ -67,7 +67,7 @@ IRQController& InterruptManagement::get_interrupt_controller(size_t index)
|
||||
return *m_interrupt_controllers[index];
|
||||
}
|
||||
|
||||
u8 InterruptManagement::acquire_mapped_interrupt_number(u8 original_irq)
|
||||
InterruptNumber InterruptManagement::acquire_mapped_interrupt_number(InterruptNumber original_irq)
|
||||
{
|
||||
if (!InterruptManagement::initialized()) {
|
||||
// This is necessary, because we install UnhandledInterruptHandlers before we actually initialize the Interrupt Management object...
|
||||
@@ -76,25 +76,25 @@ u8 InterruptManagement::acquire_mapped_interrupt_number(u8 original_irq)
|
||||
return InterruptManagement::the().get_mapped_interrupt_vector(original_irq);
|
||||
}
|
||||
|
||||
u8 InterruptManagement::acquire_irq_number(u8 mapped_interrupt_vector)
|
||||
InterruptNumber InterruptManagement::acquire_irq_number(InterruptNumber mapped_interrupt_vector)
|
||||
{
|
||||
VERIFY(InterruptManagement::initialized());
|
||||
return InterruptManagement::the().get_irq_vector(mapped_interrupt_vector);
|
||||
}
|
||||
|
||||
u8 InterruptManagement::get_mapped_interrupt_vector(u8 original_irq)
|
||||
InterruptNumber InterruptManagement::get_mapped_interrupt_vector(InterruptNumber original_irq)
|
||||
{
|
||||
// FIXME: For SMP configuration (with IOAPICs) use a better routing scheme to make redirections more efficient.
|
||||
return original_irq;
|
||||
}
|
||||
|
||||
u8 InterruptManagement::get_irq_vector(u8 mapped_interrupt_vector)
|
||||
InterruptNumber InterruptManagement::get_irq_vector(InterruptNumber mapped_interrupt_vector)
|
||||
{
|
||||
// FIXME: For SMP configuration (with IOAPICs) use a better routing scheme to make redirections more efficient.
|
||||
return mapped_interrupt_vector;
|
||||
}
|
||||
|
||||
NonnullLockRefPtr<IRQController> InterruptManagement::get_responsible_irq_controller(IRQControllerType controller_type, u8 interrupt_vector)
|
||||
NonnullLockRefPtr<IRQController> InterruptManagement::get_responsible_irq_controller(IRQControllerType controller_type, InterruptNumber interrupt_vector)
|
||||
{
|
||||
for (auto& irq_controller : m_interrupt_controllers) {
|
||||
if (irq_controller->gsi_base() <= interrupt_vector && irq_controller->type() == controller_type)
|
||||
@@ -103,7 +103,7 @@ NonnullLockRefPtr<IRQController> InterruptManagement::get_responsible_irq_contro
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
NonnullLockRefPtr<IRQController> InterruptManagement::get_responsible_irq_controller(u8 interrupt_vector)
|
||||
NonnullLockRefPtr<IRQController> InterruptManagement::get_responsible_irq_controller(InterruptNumber interrupt_vector)
|
||||
{
|
||||
if (m_interrupt_controllers.size() == 1 && m_interrupt_controllers[0]->type() == IRQControllerType::i8259) {
|
||||
return m_interrupt_controllers[0];
|
||||
|
||||
@@ -45,19 +45,19 @@ public:
|
||||
static InterruptManagement& the();
|
||||
static void initialize();
|
||||
static bool initialized();
|
||||
static u8 acquire_mapped_interrupt_number(u8 original_irq);
|
||||
static u8 acquire_irq_number(u8 mapped_interrupt_vector);
|
||||
static InterruptNumber acquire_mapped_interrupt_number(InterruptNumber original_irq);
|
||||
static InterruptNumber acquire_irq_number(InterruptNumber mapped_interrupt_vector);
|
||||
|
||||
void switch_to_pic_mode();
|
||||
void switch_to_ioapic_mode();
|
||||
|
||||
NonnullLockRefPtr<IRQController> get_responsible_irq_controller(u8 interrupt_vector);
|
||||
NonnullLockRefPtr<IRQController> get_responsible_irq_controller(IRQControllerType controller_type, u8 interrupt_vector);
|
||||
NonnullLockRefPtr<IRQController> get_responsible_irq_controller(InterruptNumber interrupt_vector);
|
||||
NonnullLockRefPtr<IRQController> get_responsible_irq_controller(IRQControllerType controller_type, InterruptNumber interrupt_vector);
|
||||
|
||||
Vector<ISAInterruptOverrideMetadata> const& isa_overrides() const { return m_isa_interrupt_overrides; }
|
||||
|
||||
u8 get_mapped_interrupt_vector(u8 original_irq);
|
||||
u8 get_irq_vector(u8 mapped_interrupt_vector);
|
||||
InterruptNumber get_mapped_interrupt_vector(InterruptNumber original_irq);
|
||||
InterruptNumber get_irq_vector(InterruptNumber mapped_interrupt_vector);
|
||||
|
||||
void enumerate_interrupt_handlers(Function<void(GenericInterruptHandler&)>);
|
||||
IRQController& get_interrupt_controller(size_t index);
|
||||
|
||||
@@ -301,7 +301,7 @@ void handle_interrupt(TrapFrame* trap)
|
||||
// reserved for when the PIC is disabled, so we can still route spurious
|
||||
// IRQs to a different interrupt handlers at different location.
|
||||
if (regs.isr_number >= pic_disabled_vector_base && regs.isr_number <= pic_disabled_vector_end) {
|
||||
u8 irq = (u8)(regs.isr_number - pic_disabled_vector_base);
|
||||
InterruptNumber irq = (InterruptNumber)(regs.isr_number - pic_disabled_vector_base);
|
||||
if (irq == 7) {
|
||||
handler = s_disabled_interrupt_handler[0];
|
||||
} else if (irq == 15) {
|
||||
@@ -309,9 +309,9 @@ void handle_interrupt(TrapFrame* trap)
|
||||
}
|
||||
} else {
|
||||
VERIFY(regs.isr_number >= IRQ_VECTOR_BASE && regs.isr_number <= (IRQ_VECTOR_BASE + GENERIC_INTERRUPT_HANDLERS_COUNT));
|
||||
u8 irq = (u8)(regs.isr_number - IRQ_VECTOR_BASE);
|
||||
InterruptNumber irq = (InterruptNumber)(regs.isr_number - IRQ_VECTOR_BASE);
|
||||
s_entropy_source_interrupts.add_random_event(irq);
|
||||
handler = s_interrupt_handler[irq];
|
||||
handler = s_interrupt_handler[irq.value()];
|
||||
}
|
||||
VERIFY(handler);
|
||||
handler->increment_call_count();
|
||||
@@ -329,14 +329,14 @@ static void unimp_trap()
|
||||
PANIC("Unhandled IRQ");
|
||||
}
|
||||
|
||||
GenericInterruptHandler& get_interrupt_handler(u8 interrupt_number)
|
||||
GenericInterruptHandler& get_interrupt_handler(InterruptNumber interrupt_number)
|
||||
{
|
||||
auto*& handler_slot = s_interrupt_handler[interrupt_number];
|
||||
auto*& handler_slot = s_interrupt_handler[interrupt_number.value()];
|
||||
VERIFY(handler_slot != nullptr);
|
||||
return *handler_slot;
|
||||
}
|
||||
|
||||
static void revert_to_unused_handler(u8 interrupt_number)
|
||||
static void revert_to_unused_handler(InterruptNumber interrupt_number)
|
||||
{
|
||||
auto handler = new UnhandledInterruptHandler(interrupt_number);
|
||||
handler->register_interrupt_handler();
|
||||
@@ -349,10 +349,10 @@ static bool is_unused_handler(GenericInterruptHandler* handler_slot)
|
||||
|
||||
// Sets the reserved flag on `number_of_irqs` if it finds unused interrupt handler on
|
||||
// a contiguous range.
|
||||
ErrorOr<u8> reserve_interrupt_handlers(u8 number_of_irqs)
|
||||
ErrorOr<InterruptNumber> reserve_interrupt_handlers(size_t number_of_irqs)
|
||||
{
|
||||
bool found_range = false;
|
||||
u8 first_irq = 0;
|
||||
InterruptNumber first_irq = 0;
|
||||
SpinlockLocker locker(s_interrupt_handler_lock);
|
||||
for (int start_irq = 0; start_irq < GENERIC_INTERRUPT_HANDLERS_COUNT; start_irq++) {
|
||||
auto*& handler_slot = s_interrupt_handler[start_irq];
|
||||
@@ -362,7 +362,7 @@ ErrorOr<u8> reserve_interrupt_handlers(u8 number_of_irqs)
|
||||
continue;
|
||||
|
||||
found_range = true;
|
||||
for (auto off = 1; off < number_of_irqs; off++) {
|
||||
for (size_t off = 1; off < number_of_irqs; off++) {
|
||||
auto*& handler = s_interrupt_handler[start_irq + off];
|
||||
VERIFY(handler_slot != nullptr);
|
||||
|
||||
@@ -382,14 +382,14 @@ ErrorOr<u8> reserve_interrupt_handlers(u8 number_of_irqs)
|
||||
return Error::from_errno(EAGAIN);
|
||||
|
||||
for (auto irq = first_irq; irq < number_of_irqs; irq++) {
|
||||
auto*& handler_slot = s_interrupt_handler[irq];
|
||||
auto*& handler_slot = s_interrupt_handler[irq.value()];
|
||||
handler_slot->set_reserved();
|
||||
}
|
||||
|
||||
return first_irq;
|
||||
}
|
||||
|
||||
void register_disabled_interrupt_handler(u8 number, GenericInterruptHandler& handler)
|
||||
void register_disabled_interrupt_handler(InterruptNumber number, GenericInterruptHandler& handler)
|
||||
{
|
||||
if (number == 15) {
|
||||
s_disabled_interrupt_handler[0] = &handler;
|
||||
@@ -401,10 +401,10 @@ void register_disabled_interrupt_handler(u8 number, GenericInterruptHandler& han
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
void register_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHandler& handler)
|
||||
void register_generic_interrupt_handler(InterruptNumber interrupt_number, GenericInterruptHandler& handler)
|
||||
{
|
||||
VERIFY(interrupt_number < GENERIC_INTERRUPT_HANDLERS_COUNT);
|
||||
auto*& handler_slot = s_interrupt_handler[interrupt_number];
|
||||
auto*& handler_slot = s_interrupt_handler[interrupt_number.value()];
|
||||
if (handler_slot == nullptr) {
|
||||
handler_slot = &handler;
|
||||
return;
|
||||
@@ -439,9 +439,9 @@ void register_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHan
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
void unregister_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHandler& handler)
|
||||
void unregister_generic_interrupt_handler(InterruptNumber interrupt_number, GenericInterruptHandler& handler)
|
||||
{
|
||||
auto*& handler_slot = s_interrupt_handler[interrupt_number];
|
||||
auto*& handler_slot = s_interrupt_handler[interrupt_number.value()];
|
||||
VERIFY(handler_slot != nullptr);
|
||||
if (handler_slot->type() == HandlerType::UnhandledInterruptHandler)
|
||||
return;
|
||||
@@ -465,14 +465,14 @@ void unregister_generic_interrupt_handler(u8 interrupt_number, GenericInterruptH
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT void register_interrupt_handler(u8 index, void (*handler)())
|
||||
UNMAP_AFTER_INIT void register_interrupt_handler(InterruptNumber index, void (*handler)())
|
||||
{
|
||||
s_idt[index] = IDTEntry((FlatPtr)handler, GDT_SELECTOR_CODE0, IDTEntryType::InterruptGate32, 0);
|
||||
s_idt[index.value()] = IDTEntry((FlatPtr)handler, GDT_SELECTOR_CODE0, IDTEntryType::InterruptGate32, 0);
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT void register_user_callable_interrupt_handler(u8 index, void (*handler)())
|
||||
UNMAP_AFTER_INIT void register_user_callable_interrupt_handler(InterruptNumber index, void (*handler)())
|
||||
{
|
||||
s_idt[index] = IDTEntry((FlatPtr)handler, GDT_SELECTOR_CODE0, IDTEntryType::TrapGate32, 3);
|
||||
s_idt[index.value()] = IDTEntry((FlatPtr)handler, GDT_SELECTOR_CODE0, IDTEntryType::TrapGate32, 3);
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT void flush_idt()
|
||||
|
||||
@@ -36,8 +36,8 @@ extern "C" void interrupt_common_asm_entry();
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
void register_interrupt_handler(u8 number, void (*handler)());
|
||||
void register_user_callable_interrupt_handler(u8 number, void (*handler)());
|
||||
void register_disabled_interrupt_handler(u8 number, GenericInterruptHandler& handler);
|
||||
void register_interrupt_handler(InterruptNumber number, void (*handler)());
|
||||
void register_user_callable_interrupt_handler(InterruptNumber number, void (*handler)());
|
||||
void register_disabled_interrupt_handler(InterruptNumber number, GenericInterruptHandler& handler);
|
||||
|
||||
}
|
||||
@@ -61,7 +61,7 @@ static Singleton<APIC> s_apic;
|
||||
|
||||
class APICIPIInterruptHandler final : public GenericInterruptHandler {
|
||||
public:
|
||||
explicit APICIPIInterruptHandler(u8 interrupt_vector)
|
||||
explicit APICIPIInterruptHandler(InterruptNumber interrupt_vector)
|
||||
: GenericInterruptHandler(interrupt_vector, true)
|
||||
{
|
||||
}
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
static void initialize(u8 interrupt_number)
|
||||
static void initialize(InterruptNumber interrupt_number)
|
||||
{
|
||||
auto* handler = new APICIPIInterruptHandler(interrupt_number);
|
||||
handler->register_interrupt_handler();
|
||||
@@ -91,7 +91,7 @@ private:
|
||||
|
||||
class APICErrInterruptHandler final : public GenericInterruptHandler {
|
||||
public:
|
||||
explicit APICErrInterruptHandler(u8 interrupt_vector)
|
||||
explicit APICErrInterruptHandler(InterruptNumber interrupt_vector)
|
||||
: GenericInterruptHandler(interrupt_vector, true)
|
||||
{
|
||||
}
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
static void initialize(u8 interrupt_number)
|
||||
static void initialize(InterruptNumber interrupt_number)
|
||||
{
|
||||
auto* handler = new APICErrInterruptHandler(interrupt_number);
|
||||
handler->register_interrupt_handler();
|
||||
@@ -171,14 +171,14 @@ u32 APIC::read_register(u32 offset)
|
||||
return *reinterpret_cast<u32 volatile*>(m_apic_base->vaddr().offset(offset).as_ptr());
|
||||
}
|
||||
|
||||
void APIC::set_lvt(u32 offset, u8 interrupt)
|
||||
void APIC::set_lvt(u32 offset, InterruptNumber interrupt)
|
||||
{
|
||||
write_register(offset, read_register(offset) | interrupt);
|
||||
write_register(offset, read_register(offset) | interrupt.value());
|
||||
}
|
||||
|
||||
void APIC::set_siv(u32 offset, u8 interrupt)
|
||||
void APIC::set_siv(u32 offset, InterruptNumber interrupt)
|
||||
{
|
||||
write_register(offset, read_register(offset) | interrupt | APIC_ENABLED);
|
||||
write_register(offset, read_register(offset) | interrupt.value() | APIC_ENABLED);
|
||||
}
|
||||
|
||||
void APIC::wait_for_pending_icr()
|
||||
@@ -226,7 +226,7 @@ void APIC::eoi()
|
||||
write_register(APIC_REG_EOI, 0x0);
|
||||
}
|
||||
|
||||
u8 APIC::spurious_interrupt_vector()
|
||||
InterruptNumber APIC::spurious_interrupt_vector()
|
||||
{
|
||||
return IRQ_APIC_SPURIOUS;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
void init_finished(u32 cpu);
|
||||
void broadcast_ipi();
|
||||
void send_ipi(u32 cpu);
|
||||
static u8 spurious_interrupt_vector();
|
||||
static InterruptNumber spurious_interrupt_vector();
|
||||
Thread* get_idle_thread(u32 cpu) const;
|
||||
u32 enabled_processor_count() const { return m_processor_enabled_cnt; }
|
||||
|
||||
@@ -106,8 +106,8 @@ private:
|
||||
void set_base(PhysicalAddress const& base);
|
||||
void write_register(u32 offset, u32 value);
|
||||
u32 read_register(u32 offset);
|
||||
void set_lvt(u32 offset, u8 interrupt);
|
||||
void set_siv(u32 offset, u8 interrupt);
|
||||
void set_lvt(u32 offset, InterruptNumber interrupt);
|
||||
void set_siv(u32 offset, InterruptNumber interrupt);
|
||||
void wait_for_pending_icr();
|
||||
void write_icr(ICRReg const& icr);
|
||||
void do_boot_aps();
|
||||
|
||||
@@ -43,7 +43,7 @@ UNMAP_AFTER_INIT void IOAPIC::initialize()
|
||||
{
|
||||
}
|
||||
|
||||
void IOAPIC::map_interrupt_redirection(u8 interrupt_vector)
|
||||
void IOAPIC::map_interrupt_redirection(InterruptNumber interrupt_vector)
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
for (auto redirection_override : InterruptManagement::the().isa_overrides()) {
|
||||
@@ -85,7 +85,7 @@ void IOAPIC::map_interrupt_redirection(u8 interrupt_vector)
|
||||
configure_redirection_entry(redirection_override.gsi() - gsi_base(), InterruptManagement::acquire_mapped_interrupt_number(redirection_override.source()) + IRQ_VECTOR_BASE, DeliveryMode::Normal, false, active_low, trigger_level_mode, true, Processor::by_id(0).info().apic_id());
|
||||
return;
|
||||
}
|
||||
isa_identity_map(interrupt_vector);
|
||||
isa_identity_map(interrupt_vector.value());
|
||||
}
|
||||
|
||||
void IOAPIC::isa_identity_map(size_t index)
|
||||
@@ -127,11 +127,11 @@ void IOAPIC::reset_redirection_entry(size_t index) const
|
||||
configure_redirection_entry(index, 0, 0, false, false, false, true, Processor::by_id(0).info().apic_id());
|
||||
}
|
||||
|
||||
void IOAPIC::configure_redirection_entry(size_t index, u8 interrupt_vector, u8 delivery_mode, bool logical_destination, bool active_low, bool trigger_level_mode, bool masked, u8 destination) const
|
||||
void IOAPIC::configure_redirection_entry(size_t index, InterruptNumber interrupt_vector, u8 delivery_mode, bool logical_destination, bool active_low, bool trigger_level_mode, bool masked, u8 destination) const
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
VERIFY(index < m_redirection_entries_count);
|
||||
u32 redirection_entry1 = interrupt_vector | (delivery_mode & 0b111) << 8 | logical_destination << 11 | active_low << 13 | trigger_level_mode << 15 | masked << 16;
|
||||
u32 redirection_entry1 = interrupt_vector.value() | (delivery_mode & 0b111) << 8 | logical_destination << 11 | active_low << 13 | trigger_level_mode << 15 | masked << 16;
|
||||
u32 redirection_entry2 = destination << 24;
|
||||
write_register((index << 1) + IOAPIC_REDIRECTION_ENTRY_OFFSET, redirection_entry1);
|
||||
|
||||
@@ -175,10 +175,10 @@ void IOAPIC::unmask_redirection_entry(u8 index) const
|
||||
write_register((index << 1) + IOAPIC_REDIRECTION_ENTRY_OFFSET, redirection_entry & ~(1 << 16));
|
||||
}
|
||||
|
||||
bool IOAPIC::is_vector_enabled(u8 interrupt_vector) const
|
||||
bool IOAPIC::is_vector_enabled(InterruptNumber interrupt_vector) const
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
return is_redirection_entry_masked(interrupt_vector);
|
||||
return is_redirection_entry_masked(interrupt_vector.value());
|
||||
}
|
||||
|
||||
u8 IOAPIC::read_redirection_entry_vector(u8 index) const
|
||||
@@ -187,7 +187,7 @@ u8 IOAPIC::read_redirection_entry_vector(u8 index) const
|
||||
return (read_register((index << 1) + IOAPIC_REDIRECTION_ENTRY_OFFSET) & 0xFF);
|
||||
}
|
||||
|
||||
Optional<int> IOAPIC::find_redirection_entry_by_vector(u8 vector) const
|
||||
Optional<int> IOAPIC::find_redirection_entry_by_vector(InterruptNumber vector) const
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
for (size_t index = 0; index < m_redirection_entries_count; index++) {
|
||||
@@ -201,7 +201,7 @@ void IOAPIC::disable(GenericInterruptHandler const& handler)
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
VERIFY(!is_hard_disabled());
|
||||
u8 interrupt_vector = handler.interrupt_number();
|
||||
InterruptNumber interrupt_vector = handler.interrupt_number();
|
||||
VERIFY(interrupt_vector >= gsi_base() && interrupt_vector < interrupt_vectors_count());
|
||||
auto found_index = find_redirection_entry_by_vector(interrupt_vector);
|
||||
if (!found_index.has_value()) {
|
||||
@@ -216,7 +216,7 @@ void IOAPIC::enable(GenericInterruptHandler const& handler)
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
VERIFY(!is_hard_disabled());
|
||||
u8 interrupt_vector = handler.interrupt_number();
|
||||
InterruptNumber interrupt_vector = handler.interrupt_number();
|
||||
VERIFY(interrupt_vector >= gsi_base() && interrupt_vector < interrupt_vectors_count());
|
||||
auto found_index = find_redirection_entry_by_vector(interrupt_vector);
|
||||
if (!found_index.has_value()) {
|
||||
|
||||
@@ -18,7 +18,7 @@ struct [[gnu::packed]] ioapic_mmio_regs {
|
||||
|
||||
class PCIInterruptOverrideMetadata {
|
||||
public:
|
||||
PCIInterruptOverrideMetadata(u8 bus_id, u8 polarity, u8 trigger_mode, u8 source_irq, u32 ioapic_id, u16 ioapic_int_pin);
|
||||
PCIInterruptOverrideMetadata(u8 bus_id, u8 polarity, u8 trigger_mode, InterruptNumber source_irq, u32 ioapic_id, u16 ioapic_int_pin);
|
||||
u8 bus() const { return m_bus_id; }
|
||||
u8 polarity() const { return m_polarity; }
|
||||
u8 trigger_mode() const { return m_trigger_mode; }
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
virtual void hard_disable() override;
|
||||
virtual void eoi(GenericInterruptHandler const&) const override;
|
||||
virtual void spurious_eoi(GenericInterruptHandler const&) const override;
|
||||
virtual bool is_vector_enabled(u8 number) const override;
|
||||
virtual bool is_vector_enabled(InterruptNumber number) const override;
|
||||
virtual bool is_enabled() const override;
|
||||
virtual u16 get_isr() const override;
|
||||
virtual u16 get_irr() const override;
|
||||
@@ -55,9 +55,9 @@ public:
|
||||
virtual IRQControllerType type() const override { return IRQControllerType::i82093AA; }
|
||||
|
||||
private:
|
||||
void configure_redirection_entry(size_t index, u8 interrupt_vector, u8 delivery_mode, bool logical_destination, bool active_low, bool trigger_level_mode, bool masked, u8 destination) const;
|
||||
void configure_redirection_entry(size_t index, InterruptNumber interrupt_vector, u8 delivery_mode, bool logical_destination, bool active_low, bool trigger_level_mode, bool masked, u8 destination) const;
|
||||
void reset_redirection_entry(size_t index) const;
|
||||
void map_interrupt_redirection(u8 interrupt_vector);
|
||||
void map_interrupt_redirection(InterruptNumber interrupt_vector);
|
||||
void reset_all_redirection_entries() const;
|
||||
|
||||
void mask_all_redirection_entries() const;
|
||||
@@ -66,7 +66,7 @@ private:
|
||||
bool is_redirection_entry_masked(u8 index) const;
|
||||
|
||||
u8 read_redirection_entry_vector(u8 index) const;
|
||||
Optional<int> find_redirection_entry_by_vector(u8 vector) const;
|
||||
Optional<int> find_redirection_entry_by_vector(InterruptNumber vector) const;
|
||||
|
||||
void write_register(u32 index, u32 value) const;
|
||||
u32 read_register(u32 index) const;
|
||||
|
||||
@@ -50,20 +50,20 @@ void PIC::disable(GenericInterruptHandler const& handler)
|
||||
InterruptDisabler disabler;
|
||||
VERIFY(!is_hard_disabled());
|
||||
VERIFY(handler.interrupt_number() >= gsi_base() && handler.interrupt_number() < interrupt_vectors_count());
|
||||
u8 irq = handler.interrupt_number();
|
||||
if (m_cached_irq_mask & (1 << irq))
|
||||
auto irq = handler.interrupt_number();
|
||||
if (m_cached_irq_mask & (1 << irq.value()))
|
||||
return;
|
||||
u8 imr;
|
||||
if (irq & 8) {
|
||||
if (irq.value() & 8) {
|
||||
imr = IO::in8(PIC1_CMD);
|
||||
imr |= 1 << (irq & 7);
|
||||
imr |= 1 << (irq.value() & 7);
|
||||
IO::out8(PIC1_CMD, imr);
|
||||
} else {
|
||||
imr = IO::in8(PIC0_CMD);
|
||||
imr |= 1 << irq;
|
||||
imr |= 1 << irq.value();
|
||||
IO::out8(PIC0_CMD, imr);
|
||||
}
|
||||
m_cached_irq_mask |= 1 << irq;
|
||||
m_cached_irq_mask |= 1 << irq.value();
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT PIC::PIC()
|
||||
@@ -82,9 +82,9 @@ void PIC::spurious_eoi(GenericInterruptHandler const& handler) const
|
||||
}
|
||||
}
|
||||
|
||||
bool PIC::is_vector_enabled(u8 irq) const
|
||||
bool PIC::is_vector_enabled(InterruptNumber irq) const
|
||||
{
|
||||
return m_cached_irq_mask & (1 << irq);
|
||||
return m_cached_irq_mask & (1 << irq.value());
|
||||
}
|
||||
|
||||
void PIC::enable(GenericInterruptHandler const& handler)
|
||||
@@ -95,48 +95,48 @@ void PIC::enable(GenericInterruptHandler const& handler)
|
||||
enable_vector(handler.interrupt_number());
|
||||
}
|
||||
|
||||
void PIC::enable_vector(u8 irq)
|
||||
void PIC::enable_vector(InterruptNumber irq)
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
VERIFY(!is_hard_disabled());
|
||||
if (!(m_cached_irq_mask & (1 << irq)))
|
||||
if (!(m_cached_irq_mask & (1 << irq.value())))
|
||||
return;
|
||||
u8 imr;
|
||||
if (irq & 8) {
|
||||
if (irq.value() & 8) {
|
||||
imr = IO::in8(PIC1_CMD);
|
||||
imr &= ~(1 << (irq & 7));
|
||||
imr &= ~(1 << (irq.value() & 7));
|
||||
IO::out8(PIC1_CMD, imr);
|
||||
} else {
|
||||
imr = IO::in8(PIC0_CMD);
|
||||
imr &= ~(1 << irq);
|
||||
imr &= ~(1 << irq.value());
|
||||
IO::out8(PIC0_CMD, imr);
|
||||
}
|
||||
m_cached_irq_mask &= ~(1 << irq);
|
||||
m_cached_irq_mask &= ~(1 << irq.value());
|
||||
}
|
||||
|
||||
void PIC::eoi(GenericInterruptHandler const& handler) const
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
VERIFY(!is_hard_disabled());
|
||||
u8 irq = handler.interrupt_number();
|
||||
auto irq = handler.interrupt_number();
|
||||
VERIFY(irq >= gsi_base() && irq < interrupt_vectors_count());
|
||||
if ((1 << irq) & m_cached_irq_mask) {
|
||||
if ((1 << irq.value()) & m_cached_irq_mask) {
|
||||
spurious_eoi(handler);
|
||||
return;
|
||||
}
|
||||
eoi_interrupt(irq);
|
||||
}
|
||||
|
||||
void PIC::eoi_interrupt(u8 irq) const
|
||||
void PIC::eoi_interrupt(InterruptNumber irq) const
|
||||
{
|
||||
if (irq & 8) {
|
||||
if (irq.value() & 8) {
|
||||
IO::in8(PIC1_CMD); /* dummy read */
|
||||
IO::out8(PIC1_CTL, 0x60 | (irq & 7));
|
||||
IO::out8(PIC1_CTL, 0x60 | (irq.value() & 7));
|
||||
IO::out8(PIC0_CTL, 0x60 | (2));
|
||||
return;
|
||||
}
|
||||
IO::in8(PIC0_CMD); /* dummy read */
|
||||
IO::out8(PIC0_CTL, 0x60 | irq);
|
||||
IO::out8(PIC0_CTL, 0x60 | irq.value());
|
||||
}
|
||||
|
||||
void PIC::complete_eoi() const
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Arch/x86_64/IRQController.h>
|
||||
#include <Kernel/Interrupts/Interrupts.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
@@ -21,7 +22,7 @@ public:
|
||||
virtual void disable(GenericInterruptHandler const&) override;
|
||||
virtual void hard_disable() override;
|
||||
virtual void eoi(GenericInterruptHandler const&) const override;
|
||||
virtual bool is_vector_enabled(u8 number) const override;
|
||||
virtual bool is_vector_enabled(InterruptNumber number) const override;
|
||||
virtual bool is_enabled() const override;
|
||||
virtual void spurious_eoi(GenericInterruptHandler const&) const override;
|
||||
virtual u16 get_isr() const override;
|
||||
@@ -33,8 +34,8 @@ public:
|
||||
|
||||
private:
|
||||
u16 m_cached_irq_mask { 0xffff };
|
||||
void eoi_interrupt(u8 irq) const;
|
||||
void enable_vector(u8 number);
|
||||
void eoi_interrupt(InterruptNumber irq) const;
|
||||
void enable_vector(InterruptNumber number);
|
||||
void remap(u8 offset);
|
||||
void complete_eoi() const;
|
||||
virtual void initialize() override;
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Kernel {
|
||||
|
||||
#define APIC_TIMER_MEASURE_CPU_CLOCK
|
||||
|
||||
UNMAP_AFTER_INIT APICTimer* APICTimer::initialize(u8 interrupt_number, HardwareTimerBase& calibration_source)
|
||||
UNMAP_AFTER_INIT APICTimer* APICTimer::initialize(InterruptNumber interrupt_number, HardwareTimerBase& calibration_source)
|
||||
{
|
||||
auto timer = adopt_lock_ref(*new APICTimer(interrupt_number, nullptr));
|
||||
timer->register_interrupt_handler();
|
||||
@@ -24,7 +24,7 @@ UNMAP_AFTER_INIT APICTimer* APICTimer::initialize(u8 interrupt_number, HardwareT
|
||||
return &timer.leak_ref();
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT APICTimer::APICTimer(u8 interrupt_number, Function<void()> callback)
|
||||
UNMAP_AFTER_INIT APICTimer::APICTimer(InterruptNumber interrupt_number, Function<void()> callback)
|
||||
: HardwareTimer<GenericInterruptHandler>(interrupt_number, move(callback))
|
||||
{
|
||||
disable_remap();
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Kernel {
|
||||
|
||||
class APICTimer final : public HardwareTimer<GenericInterruptHandler> {
|
||||
public:
|
||||
static APICTimer* initialize(u8, HardwareTimerBase&);
|
||||
static APICTimer* initialize(InterruptNumber, HardwareTimerBase&);
|
||||
virtual HardwareTimerType timer_type() const override { return HardwareTimerType::LocalAPICTimer; }
|
||||
virtual StringView model() const override { return "LocalAPIC"sv; }
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
void disable_local_timer();
|
||||
|
||||
private:
|
||||
explicit APICTimer(u8, Function<void()>);
|
||||
explicit APICTimer(InterruptNumber, Function<void()>);
|
||||
|
||||
bool calibrate(HardwareTimerBase&);
|
||||
|
||||
|
||||
@@ -359,11 +359,11 @@ Vector<unsigned> HPET::capable_interrupt_numbers(u8 comparator_number)
|
||||
return capable_interrupts;
|
||||
}
|
||||
|
||||
void HPET::set_comparator_irq_vector(u8 comparator_number, u8 irq_vector)
|
||||
void HPET::set_comparator_irq_vector(u8 comparator_number, InterruptNumber irq_vector)
|
||||
{
|
||||
VERIFY(comparator_number <= m_comparators.size());
|
||||
auto& comparator_registers = registers().timers[comparator_number];
|
||||
comparator_registers.capabilities = comparator_registers.capabilities | (irq_vector << 9);
|
||||
comparator_registers.capabilities = comparator_registers.capabilities | (irq_vector.value() << 9);
|
||||
}
|
||||
|
||||
bool HPET::is_periodic_capable(u8 comparator_number) const
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/Types.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <Kernel/Interrupts/Interrupts.h>
|
||||
#include <Kernel/Memory/PhysicalAddress.h>
|
||||
#include <Kernel/Memory/Region.h>
|
||||
|
||||
@@ -35,7 +36,7 @@ public:
|
||||
void update_periodic_comparator_value();
|
||||
void update_non_periodic_comparator_value(HPETComparator const& comparator);
|
||||
|
||||
void set_comparator_irq_vector(u8 comparator_number, u8 irq_vector);
|
||||
void set_comparator_irq_vector(u8 comparator_number, InterruptNumber irq_vector);
|
||||
|
||||
void enable_periodic_interrupt(HPETComparator const& comparator);
|
||||
void disable_periodic_interrupt(HPETComparator const& comparator);
|
||||
|
||||
@@ -13,14 +13,14 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
UNMAP_AFTER_INIT NonnullLockRefPtr<HPETComparator> HPETComparator::create(u8 number, u8 irq, bool periodic_capable, bool is_64bit_capable)
|
||||
UNMAP_AFTER_INIT NonnullLockRefPtr<HPETComparator> HPETComparator::create(u8 number, InterruptNumber irq, bool periodic_capable, bool is_64bit_capable)
|
||||
{
|
||||
auto timer = adopt_lock_ref(*new HPETComparator(number, irq, periodic_capable, is_64bit_capable));
|
||||
timer->register_interrupt_handler();
|
||||
return timer;
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT HPETComparator::HPETComparator(u8 number, u8 irq, bool periodic_capable, bool is_64bit_capable)
|
||||
UNMAP_AFTER_INIT HPETComparator::HPETComparator(u8 number, InterruptNumber irq, bool periodic_capable, bool is_64bit_capable)
|
||||
: HardwareTimer(irq)
|
||||
, m_periodic(false)
|
||||
, m_periodic_capable(periodic_capable)
|
||||
|
||||
@@ -16,7 +16,7 @@ class HPETComparator final : public HardwareTimer<IRQHandler> {
|
||||
friend class HPET;
|
||||
|
||||
public:
|
||||
static NonnullLockRefPtr<HPETComparator> create(u8 number, u8 irq, bool periodic_capable, bool is_64bit_capable);
|
||||
static NonnullLockRefPtr<HPETComparator> create(u8 number, InterruptNumber irq, bool periodic_capable, bool is_64bit_capable);
|
||||
|
||||
virtual HardwareTimerType timer_type() const override { return HardwareTimerType::HighPrecisionEventTimer; }
|
||||
virtual StringView model() const override { return "HPET"sv; }
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
private:
|
||||
void set_new_countdown();
|
||||
virtual bool handle_irq() override;
|
||||
HPETComparator(u8 number, u8 irq, bool periodic_capable, bool is_64bit_capable);
|
||||
HPETComparator(u8 number, InterruptNumber irq, bool periodic_capable, bool is_64bit_capable);
|
||||
bool m_periodic : 1;
|
||||
bool m_periodic_capable : 1;
|
||||
bool m_enabled : 1;
|
||||
|
||||
@@ -22,7 +22,7 @@ class TransportInterface final
|
||||
: public HID::TransportInterface
|
||||
, public IRQHandler {
|
||||
public:
|
||||
static ErrorOr<NonnullOwnPtr<TransportInterface>> create(I2C::Controller& i2c_controller, I2C::Address i2c_address, HIDDescriptor const& hid_descriptor, size_t interrupt_number)
|
||||
static ErrorOr<NonnullOwnPtr<TransportInterface>> create(I2C::Controller& i2c_controller, I2C::Address i2c_address, HIDDescriptor const& hid_descriptor, InterruptNumber interrupt_number)
|
||||
{
|
||||
auto input_report_buffer = TRY(ByteBuffer::create_zeroed(hid_descriptor.max_input_length));
|
||||
return TRY(adopt_nonnull_own_or_enomem(new (nothrow) TransportInterface(i2c_controller, i2c_address, hid_descriptor.input_register, interrupt_number, move(input_report_buffer))));
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TransportInterface(I2C::Controller& i2c_controller, I2C::Address i2c_address, u16 input_register_index, size_t interrupt_number, ByteBuffer input_report_buffer)
|
||||
TransportInterface(I2C::Controller& i2c_controller, I2C::Address i2c_address, u16 input_register_index, InterruptNumber interrupt_number, ByteBuffer input_report_buffer)
|
||||
: IRQHandler(interrupt_number)
|
||||
, m_i2c_controller(i2c_controller)
|
||||
, m_i2c_address(i2c_address)
|
||||
|
||||
@@ -350,7 +350,7 @@ void HostController::configure_attached_devices(PCIConfiguration& config)
|
||||
|
||||
auto interrupt_number = config.masked_interrupt_mapping.get(masked_identifier);
|
||||
if (interrupt_number.has_value())
|
||||
write8_field(device_identifier.address().bus(), device_identifier.address().device(), device_identifier.address().function(), PCI::RegisterOffset::INTERRUPT_LINE, interrupt_number.value());
|
||||
write8_field(device_identifier.address().bus(), device_identifier.address().device(), device_identifier.address().function(), PCI::RegisterOffset::INTERRUPT_LINE, interrupt_number.value().value());
|
||||
|
||||
if (read8_field(device_identifier.address().bus(), device_identifier.address().device(), device_identifier.address().function(), PCI::RegisterOffset::CLASS) != PCI::ClassID::Bridge)
|
||||
return;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <Kernel/Bus/PCI/Definitions.h>
|
||||
#include <Kernel/Interrupts/Interrupts.h>
|
||||
#include <Kernel/Locking/Spinlock.h>
|
||||
|
||||
namespace Kernel::PCI {
|
||||
@@ -70,7 +71,7 @@ struct PCIConfiguration {
|
||||
|
||||
// The keys contains the bus, device & function at the same offsets as OpenFirmware PCI addresses,
|
||||
// with the least significant 8 bits being the interrupt pin.
|
||||
HashMap<PCIInterruptSpecifier, u64> masked_interrupt_mapping;
|
||||
HashMap<PCIInterruptSpecifier, InterruptNumber> masked_interrupt_mapping;
|
||||
PCIInterruptSpecifier interrupt_mask;
|
||||
};
|
||||
|
||||
|
||||
+10
-11
@@ -92,7 +92,7 @@ PCI::InterruptType Device::get_interrupt_type()
|
||||
// is nothing left to do. The second parameter `msi` is used by the
|
||||
// driver to indicate its intent to use message signalled interrupts.
|
||||
// MSI(x) is preferred over MSI if the device supports both.
|
||||
ErrorOr<InterruptType> Device::reserve_irqs(u8 number_of_irqs, bool msi)
|
||||
ErrorOr<InterruptType> Device::reserve_irqs(size_t number_of_irqs, bool msi)
|
||||
{
|
||||
// Let us not allow partial allocation of IRQs for MSIx.
|
||||
if (msi && is_msix_capable()) {
|
||||
@@ -116,12 +116,11 @@ ErrorOr<InterruptType> Device::reserve_irqs(u8 number_of_irqs, bool msi)
|
||||
return m_interrupt_range.m_type;
|
||||
}
|
||||
|
||||
PhysicalAddress Device::msix_table_entry_address(u8 irq)
|
||||
PhysicalAddress Device::msix_table_entry_address(InterruptNumber irq)
|
||||
{
|
||||
auto index = static_cast<int>(irq) - m_interrupt_range.m_start_irq;
|
||||
auto index = static_cast<int>(irq.value()) - m_interrupt_range.m_start_irq.value();
|
||||
|
||||
VERIFY(index < m_interrupt_range.m_irq_count);
|
||||
VERIFY(index >= 0);
|
||||
auto table_bar_paddr = PCI::get_bar_address(device_identifier(), static_cast<PCI::HeaderType0BaseRegister>(m_pci_identifier->get_msix_table_bar())).release_value_but_fixme_should_propagate_errors();
|
||||
auto table_offset = m_pci_identifier->get_msix_table_offset();
|
||||
|
||||
@@ -133,14 +132,14 @@ PhysicalAddress Device::msix_table_entry_address(u8 irq)
|
||||
// mainly useful for MSI/MSIx based interrupt mechanism where the driver
|
||||
// needs to program. If the PCI device doesn't support MSIx interrupts, then
|
||||
// this function will just return the irq used for pin based interrupt.
|
||||
ErrorOr<u8> Device::allocate_irq(u8 index)
|
||||
ErrorOr<InterruptNumber> Device::allocate_irq(size_t index)
|
||||
{
|
||||
if (Checked<u8>::addition_would_overflow(m_interrupt_range.m_start_irq, index))
|
||||
if (Checked<size_t>::addition_would_overflow(m_interrupt_range.m_start_irq.value(), index))
|
||||
return Error::from_errno(EINVAL);
|
||||
|
||||
if ((m_interrupt_range.m_type == InterruptType::MSIX) && is_msix_capable()) {
|
||||
auto entry_ptr = TRY(Memory::map_typed_writable<MSIxTableEntry volatile>(msix_table_entry_address(index + m_interrupt_range.m_start_irq)));
|
||||
entry_ptr->data = msi_data_register(m_interrupt_range.m_start_irq + index, false, false);
|
||||
auto entry_ptr = TRY(Memory::map_typed_writable<MSIxTableEntry volatile>(msix_table_entry_address(index + m_interrupt_range.m_start_irq.value())));
|
||||
entry_ptr->data = msi_data_register(m_interrupt_range.m_start_irq.value() + index, false, false);
|
||||
// TODO: we map all the IRQs to cpu 0 by default. We could attach
|
||||
// cpu affinity in the future where specific LAPIC id could be used.
|
||||
u64 addr = msi_address_register(0, false, false);
|
||||
@@ -156,7 +155,7 @@ ErrorOr<u8> Device::allocate_irq(u8 index)
|
||||
if (index > 0)
|
||||
return Error::from_errno(EINVAL);
|
||||
|
||||
auto data = msi_data_register(m_interrupt_range.m_start_irq + index, false, false);
|
||||
auto data = msi_data_register(m_interrupt_range.m_start_irq.value() + index, false, false);
|
||||
auto addr = msi_address_register(0, false, false);
|
||||
for (auto& capability : m_pci_identifier->capabilities()) {
|
||||
if (capability.id().value() == PCI::Capabilities::ID::MSI) {
|
||||
@@ -177,7 +176,7 @@ ErrorOr<u8> Device::allocate_irq(u8 index)
|
||||
return m_interrupt_range.m_start_irq;
|
||||
}
|
||||
|
||||
void Device::enable_interrupt(u8 irq)
|
||||
void Device::enable_interrupt(InterruptNumber irq)
|
||||
{
|
||||
if ((m_interrupt_range.m_type == InterruptType::MSIX) && is_msix_capable()) {
|
||||
auto entry = Memory::map_typed_writable<MSIxTableEntry volatile>(PhysicalAddress(msix_table_entry_address(irq)));
|
||||
@@ -195,7 +194,7 @@ void Device::enable_interrupt(u8 irq)
|
||||
}
|
||||
}
|
||||
|
||||
void Device::disable_interrupt(u8 irq)
|
||||
void Device::disable_interrupt(InterruptNumber irq)
|
||||
{
|
||||
if ((m_interrupt_range.m_type == InterruptType::MSIX) && is_msix_capable()) {
|
||||
auto entry = Memory::map_typed_writable<MSIxTableEntry volatile>(PhysicalAddress(msix_table_entry_address(irq)));
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Bus/PCI/Definitions.h>
|
||||
#include <Kernel/Interrupts/Interrupts.h>
|
||||
|
||||
namespace Kernel::PCI {
|
||||
|
||||
@@ -21,8 +22,8 @@ enum class InterruptType {
|
||||
};
|
||||
|
||||
struct InterruptRange {
|
||||
u8 m_start_irq { 0 };
|
||||
u8 m_irq_count { 0 };
|
||||
InterruptNumber m_start_irq { 0 };
|
||||
InterruptNumber m_irq_count { 0 };
|
||||
InterruptType m_type { InterruptType::PIN };
|
||||
};
|
||||
|
||||
@@ -52,17 +53,17 @@ public:
|
||||
|
||||
void enable_extended_message_signalled_interrupts();
|
||||
void disable_extended_message_signalled_interrupts();
|
||||
ErrorOr<InterruptType> reserve_irqs(u8 number_of_irqs, bool msi);
|
||||
ErrorOr<u8> allocate_irq(u8 index);
|
||||
ErrorOr<InterruptType> reserve_irqs(size_t number_of_irqs, bool msi);
|
||||
ErrorOr<InterruptNumber> allocate_irq(size_t index);
|
||||
PCI::InterruptType get_interrupt_type();
|
||||
void enable_interrupt(u8 irq);
|
||||
void disable_interrupt(u8 irq);
|
||||
void enable_interrupt(InterruptNumber irq);
|
||||
void disable_interrupt(InterruptNumber irq);
|
||||
|
||||
protected:
|
||||
explicit Device(DeviceIdentifier const& pci_identifier);
|
||||
|
||||
private:
|
||||
PhysicalAddress msix_table_entry_address(u8 irq);
|
||||
PhysicalAddress msix_table_entry_address(InterruptNumber irq);
|
||||
|
||||
private:
|
||||
NonnullRefPtr<DeviceIdentifier> const m_pci_identifier;
|
||||
|
||||
@@ -82,7 +82,7 @@ ErrorOr<void> configure_devicetree_host_controller(HostController& host_controll
|
||||
u64 pci_64bit_mmio_size = 0;
|
||||
FlatPtr pci_io_base = 0;
|
||||
u64 pci_io_size = 0;
|
||||
HashMap<PCIInterruptSpecifier, u64> masked_interrupt_mapping;
|
||||
HashMap<PCIInterruptSpecifier, InterruptNumber> masked_interrupt_mapping;
|
||||
PCIInterruptSpecifier interrupt_mask;
|
||||
|
||||
auto const& device_tree = DeviceTree::get();
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
namespace Kernel::USB::xHCI {
|
||||
|
||||
ErrorOr<NonnullLockRefPtr<DeviceTreexHCIController>> DeviceTreexHCIController::try_to_initialize(DeviceTree::Device::Resource registers_resource, StringView node_name, size_t interrupt_number)
|
||||
ErrorOr<NonnullLockRefPtr<DeviceTreexHCIController>> DeviceTreexHCIController::try_to_initialize(DeviceTree::Device::Resource registers_resource, StringView node_name, InterruptNumber interrupt_number)
|
||||
{
|
||||
auto registers_mapping = TRY(Memory::map_typed<u8>(registers_resource.paddr, registers_resource.size, Memory::Region::Access::ReadWrite));
|
||||
|
||||
@@ -22,7 +22,7 @@ ErrorOr<NonnullLockRefPtr<DeviceTreexHCIController>> DeviceTreexHCIController::t
|
||||
return controller;
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT DeviceTreexHCIController::DeviceTreexHCIController(Memory::TypedMapping<u8> registers_mapping, StringView node_name, size_t interrupt_number)
|
||||
UNMAP_AFTER_INIT DeviceTreexHCIController::DeviceTreexHCIController(Memory::TypedMapping<u8> registers_mapping, StringView node_name, InterruptNumber interrupt_number)
|
||||
: xHCIController(move(registers_mapping))
|
||||
, m_node_name(node_name)
|
||||
, m_interrupt_number(interrupt_number)
|
||||
|
||||
@@ -13,10 +13,10 @@ namespace Kernel::USB::xHCI {
|
||||
|
||||
class DeviceTreexHCIController final : public xHCIController {
|
||||
public:
|
||||
static ErrorOr<NonnullLockRefPtr<DeviceTreexHCIController>> try_to_initialize(DeviceTree::Device::Resource, StringView node_name, size_t interrupt_number);
|
||||
static ErrorOr<NonnullLockRefPtr<DeviceTreexHCIController>> try_to_initialize(DeviceTree::Device::Resource, StringView node_name, InterruptNumber interrupt_number);
|
||||
|
||||
private:
|
||||
DeviceTreexHCIController(Memory::TypedMapping<u8> registers_mapping, StringView node_name, size_t interrupt_number);
|
||||
DeviceTreexHCIController(Memory::TypedMapping<u8> registers_mapping, StringView node_name, InterruptNumber interrupt_number);
|
||||
|
||||
// ^xHCIController
|
||||
virtual bool using_message_signalled_interrupts() const override { return m_using_message_signalled_interrupts; }
|
||||
@@ -28,7 +28,7 @@ private:
|
||||
}
|
||||
|
||||
StringView m_node_name;
|
||||
size_t m_interrupt_number { 0 };
|
||||
InterruptNumber m_interrupt_number { 0 };
|
||||
bool m_using_message_signalled_interrupts { false };
|
||||
};
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ ErrorOr<NonnullOwnPtr<xHCIPCIInterrupter>> xHCIPCIInterrupter::create(PCIxHCICon
|
||||
return TRY(adopt_nonnull_own_or_enomem(new (nothrow) xHCIPCIInterrupter(controller, interrupter_id, irq)));
|
||||
}
|
||||
|
||||
xHCIPCIInterrupter::xHCIPCIInterrupter(PCIxHCIController& controller, u16 interrupter_id, u16 irq)
|
||||
xHCIPCIInterrupter::xHCIPCIInterrupter(PCIxHCIController& controller, u16 interrupter_id, InterruptNumber irq)
|
||||
: PCI::IRQHandler(controller, irq)
|
||||
, m_controller(controller)
|
||||
, m_interrupter_id(interrupter_id)
|
||||
@@ -28,12 +28,12 @@ bool xHCIPCIInterrupter::handle_irq()
|
||||
return true;
|
||||
}
|
||||
|
||||
ErrorOr<NonnullOwnPtr<xHCIDeviceTreeInterrupter>> xHCIDeviceTreeInterrupter::create(DeviceTreexHCIController& controller, size_t irq, u16 interrupter_id)
|
||||
ErrorOr<NonnullOwnPtr<xHCIDeviceTreeInterrupter>> xHCIDeviceTreeInterrupter::create(DeviceTreexHCIController& controller, InterruptNumber irq, u16 interrupter_id)
|
||||
{
|
||||
return TRY(adopt_nonnull_own_or_enomem(new (nothrow) xHCIDeviceTreeInterrupter(controller, interrupter_id, irq)));
|
||||
}
|
||||
|
||||
xHCIDeviceTreeInterrupter::xHCIDeviceTreeInterrupter(DeviceTreexHCIController& controller, u16 interrupter_id, size_t irq)
|
||||
xHCIDeviceTreeInterrupter::xHCIDeviceTreeInterrupter(DeviceTreexHCIController& controller, u16 interrupter_id, InterruptNumber irq)
|
||||
: IRQHandler(irq)
|
||||
, m_controller(controller)
|
||||
, m_interrupter_id(interrupter_id)
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
virtual StringView purpose() const override { return "xHCI Interrupter"sv; }
|
||||
|
||||
private:
|
||||
xHCIPCIInterrupter(PCIxHCIController& controller, u16 interrupter_id, u16 irq);
|
||||
xHCIPCIInterrupter(PCIxHCIController& controller, u16 interrupter_id, InterruptNumber irq);
|
||||
|
||||
virtual bool handle_irq() override;
|
||||
|
||||
@@ -32,12 +32,12 @@ private:
|
||||
|
||||
class xHCIDeviceTreeInterrupter final : public IRQHandler {
|
||||
public:
|
||||
static ErrorOr<NonnullOwnPtr<xHCIDeviceTreeInterrupter>> create(DeviceTreexHCIController&, size_t irq, u16 interrupter_id);
|
||||
static ErrorOr<NonnullOwnPtr<xHCIDeviceTreeInterrupter>> create(DeviceTreexHCIController&, InterruptNumber irq, u16 interrupter_id);
|
||||
|
||||
virtual StringView purpose() const override { return "xHCI Interrupter"sv; }
|
||||
|
||||
private:
|
||||
xHCIDeviceTreeInterrupter(DeviceTreexHCIController& controller, u16 interrupter_id, size_t irq);
|
||||
xHCIDeviceTreeInterrupter(DeviceTreexHCIController& controller, u16 interrupter_id, InterruptNumber irq);
|
||||
|
||||
virtual bool handle_irq() override;
|
||||
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
namespace Kernel::VirtIO {
|
||||
|
||||
ErrorOr<NonnullOwnPtr<PCIeTransportInterruptHandler>> PCIeTransportInterruptHandler::create(PCIeTransportLink& transport_link, VirtIO::Device& parent_device, u8 irq)
|
||||
ErrorOr<NonnullOwnPtr<PCIeTransportInterruptHandler>> PCIeTransportInterruptHandler::create(PCIeTransportLink& transport_link, VirtIO::Device& parent_device, InterruptNumber irq)
|
||||
{
|
||||
return TRY(adopt_nonnull_own_or_enomem(new (nothrow) PCIeTransportInterruptHandler(transport_link, parent_device, irq)));
|
||||
}
|
||||
|
||||
PCIeTransportInterruptHandler::PCIeTransportInterruptHandler(PCIeTransportLink& transport_link, VirtIO::Device& parent_device, u8 irq)
|
||||
PCIeTransportInterruptHandler::PCIeTransportInterruptHandler(PCIeTransportLink& transport_link, VirtIO::Device& parent_device, InterruptNumber irq)
|
||||
: TransportInterruptHandler(parent_device)
|
||||
, PCI::IRQHandler(transport_link, irq)
|
||||
{
|
||||
|
||||
@@ -17,13 +17,13 @@ class PCIeTransportInterruptHandler final
|
||||
: public TransportInterruptHandler
|
||||
, public PCI::IRQHandler {
|
||||
public:
|
||||
static ErrorOr<NonnullOwnPtr<PCIeTransportInterruptHandler>> create(PCIeTransportLink&, VirtIO::Device&, u8 irq);
|
||||
static ErrorOr<NonnullOwnPtr<PCIeTransportInterruptHandler>> create(PCIeTransportLink&, VirtIO::Device&, InterruptNumber irq);
|
||||
virtual ~PCIeTransportInterruptHandler() override = default;
|
||||
|
||||
virtual StringView purpose() const override { return "VirtIO PCI IRQ Handler"sv; }
|
||||
|
||||
private:
|
||||
PCIeTransportInterruptHandler(PCIeTransportLink&, VirtIO::Device&, u8 irq);
|
||||
PCIeTransportInterruptHandler(PCIeTransportLink&, VirtIO::Device&, InterruptNumber irq);
|
||||
|
||||
//^ IRQHandler
|
||||
virtual bool handle_irq() override;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
UNMAP_AFTER_INIT ErrorOr<NonnullOwnPtr<AHCIInterruptHandler>> AHCIInterruptHandler::create(AHCIController& controller, u8 irq, AHCI::MaskedBitField taken_ports)
|
||||
UNMAP_AFTER_INIT ErrorOr<NonnullOwnPtr<AHCIInterruptHandler>> AHCIInterruptHandler::create(AHCIController& controller, InterruptNumber irq, AHCI::MaskedBitField taken_ports)
|
||||
{
|
||||
auto port_handler = TRY(adopt_nonnull_own_or_enomem(new (nothrow) AHCIInterruptHandler(controller, irq, taken_ports)));
|
||||
port_handler->allocate_resources_and_initialize_ports();
|
||||
@@ -22,7 +22,7 @@ void AHCIInterruptHandler::allocate_resources_and_initialize_ports()
|
||||
enable_irq();
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT AHCIInterruptHandler::AHCIInterruptHandler(AHCIController& controller, u8 irq, AHCI::MaskedBitField taken_ports)
|
||||
UNMAP_AFTER_INIT AHCIInterruptHandler::AHCIInterruptHandler(AHCIController& controller, InterruptNumber irq, AHCI::MaskedBitField taken_ports)
|
||||
: PCI::IRQHandler(controller, irq)
|
||||
, m_parent_controller(controller)
|
||||
, m_taken_ports(taken_ports)
|
||||
|
||||
@@ -28,7 +28,7 @@ class AHCIInterruptHandler final : public PCI::IRQHandler {
|
||||
friend class AHCIController;
|
||||
|
||||
public:
|
||||
static ErrorOr<NonnullOwnPtr<AHCIInterruptHandler>> create(AHCIController&, u8 irq, AHCI::MaskedBitField taken_ports);
|
||||
static ErrorOr<NonnullOwnPtr<AHCIInterruptHandler>> create(AHCIController&, InterruptNumber irq, AHCI::MaskedBitField taken_ports);
|
||||
virtual ~AHCIInterruptHandler() override;
|
||||
|
||||
virtual StringView purpose() const override { return "SATA IRQ Handler"sv; }
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
bool is_responsible_for_port_index(u32 port_index) const { return m_taken_ports.is_set_at(port_index); }
|
||||
|
||||
private:
|
||||
AHCIInterruptHandler(AHCIController&, u8 irq, AHCI::MaskedBitField taken_ports);
|
||||
AHCIInterruptHandler(AHCIController&, InterruptNumber irq, AHCI::MaskedBitField taken_ports);
|
||||
|
||||
void allocate_resources_and_initialize_ports();
|
||||
|
||||
|
||||
@@ -354,7 +354,7 @@ UNMAP_AFTER_INIT ErrorOr<void> NVMeController::create_admin_queue(QueueType queu
|
||||
m_controller_regs->acq = reinterpret_cast<u64>(AK::convert_between_host_and_little_endian(cq_dma_pages.first()->paddr().as_ptr()));
|
||||
m_controller_regs->asq = reinterpret_cast<u64>(AK::convert_between_host_and_little_endian(sq_dma_pages.first()->paddr().as_ptr()));
|
||||
|
||||
Optional<u8> irq;
|
||||
Optional<InterruptNumber> irq;
|
||||
if (queue_type == QueueType::IRQ)
|
||||
irq = TRY(allocate_irq(0)); // Admin queue always uses the 0th index when using MSIx
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
ErrorOr<NonnullLockRefPtr<NVMeInterruptQueue>> NVMeInterruptQueue::try_create(PCI::Device& device, NonnullOwnPtr<Memory::Region> rw_dma_region, NonnullRefPtr<Memory::PhysicalRAMPage> rw_dma_page, u16 qid, u8 irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, OwnPtr<Memory::Region> sq_dma_region, Doorbell db_regs)
|
||||
ErrorOr<NonnullLockRefPtr<NVMeInterruptQueue>> NVMeInterruptQueue::try_create(PCI::Device& device, NonnullOwnPtr<Memory::Region> rw_dma_region, NonnullRefPtr<Memory::PhysicalRAMPage> rw_dma_page, u16 qid, InterruptNumber irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, OwnPtr<Memory::Region> sq_dma_region, Doorbell db_regs)
|
||||
{
|
||||
auto queue = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) NVMeInterruptQueue(device, move(rw_dma_region), rw_dma_page, qid, irq, q_depth, move(cq_dma_region), move(sq_dma_region), move(db_regs))));
|
||||
queue->initialize_interrupt_queue();
|
||||
return queue;
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT NVMeInterruptQueue::NVMeInterruptQueue(PCI::Device& device, NonnullOwnPtr<Memory::Region> rw_dma_region, NonnullRefPtr<Memory::PhysicalRAMPage> rw_dma_page, u16 qid, u8 irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, OwnPtr<Memory::Region> sq_dma_region, Doorbell db_regs)
|
||||
UNMAP_AFTER_INIT NVMeInterruptQueue::NVMeInterruptQueue(PCI::Device& device, NonnullOwnPtr<Memory::Region> rw_dma_region, NonnullRefPtr<Memory::PhysicalRAMPage> rw_dma_page, u16 qid, InterruptNumber irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, OwnPtr<Memory::Region> sq_dma_region, Doorbell db_regs)
|
||||
: NVMeQueue(move(rw_dma_region), rw_dma_page, qid, q_depth, move(cq_dma_region), move(sq_dma_region), move(db_regs))
|
||||
, PCI::IRQHandler(device, irq)
|
||||
{
|
||||
|
||||
@@ -14,14 +14,14 @@ namespace Kernel {
|
||||
class NVMeInterruptQueue : public NVMeQueue
|
||||
, public PCI::IRQHandler {
|
||||
public:
|
||||
static ErrorOr<NonnullLockRefPtr<NVMeInterruptQueue>> try_create(PCI::Device& device, NonnullOwnPtr<Memory::Region> rw_dma_region, NonnullRefPtr<Memory::PhysicalRAMPage> rw_dma_page, u16 qid, u8 irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, OwnPtr<Memory::Region> sq_dma_region, Doorbell db_regs);
|
||||
static ErrorOr<NonnullLockRefPtr<NVMeInterruptQueue>> try_create(PCI::Device& device, NonnullOwnPtr<Memory::Region> rw_dma_region, NonnullRefPtr<Memory::PhysicalRAMPage> rw_dma_page, u16 qid, InterruptNumber irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, OwnPtr<Memory::Region> sq_dma_region, Doorbell db_regs);
|
||||
void submit_sqe(NVMeSubmission& submission) override;
|
||||
virtual ~NVMeInterruptQueue() override = default;
|
||||
virtual StringView purpose() const override { return "NVMe"sv; }
|
||||
void initialize_interrupt_queue();
|
||||
|
||||
protected:
|
||||
NVMeInterruptQueue(PCI::Device& device, NonnullOwnPtr<Memory::Region> rw_dma_region, NonnullRefPtr<Memory::PhysicalRAMPage> rw_dma_page, u16 qid, u8 irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, OwnPtr<Memory::Region> sq_dma_region, Doorbell db_regs);
|
||||
NVMeInterruptQueue(PCI::Device& device, NonnullOwnPtr<Memory::Region> rw_dma_region, NonnullRefPtr<Memory::PhysicalRAMPage> rw_dma_page, u16 qid, InterruptNumber irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, OwnPtr<Memory::Region> sq_dma_region, Doorbell db_regs);
|
||||
|
||||
private:
|
||||
virtual void complete_current_request(u16 cmdid, u16 status) override;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <Kernel/Library/StdLib.h>
|
||||
|
||||
namespace Kernel {
|
||||
ErrorOr<NonnullLockRefPtr<NVMeQueue>> NVMeQueue::try_create(NVMeController& device, u16 qid, Optional<u8> irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, OwnPtr<Memory::Region> sq_dma_region, Doorbell db_regs, QueueType queue_type)
|
||||
ErrorOr<NonnullLockRefPtr<NVMeQueue>> NVMeQueue::try_create(NVMeController& device, u16 qid, Optional<InterruptNumber> irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, OwnPtr<Memory::Region> sq_dma_region, Doorbell db_regs, QueueType queue_type)
|
||||
{
|
||||
// Note: Allocate DMA region for RW operation. For now the requests don't exceed more than 4096 bytes (Storage device takes care of it)
|
||||
RefPtr<Memory::PhysicalRAMPage> rw_dma_page;
|
||||
|
||||
@@ -54,7 +54,7 @@ struct NVMeIO {
|
||||
class NVMeController;
|
||||
class NVMeQueue : public AtomicRefCounted<NVMeQueue> {
|
||||
public:
|
||||
static ErrorOr<NonnullLockRefPtr<NVMeQueue>> try_create(NVMeController& device, u16 qid, Optional<u8> irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, OwnPtr<Memory::Region> sq_dma_region, Doorbell db_regs, QueueType queue_type);
|
||||
static ErrorOr<NonnullLockRefPtr<NVMeQueue>> try_create(NVMeController& device, u16 qid, Optional<InterruptNumber> irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, OwnPtr<Memory::Region> sq_dma_region, Doorbell db_regs, QueueType queue_type);
|
||||
bool is_admin_queue() { return m_admin_queue; }
|
||||
u16 submit_sync_sqe(NVMeSubmission&);
|
||||
void read(AsyncBlockDeviceRequest& request, u16 nsid, u64 index, u32 count);
|
||||
|
||||
@@ -33,7 +33,7 @@ ErrorOr<void> SysFSInterrupts::try_generate(KBufferBuilder& builder)
|
||||
result = ([&]() -> ErrorOr<void> {
|
||||
auto obj = TRY(array.add_object());
|
||||
TRY(obj.add("purpose"sv, handler.purpose()));
|
||||
TRY(obj.add("interrupt_line"sv, handler.interrupt_number()));
|
||||
TRY(obj.add("interrupt_line"sv, handler.interrupt_number().value()));
|
||||
TRY(obj.add("controller"sv, handler.controller()));
|
||||
TRY(obj.add("device_sharing"sv, (unsigned)handler.sharing_devices_count()));
|
||||
auto per_cpu_call_counts = TRY(obj.add_array("per_cpu_call_counts"sv));
|
||||
|
||||
@@ -30,7 +30,7 @@ UNMAP_AFTER_INIT void initialize()
|
||||
auto facp_table_or_error = Memory::map_typed<Structures::FADT>(facp.value());
|
||||
if (facp_table_or_error.is_error())
|
||||
return;
|
||||
u8 irq_line = facp_table_or_error.value()->sci_int;
|
||||
InterruptNumber irq_line = facp_table_or_error.value()->sci_int;
|
||||
|
||||
Parser::must_initialize(rsdp.value(), facp.value(), irq_line);
|
||||
if (kernel_command_line().acpi_feature_level() == AcpiFeatureLevel::Enabled)
|
||||
|
||||
@@ -31,7 +31,7 @@ Parser* Parser::the()
|
||||
return s_acpi_parser;
|
||||
}
|
||||
|
||||
void Parser::must_initialize(PhysicalAddress rsdp, PhysicalAddress fadt, u8 irq_number)
|
||||
void Parser::must_initialize(PhysicalAddress rsdp, PhysicalAddress fadt, InterruptNumber irq_number)
|
||||
{
|
||||
VERIFY(!s_acpi_parser);
|
||||
s_acpi_parser = new (nothrow) Parser(rsdp, fadt, irq_number);
|
||||
@@ -394,7 +394,7 @@ UNMAP_AFTER_INIT void Parser::locate_main_system_description_table()
|
||||
}
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT Parser::Parser(PhysicalAddress rsdp, PhysicalAddress fadt, u8 irq_number)
|
||||
UNMAP_AFTER_INIT Parser::Parser(PhysicalAddress rsdp, PhysicalAddress fadt, InterruptNumber irq_number)
|
||||
: IRQHandler(irq_number)
|
||||
, m_rsdp(rsdp)
|
||||
, m_fadt(fadt)
|
||||
|
||||
@@ -52,7 +52,7 @@ class Parser final : public IRQHandler {
|
||||
public:
|
||||
static Parser* the();
|
||||
|
||||
static void must_initialize(PhysicalAddress rsdp, PhysicalAddress fadt, u8 irq_number);
|
||||
static void must_initialize(PhysicalAddress rsdp, PhysicalAddress fadt, InterruptNumber irq_number);
|
||||
|
||||
virtual StringView purpose() const override { return "ACPI Parser"sv; }
|
||||
virtual bool handle_irq() override;
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
~Parser() = default;
|
||||
|
||||
private:
|
||||
Parser(PhysicalAddress rsdp, PhysicalAddress fadt, u8 irq_number);
|
||||
Parser(PhysicalAddress rsdp, PhysicalAddress fadt, InterruptNumber irq_number);
|
||||
|
||||
void locate_static_data();
|
||||
void locate_main_system_description_table();
|
||||
|
||||
@@ -19,7 +19,7 @@ ErrorOr<Device::Resource> Device::get_resource(size_t index) const
|
||||
};
|
||||
}
|
||||
|
||||
ErrorOr<size_t> Device::get_interrupt_number(size_t index) const
|
||||
ErrorOr<InterruptNumber> Device::get_interrupt_number(size_t index) const
|
||||
{
|
||||
auto interrupts = TRY(node().interrupts(DeviceTree::get()));
|
||||
auto maybe_interrupt = interrupts.get(index);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <AK/Badge.h>
|
||||
#include <AK/IntrusiveList.h>
|
||||
#include <AK/Noncopyable.h>
|
||||
#include <Kernel/Interrupts/Interrupts.h>
|
||||
#include <Kernel/Memory/PhysicalAddress.h>
|
||||
#include <LibDeviceTree/DeviceTree.h>
|
||||
|
||||
@@ -45,7 +46,7 @@ public:
|
||||
ErrorOr<Resource> get_resource(size_t index) const;
|
||||
|
||||
// FIXME: Add support for the "interrupt-names" property to resolve interrupts by name.
|
||||
ErrorOr<size_t> get_interrupt_number(size_t index) const;
|
||||
ErrorOr<InterruptNumber> get_interrupt_number(size_t index) const;
|
||||
|
||||
private:
|
||||
::DeviceTree::Node const& m_node;
|
||||
|
||||
@@ -14,7 +14,7 @@ class InterruptController {
|
||||
public:
|
||||
virtual ~InterruptController() = default;
|
||||
|
||||
virtual ErrorOr<size_t> translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes) const = 0;
|
||||
virtual ErrorOr<InterruptNumber> translate_interrupt_specifier_to_interrupt_number(ReadonlyBytes) const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -45,7 +45,7 @@ ErrorOr<void> Management::register_interrupt_controller(DeviceTree::Device const
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<size_t> Management::resolve_interrupt_number(::DeviceTree::Interrupt interrupt) const
|
||||
ErrorOr<InterruptNumber> Management::resolve_interrupt_number(::DeviceTree::Interrupt interrupt) const
|
||||
{
|
||||
auto maybe_interrupt_controller = m_interrupt_controllers.get(interrupt.domain_root);
|
||||
if (!maybe_interrupt_controller.has_value())
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <AK/HashMap.h>
|
||||
#include <Kernel/Firmware/DeviceTree/Driver.h>
|
||||
#include <Kernel/Firmware/DeviceTree/InterruptController.h>
|
||||
#include <Kernel/Interrupts/Interrupts.h>
|
||||
#include <Libraries/LibDeviceTree/DeviceTree.h>
|
||||
|
||||
namespace Kernel::I2C {
|
||||
@@ -34,7 +35,7 @@ public:
|
||||
|
||||
static ErrorOr<I2C::Controller*> i2c_controller_for(::DeviceTree::Node const&);
|
||||
|
||||
ErrorOr<size_t> resolve_interrupt_number(::DeviceTree::Interrupt) const;
|
||||
ErrorOr<InterruptNumber> resolve_interrupt_number(::DeviceTree::Interrupt) const;
|
||||
|
||||
ErrorOr<void> scan_node_for_devices(::DeviceTree::Node const& node, ShouldProbeImmediately);
|
||||
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
#include <Kernel/Library/Assertions.h>
|
||||
|
||||
namespace Kernel {
|
||||
GenericInterruptHandler& GenericInterruptHandler::from(u8 interrupt_number)
|
||||
GenericInterruptHandler& GenericInterruptHandler::from(InterruptNumber interrupt_number)
|
||||
{
|
||||
return get_interrupt_handler(interrupt_number);
|
||||
}
|
||||
|
||||
GenericInterruptHandler::GenericInterruptHandler(u8 interrupt_number, bool disable_remap)
|
||||
GenericInterruptHandler::GenericInterruptHandler(InterruptNumber interrupt_number, bool disable_remap)
|
||||
: m_interrupt_number(interrupt_number)
|
||||
, m_disable_remap(disable_remap)
|
||||
{
|
||||
@@ -55,7 +55,7 @@ void GenericInterruptHandler::unregister_interrupt_handler()
|
||||
m_registered = false;
|
||||
}
|
||||
|
||||
void GenericInterruptHandler::change_interrupt_number(u8 number)
|
||||
void GenericInterruptHandler::change_interrupt_number(InterruptNumber number)
|
||||
{
|
||||
VERIFY_INTERRUPTS_DISABLED();
|
||||
VERIFY(!m_disable_remap);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <AK/IntrusiveList.h>
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Arch/RegisterState.h>
|
||||
#include <Kernel/Interrupts/Interrupts.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
@@ -21,7 +22,7 @@ enum class HandlerType : u8 {
|
||||
|
||||
class GenericInterruptHandler {
|
||||
public:
|
||||
static GenericInterruptHandler& from(u8 interrupt_number);
|
||||
static GenericInterruptHandler& from(InterruptNumber interrupt_number);
|
||||
virtual ~GenericInterruptHandler()
|
||||
{
|
||||
VERIFY(!m_registered);
|
||||
@@ -35,7 +36,7 @@ public:
|
||||
void register_interrupt_handler();
|
||||
void unregister_interrupt_handler();
|
||||
|
||||
u8 interrupt_number() const { return m_interrupt_number; }
|
||||
InterruptNumber interrupt_number() const { return m_interrupt_number; }
|
||||
|
||||
ReadonlySpan<u32> per_cpu_call_counts() const;
|
||||
|
||||
@@ -52,15 +53,15 @@ public:
|
||||
bool reserved() const { return m_reserved; }
|
||||
|
||||
protected:
|
||||
void change_interrupt_number(u8 number);
|
||||
GenericInterruptHandler(u8 interrupt_number, bool disable_remap = false);
|
||||
void change_interrupt_number(InterruptNumber number);
|
||||
GenericInterruptHandler(InterruptNumber interrupt_number, bool disable_remap = false);
|
||||
|
||||
void disable_remap() { m_disable_remap = true; }
|
||||
|
||||
private:
|
||||
Array<u32, MAX_CPU_COUNT> m_per_cpu_call_counts {};
|
||||
|
||||
u8 m_interrupt_number { 0 };
|
||||
InterruptNumber m_interrupt_number { 0 };
|
||||
bool m_disable_remap { false };
|
||||
bool m_registered { false };
|
||||
bool m_reserved { false };
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
IRQHandler::IRQHandler(u8 irq)
|
||||
IRQHandler::IRQHandler(InterruptNumber irq)
|
||||
: GenericInterruptHandler(irq)
|
||||
, m_responsible_irq_controller(InterruptManagement::the().get_responsible_irq_controller(irq))
|
||||
{
|
||||
@@ -49,7 +49,7 @@ void IRQHandler::disable_irq()
|
||||
m_responsible_irq_controller->disable(*this);
|
||||
}
|
||||
|
||||
void IRQHandler::change_irq_number(u8 irq)
|
||||
void IRQHandler::change_irq_number(InterruptNumber irq)
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
change_interrupt_number(irq);
|
||||
|
||||
@@ -34,8 +34,8 @@ public:
|
||||
void set_shared_with_others(bool status) { m_shared_with_others = status; }
|
||||
|
||||
protected:
|
||||
void change_irq_number(u8 irq);
|
||||
explicit IRQHandler(u8 irq);
|
||||
void change_irq_number(InterruptNumber irq);
|
||||
explicit IRQHandler(InterruptNumber irq);
|
||||
|
||||
private:
|
||||
bool m_shared_with_others { false };
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Sönke Holz <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/DistinctNumeric.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(size_t, InterruptNumber, Arithmetic, Comparison, Increment)
|
||||
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace Kernel::PCI {
|
||||
|
||||
IRQHandler::IRQHandler(PCI::Device& device, u8 irq)
|
||||
IRQHandler::IRQHandler(PCI::Device& device, InterruptNumber irq)
|
||||
: GenericInterruptHandler(irq)
|
||||
, device(device)
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
void set_shared_with_others(bool status) { m_shared_with_others = status; }
|
||||
|
||||
protected:
|
||||
IRQHandler(PCI::Device& device, u8 irq);
|
||||
IRQHandler(PCI::Device& device, InterruptNumber irq);
|
||||
|
||||
private:
|
||||
bool m_shared_with_others { false };
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
UNMAP_AFTER_INIT void SharedIRQHandler::initialize(u8 interrupt_number)
|
||||
UNMAP_AFTER_INIT void SharedIRQHandler::initialize(InterruptNumber interrupt_number)
|
||||
{
|
||||
auto* handler = new SharedIRQHandler(interrupt_number);
|
||||
handler->register_interrupt_handler();
|
||||
@@ -48,7 +48,7 @@ void SharedIRQHandler::enumerate_handlers(Function<void(GenericInterruptHandler&
|
||||
m_handlers.for_each([&](auto& handler) { callback(handler); });
|
||||
}
|
||||
|
||||
SharedIRQHandler::SharedIRQHandler(u8 irq)
|
||||
SharedIRQHandler::SharedIRQHandler(InterruptNumber irq)
|
||||
: GenericInterruptHandler(irq)
|
||||
, m_responsible_irq_controller(InterruptManagement::the().get_responsible_irq_controller(irq))
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Kernel {
|
||||
class IRQHandler;
|
||||
class SharedIRQHandler final : public GenericInterruptHandler {
|
||||
public:
|
||||
static void initialize(u8 interrupt_number);
|
||||
static void initialize(InterruptNumber interrupt_number);
|
||||
virtual ~SharedIRQHandler();
|
||||
virtual bool handle_interrupt() override;
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
private:
|
||||
void enable_interrupt_vector();
|
||||
void disable_interrupt_vector();
|
||||
explicit SharedIRQHandler(u8 interrupt_number);
|
||||
explicit SharedIRQHandler(InterruptNumber interrupt_number);
|
||||
bool m_enabled { true };
|
||||
RecursiveSpinlockProtected<GenericInterruptHandler::List, LockRank::None> m_handlers;
|
||||
NonnullLockRefPtr<IRQController> m_responsible_irq_controller;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
UNMAP_AFTER_INIT void SpuriousInterruptHandler::initialize(u8 interrupt_number)
|
||||
UNMAP_AFTER_INIT void SpuriousInterruptHandler::initialize(InterruptNumber interrupt_number)
|
||||
{
|
||||
auto* handler = new SpuriousInterruptHandler(interrupt_number);
|
||||
handler->register_interrupt_handler();
|
||||
@@ -60,7 +60,7 @@ StringView SpuriousInterruptHandler::purpose() const
|
||||
return m_real_handler->purpose();
|
||||
}
|
||||
|
||||
SpuriousInterruptHandler::SpuriousInterruptHandler(u8 irq)
|
||||
SpuriousInterruptHandler::SpuriousInterruptHandler(InterruptNumber irq)
|
||||
: GenericInterruptHandler(irq)
|
||||
, m_responsible_irq_controller(InterruptManagement::the().get_responsible_irq_controller(irq))
|
||||
{
|
||||
@@ -71,7 +71,7 @@ SpuriousInterruptHandler::~SpuriousInterruptHandler() = default;
|
||||
bool SpuriousInterruptHandler::handle_interrupt()
|
||||
{
|
||||
// Actually check if IRQ7 or IRQ15 are spurious, and if not, call the real handler to handle the IRQ.
|
||||
if (m_responsible_irq_controller->get_isr() & (1 << interrupt_number())) {
|
||||
if (m_responsible_irq_controller->get_isr() & (1 << interrupt_number().value())) {
|
||||
m_real_irq = true; // remember that we had a real IRQ, when EOI later!
|
||||
if (m_real_handler->handle_interrupt()) {
|
||||
m_real_handler->increment_call_count();
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Kernel {
|
||||
|
||||
class SpuriousInterruptHandler final : public GenericInterruptHandler {
|
||||
public:
|
||||
static void initialize(u8 interrupt_number);
|
||||
static void initialize(InterruptNumber interrupt_number);
|
||||
static void initialize_for_disabled_master_pic();
|
||||
static void initialize_for_disabled_slave_pic();
|
||||
virtual ~SpuriousInterruptHandler();
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
private:
|
||||
void enable_interrupt_vector();
|
||||
void disable_interrupt_vector();
|
||||
explicit SpuriousInterruptHandler(u8 interrupt_number);
|
||||
explicit SpuriousInterruptHandler(InterruptNumber interrupt_number);
|
||||
bool m_enabled { false };
|
||||
bool m_real_irq { false };
|
||||
NonnullLockRefPtr<IRQController> m_responsible_irq_controller;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <Kernel/Library/Panic.h>
|
||||
|
||||
namespace Kernel {
|
||||
UnhandledInterruptHandler::UnhandledInterruptHandler(u8 interrupt_vector)
|
||||
UnhandledInterruptHandler::UnhandledInterruptHandler(InterruptNumber interrupt_vector)
|
||||
: GenericInterruptHandler(interrupt_vector)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace Kernel {
|
||||
class UnhandledInterruptHandler final : public GenericInterruptHandler {
|
||||
public:
|
||||
explicit UnhandledInterruptHandler(u8 interrupt_vector);
|
||||
explicit UnhandledInterruptHandler(InterruptNumber interrupt_vector);
|
||||
virtual ~UnhandledInterruptHandler();
|
||||
|
||||
virtual bool handle_interrupt() override;
|
||||
|
||||
@@ -195,7 +195,7 @@ UNMAP_AFTER_INIT ErrorOr<bool> E1000ENetworkAdapter::probe(PCI::DeviceIdentifier
|
||||
|
||||
UNMAP_AFTER_INIT ErrorOr<NonnullRefPtr<NetworkAdapter>> E1000ENetworkAdapter::create(PCI::DeviceIdentifier const& pci_device_identifier)
|
||||
{
|
||||
u8 irq = pci_device_identifier.interrupt_line().value();
|
||||
InterruptNumber irq = pci_device_identifier.interrupt_line().value();
|
||||
auto interface_name = TRY(NetworkingManagement::generate_interface_name_from_pci_address(pci_device_identifier));
|
||||
auto registers_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_device_identifier, PCI::HeaderType0BaseRegister::BAR0));
|
||||
|
||||
@@ -236,7 +236,7 @@ UNMAP_AFTER_INIT ErrorOr<void> E1000ENetworkAdapter::initialize(Badge<Networking
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT E1000ENetworkAdapter::E1000ENetworkAdapter(StringView interface_name,
|
||||
PCI::DeviceIdentifier const& device_identifier, u8 irq,
|
||||
PCI::DeviceIdentifier const& device_identifier, InterruptNumber irq,
|
||||
NonnullOwnPtr<IOWindow> registers_io_window, NonnullOwnPtr<Memory::Region> rx_buffer_region,
|
||||
NonnullOwnPtr<Memory::Region> tx_buffer_region, Memory::TypedMapping<RxDescriptor volatile[]> rx_descriptors,
|
||||
Memory::TypedMapping<TxDescriptor volatile[]> tx_descriptors)
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
virtual StringView purpose() const override { return class_name(); }
|
||||
|
||||
private:
|
||||
E1000ENetworkAdapter(StringView interface_name, PCI::DeviceIdentifier const&, u8 irq,
|
||||
E1000ENetworkAdapter(StringView interface_name, PCI::DeviceIdentifier const&, InterruptNumber irq,
|
||||
NonnullOwnPtr<IOWindow> registers_io_window, NonnullOwnPtr<Memory::Region> rx_buffer_region,
|
||||
NonnullOwnPtr<Memory::Region> tx_buffer_region, Memory::TypedMapping<RxDescriptor volatile[]> rx_descriptors,
|
||||
Memory::TypedMapping<TxDescriptor volatile[]> tx_descriptors);
|
||||
|
||||
@@ -168,7 +168,7 @@ UNMAP_AFTER_INIT ErrorOr<bool> E1000NetworkAdapter::probe(PCI::DeviceIdentifier
|
||||
|
||||
UNMAP_AFTER_INIT ErrorOr<NonnullRefPtr<NetworkAdapter>> E1000NetworkAdapter::create(PCI::DeviceIdentifier const& pci_device_identifier)
|
||||
{
|
||||
u8 irq = pci_device_identifier.interrupt_line().value();
|
||||
InterruptNumber irq = pci_device_identifier.interrupt_line().value();
|
||||
auto interface_name = TRY(NetworkingManagement::generate_interface_name_from_pci_address(pci_device_identifier));
|
||||
auto registers_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_device_identifier, PCI::HeaderType0BaseRegister::BAR0));
|
||||
|
||||
@@ -228,7 +228,7 @@ UNMAP_AFTER_INIT void E1000NetworkAdapter::setup_interrupts()
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT E1000NetworkAdapter::E1000NetworkAdapter(StringView interface_name,
|
||||
PCI::DeviceIdentifier const& device_identifier, u8 irq,
|
||||
PCI::DeviceIdentifier const& device_identifier, InterruptNumber irq,
|
||||
NonnullOwnPtr<IOWindow> registers_io_window, NonnullOwnPtr<Memory::Region> rx_buffer_region,
|
||||
NonnullOwnPtr<Memory::Region> tx_buffer_region, Memory::TypedMapping<RxDescriptor volatile[]> rx_descriptors,
|
||||
Memory::TypedMapping<TxDescriptor volatile[]> tx_descriptors)
|
||||
|
||||
@@ -64,7 +64,7 @@ protected:
|
||||
void setup_interrupts();
|
||||
void setup_link();
|
||||
|
||||
E1000NetworkAdapter(StringView, PCI::DeviceIdentifier const&, u8 irq,
|
||||
E1000NetworkAdapter(StringView, PCI::DeviceIdentifier const&, InterruptNumber irq,
|
||||
NonnullOwnPtr<IOWindow> registers_io_window, NonnullOwnPtr<Memory::Region> rx_buffer_region,
|
||||
NonnullOwnPtr<Memory::Region> tx_buffer_region,
|
||||
Memory::TypedMapping<RxDescriptor volatile[]> rx_descriptors,
|
||||
|
||||
@@ -205,7 +205,7 @@ UNMAP_AFTER_INIT ErrorOr<bool> RTL8168NetworkAdapter::probe(PCI::DeviceIdentifie
|
||||
|
||||
UNMAP_AFTER_INIT ErrorOr<NonnullRefPtr<NetworkAdapter>> RTL8168NetworkAdapter::create(PCI::DeviceIdentifier const& pci_device_identifier)
|
||||
{
|
||||
u8 irq = pci_device_identifier.interrupt_line().value();
|
||||
InterruptNumber irq = pci_device_identifier.interrupt_line().value();
|
||||
auto interface_name = TRY(NetworkingManagement::generate_interface_name_from_pci_address(pci_device_identifier));
|
||||
auto registers_io_window = TRY(IOWindow::create_for_pci_device_bar(pci_device_identifier, PCI::HeaderType0BaseRegister::BAR0));
|
||||
return TRY(adopt_nonnull_ref_or_enomem(new (nothrow) RTL8168NetworkAdapter(interface_name.representable_view(), pci_device_identifier, irq, move(registers_io_window))));
|
||||
@@ -256,7 +256,7 @@ bool RTL8168NetworkAdapter::determine_supported_version() const
|
||||
}
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT RTL8168NetworkAdapter::RTL8168NetworkAdapter(StringView interface_name, PCI::DeviceIdentifier const& device_identifier, u8 irq, NonnullOwnPtr<IOWindow> registers_io_window)
|
||||
UNMAP_AFTER_INIT RTL8168NetworkAdapter::RTL8168NetworkAdapter(StringView interface_name, PCI::DeviceIdentifier const& device_identifier, InterruptNumber irq, NonnullOwnPtr<IOWindow> registers_io_window)
|
||||
: NetworkAdapter(interface_name)
|
||||
, PCI::Device(device_identifier)
|
||||
, IRQHandler(irq)
|
||||
|
||||
@@ -42,7 +42,7 @@ private:
|
||||
static constexpr size_t number_of_rx_descriptors = 64;
|
||||
static constexpr size_t number_of_tx_descriptors = 16;
|
||||
|
||||
RTL8168NetworkAdapter(StringView, PCI::DeviceIdentifier const&, u8 irq, NonnullOwnPtr<IOWindow> registers_io_window);
|
||||
RTL8168NetworkAdapter(StringView, PCI::DeviceIdentifier const&, InterruptNumber irq, NonnullOwnPtr<IOWindow> registers_io_window);
|
||||
|
||||
virtual bool handle_irq() override;
|
||||
virtual StringView class_name() const override { return "RTL8168NetworkAdapter"sv; }
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
virtual size_t ticks_per_second() const override { return m_frequency; }
|
||||
|
||||
protected:
|
||||
HardwareTimer(u8 irq_number, Function<void()> callback = nullptr)
|
||||
HardwareTimer(InterruptNumber irq_number, Function<void()> callback = nullptr)
|
||||
: IRQHandler(irq_number)
|
||||
, m_callback(move(callback))
|
||||
{
|
||||
@@ -143,7 +143,7 @@ public:
|
||||
virtual size_t ticks_per_second() const override { return m_frequency; }
|
||||
|
||||
protected:
|
||||
HardwareTimer(u8 irq_number, Function<void()> callback = nullptr)
|
||||
HardwareTimer(InterruptNumber irq_number, Function<void()> callback = nullptr)
|
||||
: GenericInterruptHandler(irq_number)
|
||||
, m_callback(move(callback))
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ ErrorOr<int> serenity_main(Main::Arguments)
|
||||
json.as_array().for_each([cpu_count](JsonValue const& value) {
|
||||
auto& handler = value.as_object();
|
||||
auto purpose = handler.get_byte_string("purpose"sv).value_or({});
|
||||
auto interrupt = handler.get_u8("interrupt_line"sv).value();
|
||||
auto interrupt = handler.get_integer<size_t>("interrupt_line"sv).value();
|
||||
auto controller = handler.get_byte_string("controller"sv).value_or({});
|
||||
auto call_counts = handler.get_array("per_cpu_call_counts"sv).value();
|
||||
|
||||
|
||||
Reference in new issue
Block a user