mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 06:58:22 +00:00
nvme: hook to block abstraction and fixes
This commit is contained in:
+43
-16
@@ -15,6 +15,7 @@
|
|||||||
#include <arch/idt.h>
|
#include <arch/idt.h>
|
||||||
#include <arch/cls.h>
|
#include <arch/cls.h>
|
||||||
#include <arch/isr.h>
|
#include <arch/isr.h>
|
||||||
|
#include <kernel/block.h>
|
||||||
|
|
||||||
#define CAP_QUEUESIZE 0xFFFF
|
#define CAP_QUEUESIZE 0xFFFF
|
||||||
#define CAP_MINPAGESIZE 0xF000000
|
#define CAP_MINPAGESIZE 0xF000000
|
||||||
@@ -255,11 +256,13 @@ static ctlrinfo_t** controllers;
|
|||||||
|
|
||||||
void nvme_irq(){
|
void nvme_irq(){
|
||||||
|
|
||||||
controllers[0]->adminqueue.comp.hasdata = true;
|
for(int ctlr = 0; ctlr < controllercount; ++ctlr){
|
||||||
event_signal(&controllers[0]->adminqueue.update, false);
|
controllers[ctlr]->adminqueue.comp.hasdata = true;
|
||||||
if(controllers[0]->ioqueue){
|
event_signal(&controllers[ctlr]->adminqueue.update, false);
|
||||||
controllers[0]->ioqueue->comp.hasdata = true;
|
if(controllers[ctlr]->ioqueue){
|
||||||
event_signal(&controllers[0]->ioqueue->update, false);
|
controllers[ctlr]->ioqueue->comp.hasdata = true;
|
||||||
|
event_signal(&controllers[ctlr]->ioqueue->update, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
apic_eoi();
|
apic_eoi();
|
||||||
|
|
||||||
@@ -292,10 +295,10 @@ __attribute__((noreturn)) static void nvme_workerthread(){
|
|||||||
|
|
||||||
userentries[pair]->sub.d0.cmdid = pair;
|
userentries[pair]->sub.d0.cmdid = pair;
|
||||||
|
|
||||||
subqentry* targentry = &subq[queuepair->sub.idx++];
|
subqentry* targentry = &subq[queuepair->sub.idx++];
|
||||||
|
|
||||||
queuepair->sub.idx %= queuepair->sub.entrycount;
|
|
||||||
|
|
||||||
|
queuepair->sub.idx %= queuepair->sub.entrycount;
|
||||||
|
|
||||||
*targentry = userentries[pair]->sub;
|
*targentry = userentries[pair]->sub;
|
||||||
|
|
||||||
*subqdoorbell = queuepair->sub.idx;
|
*subqdoorbell = queuepair->sub.idx;
|
||||||
@@ -311,14 +314,16 @@ __attribute__((noreturn)) static void nvme_workerthread(){
|
|||||||
while(1){
|
while(1){
|
||||||
|
|
||||||
if(compq[queuepair->comp.idx].phase == 0)
|
if(compq[queuepair->comp.idx].phase == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
int pair = compq[queuepair->comp.idx].cmdid;
|
int pair = compq[queuepair->comp.idx].cmdid;
|
||||||
|
|
||||||
userentries[pair]->comp = compq[queuepair->comp.idx];
|
userentries[pair]->comp = compq[queuepair->comp.idx];
|
||||||
|
|
||||||
event_signal(&userentries[pair]->completion, false);
|
event_signal(&userentries[pair]->completion, false);
|
||||||
|
|
||||||
|
userentries[pair] = NULL;
|
||||||
|
|
||||||
++queuepair->comp.idx;
|
++queuepair->comp.idx;
|
||||||
queuepair->comp.idx %= queuepair->comp.entrycount;
|
queuepair->comp.idx %= queuepair->comp.entrycount;
|
||||||
|
|
||||||
@@ -417,9 +422,11 @@ int nvme_createiocompqueue(ctlrinfo_t* ctlr, size_t size, int id, int intvec, in
|
|||||||
|
|
||||||
pair.sub.dataptr[0] = (uint64_t)addr;
|
pair.sub.dataptr[0] = (uint64_t)addr;
|
||||||
|
|
||||||
pair.sub.command[0] = id | (entrycount << 16);
|
pair.sub.command[0] = id | ((entrycount-1) << 16);
|
||||||
pair.sub.command[1] = IOQUEUE_FLAG_CONTIGUOUS | flags | (intvec << 16);
|
pair.sub.command[1] = IOQUEUE_FLAG_CONTIGUOUS | flags | (intvec << 16);
|
||||||
|
|
||||||
|
memset(MAKEHHDM(addr), 0, size);
|
||||||
|
|
||||||
dispatchandwait(&pair, &ctlr->adminqueue);
|
dispatchandwait(&pair, &ctlr->adminqueue);
|
||||||
|
|
||||||
if(pair.comp.status)
|
if(pair.comp.status)
|
||||||
@@ -439,7 +446,7 @@ int nvme_createiosubqueue(ctlrinfo_t* ctlr, size_t size, int id, int flags, int
|
|||||||
pair.sub.d0.opcode = OPCODE_CREATEIOSUBQUEUE;
|
pair.sub.d0.opcode = OPCODE_CREATEIOSUBQUEUE;
|
||||||
|
|
||||||
size_t psize = size / PAGE_SIZE + ((size % PAGE_SIZE) ? 1 : 0);
|
size_t psize = size / PAGE_SIZE + ((size % PAGE_SIZE) ? 1 : 0);
|
||||||
size_t entrycount = size / sizeof(compqentry);
|
size_t entrycount = size / sizeof(subqentry);
|
||||||
|
|
||||||
void* addr = pmm_alloc(psize);
|
void* addr = pmm_alloc(psize);
|
||||||
|
|
||||||
@@ -448,9 +455,11 @@ int nvme_createiosubqueue(ctlrinfo_t* ctlr, size_t size, int id, int flags, int
|
|||||||
|
|
||||||
pair.sub.dataptr[0] = (uint64_t)addr;
|
pair.sub.dataptr[0] = (uint64_t)addr;
|
||||||
|
|
||||||
pair.sub.command[0] = id | (entrycount << 16);
|
pair.sub.command[0] = id | ((entrycount-1) << 16);
|
||||||
pair.sub.command[1] = IOQUEUE_FLAG_CONTIGUOUS | flags | (compid << 16);
|
pair.sub.command[1] = IOQUEUE_FLAG_CONTIGUOUS | flags | (compid << 16);
|
||||||
|
|
||||||
|
memset(MAKEHHDM(addr), 0, size);
|
||||||
|
|
||||||
dispatchandwait(&pair, &ctlr->adminqueue);
|
dispatchandwait(&pair, &ctlr->adminqueue);
|
||||||
|
|
||||||
if(pair.comp.status)
|
if(pair.comp.status)
|
||||||
@@ -458,7 +467,6 @@ int nvme_createiosubqueue(ctlrinfo_t* ctlr, size_t size, int id, int flags, int
|
|||||||
else
|
else
|
||||||
*ret_addr = MAKEHHDM(addr);
|
*ret_addr = MAKEHHDM(addr);
|
||||||
|
|
||||||
|
|
||||||
return pair.comp.status ? EIO : 0;
|
return pair.comp.status ? EIO : 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -540,6 +548,12 @@ static void nvme_newworkerthread(ctlrinfo_t* ctlr, queuepair_t* qpair){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static blockcalls_t calls = {
|
||||||
|
.read = nvme_read
|
||||||
|
};
|
||||||
|
|
||||||
|
static int blockid;
|
||||||
|
|
||||||
static void nvme_initns(ctlrinfo_t* ctlr, uint32_t nsid){
|
static void nvme_initns(ctlrinfo_t* ctlr, uint32_t nsid){
|
||||||
namespaceid_t* identify = alloc(4096);
|
namespaceid_t* identify = alloc(4096);
|
||||||
namespace_t* ns = alloc(sizeof(namespace_t));
|
namespace_t* ns = alloc(sizeof(namespace_t));
|
||||||
@@ -560,8 +574,21 @@ static void nvme_initns(ctlrinfo_t* ctlr, uint32_t nsid){
|
|||||||
|
|
||||||
printf("ns %d: lbaformat %d, capacity -> %d blocks, block size -> %d bytes\n", nsid, lbaformat, identify->lbacapacity, blocksize);
|
printf("ns %d: lbaformat %d, capacity -> %d blocks, block size -> %d bytes\n", nsid, lbaformat, identify->lbacapacity, blocksize);
|
||||||
|
|
||||||
|
blockdesc_t desc;
|
||||||
|
|
||||||
|
desc.blocksize = blocksize;
|
||||||
|
desc.capacity = ns->capacity;
|
||||||
|
desc.internal = ns;
|
||||||
|
desc.calls = calls;
|
||||||
|
|
||||||
|
char name[20];
|
||||||
|
|
||||||
|
sprintf(name, "nvme%d", blockid);
|
||||||
|
|
||||||
|
++blockid;
|
||||||
|
|
||||||
|
__assert(block_registernew(&desc, name) == 0);
|
||||||
|
|
||||||
free(identify);
|
free(identify);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user