Compare commits

..

No commits in common. "090c3c99304c574c327128f1658a93ff55fe3e35" and "e65bc040af3ef27c2535eb327f261ffc4523d4e3" have entirely different histories.

5 changed files with 30 additions and 76 deletions

View File

@ -145,8 +145,8 @@ namespace Kernel
{ {
if (g_paniced) if (g_paniced)
{ {
// FIXME: tell other processors kernel panic has occured
dprintln("Processor {} halted", Processor::current_id()); dprintln("Processor {} halted", Processor::current_id());
InterruptController::get().broadcast_ipi();
asm volatile("cli; 1: hlt; jmp 1b"); asm volatile("cli; 1: hlt; jmp 1b");
} }
@ -299,13 +299,6 @@ done:
extern "C" void cpp_irq_handler(uint64_t irq, InterruptStack& interrupt_stack) extern "C" void cpp_irq_handler(uint64_t irq, InterruptStack& interrupt_stack)
{ {
if (g_paniced)
{
dprintln("Processor {} halted", Processor::current_id());
InterruptController::get().broadcast_ipi();
asm volatile("cli; 1: hlt; jmp 1b");
}
if (Scheduler::current_tid()) if (Scheduler::current_tid())
{ {
Thread::current().set_return_rsp(interrupt_stack.rsp); Thread::current().set_return_rsp(interrupt_stack.rsp);

View File

@ -64,7 +64,7 @@ namespace Kernel::Input
BAN::CircularQueue<Command, 128> m_command_queue; BAN::CircularQueue<Command, 128> m_command_queue;
uint64_t m_command_send_time { 0 }; uint64_t m_command_send_time { 0 };
RecursiveSpinLock m_command_lock; SpinLock m_command_lock;
}; };
} }

View File

@ -3,6 +3,7 @@
#include <BAN/UniqPtr.h> #include <BAN/UniqPtr.h>
#include <BAN/Vector.h> #include <BAN/Vector.h>
#include <kernel/Interruptable.h> #include <kernel/Interruptable.h>
#include <kernel/Lock/Mutex.h>
#include <kernel/Memory/DMARegion.h> #include <kernel/Memory/DMARegion.h>
#include <kernel/Semaphore.h> #include <kernel/Semaphore.h>
#include <kernel/Storage/NVMe/Definitions.h> #include <kernel/Storage/NVMe/Definitions.h>
@ -20,9 +21,7 @@ namespace Kernel
virtual void handle_irq() final override; virtual void handle_irq() final override;
private: private:
uint16_t reserve_cid(); Mutex m_mutex;
private:
BAN::UniqPtr<Kernel::DMARegion> m_completion_queue; BAN::UniqPtr<Kernel::DMARegion> m_completion_queue;
BAN::UniqPtr<Kernel::DMARegion> m_submission_queue; BAN::UniqPtr<Kernel::DMARegion> m_submission_queue;
volatile NVMe::DoorbellRegisters& m_doorbell; volatile NVMe::DoorbellRegisters& m_doorbell;
@ -32,10 +31,8 @@ namespace Kernel
uint16_t m_cq_valid_phase { 1 }; uint16_t m_cq_valid_phase { 1 };
Semaphore m_semaphore; Semaphore m_semaphore;
SpinLock m_lock; volatile uint16_t m_status;
BAN::Atomic<uint64_t> m_used_mask { 0 }; volatile bool m_done { false };
BAN::Atomic<uint64_t> m_done_mask { 0 };
volatile uint16_t m_status_codes[64] { };
}; };
} }

View File

