Example #1
0
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);
}
Example #2
0
void
PRP1PRP2_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     *  \endverbatim
     */
    // Lookup objs which were created in a prior test within group
    string work;
    uint64_t i;
    
    SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID))
    SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID))

    LOG_NRM("Create get log page cmd and assoc some buffer memory");
    SharedGetLogPagePtr getLogPgCmd = SharedGetLogPagePtr(new GetLogPage());

    LOG_NRM("Get log page to request firmware slot information");
    getLogPgCmd->SetNUMD(PRP1_ONLY_NUMD - 1); // 0-based
    getLogPgCmd->SetLID(FIRM_SLOT_INFO_LID);
    getLogPgCmd->SetNSID(0xFFFFFFFF);    
    
    LOG_NRM("Set the offset into the buffer at 0x%04X", BUFFER_OFFSET);
    SharedMemBufferPtr getLogPageMem = SharedMemBufferPtr(new MemBuffer());
    getLogPageMem->InitOffset1stPage(GetLogPage::FIRMSLOT_DATA_SIZE,
        BUFFER_OFFSET, true);
    send_64b_bitmask prpReq =
        (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE);
    getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem);

    IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq,
        getLogPgCmd, "prp1prp2", true);
}
void
InvalidLogPageNVMSet_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     *  \endverbatim
     */
    string work;
    // 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("Create get log page cmd and assoc some buffer memory");
    SharedGetLogPagePtr getLogPgCmd = SharedGetLogPagePtr(new GetLogPage());
    SharedMemBufferPtr getLogPageMem = SharedMemBufferPtr(new MemBuffer());
    send_64b_bitmask prpReq =
            (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE);

    getLogPageMem->InitOffset1stPage(BUFFER_SIZE, 0, true);
    getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem);
    getLogPgCmd->SetNUMD(NUMD - 1); // 0-based
    getLogPgCmd->SetNSID(0xFFFFFFFF);
    list<uint32_t> invalidLIDs = GetInvalidLIDs();
    for (list<uint32_t>::iterator invalidLID = invalidLIDs.begin();
        invalidLID != invalidLIDs.end(); invalidLID++) {
        LOG_NRM("Processing for invalid LID = 0x%04X", *invalidLID);
        getLogPgCmd->SetLID(*invalidLID);

        work = str(boost::format("invalidLID.%d") % *invalidLID);
        IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq,
            getLogPgCmd, work, true, CESTAT_INVAL_LOG_PAGE);
    }
}
Example #4
0
void
CIDAcceptedIOSQ_r10b::InitTstRsrcs(SharedASQPtr asq, SharedACQPtr acq,
    vector <SharedIOSQPtr> &iosqs, SharedIOCQPtr &iocq)
{
    uint8_t iocqes = (gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_CQES) & 0xf);
    uint8_t iosqes = (gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_SQES) & 0xf);

    gCtrlrConfig->SetIOCQES(iocqes);
    gCtrlrConfig->SetIOSQES(iosqes);

    uint32_t numIOSQs = (NUM_IO_SQS <= gInformative->GetFeaturesNumOfIOSQs()) ?
        NUM_IO_SQS : gInformative->GetFeaturesNumOfIOSQs();

    LOG_NRM("Initialize test resources.");
    const uint32_t nEntriesIOQ = 2; // minimum Q entries always supported.
    SharedIOSQPtr iosq;
    if (Queues::SupportDiscontigIOQ() == true) {
        SharedMemBufferPtr iocqMem =  SharedMemBufferPtr(new MemBuffer());
        iocqMem->InitOffset1stPage((nEntriesIOQ * (1 << iocqes)), 0, true);

        iocq = Queues::CreateIOCQDiscontigToHdw(mGrpName, mTestName,
            CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, nEntriesIOQ, false,
            IOCQ_GROUP_ID, true, 1, iocqMem);

        for (uint32_t iosqId = 1; iosqId <= numIOSQs; iosqId++) {
            SharedMemBufferPtr iosqMem = SharedMemBufferPtr(new MemBuffer());
            iosqMem->InitOffset1stPage((nEntriesIOQ * (1 << iosqes)), 0, true);
            iosq = Queues::CreateIOSQDiscontigToHdw(mGrpName, mTestName,
                CALC_TIMEOUT_ms(1), asq, acq, iosqId, nEntriesIOQ, false,
                IOSQ_GROUP_ID, IOQ_ID, 0, iosqMem);
            iosqs.push_back(iosq);
        }
    } else {
       iocq = Queues::CreateIOCQContigToHdw(mGrpName, mTestName,
           CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, nEntriesIOQ, false,
           IOCQ_GROUP_ID, true, 1);

       for (uint32_t iosqId = 1; iosqId <= numIOSQs; iosqId++) {
           iosq = Queues::CreateIOSQContigToHdw(mGrpName, mTestName,
               CALC_TIMEOUT_ms(1), asq, acq, iosqId, nEntriesIOQ, false,
               IOSQ_GROUP_ID, IOQ_ID, 0);
           iosqs.push_back(iosq);
       }
    }
}
void
UnsupportRsvdFields_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     *  \endverbatim
     */
    // Lookup objs which were created in a prior test within group
    string globalWork;
    //uint64_t i;
    
    SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID))
    SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID))

    LOG_NRM("Create get log page cmd and assoc some buffer memory");
    SharedGetLogPagePtr getLogPgCmd = SharedGetLogPagePtr(new GetLogPage());

    LOG_NRM("Get log page to request firmware slot information");
    getLogPgCmd->SetNUMD(PRP1_ONLY_NUMD - 1); // 0-based
    getLogPgCmd->SetLID(FIRM_SLOT_INFO_LID);
    getLogPgCmd->SetNSID(0xFFFFFFFF);
    
    SharedMemBufferPtr getLogPageMem = SharedMemBufferPtr(new MemBuffer());
    getLogPageMem->InitOffset1stPage(GetLogPage::FIRMSLOT_DATA_SIZE,
        BUFFER_OFFSET, true);
    send_64b_bitmask prpReq =
        (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE);
    getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem);

    LOG_NRM("Issue GetLogPage cmd without setting reserved bits.");
    IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq,
        getLogPgCmd, "rsvd.notset", true);

    LOG_NRM("Set all cmd's rsvd bits");
    uint32_t work = getLogPgCmd->GetDword(0);
    work |= 0x0000fc00;      // Set DW0_b15:10 bits
    getLogPgCmd->SetDword(work, 0);

    getLogPgCmd->SetDword(0xffffffff, 2);
    getLogPgCmd->SetDword(0xffffffff, 3);
    getLogPgCmd->SetDword(0xffffffff, 4);
    getLogPgCmd->SetDword(0xffffffff, 5);

    work = getLogPgCmd->GetDword(10);
    work |= 0xf0000000;      // Set DW10_b31:28 bits
    getLogPgCmd->SetDword(work, 10);

    getLogPgCmd->SetDword(0xffffffff, 11);
    getLogPgCmd->SetDword(0xffffffff, 12);
    getLogPgCmd->SetDword(0xffffffff, 13);
    getLogPgCmd->SetDword(0xffffffff, 14);
    getLogPgCmd->SetDword(0xffffffff, 15);

    LOG_NRM("Issue GetLogPage cmd after setting reserved bits.");
    IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq,
        getLogPgCmd, "rsvd.set", true);
}
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
ProtInfoIgnoreMeta_r10b::CreateIOQs(SharedASQPtr asq, SharedACQPtr acq,
    uint32_t ioqId, SharedIOSQPtr &iosq, SharedIOCQPtr &iocq)
{
    uint32_t numEntries = 2;

    gCtrlrConfig->SetIOCQES((gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_CQES) & 0xf));
    gCtrlrConfig->SetIOSQES((gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_SQES) & 0xf));

    if (Queues::SupportDiscontigIOQ() == true) {
        uint8_t iocqes = (gInformative->GetIdentifyCmdCtrlr()->
            GetValue(IDCTRLRCAP_CQES) & 0xf);
        uint8_t iosqes = (gInformative->GetIdentifyCmdCtrlr()->
            GetValue(IDCTRLRCAP_SQES) & 0xf);
        SharedMemBufferPtr iocqBackedMem = SharedMemBufferPtr(new MemBuffer());
        iocqBackedMem->InitOffset1stPage((numEntries * (1 << iocqes)), 0, true);
        iocq = Queues::CreateIOCQDiscontigToHdw(mGrpName, mTestName,
            CALC_TIMEOUT_ms(1), asq, acq, ioqId, numEntries,
            false, IOCQ_GROUP_ID, true, 0, iocqBackedMem);

        SharedMemBufferPtr iosqBackedMem = SharedMemBufferPtr(new MemBuffer());
        iosqBackedMem->InitOffset1stPage((numEntries * (1 << iosqes)), 0,true);
        iosq = Queues::CreateIOSQDiscontigToHdw(mGrpName, mTestName,
            CALC_TIMEOUT_ms(1), asq, acq, ioqId, numEntries, false,
            IOSQ_GROUP_ID, ioqId, 0, iosqBackedMem);
    } else {
        iocq = Queues::CreateIOCQContigToHdw(mGrpName, mTestName,
            CALC_TIMEOUT_ms(1), asq, acq, ioqId, numEntries, false,
            IOCQ_GROUP_ID, true, 0);
        iosq = Queues::CreateIOSQContigToHdw(mGrpName, mTestName,
            CALC_TIMEOUT_ms(1), asq, acq, ioqId, numEntries, false,
            IOSQ_GROUP_ID, ioqId, 0);
    }
}
void
PRPOffsetDualPgMultiBlk_r10b::InitTstRsrcs(SharedASQPtr asq, SharedACQPtr acq,
    SharedIOSQPtr &iosq, SharedIOCQPtr &iocq)
{
    uint8_t iocqes = (gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_CQES) & 0xf);
    uint8_t iosqes = (gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_SQES) & 0xf);

    gCtrlrConfig->SetIOCQES(iocqes);
    gCtrlrConfig->SetIOSQES(iosqes);

    const uint32_t nEntriesIOQ = 2; // minimum Q entries always supported.
    if (Queues::SupportDiscontigIOQ() == true) {
        SharedMemBufferPtr iocqBackMem =  SharedMemBufferPtr(new MemBuffer());
        iocqBackMem->InitOffset1stPage((nEntriesIOQ * (1 << iocqes)), 0, true);

        iocq = Queues::CreateIOCQDiscontigToHdw(mGrpName, mTestName,
            DEFAULT_CMD_WAIT_ms, asq, acq, IOQ_ID, nEntriesIOQ, false,
            IOCQ_GROUP_ID, true, 1, iocqBackMem);

        SharedMemBufferPtr iosqBackMem = SharedMemBufferPtr(new MemBuffer());
        iosqBackMem->InitOffset1stPage((nEntriesIOQ * (1 << iosqes)), 0, true);
        iosq = Queues::CreateIOSQDiscontigToHdw(mGrpName, mTestName,
            DEFAULT_CMD_WAIT_ms, asq, acq, IOQ_ID, nEntriesIOQ, false,
            IOSQ_GROUP_ID, IOQ_ID, 0, iosqBackMem);
    } else {
       iocq = Queues::CreateIOCQContigToHdw(mGrpName, mTestName,
           DEFAULT_CMD_WAIT_ms, asq, acq, IOQ_ID, nEntriesIOQ, false,
           IOCQ_GROUP_ID, true, 1);

       iosq = Queues::CreateIOSQContigToHdw(mGrpName, mTestName,
           DEFAULT_CMD_WAIT_ms, asq, acq, IOQ_ID, nEntriesIOQ, false,
           IOSQ_GROUP_ID, IOQ_ID, 0);
    }
}
Example #9
0
void
NUMDIsAdhered_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     *  \endverbatim
     */
    // Lookup objs which were created in a prior test within group
    string work;
    uint64_t i;
    
    SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID))
    SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID))

    LOG_NRM("Create get log page cmd and assoc some buffer memory");
    SharedGetLogPagePtr getLogPgCmd = SharedGetLogPagePtr(new GetLogPage());

    LOG_NRM("Get log page to request firmware slot information");
    getLogPgCmd->SetNUMD(NUMDW_ADHERED - 1);  // 0-based
    getLogPgCmd->SetLID(FIRM_SLOT_INFO_LID);
    getLogPgCmd->SetNSID(0xFFFFFFFF);
    
    LOG_NRM("Set the offset into the buffer at 0x%04X", BUFFER_OFFSET);
    SharedMemBufferPtr getLogPageMem = SharedMemBufferPtr(new MemBuffer());
    getLogPageMem->InitOffset1stPage(GetLogPage::FIRMSLOT_DATA_SIZE,
        BUFFER_OFFSET, true, BUFFER_INIT_VAL);
    send_64b_bitmask prpReq =
        (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE);
    getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem);

    IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq,
        getLogPgCmd, "NUMD.adhered", true);

    LOG_NRM("Compare cmd buffer to verify the last half of buffer = 0xA5");
    SharedMemBufferPtr cmdPayload = getLogPgCmd->GetRWPrpBuffer();
    uint16_t offset = (NUMDW_ADHERED * 4);
    uint8_t *cmdPayloadBuff = (uint8_t *)cmdPayload->GetBuffer() + offset;
    for (; offset < (GetLogPage::FIRMSLOT_DATA_SIZE); offset++) {
        LOG_NRM("Verify data at offset = 0x%X", offset);
        if (*cmdPayloadBuff != BUFFER_INIT_VAL) {
            throw FrmwkEx(HERE, "NUMD not adhered at offset = 0x%08X, "
                "value = 0x%08X", cmdPayloadBuff, *cmdPayloadBuff);
        }
        cmdPayloadBuff++;
    }
}
Example #10
0
void
CreateResources_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) This is the 1st within GrpNVMWriteReadCombo.
     * \endverbatim
     */
    if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
        throw FrmwkEx(HERE);

    SharedACQPtr acq = CAST_TO_ACQ(
        gRsrcMngr->AllocObj(Trackable::OBJ_ACQ, ACQ_GROUP_ID))
    acq->Init(5);

    SharedASQPtr asq = CAST_TO_ASQ(
        gRsrcMngr->AllocObj(Trackable::OBJ_ASQ, ASQ_GROUP_ID))
    asq->Init(5);

    // All queues will use identical IRQ vector
    IRQ::SetAnySchemeSpecifyNum(1);     // throws upon error

    gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw FrmwkEx(HERE);

    {
        uint64_t maxIOQEntries;
        // Determine the max IOQ entries supported
        if (gRegisters->Read(CTLSPC_CAP, maxIOQEntries) == false)
            throw FrmwkEx(HERE, "Unable to determine MQES");

        maxIOQEntries &= CAP_MQES;
        maxIOQEntries += 1;      // convert to 1-based
        if (maxIOQEntries < (uint64_t)NumEntriesIOQ) {
            LOG_NRM("Changing number of Q elements from %d to %lld",
                NumEntriesIOQ, (unsigned long long)maxIOQEntries);
            NumEntriesIOQ = maxIOQEntries;
        }

        uint8_t iocqes = (gInformative->GetIdentifyCmdCtrlr()->
            GetValue(IDCTRLRCAP_CQES) & 0xf);
        uint8_t iosqes = (gInformative->GetIdentifyCmdCtrlr()->
            GetValue(IDCTRLRCAP_SQES) & 0xf);
        gCtrlrConfig->SetIOCQES(iocqes);
        gCtrlrConfig->SetIOSQES(iosqes);
        if (Queues::SupportDiscontigIOQ() == true) {
            SharedMemBufferPtr iocqBackedMem =
                SharedMemBufferPtr(new MemBuffer());
            iocqBackedMem->InitOffset1stPage
                ((NumEntriesIOQ * (1 << iocqes)), 0, true);
            Queues::CreateIOCQDiscontigToHdw(mGrpName, mTestName,
                CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, NumEntriesIOQ, true,
                IOCQ_GROUP_ID, true, 0, iocqBackedMem);

            SharedMemBufferPtr iosqBackedMem =
                SharedMemBufferPtr(new MemBuffer());
            iosqBackedMem->InitOffset1stPage
                ((NumEntriesIOQ * (1 << iosqes)), 0, true);
            Queues::CreateIOSQDiscontigToHdw(mGrpName, mTestName,
                CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, NumEntriesIOQ, true,
                IOSQ_GROUP_ID, IOQ_ID, 0, iosqBackedMem);
        } else {
           Queues::CreateIOCQContigToHdw(mGrpName, mTestName,
               CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, NumEntriesIOQ, true,
               IOCQ_GROUP_ID, true, 0);
           Queues::CreateIOSQContigToHdw(mGrpName, mTestName,
               CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, NumEntriesIOQ, true,
               IOSQ_GROUP_ID, IOQ_ID, 0);
        }
    }
}
void
PRPOffsetSinglePgSingleBlk_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     * \endverbatim
     */
    string work;
    int64_t X;
    bool enableLog;

    LOG_NRM("Initialize random seed");
    srand (17);

    // 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));

    LOG_NRM("Get namspc and determine LBA size");
    Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E();
    send_64b_bitmask prpBitmask = (send_64b_bitmask)(MASK_PRP1_PAGE);
    LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat();
    uint64_t lbaDataSize = namspcData.idCmdNamspc->GetLBADataSize();

    uint8_t mpsRegVal;
    if (gCtrlrConfig->GetMPS(mpsRegVal) == false)
        throw FrmwkEx(HERE, "Unable to get MPS value from CC.");

    switch (namspcData.type) {
    case Informative::NS_BARE:
        X =  (int64_t)(1 << (mpsRegVal + 12)) - lbaDataSize;
        break;
    case Informative::NS_METAS:
        if (gRsrcMngr->SetMetaAllocSize(lbaFormat.MS) == false)
            throw FrmwkEx(HERE);
        X =  (int64_t)(1 << (mpsRegVal + 12)) - lbaDataSize;
        break;
    case Informative::NS_METAI:
        X =  (int64_t)(1 << (mpsRegVal + 12)) - (lbaDataSize + lbaFormat.MS);
        break;
    case Informative::NS_E2ES:
    case Informative::NS_E2EI:
        throw FrmwkEx(HERE, "Deferring work to handle this case in future");
        break;
    }
    if (X <= 0) {
        LOG_WARN("CC.MPS (0x%04X) < lba data size(LBADS) + MS "
            "(0x08%lX + 0x04%X) ; Can't run test.", (1 << (mpsRegVal + 12)),
            lbaDataSize, lbaFormat.MS);
        return;
    }

    LOG_NRM("Prepare cmds to send to the queues.");
    SharedWritePtr writeCmd = CreateWriteCmd(namspcData);
    SharedReadPtr readCmd = CreateReadCmd(namspcData);

    DataPattern dataPattern;
    uint64_t wrVal;
    uint32_t prp2RandVal[2];
    for (int64_t pgOff = 0; pgOff <= X; pgOff += 4) {
        LOG_NRM("Processing at page offset #%ld", pgOff);
        if ((pgOff % 8) != 0) {
            dataPattern = DATAPAT_CONST_8BIT;
            wrVal = pgOff;
            prp2RandVal[0] = rand();
            prp2RandVal[1] = rand();
            work = str(boost::format("dataPat.constb.memOff.%d") % pgOff);
        } else {
            dataPattern = DATAPAT_INC_16BIT;
            wrVal = pgOff;
            prp2RandVal[0] = 0;
            prp2RandVal[1] = 0;
            work = str(boost::format("dataPat.incw.memOff.%d") % pgOff);
        }
        SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer());

        switch (namspcData.type) {
        case Informative::NS_BARE:
            writeMem->InitOffset1stPage(lbaDataSize, pgOff, false);
            break;
        case Informative::NS_METAS:
            writeMem->InitOffset1stPage(lbaDataSize, pgOff, false);
            writeCmd->SetMetaDataPattern(dataPattern, wrVal);
            break;
        case Informative::NS_METAI:
            writeMem->InitOffset1stPage
                (lbaDataSize + lbaFormat.MS, pgOff, false);
            break;
        case Informative::NS_E2ES:
        case Informative::NS_E2EI:
            throw FrmwkEx(HERE, "Deferring work to handle this case in future");
            break;
        }
        writeCmd->SetPrpBuffer(prpBitmask, writeMem);
        writeMem->SetDataPattern(dataPattern, wrVal);

        LOG_NRM("Set 64 bits of PRP2 CDW 8 & 9 with random or 0 for wr cmd.");
        writeCmd->SetDword(prp2RandVal[0], 8);
        writeCmd->SetDword(prp2RandVal[1], 9);

        enableLog = false;
        if ((pgOff <= 8) || (pgOff >= (X - 8)))
            enableLog = true;

        IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq, iocq,
            writeCmd, work, enableLog);

        SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer());
        switch (namspcData.type) {
        case Informative::NS_BARE:
            readMem->InitOffset1stPage(lbaDataSize, pgOff, false);
            break;
        case Informative::NS_METAS:
            readMem->InitOffset1stPage(lbaDataSize, pgOff, false);
            break;
        case Informative::NS_METAI:
            readMem->InitOffset1stPage
                (lbaDataSize + lbaFormat.MS, pgOff, false);
            break;
        case Informative::NS_E2ES:
        case Informative::NS_E2EI:
            throw FrmwkEx(HERE, "Deferring work to handle this case in future");
            break;
        }
        readCmd->SetPrpBuffer(prpBitmask, readMem);

        LOG_NRM("Set 64 bits of PRP2 CDW 8 & 9 with random or 0 for rd cmd.");
        readCmd->SetDword(prp2RandVal[0], 8);
        readCmd->SetDword(prp2RandVal[1], 9);

        IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq, iocq,
            readCmd, work, enableLog);

        VerifyDataPattern(readCmd, dataPattern, wrVal);
    }
}
void
PRPOffsetDualPgMultiBlk_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * None.
     * \endverbatim
     */
    string work;
    int64_t X;
    bool enableLog;

    if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
        throw FrmwkEx(HERE);

    LOG_NRM("Create ACQ and ASQ objects which have test life time");
    SharedACQPtr acq = CAST_TO_ACQ(SharedACQPtr(new ACQ(mFd)))
    acq->Init(5);
    SharedASQPtr asq = CAST_TO_ASQ(SharedASQPtr(new ASQ(mFd)))
    asq->Init(5);

    IRQ::SetAnySchemeSpecifyNum(2);     // throws upon error

    gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw FrmwkEx(HERE);

    SharedIOCQPtr iocq;
    SharedIOSQPtr iosq;
    InitTstRsrcs(asq, acq, iosq, iocq);

    LOG_NRM("Compute memory page size from CC.MPS.");
    uint8_t mpsRegVal;
    if (gCtrlrConfig->GetMPS(mpsRegVal) == false)
        throw FrmwkEx(HERE, "Unable to get MPS value from CC.");
    uint64_t ccMPS = (uint64_t)(1 << (mpsRegVal + 12));

    LOG_NRM("Get namspc and determine LBA size");
    Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E();
    send_64b_bitmask prpBitmask =
        (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE);
    LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat();
    uint64_t lbaDataSize = (1 << lbaFormat.LBADS);
    LOG_NRM("LBA data size is %ld.", lbaDataSize);

    LOG_NRM("Seeking max data xfer size for chosen namspc");
    ConstSharedIdentifyPtr idCmdCtrlr = gInformative->GetIdentifyCmdCtrlr();
    uint32_t maxDtXferSz = idCmdCtrlr->GetMaxDataXferSize();

    SharedWritePtr writeCmd = SharedWritePtr(new Write());
    writeCmd->SetNSID(namspcData.id);

    SharedReadPtr readCmd = SharedReadPtr(new Read());
    readCmd->SetNSID(namspcData.id);

    SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer());
    SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer());

    switch (namspcData.type) {
    case Informative::NS_BARE:
        X =  ccMPS - lbaDataSize;
        break;
    case Informative::NS_METAS:
        X =  ccMPS - lbaDataSize;
        LOG_NRM("Allocating separate meta data buffer.");
        if (gRsrcMngr->SetMetaAllocSize(
            lbaFormat.MS * ((2 * ccMPS) / lbaDataSize)) == false) {
            throw FrmwkEx(HERE, "Unable to allocate Meta buffers.");
        }
        writeCmd->AllocMetaBuffer();
        readCmd->AllocMetaBuffer();
        break;
    case Informative::NS_METAI:
        X =  ccMPS - (lbaDataSize + lbaFormat.MS);
        break;
    case Informative::NS_E2ES:
    case Informative::NS_E2EI:
        throw FrmwkEx(HERE, "Deferring work to handle this case in future");
        break;
    }
    if (X < 0) {
        LOG_WARN("CC.MPS < lba data size(LBADS); Can't run test.");
        return;
    }

    DataPattern dataPat;
    uint64_t wrVal;
    uint64_t Y;

    for (int64_t pgOff = 0; pgOff <= X; pgOff += 4) {
        switch (namspcData.type) {
        case Informative::NS_BARE:
        case Informative::NS_METAS:
            Y = ((2 * ccMPS) - pgOff) / lbaDataSize;
            break;
        case Informative::NS_METAI:
            Y = ((2 * ccMPS) - pgOff) / (lbaDataSize + lbaFormat.MS);
            break;
        case Informative::NS_E2ES:
        case Informative::NS_E2EI:
            throw FrmwkEx(HERE, "Deferring work to handle this case in future");
            break;
        }
        for (uint64_t nLBAs = 1; nLBAs <= Y; nLBAs++) {
            LOG_NRM("Sending LBA #%ld of #%ld", nLBAs, Y);
            if ((maxDtXferSz != 0) && (maxDtXferSz < (lbaDataSize * nLBAs))) {
                // If the total data xfer exceeds the maximum data xfer
                // allowed then we break from the inner loop and continue
                // test with next offset (outer loop).
                LOG_WARN("Data xfer size exceeds max allowed, continuing..");
                break;
            }
            if ((nLBAs % 2) != 0) {
                dataPat = DATAPAT_INC_32BIT;
                wrVal = pgOff + nLBAs;
            } else {
                dataPat = DATAPAT_CONST_16BIT;
                wrVal = pgOff + nLBAs;
            }

            uint64_t metabufSz = nLBAs * lbaFormat.MS;
            switch (namspcData.type) {
            case Informative::NS_BARE:
                writeMem->InitOffset1stPage((lbaDataSize * nLBAs), pgOff,
                    false);
                readMem->InitOffset1stPage((lbaDataSize * nLBAs), pgOff, false);
                break;
            case Informative::NS_METAS:
                writeMem->InitOffset1stPage((lbaDataSize * nLBAs), pgOff,
                    false);
                readMem->InitOffset1stPage((lbaDataSize * nLBAs), pgOff, false);
                writeCmd->SetMetaDataPattern(dataPat, wrVal, 0, metabufSz);
                break;
            case Informative::NS_METAI:
                writeMem->InitOffset1stPage(
                    ((lbaDataSize + lbaFormat.MS) * nLBAs), pgOff, false);
                readMem->InitOffset1stPage(
                    ((lbaDataSize + lbaFormat.MS) * nLBAs), pgOff, false);
                break;
            case Informative::NS_E2ES:
            case Informative::NS_E2EI:
                throw FrmwkEx(HERE,
                    "Deferring work to handle this case in future");
                break;
            }
            work = str(boost::format("pgOff.%d.nlba.%d") % pgOff % nLBAs);
            writeCmd->SetPrpBuffer(prpBitmask, writeMem);
            writeMem->SetDataPattern(dataPat, wrVal);
            writeCmd->SetNLB(nLBAs - 1); // convert to 0 based.

            enableLog = false;
            if ((pgOff <= 8) || (pgOff >= (X - 8)))
                enableLog = true;

            IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq,
                iocq, writeCmd, work, enableLog);

            readCmd->SetPrpBuffer(prpBitmask, readMem);
            readCmd->SetNLB(nLBAs - 1); // convert to 0 based.

            IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq,
                iocq, readCmd, work, enableLog);

            VerifyDataPat(readCmd, dataPat, wrVal, metabufSz);
        }
    }
}
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);
        }
    }
}
Example #14
0
void
InvalidNamspc_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     *  \endverbatim
     */
    string work;
    uint64_t inc, i;

    // 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("Create get log page cmd and assoc some buffer memory");
    SharedGetLogPagePtr getLogPgCmd = SharedGetLogPagePtr(new GetLogPage());
    SharedMemBufferPtr getLogPageMem = SharedMemBufferPtr(new MemBuffer());
    send_64b_bitmask prpReq =
            (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE);

    getLogPageMem->InitOffset1stPage(GetLogPage::SMART_DATA_SIZE, 0, true);
    getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem);
    getLogPgCmd->SetLID(SMART_HEALTH_INFO_LID);
    getLogPgCmd->SetNUMD(SMART_NUMD - 1); // 0 - based

    ConstSharedIdentifyPtr idCtrlrStruct = gInformative->GetIdentifyCmdCtrlr();
    uint32_t nn = (uint32_t)idCtrlrStruct->GetValue(IDCTRLRCAP_NN);
    if (nn == 0 )
        throw FrmwkEx(HERE, "Required to support >= 1 namespace");

    uint8_t logPageAttr = (uint8_t)idCtrlrStruct->GetValue(IDCTRLRCAP_LPA);
    // bits 7:1 are reserved, need bit 0
    uint8_t suppSmartPerNamspc = logPageAttr & 0x1;

    if(suppSmartPerNamspc > 0) {
    	LOG_NRM("IDCTRLRCAP_LPA bit0 is set. Per Namespace Smart Pages supported")
    }
    else {
    	LOG_NRM("IDCTRLRCAP_LPA bit0 is not set. Per Namespace Smart Pages is not supported")
    }

    // for all illegal nsid's verify get log page cmd.
    for (i = (nn + 1), inc = 1; i < 0xffffffff; i += (2 * inc), inc += 1327) {
        LOG_NRM("Issue Get log page cmd with illegal namspc ID = 0x%llX",
            (unsigned long long)i);
        getLogPgCmd->SetNSID(i);

        work = str(boost::format("namspc%d") % i);
        // Determine the status based on the per namespace mask bit.
        // While the 1.1+ spec requires the device to return invalid field
        //   the 1.0 spec does NOT require the device to return SUCCESS and
        //   a global log page no matter what value of NSID is provided
        // Instead only the global 0xFFFFFFFF NSID MUST be supported
        IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq,
            getLogPgCmd, work, true, CESTAT_INVAL_NAMSPC);
    }

    // If per namespc smart log is supported, check all legal nn.
    if (suppSmartPerNamspc) {
        for (i = 1; i <= nn; i++) {
            LOG_NRM("Issue Get log page cmd with legal namspc ID = 0x%llX (per namespace smart log supported)",
                (unsigned long long)i);
            getLogPgCmd->SetNSID(i);

            work = str(boost::format("namspc%d") % i);
            // Determine the status based on the per namespace mask bit.
            IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1),
                asq, acq, getLogPgCmd, work, true);
        }
    }

	// GetLogPage of NSID == 0 is not expected to pass when LPA bit 0 is not set
	// The only requirement is that 0xFFFFFFFF is supported, not that the NSID field
	//   is completely ignored and a global page is always returned...
    /*
    else {
        i = 0;
        getLogPgCmd->SetNSID(i);
        work = str(boost::format("namspc%d") % i);
        IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq,
            getLogPgCmd, work, true);
    }
    */

    // If name space is 0xffffffff, then we should get the global log info.
    i = 0xffffffff;
    getLogPgCmd->SetNSID(i);
    work = str(boost::format("namspc%d") % i);
    IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq,
        getLogPgCmd, work, true);
}
Example #15
0
void
QIDVariations_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     *  \endverbatim
     */
    uint16_t uniqueId;
    // 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))

    uint64_t maxIOQEntries;
    LOG_NRM("Determine the max IOQ entries supported");
    if (gRegisters->Read(CTLSPC_CAP, maxIOQEntries) == false)
        throw FrmwkEx(HERE, "Unable to determine MQES");
    maxIOQEntries &= CAP_MQES;
    maxIOQEntries += 1;      // convert to 1-based

    SharedWritePtr writeCmd = SetWriteCmd();

    uint32_t maxIOQSupport = MIN(gInformative->GetFeaturesNumOfIOSQs(),
        gInformative->GetFeaturesNumOfIOCQs());
    uint32_t NumEntriesIOSQ = 2; // IOSQ range: 2 to X + 2
    uint32_t NumEntriesIOCQ = ((maxIOQSupport + 2) > maxIOQEntries) ?
        maxIOQEntries : (maxIOQSupport + 2); // IOCQ range: X + 2 to 2

    uint8_t iocqes = (gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_CQES) & 0xf);
    uint8_t iosqes = (gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_SQES) & 0xf);

    vector<SharedIOSQPtr> IOSQVec;
    vector<SharedIOCQPtr> IOCQVec;
    // Create all supported  queues.
    for (uint32_t ioqId = 1; ioqId <= maxIOQSupport; ioqId++) {
        SharedIOCQPtr iocq;
        SharedIOSQPtr iosq;
        LOG_NRM("Create IOSQ and IOCQ with IDs #%d of maximum IDs %d",
            ioqId, maxIOQSupport);
        if (Queues::SupportDiscontigIOQ() == true) {
            SharedMemBufferPtr iocqBackedMem =
                SharedMemBufferPtr(new MemBuffer());
            iocqBackedMem->InitOffset1stPage
                ((NumEntriesIOCQ * (1 << iocqes)), 0, true);
            iocq = Queues::CreateIOCQDiscontigToHdw(mGrpName, mTestName,
                CALC_TIMEOUT_ms(1), asq, acq, ioqId, NumEntriesIOCQ,
                false, IOCQ_CONTIG_GROUP_ID, false, 0, iocqBackedMem);

            SharedMemBufferPtr iosqBackedMem =
                SharedMemBufferPtr(new MemBuffer());
            iosqBackedMem->InitOffset1stPage
                ((NumEntriesIOSQ * (1 << iosqes)), 0,true);
            iosq = Queues::CreateIOSQDiscontigToHdw(mGrpName, mTestName,
                CALC_TIMEOUT_ms(1), asq, acq, ((maxIOQSupport - ioqId) + 1),
                NumEntriesIOSQ, false, IOSQ_CONTIG_GROUP_ID, ioqId, 0,
                iosqBackedMem);
        } else {
            iocq = Queues::CreateIOCQContigToHdw(mGrpName,
                mTestName, CALC_TIMEOUT_ms(1), asq, acq, ioqId, NumEntriesIOCQ,
                false, IOCQ_CONTIG_GROUP_ID, false, 0);
            iosq = Queues::CreateIOSQContigToHdw(mGrpName,
                mTestName, CALC_TIMEOUT_ms(1), asq, acq,
                ((maxIOQSupport - ioqId) + 1), NumEntriesIOSQ, false,
                IOSQ_CONTIG_GROUP_ID, ioqId, 0);
        }

        IOSQVec.push_back(iosq);
        IOCQVec.push_back(iocq);

        if (NumEntriesIOSQ < maxIOQEntries) {
            NumEntriesIOSQ++;
            NumEntriesIOCQ--;
        }
    }

    vector <SharedIOSQPtr>::iterator iosq;
    vector <SharedIOCQPtr>::iterator iocq;
    LOG_NRM("Send cmds until all SQs fill up.");
    for (iosq = IOSQVec.begin(); iosq != IOSQVec.end(); iosq++) {
        for (uint32_t numCmds = 1; numCmds < ((*iosq)->GetNumEntries());
            numCmds++) {
            (*iosq)->Send(writeCmd, uniqueId);
        }
        (*iosq)->Ring();
    }

    LOG_NRM("Reap and verify all cmds submitted.");
    iosq = IOSQVec.begin();
    for (iocq = IOCQVec.begin(); iocq != IOCQVec.end(); iocq++, iosq++)
        ReapVerifyOnCQ(*iocq, *iosq);

    // Clean up after the test by deleting all the Q's created.
    iocq = IOCQVec.begin();
    for (iosq = IOSQVec.begin(); iosq != IOSQVec.end(); iosq++, iocq++) {
        // Delete IOSQ before the IOCQ to comply with spec.
        Queues::DeleteIOSQToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1),
            *iosq, asq, acq);
        Queues::DeleteIOCQToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1),
            *iocq, asq, acq);
    }

}
Example #16
0
void
PRPLessPageDiscontig_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * None
     * \endverbatim
     */
    string work;
    bool enableLog;

    if (Queues::SupportDiscontigIOQ() == false) {
        LOG_WARN("DUT must support discontig Q's for this test.");
        return;
    }

    uint64_t ctrlCapReg;
    LOG_NRM("Determine the max IOQ entries supported");
    if (gRegisters->Read(CTLSPC_CAP, ctrlCapReg) == false)
        throw FrmwkEx(HERE, "Unable to determine MQES");
    uint32_t maxIOQEntries = (ctrlCapReg & CAP_MQES);
    maxIOQEntries += 1;      // convert to 1-based

    LOG_NRM("Compute memory page size from CC.MPS.");
    uint8_t mps;
    if (gCtrlrConfig->GetMPS(mps) == false)
        throw FrmwkEx(HERE, "Unable to get MPS value from CC.");
    uint64_t capMPS = (uint64_t)(1 << (mps + 12));

    LOG_NRM("Determine element sizes for the IOCQ's");
    uint8_t iocqes = (gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_CQES) & 0xf);
    uint32_t Y = ((capMPS / (1 << iocqes)) - 1);
    if (maxIOQEntries < Y) {
        LOG_WARN("Desired to support >= %d elements in IOCQ for this test", Y);
        return;
    }

    LOG_NRM("Determine element sizes for the IOSQ's");
    uint8_t iosqes = (gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_SQES) & 0xf);
    uint32_t Z = ((capMPS / (1 << iosqes)) - 1);

    LOG_NRM("Computed memory page size from CC.MPS = %ld", capMPS);
    LOG_NRM("Max IOQ entries supported CAP.MQES = %d", maxIOQEntries);
    LOG_NRM("Number of IOCQ elements = %d", Y);
    LOG_NRM("Number of IOSQ elements = %d", Z);

    if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
        throw FrmwkEx(HERE);

    LOG_NRM("Create admin queues ACQ and ASQ");
    SharedACQPtr acq = SharedACQPtr(new ACQ(gDutFd));
    acq->Init(5);

    SharedASQPtr asq = SharedASQPtr(new ASQ(gDutFd));
    asq->Init(5);

    // All queues will use identical IRQ vector
    IRQ::SetAnySchemeSpecifyNum(1);     // throws upon error

    gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw FrmwkEx(HERE);

    Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E();
    LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat();
    uint64_t lbaDataSize = namspcData.idCmdNamspc->GetLBADataSize();

    LOG_NRM("Setup element sizes for the IOQ's");
    gCtrlrConfig->SetIOCQES(iocqes);
    gCtrlrConfig->SetIOSQES(iosqes);

    LOG_NRM("Create discontig IOSQ and IOCQ with IDs 1");
    SharedMemBufferPtr iocqBackedMem = SharedMemBufferPtr(new MemBuffer());
    iocqBackedMem->InitOffset1stPage((Y * (1 << iocqes)), 0, true);
    SharedIOCQPtr iocq = Queues::CreateIOCQDiscontigToHdw(mGrpName, mTestName,
        DEFAULT_CMD_WAIT_ms, asq, acq, IOQ_ID, Y, false, IOCQ_GROUP_ID,
        true, 0, iocqBackedMem);

    SharedMemBufferPtr iosqBackedMem = SharedMemBufferPtr(new MemBuffer());
    iosqBackedMem->InitOffset1stPage((Z * (1 << iosqes)), 0,true);
    SharedIOSQPtr iosq = Queues::CreateIOSQDiscontigToHdw(mGrpName, mTestName,
        DEFAULT_CMD_WAIT_ms, asq, acq, IOQ_ID, Z, false, IOSQ_GROUP_ID,
        IOQ_ID, 0, iosqBackedMem);

    SharedWritePtr writeCmd = SharedWritePtr(new Write());
    SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer());

    SharedReadPtr readCmd = SharedReadPtr(new Read());
    SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer());

    send_64b_bitmask prpBitmask = (send_64b_bitmask)(MASK_PRP1_PAGE |
        MASK_PRP2_PAGE | MASK_PRP2_LIST);

    switch (namspcData.type) {
    case Informative::NS_BARE:
        writeMem->Init(lbaDataSize);
        readMem->Init(lbaDataSize);
        break;
    case Informative::NS_METAS:
        writeMem->Init(lbaDataSize);
        readMem->Init(lbaDataSize);
        if (gRsrcMngr->SetMetaAllocSize(lbaFormat.MS) == false)
            throw FrmwkEx(HERE);
        writeCmd->AllocMetaBuffer();
        readCmd->AllocMetaBuffer();
        break;
    case Informative::NS_METAI:
        writeMem->Init(lbaDataSize + lbaFormat.MS);
        readMem->Init(lbaDataSize + lbaFormat.MS);
        break;
    case Informative::NS_E2ES:
    case Informative::NS_E2EI:
        throw FrmwkEx(HERE, "Deferring work to handle this case in future");
        break;
    }

    writeCmd->SetPrpBuffer(prpBitmask, writeMem);
    writeCmd->SetNSID(namspcData.id);
    writeCmd->SetNLB(0);

    readCmd->SetPrpBuffer(prpBitmask, readMem);
    readCmd->SetNSID(namspcData.id);
    readCmd->SetNLB(0);

    // Fill the IOSQ and roll over
    for (int64_t X = 1; X <= (iosq->GetNumEntries() + 1); X++) {
        LOG_NRM("Processing #%ld of %d cmds", X, (iosq->GetNumEntries() + 1));
        switch (namspcData.type) {
        case Informative::NS_BARE:
            writeMem->SetDataPattern(DATAPAT_INC_32BIT, X);
            break;
        case Informative::NS_METAS:
            writeMem->SetDataPattern(DATAPAT_INC_32BIT, X);
            writeCmd->SetMetaDataPattern(DATAPAT_INC_32BIT, X);
            break;
        case Informative::NS_METAI:
            writeMem->SetDataPattern(DATAPAT_INC_32BIT, X);
            break;
        case Informative::NS_E2ES:
        case Informative::NS_E2EI:
            throw FrmwkEx(HERE, "Deferring work to handle this case in future");
            break;
        }

        enableLog = false;
        if ((X <= 8) || (X >= (X - 8)))
            enableLog = true;

        work = str(boost::format("X.%d") % X);
        IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq,
            iocq, writeCmd, work, enableLog);

        IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq,
            iocq, readCmd, work, enableLog);

        VerifyDataPat(readCmd, writeCmd);
    }
}