Kernel: Fix interrupt system

I had not understood how MSIs work and I was unnecessarily routing them
through IOAPIC. This is not necessary and should not be done :D

Also MSIs were reserving interrupts that IOAPIC was capable of
generating. Now IOAPIC and MSIs use different set of interrupts so
IOAPIC can use more interrupts if needed.
This commit is contained in:
2024-09-27 15:31:31 +03:00
parent e4982a1a5c
commit 2d11ce9669
25 changed files with 618 additions and 199 deletions

View File

@@ -703,10 +703,9 @@ acpi_release_global_lock:
);
}
set_irq(irq);
enable_interrupt();
InterruptController::get().enable_irq(irq);
Process::create_kernel([](void*) { get().acpi_event_task(); }, nullptr);
}

View File

@@ -371,7 +371,7 @@ namespace Kernel
| ICR_LO_level_assert
| ICR_LO_trigger_mode_level
| ICR_LO_destination_shorthand_none
| (IRQ_VECTOR_BASE + IRQ_IPI)
| IRQ_IPI
);
}
@@ -388,7 +388,7 @@ namespace Kernel
| ICR_LO_level_assert
| ICR_LO_trigger_mode_level
| ICR_LO_destination_shorthand_all_excluding_self
| (IRQ_VECTOR_BASE + IRQ_IPI)
| IRQ_IPI
);
}
@@ -423,7 +423,7 @@ namespace Kernel
dprintln("CPU {}: lapic timer frequency: {} Hz", Kernel::Processor::current_id(), m_lapic_timer_frequency_hz);
write_to_local_apic(LAPIC_TIMER_LVT, TimerModePeriodic | (IRQ_VECTOR_BASE + IRQ_TIMER));
write_to_local_apic(LAPIC_TIMER_LVT, TimerModePeriodic | IRQ_TIMER);
write_to_local_apic(LAPIC_TIMER_INITIAL_REG, m_lapic_timer_frequency_hz / 2 / 100);
}
@@ -536,9 +536,9 @@ namespace Kernel
BAN::Optional<uint8_t> APIC::get_free_irq()
{
SpinLockGuard _(m_lock);
for (int irq = 0; irq <= 0xFF; irq++)
for (uint8_t irq = 0; irq < m_irq_count; irq++)
{
uint32_t gsi = m_irq_overrides[irq];
const uint8_t gsi = m_irq_overrides[irq];
IOAPIC* ioapic = nullptr;
for (IOAPIC& io : m_io_apics)
@@ -553,8 +553,8 @@ namespace Kernel
if (!ioapic)
continue;
int byte = gsi / 8;
int bit = gsi % 8;
const uint8_t byte = gsi / 8;
const uint8_t bit = gsi % 8;
if (m_reserved_gsis[byte] & (1 << bit))
continue;
m_reserved_gsis[byte] |= 1 << bit;

View File

@@ -10,7 +10,15 @@
#include <kernel/Timer/PIT.h>
#define ISR_LIST_X X(0) X(1) X(2) X(3) X(4) X(5) X(6) X(7) X(8) X(9) X(10) X(11) X(12) X(13) X(14) X(15) X(16) X(17) X(18) X(19) X(20) X(21) X(22) X(23) X(24) X(25) X(26) X(27) X(28) X(29) X(30) X(31)
#define IRQ_LIST_X X(0) X(1) X(2) X(3) X(4) X(5) X(6) X(7) X(8) X(9) X(10) X(11) X(12) X(13) X(14) X(15) X(16) X(17) X(18) X(19) X(20) X(21) X(22) X(23) X(24) X(25) X(26) X(27) X(28) X(29) X(30) X(31)
#define IRQ_LIST_X X( 0) X( 1) X( 2) X( 3) X( 4) X( 5) X( 6) X( 7) X( 8) X( 9) X( 10) X( 11) X( 12) X( 13) X( 14) X( 15) X( 16) X( 17) X( 18) X( 19) X( 20) X( 21) X( 22) X( 23) X( 24) X( 25) X( 26) X( 27) X( 28) X( 29) X( 30) X( 31) \
X( 32) X( 33) X( 34) X( 35) X( 36) X( 37) X( 38) X( 39) X( 40) X( 41) X( 42) X( 43) X( 44) X( 45) X( 46) X( 47) X( 48) X( 49) X( 50) X( 51) X( 52) X( 53) X( 54) X( 55) X( 56) X( 57) X( 58) X( 59) X( 60) X( 61) X( 62) X( 63) \
X( 64) X( 65) X( 66) X( 67) X( 68) X( 69) X( 70) X( 71) X( 72) X( 73) X( 74) X( 75) X( 76) X( 77) X( 78) X( 79) X( 80) X( 81) X( 82) X( 83) X( 84) X( 85) X( 86) X( 87) X( 88) X( 89) X( 90) X( 91) X( 92) X( 93) X( 94) X( 95) \
X( 96) X( 97) X( 98) X( 99) X(100) X(101) X(102) X(103) X(104) X(105) X(106) X(107) X(108) X(109) X(110) X(111) X(112) X(113) X(114) X(115) X(116) X(117) X(118) X(119) X(120) X(121) X(122) X(123) X(124) X(125) X(126) X(127) \
X(128) X(129) X(130) X(131) X(132) X(133) X(134) X(135) X(136) X(137) X(138) X(139) X(140) X(141) X(142) X(143) X(144) X(145) X(146) X(147) X(148) X(149) X(150) X(151) X(152) X(153) X(154) X(155) X(156) X(157) X(158) X(159) \
X(160) X(161) X(162) X(163) X(164) X(165) X(166) X(167) X(168) X(169) X(170) X(171) X(172) X(173) X(174) X(175) X(176) X(177) X(178) X(179) X(180) X(181) X(182) X(183) X(184) X(185) X(186) X(187) X(188) X(189) X(190) X(191) \
X(192) X(193) X(194) X(195) X(196) X(197) X(198) X(199) X(200) X(201) X(202) X(203) X(204) X(205) X(206) X(207)
static_assert(Kernel::IRQ_SYSCALL == Kernel::IRQ_VECTOR_BASE + 208);
namespace Kernel
{
@@ -321,15 +329,15 @@ done:
extern "C" void cpp_yield_handler(InterruptStack* interrupt_stack, InterruptRegisters* interrupt_registers)
{
// yield is raised through kernel software interrupt
ASSERT(!InterruptController::get().is_in_service(IRQ_YIELD));
ASSERT(!InterruptController::get().is_in_service(IRQ_YIELD - IRQ_VECTOR_BASE));
ASSERT(!GDT::is_user_segment(interrupt_stack->cs));
Processor::scheduler().reschedule(interrupt_stack, interrupt_registers);
}
extern "C" void cpp_ipi_handler()
{
ASSERT(InterruptController::get().is_in_service(IRQ_IPI));
InterruptController::get().eoi(IRQ_IPI);
ASSERT(InterruptController::get().is_in_service(IRQ_IPI - IRQ_VECTOR_BASE));
InterruptController::get().eoi(IRQ_IPI - IRQ_VECTOR_BASE);
Processor::handle_ipi();
}
@@ -343,8 +351,8 @@ done:
asm volatile("cli; 1: hlt; jmp 1b");
}
ASSERT(InterruptController::get().is_in_service(IRQ_TIMER));
InterruptController::get().eoi(IRQ_TIMER);
ASSERT(InterruptController::get().is_in_service(IRQ_TIMER - IRQ_VECTOR_BASE));
InterruptController::get().eoi(IRQ_TIMER - IRQ_VECTOR_BASE);
if (Processor::current_is_bsb())
Process::update_alarm_queue();
@@ -452,11 +460,10 @@ done:
IRQ_LIST_X
#undef X
idt->register_interrupt_handler(IRQ_VECTOR_BASE + IRQ_YIELD, asm_yield_handler);
idt->register_interrupt_handler(IRQ_VECTOR_BASE + IRQ_IPI, asm_ipi_handler);
idt->register_interrupt_handler(IRQ_VECTOR_BASE + IRQ_TIMER, asm_timer_handler);
idt->register_syscall_handler(0x80, asm_syscall_handler);
idt->register_interrupt_handler(IRQ_YIELD, asm_yield_handler);
idt->register_interrupt_handler(IRQ_IPI, asm_ipi_handler);
idt->register_interrupt_handler(IRQ_TIMER, asm_timer_handler);
idt->register_syscall_handler(IRQ_SYSCALL, asm_syscall_handler);
return idt;
}

View File

@@ -342,13 +342,13 @@ namespace Kernel::Input
if (m_devices[0])
{
m_devices[0]->set_irq(PS2::IRQ::DEVICE0);
m_devices[0]->enable_interrupt();
InterruptController::get().enable_irq(PS2::IRQ::DEVICE0);
config |= PS2::Config::INTERRUPT_FIRST_PORT;
}
if (m_devices[1])
{
m_devices[1]->set_irq(PS2::IRQ::DEVICE1);
m_devices[1]->enable_interrupt();
InterruptController::get().enable_irq(PS2::IRQ::DEVICE1);
config |= PS2::Config::INTERRUPT_SECOND_PORT;
}

View File

@@ -14,15 +14,4 @@ namespace Kernel
Processor::idt().register_irq_handler(irq, this);
}
void Interruptable::enable_interrupt()
{
ASSERT(m_irq != -1);
InterruptController::get().enable_irq(m_irq);
}
void Interruptable::disable_interrupt()
{
ASSERT_NOT_REACHED();
}
}

