Esempio n. 1
0
        /// <summary>
        /// Submit item in queue
        /// </summary>
        /// <param name="queue">Queue</param>
        /// <param name="item">Item</param>
        private int SubmitCMD(NVMe_Queue queue, NVMe_Submission_Item *item)
        {
            int tail = queue.Tail;

            queue.mSubmissionMutex.Lock();

            item->CommandID = CurrentCID;


            Memory.Memcpy((void *)((int)queue.SubmissionQueue + (sizeof(NVMe_Submission_Item) * tail)), item, sizeof(NVMe_Submission_Item));

            var itemm = (NVMe_Submission_Item *)((int)queue.SubmissionQueue + (sizeof(NVMe_Submission_Item) * tail));

            tail = tail + 1;

            if (tail == queue.Max)
            {
                tail = 0;
            }

            queue.Tail = tail;

            *queue.TailPtr = tail;

            if (++CurrentCID >= 65535)
            {
                item->CommandID = 0;
            }

            queue.mSubmissionMutex.Unlock();

            return(CurrentCID - 1);
        }
Esempio n. 2
0
        private NVMe_Queue CreateQueue(int qid)
        {
            NVMe_Queue queue = AllocQueue(qid);


            int status = CreateCompletionQueue(queue);

            int statusCode = (status >> COMP_STATUS_SC_SHIFT) & COMP_STATUS_SC_MASK;

            if (statusCode != COMP_STATUS_SC_SUC)
            {
                return(null);
            }


            status     = CreateSubmissionQueue(queue);
            statusCode = (status >> COMP_STATUS_SC_SHIFT) & COMP_STATUS_SC_MASK;

            if (statusCode != COMP_STATUS_SC_SUC)
            {
                return(null);
            }

            return(queue);
        }
Esempio n. 3
0
        /// <summary>
        /// Configure admin queue
        /// </summary>
        private void ConfigureAdminQueue()
        {
            mAdminQueue = AllocQueue(0);

            mRegs->ControllerStatus   = 0x00;
            mRegs->AdminQueueAttribs  = (uint)((uint)(mQueueSize - 1) & AQA_ASQS_MASK);
            mRegs->AdminQueueAttribs |= (uint)(((mQueueSize - 1) & AQA_ACQS_SHIFT) << AQA_ACQS_SHIFT);

            mRegs->AdminSubmissionQueueAddress = (ulong)Paging.GetPhysicalFromVirtual(mAdminQueue.SubmissionQueue);
            mRegs->AdminCompletionQueueAddress = (ulong)Paging.GetPhysicalFromVirtual(mAdminQueue.CompletionQueue);
        }
Esempio n. 4
0
        /// <summary>
        /// Create queues (for now just 1..)
        /// </summary>
        private void CreateQueues()
        {
            var queue = CreateQueue(1);

            if (queue == null)
            {
                Panic.DoPanic("[NVMe] Couldn't make queue");
            }


            mIOQueue = queue;
        }
Esempio n. 5
0
        private NVMe_Completion_Item *PollAndWait(NVMe_Queue queue, int cid)
        {
            while (true)
            {
                for (int i = 0; i < mQueueSize; i++)
                {
                    var item = (NVMe_Completion_Item *)((int)queue.CompletionQueue + (sizeof(NVMe_Completion_Item) * i));

                    if (item->CommandID == cid)
                    {
                        return(item);
                    }
                }

                Tasking.CurrentTask.CurrentThread.Sleep(0, 100);
            }
        }
Esempio n. 6
0
        private int CreateCompletionQueue(NVMe_Queue queue)
        {
            NVMe_Create_Cq_Cmd *item = (NVMe_Create_Cq_Cmd *)Heap.Alloc(sizeof(NVMe_Create_Cq_Cmd));

            Memory.Memclear(item, sizeof(NVMe_Create_Cq_Cmd));

            item->Opcode  = ADMIN_OPCODE_CREATE_CQ;
            item->PRP1    = (uint)Paging.GetPhysicalFromVirtual(queue.CompletionQueue);
            item->CqID    = (ushort)queue.SQID;
            item->CqSize  = (ushort)(mQueueSize - 1);
            item->CqFlags = (ushort)(QUEUE_PHYS_CONFIG | SQ_PRIO_MEDIUM);

            int cid = SubmitCMD(mAdminQueue, (NVMe_Submission_Item *)item);

            Heap.Free(item);

            NVMe_Completion_Item *compItem = PollAndWait(mAdminQueue, cid);

            return(compItem->Status);
        }
Esempio n. 7
0
        /// <summary>
        /// Alocate queue
        /// </summary>
        /// <param name="sqID">Submission Queue ID</param>
        /// <returns>Queue</returns>
        private unsafe NVMe_Queue AllocQueue(int sqID)
        {
            NVMe_Queue queue = new NVMe_Queue();

            queue.SQID = sqID;

            queue.SubmissionQueue = (NVMe_Submission_Item *)Heap.AlignedAlloc(0x1000, sizeof(NVMe_Submission_Item) * mQueueSize);
            queue.CompletionQueue = (NVMe_Completion_Item *)Heap.AlignedAlloc(0x1000, sizeof(NVMe_Completion_Item) * mQueueSize);
            Memory.Memclear(queue.SubmissionQueue, sizeof(NVMe_Submission_Item) * mQueueSize);
            Memory.Memclear(queue.CompletionQueue, sizeof(NVMe_Completion_Item) * mQueueSize);

            queue.mSubmissionMutex = new Mutex();
            queue.Max  = mQueueSize;
            queue.Tail = 0;

            uint tail = (uint)mTailsAndHeads + (uint)((2 * sqID) * (sizeof(int) << mStride));
            uint head = (uint)mTailsAndHeads + (uint)((2 * sqID + 1) * (sizeof(int) << mStride));

            queue.TailPtr = (int *)tail;
            queue.HeadPtr = (int *)head;

            return(queue);
        }