mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 23:18:21 +00:00
nvme: software progress reset and namespace list
This commit is contained in:
+50
-14
@@ -27,9 +27,11 @@
|
|||||||
#define CC_AMS_MASK 0b11100000000000
|
#define CC_AMS_MASK 0b11100000000000
|
||||||
|
|
||||||
#define OPCODE_IDENTIFY 0x6
|
#define OPCODE_IDENTIFY 0x6
|
||||||
|
#define OPCODE_SETFEATURE 0x9
|
||||||
|
#define SETFEATURE_DW10_SAVE 0x80000000
|
||||||
|
|
||||||
#define IDENTIFY_TYPE_CONTROLLER 0
|
#define IDENTIFY_TYPE_NAMESPACE 0
|
||||||
#define IDENTIFY_TYPE_NAMESPACE 1
|
#define IDENTIFY_TYPE_CONTROLLER 1
|
||||||
#define IDENTIFY_TYPE_NAMESPACELIST 2
|
#define IDENTIFY_TYPE_NAMESPACELIST 2
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
@@ -152,12 +154,12 @@ typedef struct{
|
|||||||
uint16_t pcivendor;
|
uint16_t pcivendor;
|
||||||
uint16_t pcisubsystemvendor;
|
uint16_t pcisubsystemvendor;
|
||||||
uint8_t serialnum[20];
|
uint8_t serialnum[20];
|
||||||
uint8_t modelnum[20];
|
uint8_t modelnum[40];
|
||||||
uint64_t fwrevision;
|
uint64_t fwrevision;
|
||||||
uint8_t recommendedburst;
|
uint8_t recommendedburst;
|
||||||
uint8_t ouiid[3];
|
uint8_t ouiid[3];
|
||||||
uint8_t namespacesharing;
|
uint8_t namespacesharing;
|
||||||
uint8_t maxdatatransfer; // power of two
|
uint8_t maxdatatransfer;
|
||||||
uint16_t controllerid;
|
uint16_t controllerid;
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
uint32_t rtd3resumelatency;
|
uint32_t rtd3resumelatency;
|
||||||
@@ -165,7 +167,7 @@ typedef struct{
|
|||||||
uint32_t optionalasyncevents;
|
uint32_t optionalasyncevents;
|
||||||
uint32_t attributes;
|
uint32_t attributes;
|
||||||
uint16_t rrlsupported;
|
uint16_t rrlsupported;
|
||||||
uint64_t reserved;
|
uint8_t reserved[9];
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint64_t fguid[2];
|
uint64_t fguid[2];
|
||||||
uint16_t crdt[3];
|
uint16_t crdt[3];
|
||||||
@@ -221,7 +223,7 @@ typedef struct{
|
|||||||
uint16_t acwu;
|
uint16_t acwu;
|
||||||
} __attribute__((packed)) controllerid_t;
|
} __attribute__((packed)) controllerid_t;
|
||||||
|
|
||||||
|
#define CONTROLLER_TYPE_IO 1
|
||||||
|
|
||||||
#define ASQSIZE PAGE_SIZE / sizeof(subqentry)
|
#define ASQSIZE PAGE_SIZE / sizeof(subqentry)
|
||||||
#define ACQSIZE PAGE_SIZE / sizeof(compqentry)
|
#define ACQSIZE PAGE_SIZE / sizeof(compqentry)
|
||||||
@@ -279,7 +281,7 @@ __attribute__((noreturn)) static void nvme_workerthread(){
|
|||||||
|
|
||||||
*targentry = userentries[pair]->sub;
|
*targentry = userentries[pair]->sub;
|
||||||
|
|
||||||
*subqdoorbell = 1;
|
*subqdoorbell = queuepair->sub.idx;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,7 +310,7 @@ __attribute__((noreturn)) static void nvme_workerthread(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(processed)
|
if(processed)
|
||||||
*compqdoorbell = processed;
|
*compqdoorbell = queuepair->comp.idx;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -330,6 +332,8 @@ static inline void dispatchandwait(entrypair_t* e, queuepair_t* q){
|
|||||||
|
|
||||||
#define IDENTIFY_SIZE 4096
|
#define IDENTIFY_SIZE 4096
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int nvme_identify(ctlrinfo_t* ctlr, void* buff, int type, int what){
|
int nvme_identify(ctlrinfo_t* ctlr, void* buff, int type, int what){
|
||||||
|
|
||||||
__assert(type < 3); // anything else is not supported atm
|
__assert(type < 3); // anything else is not supported atm
|
||||||
@@ -338,7 +342,7 @@ int nvme_identify(ctlrinfo_t* ctlr, void* buff, int type, int what){
|
|||||||
|
|
||||||
memset(&pair, 0, sizeof(entrypair_t));
|
memset(&pair, 0, sizeof(entrypair_t));
|
||||||
|
|
||||||
pair.sub.dataptr[0] = pmm_alloc(1);
|
pair.sub.dataptr[0] = (uint64_t)pmm_alloc(1);
|
||||||
if(!pair.sub.dataptr[0])
|
if(!pair.sub.dataptr[0])
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
@@ -357,20 +361,41 @@ int nvme_identify(ctlrinfo_t* ctlr, void* buff, int type, int what){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FEATURE_SOFTWAREPROGRESS 0x80
|
||||||
|
|
||||||
|
int nvme_resetsoftwareprogress(ctlrinfo_t* ctlr){
|
||||||
|
|
||||||
|
entrypair_t pair;
|
||||||
|
|
||||||
|
memset(&pair, 0, sizeof(entrypair_t));
|
||||||
|
|
||||||
|
pair.sub.command[0] = FEATURE_SOFTWAREPROGRESS;
|
||||||
|
pair.sub.d0.opcode = OPCODE_SETFEATURE;
|
||||||
|
|
||||||
|
dispatchandwait(&pair, &ctlr->adminqueue);
|
||||||
|
|
||||||
|
return pair.comp.status ? EIO : 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int nvme_identifycontroller(ctlrinfo_t* ctlr, void* buff){
|
int nvme_identifycontroller(ctlrinfo_t* ctlr, void* buff){
|
||||||
return nvme_identify(ctlr, buff, IDENTIFY_TYPE_CONTROLLER, 0);
|
return nvme_identify(ctlr, buff, IDENTIFY_TYPE_CONTROLLER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nvme_listnamespaces(ctlrinfo_t* ctlr, uint32_t startns, uint32_t* nslist){
|
||||||
|
return nvme_identify(ctlr, nslist, IDENTIFY_TYPE_NAMESPACELIST, startns);
|
||||||
|
}
|
||||||
|
|
||||||
static void nvme_initctlr(pci_enumeration* pci){
|
static void nvme_initctlr(pci_enumeration* pci){
|
||||||
|
|
||||||
void* bar0p = getbarmemaddr(pci->header, 0);
|
void* bar0p = getbarmemaddr((pci_deviceheader*)pci->header, 0);
|
||||||
|
|
||||||
volatile nvme_bar0* bar0 = vmm_alloc(10, ARCH_MMU_MAP_READ | ARCH_MMU_MAP_WRITE);
|
volatile nvme_bar0* bar0 = vmm_alloc(10, ARCH_MMU_MAP_READ | ARCH_MMU_MAP_WRITE);
|
||||||
|
|
||||||
if(!bar0)
|
if(!bar0)
|
||||||
_panic("Out of memory", NULL);
|
_panic("Out of memory", NULL);
|
||||||
|
|
||||||
if(!vmm_map(bar0p, bar0, 10, ARCH_MMU_MAP_READ | ARCH_MMU_MAP_WRITE))
|
if(!vmm_map(bar0p, (void*)bar0, 10, ARCH_MMU_MAP_READ | ARCH_MMU_MAP_WRITE))
|
||||||
_panic("Out of memory", NULL);
|
_panic("Out of memory", NULL);
|
||||||
|
|
||||||
int maj = bar0->vs >> 16;
|
int maj = bar0->vs >> 16;
|
||||||
@@ -441,8 +466,8 @@ static void nvme_initctlr(pci_enumeration* pci){
|
|||||||
if(!adminqueues)
|
if(!adminqueues)
|
||||||
_panic("Out of memory", NULL);
|
_panic("Out of memory", NULL);
|
||||||
|
|
||||||
bar0->asq = adminqueues;
|
bar0->asq = (uint64_t)adminqueues;
|
||||||
bar0->acq = adminqueues + PAGE_SIZE;
|
bar0->acq = (uint64_t)adminqueues + PAGE_SIZE;
|
||||||
|
|
||||||
// enable
|
// enable
|
||||||
|
|
||||||
@@ -493,7 +518,18 @@ static void nvme_initctlr(pci_enumeration* pci){
|
|||||||
|
|
||||||
controllerid_t* ctlrid = alloc(4096);
|
controllerid_t* ctlrid = alloc(4096);
|
||||||
|
|
||||||
nvme_identifycontroller(info, ctlrid);
|
if(!ctlrid)
|
||||||
|
_panic("Out of memoru!", NULL);
|
||||||
|
|
||||||
|
__assert(nvme_identifycontroller(info, ctlrid) == 0);
|
||||||
|
|
||||||
|
__assert(ctlrid->type == CONTROLLER_TYPE_IO);
|
||||||
|
|
||||||
|
nvme_resetsoftwareprogress(info);
|
||||||
|
|
||||||
|
uint32_t nslist[1024];
|
||||||
|
|
||||||
|
__assert(nvme_listnamespaces(info, 0, nslist) == 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user