View File

@@ -245,9 +245,8 @@ namespace Kernel
write32(REG_IMS, IMC_RxQ0);
read32(REG_ICR);
TRY(m_pci_device.reserve_irqs(1));
set_irq(m_pci_device.get_irq(0));
Interruptable::enable_interrupt();
TRY(m_pci_device.reserve_interrupts(1));
m_pci_device.enable_interrupt(0, *this);
return {};
}

View File

@@ -161,9 +161,8 @@ namespace Kernel
BAN::ErrorOr<void> RTL8169::enable_interrupt()
{
TRY(m_pci_device.reserve_irqs(1));
set_irq(m_pci_device.get_irq(0));
Interruptable::enable_interrupt();
TRY(m_pci_device.reserve_interrupts(1));
m_pci_device.enable_interrupt(0, *this);
m_io_bar_region->write16(RTL8169_IO_IMR,
RTL8169_IR_ROK

View File

@@ -175,6 +175,23 @@ namespace Kernel::PCI
}
}
BAN::Optional<uint8_t> PCIManager::reserve_msi()
{
SpinLockGuard _(m_reserved_msi_lock);
for (uint8_t i = 0; i < m_msi_count; i++)
{
const uint8_t byte = i / 8;
const uint8_t bit = i % 8;
if (m_reserved_msi_bitmap[byte] & (1 << bit))
continue;
m_reserved_msi_bitmap[byte] |= 1 << bit;
return IRQ_MSI_BASE - IRQ_VECTOR_BASE + i;
}
return {};
}
void PCIManager::initialize_devices(bool disable_usb)
{
for_each_device(
@@ -360,63 +377,24 @@ namespace Kernel::PCI
}
}
BAN::ErrorOr<void> PCI::Device::reserve_irqs(uint8_t count)
uint8_t PCI::Device::get_interrupt(uint8_t index) const
{
if (!InterruptController::get().is_using_apic())
ASSERT(m_offset_msi.has_value() || m_offset_msi_x.has_value() || !InterruptController::get().is_using_apic());
ASSERT(index < m_reserved_interrupt_count);
uint8_t count_found = 0;
for (uint32_t irq = 0; irq < 0x100; irq++)
{
if (count > 1)
{
dwarnln("PIC: could not allocate {} interrupts, (currently) only {} supported", count, 1);
return BAN::Error::from_errno(EFAULT);
}
enable_pin_interrupts();
}
else if (m_offset_msi_x.has_value())
{
uint16_t msg_ctrl = read_word(*m_offset_msi_x + 0x02);
if (count > (msg_ctrl & 0x7FF) + 1)
{
dwarnln("MSI-X: could not allocate {} interrupts, only {} supported", count, (msg_ctrl & 0x7FF) + 1);
return BAN::Error::from_errno(EFAULT);
}
msg_ctrl |= 1 << 15; // Enable
write_word(*m_offset_msi_x + 0x02, msg_ctrl);
disable_pin_interrupts();
}
else if (m_offset_msi.has_value())
{
if (count > 1)
{
dwarnln("MSI: could not allocate {} interrupts, (currently) only {} supported", count, 1);
return BAN::Error::from_errno(EFAULT);
}
uint16_t msg_ctrl = read_word(*m_offset_msi + 0x02);
msg_ctrl &= ~(0x07 << 4); // Only one interrupt
msg_ctrl |= 1u << 0; // Enable
write_word(*m_offset_msi + 0x02, msg_ctrl);
disable_pin_interrupts();
}
else
{
dwarnln("Could not reserve interrupt for PCI device. No MSI, MSI-X or interrupt line is used");
return BAN::Error::from_errno(EFAULT);
const uint8_t byte = irq / 8;
const uint8_t bit = irq % 8;
if (m_reserved_interrupts[byte] & (1 << bit))
count_found++;
if (index + 1 == count_found)
return irq;
}
for (; m_reserved_irq_count < count; m_reserved_irq_count++)
{
auto irq = InterruptController::get().get_free_irq();
if (!irq.has_value())
{
dwarnln("Could not reserve interrupt for PCI {}:{}.{}", m_bus, m_dev, m_func);
return BAN::Error::from_errno(EFAULT);
}
ASSERT(*irq < 32);
ASSERT(!(m_reserved_irqs & (1 << *irq)));
m_reserved_irqs |= 1 << *irq;
}
return {};
ASSERT_NOT_REACHED();
}
static constexpr uint64_t msi_message_address()
@@ -429,79 +407,145 @@ namespace Kernel::PCI
return (IRQ_VECTOR_BASE + irq) & 0xFF;
}
uint8_t PCI::Device::get_irq(uint8_t index)
void PCI::Device::enable_interrupt(uint8_t index, Interruptable& interruptable)
{
ASSERT(m_offset_msi.has_value() || m_offset_msi_x.has_value() || !InterruptController::get().is_using_apic());
ASSERT(index < m_reserved_irq_count);
const uint8_t irq = get_interrupt(index);
interruptable.set_irq(irq);
uint8_t count_found = 0;
uint8_t irq = 0xFF;
for (uint8_t i = 0; i < 32; i++)
switch (m_interrupt_mechanism)
{
if (m_reserved_irqs & (1 << i))
count_found++;
if (count_found > index)
case InterruptMechanism::NONE:
ASSERT_NOT_REACHED();
case InterruptMechanism::PIN:
enable_pin_interrupts();
write_byte(PCI_REG_IRQ_LINE, irq);
InterruptController::get().enable_irq(irq);
break;
case InterruptMechanism::MSI:
{
irq = i;
disable_pin_interrupts();
uint16_t msg_ctrl = read_word(*m_offset_msi + 0x02);
msg_ctrl &= ~(0x07 << 4); // Only one interrupt
msg_ctrl |= 1u << 0; // Enable
write_word(*m_offset_msi + 0x02, msg_ctrl);
const uint64_t msg_addr = msi_message_address();
const uint32_t msg_data = msi_message_data(irq);
if (msg_ctrl & (1 << 7))
{
write_dword(*m_offset_msi + 0x04, msg_addr & 0xFFFFFFFF);
write_dword(*m_offset_msi + 0x08, msg_addr >> 32);
write_word(*m_offset_msi + 0x12, msg_data);
}
else
{
write_dword(*m_offset_msi + 0x04, msg_addr & 0xFFFFFFFF);
write_word(*m_offset_msi + 0x08, msg_data);
}
break;
}
case InterruptMechanism::MSIX:
{
disable_pin_interrupts();
uint16_t msg_ctrl = read_word(*m_offset_msi_x + 0x02);
msg_ctrl |= 1 << 15; // Enable
write_word(*m_offset_msi_x + 0x02, msg_ctrl);
const uint32_t dword1 = read_dword(*m_offset_msi_x + 0x04);
const uint32_t offset = dword1 & ~7u;
const uint8_t bir = dword1 & 7u;
const uint64_t msg_addr = msi_message_address();
const uint32_t msg_data = msi_message_data(irq);
auto bar = MUST(allocate_bar_region(bir));
ASSERT(bar->type() == BarType::MEM);
auto& msi_x_entry = reinterpret_cast<volatile MSIXEntry*>(bar->vaddr() + offset)[index];
msi_x_entry.msg_addr_low = msg_addr & 0xFFFFFFFF;
msi_x_entry.msg_addr_high = msg_addr >> 32;;
msi_x_entry.msg_data = msg_data;
msi_x_entry.vector_ctrl = msi_x_entry.vector_ctrl & ~1u;
break;
}
}
ASSERT(irq != 0xFF);
}
// Legacy PIC just uses the interrupt line field
if (!InterruptController::get().is_using_apic())
{
write_byte(PCI_REG_IRQ_LINE, irq);
return irq;
}
BAN::ErrorOr<void> PCI::Device::reserve_interrupts(uint8_t count)
{
// FIXME: Allow "late" interrupt reserving
ASSERT(m_reserved_interrupt_count == 0);
if (m_offset_msi_x.has_value())
{
uint32_t dword0 = read_dword(*m_offset_msi_x);
ASSERT((dword0 & 0xFF) == 0x11);
uint32_t dword1 = read_dword(*m_offset_msi_x + 0x04);
uint32_t offset = dword1 & ~7u;
uint8_t bir = dword1 & 7u;
uint64_t msg_addr = msi_message_address();
uint32_t msg_data = msi_message_data(irq);
auto bar = MUST(allocate_bar_region(bir));
ASSERT(bar->type() == BarType::MEM);
auto& msi_x_entry = reinterpret_cast<volatile MSIXEntry*>(bar->vaddr() + offset)[index];
msi_x_entry.msg_addr_low = msg_addr & 0xFFFFFFFF;
msi_x_entry.msg_addr_high = msg_addr >> 32;;
msi_x_entry.msg_data = msg_data;
msi_x_entry.vector_ctrl = msi_x_entry.vector_ctrl & ~1u;
return irq;
}
if (m_offset_msi.has_value())
{
uint32_t dword0 = read_dword(*m_offset_msi);
ASSERT((dword0 & 0xFF) == 0x05);
uint64_t msg_addr = msi_message_address();
uint32_t msg_data = msi_message_data(irq);
if (dword0 & (1 << 23))
const auto mechanism =
[&]() -> InterruptMechanism
{
write_dword(*m_offset_msi + 0x04, msg_addr & 0xFFFFFFFF);
write_dword(*m_offset_msi + 0x08, msg_addr >> 32);
write_word(*m_offset_msi + 0x12, msg_data);
}
else
{
write_dword(*m_offset_msi + 0x04, msg_addr & 0xFFFFFFFF);
write_word(*m_offset_msi + 0x08, msg_data);
}
if (!InterruptController::get().is_using_apic())
{
// FIXME: support multiple PIN interrupts
if (count == 1)
return InterruptMechanism::PIN;
return irq;
// MSI cannot be used without LAPIC
return InterruptMechanism::NONE;
}
if (m_offset_msi_x.has_value())
{
const uint16_t msg_ctrl = read_word(*m_offset_msi_x + 0x02);
if (count <= (msg_ctrl & 0x7FF) + 1)
return InterruptMechanism::MSIX;
}
if (m_offset_msi.has_value())
{
if (count == 1)
return InterruptMechanism::MSI;
// FIXME: support multiple message
}
// FIXME: support ioapic
return InterruptMechanism::NONE;
}();
auto get_interrupt_func =
[mechanism]() -> BAN::Optional<uint8_t>
{
switch (mechanism)
{
case InterruptMechanism::NONE:
return {};
case InterruptMechanism::PIN:
return InterruptController::get().get_free_irq();
case InterruptMechanism::MSI:
case InterruptMechanism::MSIX:
return PCIManager::get().reserve_msi();
}
ASSERT_NOT_REACHED();
};
for (uint8_t i = 0; i < count; i++)
{
const auto irq = get_interrupt_func();
if (!irq.has_value())
{
dwarnln("Could not reserve {} MSI(-X) interrupts", count);
return BAN::Error::from_errno(EFAULT);
}
const uint8_t byte = irq.value() / 8;
const uint8_t bit = irq.value() % 8;
m_reserved_interrupts[byte] |= 1 << bit;
}
ASSERT_NOT_REACHED();
m_interrupt_mechanism = mechanism;
m_reserved_interrupt_count = count;
return {};
}
void PCI::Device::set_command_bits(uint16_t mask)

