forked from Bananymous/banan-os
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:
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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 {};
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user