@ -15,8 +15,6 @@ namespace Kernel
, m_doorbell(db) , m_doorbell(db)
, m_qdepth(qdepth) , m_qdepth(qdepth)
{ {
for (uint32_t i = qdepth; i < 64; i++)
m_used_mask |= (uint64_t)1 << i;
set_irq(irq); set_irq(irq);
enable_interrupt(); enable_interrupt();
} }
@ -29,13 +27,12 @@ namespace Kernel
{ {
uint16_t sts = cq_ptr[m_cq_head].sts >> 1; uint16_t sts = cq_ptr[m_cq_head].sts >> 1;
uint16_t cid = cq_ptr[m_cq_head].cid; uint16_t cid = cq_ptr[m_cq_head].cid;
uint64_t cid_mask = (uint64_t)1 << cid; ASSERT(cid == 0);
ASSERT(cid < 64);
ASSERT((m_done_mask & cid_mask) == 0); ASSERT(!m_done);
m_status = sts;
m_status_codes[cid] = sts; m_done = true;
m_done_mask |= cid_mask; m_semaphore.unblock();
m_cq_head = (m_cq_head + 1) % m_qdepth; m_cq_head = (m_cq_head + 1) % m_qdepth;
if (m_cq_head == 0) if (m_cq_head == 0)
@ -43,75 +40,42 @@ namespace Kernel
} }
m_doorbell.cq_head = m_cq_head; m_doorbell.cq_head = m_cq_head;
m_semaphore.unblock();
} }
uint16_t NVMeQueue::submit_command(NVMe::SubmissionQueueEntry& sqe) uint16_t NVMeQueue::submit_command(NVMe::SubmissionQueueEntry& sqe)
{ {
uint16_t cid = reserve_cid(); LockGuard _(m_mutex);
uint64_t cid_mask = (uint64_t)1 << cid;
{ ASSERT(m_done == false);
SpinLockGuard _(m_lock); m_status = 0;
m_done_mask &= ~cid_mask; sqe.cid = 0;
m_status_codes[cid] = 0;
sqe.cid = cid;
auto* sqe_ptr = reinterpret_cast<NVMe::SubmissionQueueEntry*>(m_submission_queue->vaddr()); auto* sqe_ptr = reinterpret_cast<NVMe::SubmissionQueueEntry*>(m_submission_queue->vaddr());
memcpy(&sqe_ptr[m_sq_tail], &sqe, sizeof(NVMe::SubmissionQueueEntry)); memcpy(&sqe_ptr[m_sq_tail], &sqe, sizeof(NVMe::SubmissionQueueEntry));
m_sq_tail = (m_sq_tail + 1) % m_qdepth; m_sq_tail = (m_sq_tail + 1) % m_qdepth;
m_doorbell.sq_tail = m_sq_tail; m_doorbell.sq_tail = m_sq_tail;
}
const uint64_t start_time = SystemTimer::get().ms_since_boot(); const uint64_t start_time = SystemTimer::get().ms_since_boot();
while (SystemTimer::get().ms_since_boot() < start_time + s_nvme_command_poll_timeout_ms) while (SystemTimer::get().ms_since_boot() < start_time + s_nvme_command_poll_timeout_ms)
{ {
if (m_done_mask & cid_mask) if (!m_done)
{ continue;
uint16_t status = m_status_codes[cid]; m_done = false;
m_used_mask &= ~cid_mask; return m_status;
return status;
}
} }
while (SystemTimer::get().ms_since_boot() < start_time + s_nvme_command_timeout_ms) while (SystemTimer::get().ms_since_boot() < start_time + s_nvme_command_timeout_ms)
{ {
if (m_done_mask & cid_mask) if (m_done)
{ {
uint16_t status = m_status_codes[cid]; m_done = false;
m_used_mask &= ~cid_mask; return m_status;
return status;
} }
m_semaphore.block_with_wake_time(start_time + s_nvme_command_timeout_ms);
} }
m_used_mask &= ~cid_mask;
return 0xFFFF; return 0xFFFF;
} }
uint16_t NVMeQueue::reserve_cid()
{
auto state = m_lock.lock();
while (~m_used_mask == 0)
{
m_lock.unlock(state);
m_semaphore.block_with_timeout(s_nvme_command_timeout_ms);
state = m_lock.lock();
}
uint16_t cid = 0;
for (; cid < 64; cid++)
if ((m_used_mask & ((uint64_t)1 << cid)) == 0)
break;
ASSERT(cid < 64);
ASSERT(cid < m_qdepth);
m_used_mask |= (uint64_t)1 << cid;
m_lock.unlock(state);
return cid;
}
} }