View File

@@ -368,7 +368,7 @@ namespace Kernel
// NOTE: This is offset by 2 pointers since interrupt without PL change
// does not push SP and SS. This allows accessing "whole" interrupt stack.
:: [load_sp]"r"(Processor::current_stack_top() - 2 * sizeof(uintptr_t)),
[yield]"i"(IRQ_VECTOR_BASE + IRQ_YIELD)
[yield]"i"(IRQ_YIELD)
: "memory", "rcx"
);
#elif ARCH(i686)
@@ -380,7 +380,7 @@ namespace Kernel
// NOTE: This is offset by 2 pointers since interrupt without PL change
// does not push SP and SS. This allows accessing "whole" interrupt stack.
:: [load_sp]"r"(Processor::current_stack_top() - 2 * sizeof(uintptr_t)),
[yield]"i"(IRQ_VECTOR_BASE + IRQ_YIELD)
[yield]"i"(IRQ_YIELD)
: "memory", "ecx"
);
#else

View File

@@ -25,9 +25,8 @@ namespace Kernel
// Enable interrupts and bus mastering
m_pci_device.enable_bus_mastering();
TRY(m_pci_device.reserve_irqs(1));
set_irq(m_pci_device.get_irq(0));
enable_interrupt();
TRY(m_pci_device.reserve_interrupts(1));
m_pci_device.enable_interrupt(0, *this);
abar_mem.ghc = abar_mem.ghc | SATA_GHC_INTERRUPT_ENABLE;
m_command_slot_count = ((abar_mem.cap >> 8) & 0x1F) + 1;

