void PRP1PRP2_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ LOG_NRM("Lookup objs which were created in a prior test within group"); SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)) SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)) LOG_NRM("Determine if DUT has atleast one namespace support"); ConstSharedIdentifyPtr idCmdCtrlr = gInformative->GetIdentifyCmdCtrlr(); if ((idCmdCtrlr->GetValue(IDCTRLRCAP_NN)) == 0) throw FrmwkEx(HERE, "Required to support >= 1 namespace"); LOG_NRM("Form identify namespace cmd and associate some buffer"); SharedIdentifyPtr idCmdNamSpc = SharedIdentifyPtr(new Identify()); idCmdNamSpc->SetCNS(false); idCmdNamSpc->SetNSID(1); SharedMemBufferPtr idMemNamSpc = SharedMemBufferPtr(new MemBuffer()); idMemNamSpc->InitOffset1stPage(Identify::IDEAL_DATA_SIZE, PRP_BUFFER_OFFSET, true); LOG_NRM("Allow PRP1 and PRP2"); send_64b_bitmask idPrpNamSpc = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); idCmdNamSpc->SetPrpBuffer(idPrpNamSpc, idMemNamSpc); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, "prp1Prp2", true); }
void AdminQFull_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) none * \endverbatim */ LOG_NRM("Create identify cmd and assoc some buffer memory"); SharedIdentifyPtr idCmdCtrlr = SharedIdentifyPtr(new Identify()); LOG_NRM("Force identify to request ctrlr capabilities struct"); idCmdCtrlr->SetCNS(true); SharedMemBufferPtr idMemCap = SharedMemBufferPtr(new MemBuffer()); idMemCap->InitAlignment(Identify::IDEAL_DATA_SIZE, sizeof(uint64_t), false, 0); send_64b_bitmask prpReq = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); idCmdCtrlr->SetPrpBuffer(prpReq, idMemCap); // Case 1 - ASQ = ACQ (min, middle and max) AdminQFull(2, 2, idCmdCtrlr); AdminQFull((MAX_ADMIN_Q_SIZE/2), (MAX_ADMIN_Q_SIZE/2), idCmdCtrlr); AdminQFull(MAX_ADMIN_Q_SIZE, MAX_ADMIN_Q_SIZE, idCmdCtrlr); // Case 2 - ASQ = ACQ + 1 (min , middle and max) AdminQFull(3, 2, idCmdCtrlr); AdminQFull((MAX_ADMIN_Q_SIZE/2), ((MAX_ADMIN_Q_SIZE/2) - 1), idCmdCtrlr); AdminQFull(MAX_ADMIN_Q_SIZE, (MAX_ADMIN_Q_SIZE - 1), idCmdCtrlr); }
void UnsupportRsvdFields_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ LOG_NRM("Lookup objs which were created in a prior test within group"); SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)) SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)) LOG_NRM("Determine if DUT has atleast one namespace support"); ConstSharedIdentifyPtr idCmdCtrlr = gInformative->GetIdentifyCmdCtrlr(); if ((idCmdCtrlr->GetValue(IDCTRLRCAP_NN)) == 0) throw FrmwkEx(HERE, "Required to support >= 1 namespace"); LOG_NRM("Form identify namespace cmd and associate some buffer"); SharedIdentifyPtr idCmdNamSpc = SharedIdentifyPtr(new Identify()); idCmdNamSpc->SetCNS(0); idCmdNamSpc->SetNSID(1); SharedMemBufferPtr idMemNamSpc = SharedMemBufferPtr(new MemBuffer()); idMemNamSpc->InitOffset1stPage(Identify::IDEAL_DATA_SIZE, PRP_BUFFER_OFFSET, true); LOG_NRM("Allow PRP1 and PRP2"); send_64b_bitmask idPrpNamSpc = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); idCmdNamSpc->SetPrpBuffer(idPrpNamSpc, idMemNamSpc); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, "rsvdnone.set", true); LOG_NRM("Set all cmd's rsvd bits"); uint32_t work = idCmdNamSpc->GetDword(0); work |= 0x0000fc00; // Set DW0_b15:10 bits idCmdNamSpc->SetDword(work, 0); idCmdNamSpc->SetDword(0xffffffff, 2); idCmdNamSpc->SetDword(0xffffffff, 3); idCmdNamSpc->SetDword(0xffffffff, 4); idCmdNamSpc->SetDword(0xffffffff, 5); work = idCmdNamSpc->GetDword(10); work |= 0xfffffffe; // Set DW10_b31:1 bits idCmdNamSpc->SetDword(work, 10); idCmdNamSpc->SetDword(0xffffffff, 11); idCmdNamSpc->SetDword(0xffffffff, 12); idCmdNamSpc->SetDword(0xffffffff, 13); idCmdNamSpc->SetDword(0xffffffff, 14); idCmdNamSpc->SetDword(0xffffffff, 15); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, "rsvdall.set", true); }
void CIDAcceptedASQ_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ uint32_t isrCount; // Lookup objs which were created in a prior test within group SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)) SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)) LOG_NRM("Verifying that the ACQ is empty"); if (acq->ReapInquiry(isrCount, true) != 0) { acq->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "acq", "notEmpty"), "Test assumption have not been met"); throw FrmwkEx(HERE, "The ACQ should not have any CE's waiting before testing"); } LOG_NRM("Create identify cmd and assoc some buffer memory"); SharedIdentifyPtr idCmdCap = SharedIdentifyPtr(new Identify()); LOG_NRM("Force identify to request ctrlr capabilities struct"); idCmdCap->SetCNS(CNS_Controller); SharedMemBufferPtr idMemCap = SharedMemBufferPtr(new MemBuffer()); idMemCap->InitAlignment(Identify::IDEAL_DATA_SIZE, PRP_BUFFER_ALIGNMENT, false, 0); send_64b_bitmask idPrpCap = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); idCmdCap->SetPrpBuffer(idPrpCap, idMemCap); LOG_NRM("Learn initial unique command id assigned by dnvme."); uint16_t currCID; asq->Send(idCmdCap, currCID); uint16_t prevCID = currCID; for (uint32_t nCmds = 0; nCmds < MAX_CMDS; nCmds++) { asq->Ring(); LOG_NRM("Verify unique CID #%d for Cmd #%d", currCID, nCmds + 1); ReapVerifyCID(asq, acq, currCID); asq->Send(idCmdCap, currCID); if (currCID != (uint16_t)(prevCID + 1)) { asq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "asq.fail"), "Dump Entire ASQ"); acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "acq.fail"), "Dump Entire ACQ"); throw FrmwkEx(HERE, "Current CID(%d) != prev + 1(%d)", currCID, prevCID); } prevCID = currCID; } }
bool CompareGolden(Golden &golden) { string work; try { // The objects to perform this work throw exceptions FileSystem::SetBaseDumpDir(false); // Log into GrpPending if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false) throw FrmwkEx(HERE); LOG_NRM("Prepare the admin Q's to setup this request"); SharedACQPtr acq = SharedACQPtr(new ACQ(gDutFd)); acq->Init(2); SharedASQPtr asq = SharedASQPtr(new ASQ(gDutFd)); asq->Init(2); gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET); if (gCtrlrConfig->SetState(ST_ENABLE) == false) throw FrmwkEx(HERE); SharedIdentifyPtr idCmd = SharedIdentifyPtr(new Identify()); SharedMemBufferPtr idMem = SharedMemBufferPtr(new MemBuffer()); idMem->InitAlignment(Identify::IDEAL_DATA_SIZE, sizeof(uint64_t), true, 0); send_64b_bitmask prpReq = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); idCmd->SetPrpBuffer(prpReq, idMem); for (size_t i = 0; i < golden.cmds.size(); i++) { LOG_NRM("Identify cmd #%ld", i); LOG_NRM(" Identify:DW1.nsid = 0x%02x", golden.cmds[i].nsid); LOG_NRM(" Identify.DW10.cns = %c", golden.cmds[i].cns ? 'T' : 'F'); LOG_NRM(" sizeof(Identify.raw) = %ld", golden.cmds[i].raw.size()); LOG_NRM("Formulate an identical idenitfy cmd to issue"); idCmd->SetCNS(golden.cmds[i].cns); idCmd->SetNSID(golden.cmds[i].nsid); idMem->InitAlignment(Identify::IDEAL_DATA_SIZE, sizeof(uint64_t), true, 0); work = str(boost::format("IdCmd%d") % i); IO::SendAndReapCmd("tnvme", "golden", SYSTEMWIDE_CMD_WAIT_ms, asq, acq, idCmd, work, false); if (idMem->Compare(golden.cmds[i].raw) == false) { idMem->Dump(FileSystem::PrepDumpFile("tnvme", "golden", "identify", "dut.miscompare"), "DUT data miscompare"); SharedMemBufferPtr userMem = SharedMemBufferPtr( new MemBuffer(golden.cmds[i].raw)); userMem->Dump(FileSystem::PrepDumpFile("tnvme", "golden", "identify", "cmdline.miscompare"), "Golden user data miscompare"); throw FrmwkEx(HERE, "Golden identify data miscompare"); } } LOG_NRM("The operation succeeded to compare golden data"); } catch (...) { LOG_ERR("Operation failed to compare golden data"); gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY); return false; } gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY); return true; }
void UnsupportRsvdFields_r12::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ CE ce; vector<uint32_t> activeNamespaces; string work; LOG_NRM("Admin queue setup"); SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)); SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)); LOG_NRM("Test proper"); LOG_NRM("Form identify cmd for namespace list and associate some buffer"); SharedIdentifyPtr idCmdNamSpcList = SharedIdentifyPtr(new Identify()); idCmdNamSpcList->SetCNS(CNS_NamespaceListActive); idCmdNamSpcList->SetNSID(0); SharedMemBufferPtr idMemNamSpcList = SharedMemBufferPtr(new MemBuffer()); idMemNamSpcList->InitAlignment(NAMSPC_LIST_SIZE * NAMSPC_ENTRY_SIZE); send_64b_bitmask idPrpNamSpc = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); idCmdNamSpcList->SetPrpBuffer(idPrpNamSpc, idMemNamSpcList); LOG_NRM("Sending Identify command CNS.%02Xh", CNS_NamespaceListActive); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpcList, "namspcList", true); LOG_NRM("Reading in active Namespaces."); const uint8_t *data = &((idCmdNamSpcList->GetROPrpBuffer())[0]); while ((*((uint32_t *)data) & 0xffff) != 0x0000){ uint32_t nsid = (*((uint32_t *)data) & 0xffff); LOG_NRM("Found active NSID: %08X", nsid); activeNamespaces.push_back(nsid); data += 4; } // Lookup objs which were created in a prior test within group SharedIOSQPtr iosq = CAST_TO_IOSQ(gRsrcMngr->GetObj(IOSQ_GROUP_ID)); SharedIOCQPtr iocq = CAST_TO_IOCQ(gRsrcMngr->GetObj(IOCQ_GROUP_ID)); ConstSharedIdentifyPtr idCtrlr = gInformative->GetIdentifyCmdCtrlr(); for (size_t i = 0; i < activeNamespaces.size(); i++) { LOG_NRM("Processing namspc %ld", i); SharedFlushPtr flushCmd = SharedFlushPtr(new Flush()); flushCmd->SetNSID(activeNamespaces[i]); ce = IO::SendAndReapCmdWhole(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, flushCmd, "none.set", true); if (ce.n.SF.b.SC != 0x0 || ce.n.SF.b.SCT != 0x0){ throw new FrmwkEx(HERE, "Error sending flush command expected (SCT:SC) 0x00:0x00, " "but detected 0x%02X:0x%02X", ce.n.SF.b.SCT, ce.n.SF.b.SC); } if (ce.n.reserved != 0){ throw new FrmwkEx(HERE, "Reserved completion entry not cleared found: %08X", ce.n.reserved); } else if(ce.n.cmdSpec != 0){ throw new FrmwkEx(HERE, "Command specific field not cleared found: %08X", ce.n.cmdSpec); } LOG_NRM("Set all cmd's rsvd bits"); uint32_t work = flushCmd->GetDword(0); work |= 0x00003c00; // Set DW0_b13:10 bits flushCmd->SetDword(work, 0); flushCmd->SetDword(0xffffffff, 2); flushCmd->SetDword(0xffffffff, 3); flushCmd->SetDword(0xffffffff, 4); flushCmd->SetDword(0xffffffff, 5); flushCmd->SetDword(0xffffffff, 6); flushCmd->SetDword(0xffffffff, 7); flushCmd->SetDword(0xffffffff, 8); flushCmd->SetDword(0xffffffff, 9); flushCmd->SetDword(0xffffffff, 10); flushCmd->SetDword(0xffffffff, 11); flushCmd->SetDword(0xffffffff, 12); flushCmd->SetDword(0xffffffff, 13); flushCmd->SetDword(0xffffffff, 14); flushCmd->SetDword(0xffffffff, 15); ce = IO::SendAndReapCmdWhole(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq,flushCmd, "all.set", true); if (ce.n.SF.b.SC != 0x0 || ce.n.SF.b.SCT != 0x0){ throw new FrmwkEx(HERE, "Error sending flush command expected (SCT:SC) 0x00:0x00, " "but detected 0x%02X:0x%02X", ce.n.SF.b.SCT, ce.n.SF.b.SC); } if (ce.n.reserved != 0){ throw new FrmwkEx(HERE, "Reserved completion entry not cleared found: %08X", ce.n.reserved); } else if(ce.n.cmdSpec != 0){ throw new FrmwkEx(HERE, "Command specific field not cleared found: %08X", ce.n.cmdSpec); } } // This highestNSID could provide a case where it issues to an inactive NSID // In the case of an inactive NSID the error status would be Invalid Field /*uint32_t highestNSID = 0; for (uint32_t i = 0; i < activeNamespaces.size(); i++){ if (activeNamespaces[i] > highestNSID) highestNSID = activeNamespaces[i]; } if (highestNSID != 0xffffffff){ SharedFlushPtr invalidFlushCmd = SharedFlushPtr(new Flush()); invalidFlushCmd->SetNSID(highestNSID + 1); // Could be Invalid Field or Invalid Namespace or Format IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, invalidFlushCmd, "none.set", true, CESTAT_INVAL_NAMSPC); }*/ ConstSharedIdentifyPtr idCtrlrStruct = gInformative->GetIdentifyCmdCtrlr(); uint32_t nn = (uint32_t)idCtrlrStruct->GetValue(IDCTRLRCAP_NN); // Issuing flush cmd with a few invalid NSIDs int count = 0; for (uint64_t i = 0; pow(2, i) <= 0xffffffff; i++) { if (pow(2, i) <= nn) continue; LOG_NRM("Issue flush cmd with illegal namspc ID=%llu", (unsigned long long)i); SharedFlushPtr invalidFlushCmd = SharedFlushPtr(new Flush()); invalidFlushCmd->SetNSID(pow(2, i)); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, invalidFlushCmd, "Flush.Invalid", true, CESTAT_INVAL_NAMSPC); count++; } LOG_NRM("Ran with: %d invalid NSIDs", count); }
void AdminQRollChkDiff_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) none. * \endverbatim */ uint16_t mACQSize = MIN_ADMIN_Q_SIZE; // Start ACQ with min size. uint16_t mASQSize = MAX_ADMIN_Q_SIZE; uint16_t loopCnt = 0; if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false) throw FrmwkEx(HERE); while (1) { LOG_NRM("(ASQSize, ACQSize, Loop Cnt) = (%d, %d, %d)", mASQSize, mACQSize, loopCnt++); // Issue cntl'r disable completely for every iteration. if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false) throw FrmwkEx(HERE); // Create ACQ and ASQ objects which have test life time SharedACQPtr acq = CAST_TO_ACQ(SharedACQPtr(new ACQ(gDutFd))) acq->Init(mACQSize); SharedASQPtr asq = CAST_TO_ASQ(SharedASQPtr(new ASQ(gDutFd))) asq->Init(mASQSize); gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET); if (gCtrlrConfig->SetState(ST_ENABLE) == false) throw FrmwkEx(HERE); LOG_NRM("Create identify cmd and assoc some buffer memory"); SharedIdentifyPtr idCmdCap = SharedIdentifyPtr(new Identify()); LOG_NRM("Force identify to request ctrlr capabilities struct"); idCmdCap->SetCNS(true); SharedMemBufferPtr idMemCap = SharedMemBufferPtr(new MemBuffer()); idMemCap->InitAlignment(Identify::IDEAL_DATA_SIZE, PRP_BUFFER_ALIGNMENT, false, 0); send_64b_bitmask idPrpCap = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); idCmdCap->SetPrpBuffer(idPrpCap, idMemCap); LOG_NRM("Submit Idtfy cmds to fill & roll over the Q (Q_SIZE plus 2)."); for (uint16_t nsubmitTimes = 0; nsubmitTimes < MAX(asq->GetNumEntries(), acq->GetNumEntries()) + 2; nsubmitTimes++) { LOG_NRM("Sending #%d times of %d", (nsubmitTimes + 1), (acq->GetNumEntries() + 2)); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdCap, "AdminQRollChkDiff", false); VerifyCESQValues(acq, (nsubmitTimes + 1) % asq->GetNumEntries()); } // Verify final Q pointers after all the cmds are submitted and reaped VerifyQPointers(acq, asq); if (mACQSize >= MAX_ADMIN_Q_SIZE) { break; } // If the test requires incremental sizes then edit here. mACQSize = MAX_ADMIN_Q_SIZE; // Assign MAX Q Size of ACQ. mASQSize = MIN_ADMIN_Q_SIZE; } }
void CreateAndAttachMaxNamespacesAndVerify::RunCoreTest() { /** \verbatim * Assumptions: * None. * \endverbatim */ LOG_NRM("Start CreateAndAttachMaxNamespacesAndVerify::RunCoreTest"); SharedIOSQPtr iosq = CAST_TO_IOSQ(gRsrcMngr->GetObj(IOSQ_GROUP_ID)); SharedIOCQPtr iocq = CAST_TO_IOCQ(gRsrcMngr->GetObj(IOCQ_GROUP_ID)); SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)); SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)); //uint8_t keyToRegister[16]; //uint32_t memAlignment = sysconf(_SC_PAGESIZE); //CEStat retStat; send_64b_bitmask prpBitmask = (send_64b_bitmask) (MASK_PRP1_PAGE | MASK_PRP2_PAGE); uint8_t userBuffer[4096]; if (userBuffer == 0){} // Suppress unused variable warning const uint32_t *namespaceIdListBuffer32BitPtr = NULL; const uint16_t *controllerIdListBuffer16BitPtr; ConstSharedIdentifyPtr idCtrlrCap = gInformative->GetIdentifyCmdCtrlr(); uint32_t identifyControllerMaxNSID = (uint32_t)idCtrlrCap->GetValue(IDCTRLRCAP_NN); // BUGBUG large assumption that NVMCAP values will not be larger than 64bit num bytes, which is 16384 PETAbytes // BUGBUG Also assume we need to create on GB multiples uint64_t identifyControllerUnallocatedCapacity = idCtrlrCap->GetValue(IDCTRLRCAP_UNVMCAP_LOWER); uint64_t identifyControllerTotalCapacity = idCtrlrCap->GetValue(IDCTRLRCAP_TNVMCAP_LOWER); uint64_t individualNamespaceCapacityInGB = (uint64_t) floor( identifyControllerUnallocatedCapacity / 1024.0 / 1024.0 / 1024.0 / identifyControllerMaxNSID); // In GB units uint64_t individualNamespaceCapacity = individualNamespaceCapacityInGB * 1024 * 1024 * 1024 / 512; // In 512B LBA units uint32_t newlyCreatedNSID = 0; if( identifyControllerUnallocatedCapacity != identifyControllerTotalCapacity) { LOG_NRM("TNVMCAP != UNVMCAP, which points to a namespace being allocated but the previous test should have deleted all"); } LOG_NRM("Create Identify Command To Get All Present NSIDs"); SharedIdentifyPtr identifyCmd = SharedIdentifyPtr(new Identify()); SharedMemBufferPtr identifyControllerStruct = SharedMemBufferPtr(new MemBuffer()); identifyControllerStruct->Init(4096, true, 0x0); SharedMemBufferPtr identifyNamespaceStruct = SharedMemBufferPtr(new MemBuffer()); identifyNamespaceStruct->Init(4096, true, 0x0); SharedMemBufferPtr identifyNamespaceList = SharedMemBufferPtr(new MemBuffer()); identifyNamespaceList->Init(4096, true, 0x0); SharedMemBufferPtr identifyControllerList = SharedMemBufferPtr(new MemBuffer()); identifyControllerList->Init(4096, true, 0x0); // Figure 86 in 1.2 spec CNS NSID CNTID Returns // CNS_Namespace 0x00 X - (Identify Namespace from NSID X. If attached, receive struct, else all 0's, else invalid namespace ID) // CNS_Controller 0x01 - - (Identify Controller struct) // CNS_NamespaceListAttached 0x02 Y - (Identify Namespace LIST, starting at NSID Y and in an increasing order) // CNS_NamespaceListSubsystem 0x10 Z - (Identify Namespace LIST, starting at NSID Z present in subsystem that may or may not be attached) // CNS_NamespaceStructSubsystem 0x11 X - (Identify Namespace from NSID A. If attached or not, receive the struct, else invalid namespace ID) // CNS_ControllerListAttachedToNSID 0x12 X A (Controller List that are attached to NSID X, starting with CNTID greater than A) // CNS_ControllerListSubsystem 0x13 - B (Controller List present in subsystem starting with CNTID greater than B) LOG_NRM("First ensure there are no namespaces present, as this test depends on deleteAllNamespacesAndVerify to complete successfully"); // See 8.11 in 1.2 spec for describing the process this test is following identifyCmd->SetPrpBuffer(prpBitmask, identifyNamespaceList); identifyCmd->SetNSID( 0 ); identifyCmd->SetCNS( CNS_NamespaceListSubsystem ); // Get all NSIDs attached (or not) to controllers identifyCmd->SetCNTID(0); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, identifyCmd, "Reading back (up to) 1024 NSIDs attached to this controller (CNS=2). Command should pass, with 0 NSIDs to be returned", false, CESTAT_SUCCESS); namespaceIdListBuffer32BitPtr = (uint32_t*) identifyCmd->GetROPrpBuffer(); if( namespaceIdListBuffer32BitPtr[0] != 0) { throw FrmwkEx(HERE, "Before creating any namespaces, subsystem was expected to have no NSIDs active and present, but Identify CNS=0x10 returned at least one NSID."); } LOG_NRM("No namespaces are active, test can continue. Pull back the controller list to be used to attach all NSIDs to all controllers on subsystem"); identifyCmd->SetPrpBuffer(prpBitmask, identifyControllerList); identifyCmd->SetNSID( 0 ); identifyCmd->SetCNS( CNS_ControllerListSubsystem ); // Get all controllers in this subsystem identifyCmd->SetCNTID(0); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, identifyCmd, "Reading back what controllers are on this subsystem (CNS=0x13), should find at LEAST one.", false, CESTAT_SUCCESS); controllerIdListBuffer16BitPtr = (uint16_t*) identifyCmd->GetROPrpBuffer(); if( controllerIdListBuffer16BitPtr[0] == 0) { throw FrmwkEx(HERE, "Before creating any namespaces, subsystem was expected to have at least one controller ID present, but found zero."); } SharedNamespaceAttachPtr namespaceAttachCmd = SharedNamespaceAttachPtr(new NamespaceAttach() ); /* //BUGBUG APL is returning an improper list (Ctrlr IDs 1/2 wheras they ID themselves as actually 0/1) for(uint32_t bufferIndex = 0; bufferIndex < 4096; bufferIndex++) { userBuffer[bufferIndex]=0; } userBuffer[0] = 2; // 2 Controllers userBuffer[4] = 1; // 1st (byte 2) is 0 and 2nd (byte 4) is 1 to match APL identifyControllerList->InitAlignment(4096, 4096, false, 0, userBuffer); LOG_NRM("Controller list hardcoded to 0/1 for the time being... BUGBUG"); // END BUG BUG */ // Set attach namespace buffer to be the full controller list, to attach all new NSIDs to to all on this subsystem namespaceAttachCmd->SetPrpBuffer(prpBitmask, identifyControllerList); LOG_NRM("Create Namespace Management to create all namespaces before attaching to all contollers"); SharedNamespaceManagementPtr namespaceManagementCmd = SharedNamespaceManagementPtr(new NamespaceManagement() ); SharedMemBufferPtr managementBuffer = SharedMemBufferPtr(new MemBuffer() ); NamespaceManagementCreateStruct nscreate; nscreate.NSZE = individualNamespaceCapacity; nscreate.NCAP = individualNamespaceCapacity; nscreate.FLBAS = 0; nscreate.DPS = 0; nscreate.NMIC = 1; //NamespaceManagementCreateStruct nscreate( individualNamespaceCapacity, individualNamespaceCapacity, 0, 0, 1 ); // BUGBUG we are going to assume a 512B size and barenamespace as FLBAS=0... otherwise we need to determine what format via namespace structs... //CreateNamespaceManagementStructure( individualNamespaceCapacity, individualNamespaceCapacity, 0, 0, 1, userBuffer); LOG_NRM("Each of the %d namespaces will be of 0x%llx size", identifyControllerMaxNSID, (long long unsigned int) individualNamespaceCapacity); nscreate.print(); managementBuffer->InitAlignment(384, 4096, false, 0x0, (uint8_t*) &nscreate); // Contains namespace struct info for namespace management to consume (384B) namespaceManagementCmd->SetPrpBuffer(prpBitmask, managementBuffer); namespaceAttachCmd->SetSEL( 0 ); namespaceAttachCmd->SetNSID( 0 ); LOG_NRM("Start main loop over valid NSIDs to create/attach them."); for(uint64_t currentNamespaceIdToCreate = 0; currentNamespaceIdToCreate < identifyControllerMaxNSID; currentNamespaceIdToCreate++ ) { // Get the current // Create this namespace using 1/NNth amount of the total available space. namespaceManagementCmd->SetSEL(0); namespaceManagementCmd->SetNSID(0); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, namespaceManagementCmd, "Creating namespace that is 1/NNth size of total NVM capacity, 512B bare LBAs.", false, CESTAT_SUCCESS); newlyCreatedNSID = (acq->PeekCEwithCID( namespaceManagementCmd->GetCID() ) ).t.dw0; LOG_NRM("Newly created NS has NSID of 0x%llu", (long long unsigned) newlyCreatedNSID); // ID this namespace and see if it is all 0s. Namespace should be created but 'inactive'. identifyCmd->SetCNS(CNS_Namespace ); // Standard Namespace ID, should also be attached to this controller identifyCmd->SetNSID( newlyCreatedNSID ); // identifyCmd->SetCNTID(0); identifyCmd->SetPrpBuffer(prpBitmask, identifyNamespaceStruct); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, identifyCmd, "Read Identify Controller struct from created NSID, expecting it to be all 0's since it has not yet attached", false, CESTAT_SUCCESS); // Currently fails on FW for(uint32_t bufferIndex = 0; bufferIndex < 4096; bufferIndex++) { if ( identifyCmd->GetROPrpBuffer()[bufferIndex] != 0) { throw FrmwkEx(HERE, "Expected Identify Namespace to returned all zero buffer as namespace should be inactive and non-attached"); } } // Now attach the drive to all controllers on the subsystem namespaceAttachCmd->SetNSID( newlyCreatedNSID ); namespaceAttachCmd->SetSEL(0); // Should already have the ControllerList associated with the NamespaceAttach command IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, namespaceAttachCmd, "Attaching NSID to all controllers on subsystem", false, CESTAT_SUCCESS); // Reread this NS struct back and make sure the values match what we had requested... IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, identifyCmd, "Read Identify Controller struct from created NSID, expecting non-zero since it is now attached", false, CESTAT_SUCCESS); // First ensure the buffer is not completely non-zero bool identifyNamespaceBufferIsZeroFilled = true; for(uint32_t bufferIndex = 0; bufferIndex < 4096; bufferIndex++) { if ( identifyCmd->GetROPrpBuffer()[bufferIndex] != 0) { identifyNamespaceBufferIsZeroFilled = false; break; } } if( identifyNamespaceBufferIsZeroFilled == true) { throw FrmwkEx(HERE, "Expected Identify Namespace to returned a non-zero buffer as namespace should now be attached"); } // Now check a couple fields (BUGBUG should check all!) IdNamespcStruct *currentNamespaceStruct = (IdNamespcStruct*) identifyCmd->GetROPrpBuffer(); if(currentNamespaceStruct->NSZE != individualNamespaceCapacity) { LOG_NRM("Namespace NSZE 0x%llx != what was passed to namespaceManagement 0x%08llx", (long long unsigned) currentNamespaceStruct->NSZE, (long long unsigned) individualNamespaceCapacity); throw FrmwkEx(HERE, "Newly created namespace's NSZE does not match what was sent to namespaceManagement"); } if(currentNamespaceStruct->NCAP != individualNamespaceCapacity) { LOG_NRM("Namespace NCAP 0x%llx != what was passed to namespaceManagement 0x%08llx", (long long unsigned) currentNamespaceStruct->NCAP, (long long unsigned) individualNamespaceCapacity); throw FrmwkEx(HERE, "Newly created namespace's NCAP does not match what was sent to namespaceManagement"); } // Repull the Identify Controller information and make sure the UNVMCAP values have decreased the amount we just allocatd for this create namespace identifyCmd->SetCNS(CNS_Controller); identifyCmd->SetNSID(0); identifyCmd->SetCNTID(0); identifyCmd->SetPrpBuffer(prpBitmask, identifyControllerStruct); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, identifyCmd, "Pull Identify Controller to check usage sizes have changed.", false, CESTAT_SUCCESS); IdCtrlrCapStruct *currentControllerStruct = (IdCtrlrCapStruct*) identifyCmd->GetROPrpBuffer(); uint64_t expectedNVMCAP = identifyControllerTotalCapacity - (individualNamespaceCapacity * (currentNamespaceIdToCreate+1) * 512); if(currentControllerStruct->UNVMCAP_LOWER != expectedNVMCAP) { LOG_NRM("Expecting UNVMCAP to decrease by last allocated namespace. UNVMCAP = 0x%llx expecting 0x%llx", (long long unsigned) currentControllerStruct->UNVMCAP_LOWER, (long long unsigned) expectedNVMCAP); throw FrmwkEx(HERE, "Identify Controller UNVMCAP is not adjusted after creating a namespace of 1/NNth size"); } // Try to retry the attachment again and ensure a proper fail case IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, namespaceAttachCmd, "Attaching an already attached NSID to all controllers again to check fail case", false, CESTAT_NS_ALREADY_ATTACHED); } // At this point we can double sanity check. // 1) Controller should state 0 bytes available // 2) Should be Cntrl.NN namespaces active and attached to all controllers on the subsystem LOG_NRM("Completed CreateAndAttachMaxNamespacesAndVerify::RunCoreTest"); }
void VerifyNUSE_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ string work; LOG_NRM("Lookup Q'S which were created in a prior test within group"); SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)) SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)) SharedIOSQPtr iosq = CAST_TO_IOSQ(gRsrcMngr->GetObj(IOSQ_GROUP_ID)); SharedIOCQPtr iocq = CAST_TO_IOCQ(gRsrcMngr->GetObj(IOCQ_GROUP_ID)); LOG_NRM("Search for 1st bare/meta or e2e namespace."); Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E(); uint64_t ncap = namspcData.idCmdNamspc->GetValue(IDNAMESPC_NCAP); LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat(); uint64_t lbaDataSize = namspcData.idCmdNamspc->GetLBADataSize(); LOG_NRM("For namespace ID #%d; NCAP = 0x%08lX; LBA Size (B): %lu; NCAP*LBA " "Size (GB): %.2f", namspcData.id, ncap, lbaDataSize, ncap * lbaDataSize / 1e9); LOG_NRM("Create dataset mgmt cmd to be used subsequently"); SharedDatasetMgmtPtr datasetMgmtCmd = SharedDatasetMgmtPtr(new DatasetMgmt()); SharedMemBufferPtr rangeMem = SharedMemBufferPtr(new MemBuffer()); rangeMem->Init((NUM_RANGES * sizeof(RangeDef)), true); send_64b_bitmask prpBitmask = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); datasetMgmtCmd->SetNSID(namspcData.id); datasetMgmtCmd->SetNR(NUM_RANGES - 1); // convert to 0-based datasetMgmtCmd->SetPrpBuffer(prpBitmask, rangeMem); datasetMgmtCmd->SetAD(true); LOG_NRM("Deallocate every LBA in namespace ID #%d", namspcData.id); RangeDef *rangePtr = (RangeDef *)rangeMem->GetBuffer(); rangePtr->slba = 0; rangePtr->length = ncap; const double deallocRate = 1.6e8; // bytes / ms work = str(boost::format("deallocate.%08Xh") % ncap); IO::SendAndReapCmd(mGrpName, mTestName, ncap * lbaDataSize / deallocRate + 10000, iosq, iocq, datasetMgmtCmd, work, true); LOG_NRM("Create identify cmd & assoc some buffer memory"); SharedIdentifyPtr idCmdNamSpc = SharedIdentifyPtr(new Identify()); LOG_NRM("Force identify to request namespace struct"); idCmdNamSpc->SetCNS(CNS_Namespace); idCmdNamSpc->SetNSID(namspcData.id); SharedMemBufferPtr idMemNamSpc = SharedMemBufferPtr(new MemBuffer()); idMemNamSpc->InitAlignment(Identify::IDEAL_DATA_SIZE, PRP_BUFFER_ALIGNMENT, true, 0); send_64b_bitmask idPrpNamSpc = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); idCmdNamSpc->SetPrpBuffer(idPrpNamSpc, idMemNamSpc); work = str(boost::format("IdentifyNamspc.nsid.%d.lba.all") % namspcData.id); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, work, true); LOG_NRM("Verify namespace utilization is zero after de-allocation."); uint64_t nuse = idCmdNamSpc->GetValue(IDNAMESPC_NUSE); uint64_t nsfeat = idCmdNamSpc->GetValue(IDNAMESPC_NSFEAT); if (nuse != 0x0 && ((nsfeat & 0x1) == 0x1)) { throw FrmwkEx(HERE, "Expected namspc utilization = 0x0 but found " "namspc utilization = 0x%08X", nuse); } LOG_NRM("Write data pattern and issue a single block to LBA 0"); SharedWritePtr writeCmd = SharedWritePtr(new Write()); SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer()); switch (namspcData.type) { case Informative::NS_BARE: writeMem->Init(lbaDataSize); writeMem->SetDataPattern(DATAPAT_INC_32BIT); break; case Informative::NS_METAS: writeMem->Init(lbaDataSize); if (gRsrcMngr->SetMetaAllocSize(lbaFormat.MS) == false) throw FrmwkEx(HERE); writeCmd->AllocMetaBuffer(); writeMem->SetDataPattern(DATAPAT_INC_32BIT); writeCmd->SetMetaDataPattern(DATAPAT_INC_32BIT); break; case Informative::NS_METAI: writeMem->Init(lbaDataSize + lbaFormat.MS); writeMem->SetDataPattern(DATAPAT_INC_32BIT); break; case Informative::NS_E2ES: case Informative::NS_E2EI: throw FrmwkEx(HERE, "Deferring work to handle this case in future"); break; } prpBitmask = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST); writeCmd->SetPrpBuffer(prpBitmask, writeMem); writeCmd->SetNSID(namspcData.id); writeCmd->SetNLB(0); work = str(boost::format("write.nsid.%d.nlba.0") % namspcData.id); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, writeCmd, work, true); work = str(boost::format("IdentifyNamspc.nsid.%d.nlba.0") % namspcData.id); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, work, true); LOG_NRM("Verify namespace utilization is one after single LBA write cmd."); nuse = idCmdNamSpc->GetValue(IDNAMESPC_NUSE); nsfeat = idCmdNamSpc->GetValue(IDNAMESPC_NSFEAT); if (nuse != 0x1 && ((nsfeat & 0x1) == 0x1)) { throw FrmwkEx(HERE, "Expected namspc utilization = 0x1 but found " "namspc utilization = 0x%08X", nuse); } }
void UnsupportRsvdFields_r12::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ LOG_NRM("Lookup objs which were created in a prior test within group"); SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)) SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)) LOG_NRM("Determine if DUT has atleast one namespace support"); ConstSharedIdentifyPtr idCmdCtrlr = gInformative->GetIdentifyCmdCtrlr(); if ((idCmdCtrlr->GetValue(IDCTRLRCAP_NN)) == 0) throw FrmwkEx(HERE, "Required to support >= 1 namespace"); LOG_NRM("Form identify namespace cmd and associate some buffer"); SharedIdentifyPtr idCmdNamSpc = SharedIdentifyPtr(new Identify()); idCmdNamSpc->SetCNS(CNS_Namespace); idCmdNamSpc->SetNSID(1); SharedMemBufferPtr idMemNamSpc = SharedMemBufferPtr(new MemBuffer()); idMemNamSpc->InitOffset1stPage(Identify::IDEAL_DATA_SIZE, PRP_BUFFER_OFFSET, true); LOG_NRM("Allow PRP1 and PRP2"); send_64b_bitmask idPrpNamSpc = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); idCmdNamSpc->SetPrpBuffer(idPrpNamSpc, idMemNamSpc); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, "rsvdnone.set", true); LOG_NRM("Set all cmd's rsvd bits"); uint32_t work = idCmdNamSpc->GetDword(0); work |= 0x00003c00; // Set DW0_b13:10 bits idCmdNamSpc->SetDword(work, 0); idCmdNamSpc->SetDword(0xffffffff, 2); idCmdNamSpc->SetDword(0xffffffff, 3); idCmdNamSpc->SetDword(0xffffffff, 4); idCmdNamSpc->SetDword(0xffffffff, 5); work = idCmdNamSpc->GetDword(10); //work |= 0xfffffffc; // Set DW10_b31:2 bits work |= 0x0000ff00; // Set DW10_b31:8 bits idCmdNamSpc->SetDword(work, 10); idCmdNamSpc->SetDword(0xffffffff, 11); idCmdNamSpc->SetDword(0xffffffff, 12); idCmdNamSpc->SetDword(0xffffffff, 13); idCmdNamSpc->SetDword(0xffffffff, 14); idCmdNamSpc->SetDword(0xffffffff, 15); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, "rsvdall.set", true); LOG_NRM("Set CNS field reserved coded value"); uint32_t cdw10 = idCmdNamSpc->GetDword(10); //work = cdw10 | 0x3; //idCmdNamSpc->SetDword(work, 10); const uint32_t cnsNonRsvdVal[] = { 0x00, 0x01, 0x02, 0x10, 0x11, 0x12, 0x13 }; const uint32_t cnsNonRevdValCnt = sizeof(cnsNonRsvdVal) / sizeof(uint32_t); /*IO::SendAndReapCmdNot(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, "rsvdall.val.set", true, CESTAT_SUCCESS); */ for (uint32_t cnsVal = 0; cnsVal <= 0xff; cnsVal++){ uint32_t idx = 0; while ((idx < cnsNonRevdValCnt) && (cnsVal != cnsNonRsvdVal[idx])){ ++idx; } if (idx == cnsNonRevdValCnt) { work = cdw10 | cnsVal; idCmdNamSpc->SetDword(work, 10); IO::SendAndReapCmdNot(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, "rsvdall.val.set", true, CESTAT_SUCCESS); } } }