View File

@@ -25,14 +25,13 @@ namespace Kernel
return BAN::Error::from_errno(ENODEV);
}
bus->set_irq(irq);
InterruptController::get().enable_irq(irq);
TRY(bus->initialize());
return bus;
}
BAN::ErrorOr<void> ATABus::initialize()
{
enable_interrupt();
BAN::Vector<uint16_t> identify_buffer;
MUST(identify_buffer.resize(256));

View File

@@ -82,7 +82,7 @@ namespace Kernel
}
// One for aq and one for ioq
TRY(m_pci_device.reserve_irqs(2));
TRY(m_pci_device.reserve_interrupts(2));
auto& cc = m_controller_registers->cc;
@@ -237,12 +237,12 @@ namespace Kernel
m_controller_registers->acq = completion_queue->paddr();
m_controller_registers->asq = submission_queue->paddr();
uint8_t irq = m_pci_device.get_irq(0);
dprintln_if(DEBUG_NVMe, " admin queue using irq {}", irq);
dprintln_if(DEBUG_NVMe, " admin queue using irq {}", m_pci_device.get_interrupt(0));
auto& doorbell = *reinterpret_cast<volatile NVMe::DoorbellRegisters*>(m_bar0->vaddr() + NVMe::ControllerRegisters::SQ0TDBL);
m_admin_queue = TRY(BAN::UniqPtr<NVMeQueue>::create(BAN::move(completion_queue), BAN::move(submission_queue), doorbell, admin_queue_depth, irq));
m_admin_queue = TRY(BAN::UniqPtr<NVMeQueue>::create(BAN::move(completion_queue), BAN::move(submission_queue), doorbell, admin_queue_depth));
m_pci_device.enable_interrupt(0, *m_admin_queue);
return {};
}
@@ -290,14 +290,14 @@ namespace Kernel
}
}
uint8_t irq = m_pci_device.get_irq(1);
dprintln_if(DEBUG_NVMe, " io queue using irq {}", irq);
dprintln_if(DEBUG_NVMe, " io queue using irq {}", m_pci_device.get_interrupt(1));
const uint32_t doorbell_stride = 1 << (2 + m_controller_registers->cap.dstrd);
const uint32_t doorbell_offset = 2 * doorbell_stride;
auto& doorbell = *reinterpret_cast<volatile NVMe::DoorbellRegisters*>(m_bar0->vaddr() + NVMe::ControllerRegisters::SQ0TDBL + doorbell_offset);
m_io_queue = TRY(BAN::UniqPtr<NVMeQueue>::create(BAN::move(completion_queue), BAN::move(submission_queue), doorbell, queue_elems, irq));
m_io_queue = TRY(BAN::UniqPtr<NVMeQueue>::create(BAN::move(completion_queue), BAN::move(submission_queue), doorbell, queue_elems));
m_pci_device.enable_interrupt(1, *m_io_queue);
return {};
}

View File

@@ -9,7 +9,7 @@ namespace Kernel
static constexpr uint64_t s_nvme_command_timeout_ms = 1000;
static constexpr uint64_t s_nvme_command_poll_timeout_ms = 20;
NVMeQueue::NVMeQueue(BAN::UniqPtr<Kernel::DMARegion>&& cq, BAN::UniqPtr<Kernel::DMARegion>&& sq, volatile NVMe::DoorbellRegisters& db, uint32_t qdepth, uint8_t irq)
NVMeQueue::NVMeQueue(BAN::UniqPtr<Kernel::DMARegion>&& cq, BAN::UniqPtr<Kernel::DMARegion>&& sq, volatile NVMe::DoorbellRegisters& db, uint32_t qdepth)
: m_completion_queue(BAN::move(cq))
, m_submission_queue(BAN::move(sq))
, m_doorbell(db)
@@ -17,8 +17,6 @@ namespace Kernel
{
for (uint32_t i = qdepth; i < m_mask_bits; i++)
m_used_mask |= (size_t)1 << i;
set_irq(irq);
enable_interrupt();
}
void NVMeQueue::handle_irq()

View File

@@ -188,14 +188,14 @@ namespace Kernel
IO::outb(COM1_PORT + 1, 1);
TRY(InterruptController::get().reserve_irq(COM1_IRQ));
tty->set_irq(COM1_IRQ);
tty->enable_interrupt();
InterruptController::get().enable_irq(COM1_IRQ);
}
else if (serial.port() == COM2_PORT)
{
IO::outb(COM2_PORT + 1, 1);
TRY(InterruptController::get().reserve_irq(COM2_IRQ));
tty->set_irq(COM2_IRQ);
tty->enable_interrupt();
InterruptController::get().enable_irq(COM2_IRQ);
}
auto ref_ptr = BAN::RefPtr<SerialTTY>::adopt(tty);

View File

@@ -223,7 +223,7 @@ namespace Kernel
TRY(InterruptController::get().reserve_irq(0));
set_irq(0);
enable_interrupt();
InterruptController::get().enable_irq(0);
return {};
}

View File

@@ -48,7 +48,7 @@ namespace Kernel
MUST(InterruptController::get().reserve_irq(PIT_IRQ));
set_irq(PIT_IRQ);
enable_interrupt();
InterruptController::get().enable_irq(PIT_IRQ);
}
void PIT::handle_irq()

View File

@@ -204,7 +204,7 @@ namespace Kernel
BAN::ErrorOr<void> XHCIController::initialize_primary_interrupter()
{
TRY(m_pci_device.reserve_irqs(1));
TRY(m_pci_device.reserve_interrupts(1));
auto& runtime = runtime_regs();
@@ -227,8 +227,7 @@ namespace Kernel
primary_interrupter.iman = primary_interrupter.iman | XHCI::IMAN::InterruptPending | XHCI::IMAN::InterruptEnable;
set_irq(m_pci_device.get_irq(0));
enable_interrupt();
m_pci_device.enable_interrupt(0, *this);
return {};
}