def test_cq_p_phase_bit(nvme0): cq = IOCQ(nvme0, 1, 3, PRP()) sq = IOSQ(nvme0, 1, 5, PRP(), cqid=1) # send commands sq[0] = SQE(4 << 16 + 0, 1) sq[1] = SQE(3 << 16 + 0, 1) sq[2] = SQE(2 << 16 + 0, 1) sq[3] = SQE(1 << 16 + 0, 1) sq.tail = 4 # check cq time.sleep(0.1) assert cq[0][3] == 0x10004 assert cq[1][3] == 0x10003 assert cq[2][3] == 0 cq.head = 1 time.sleep(0.1) assert cq[2][3] == 0x10002 assert cq[0][3] == 0x10004 cq.head = 2 time.sleep(0.1) # p-bit changed to 0 assert cq[0][3] == 0x00001
def test_create_sq_with_invalid_queue_size(nvme0, mqes): if mqes == 0x10000: pytest.skip("no invalid queue size") cq = IOCQ(nvme0, 2, 10, PRP(4096)) with pytest.warns(UserWarning, match="ERROR status: 01/02"): IOSQ(nvme0, 1, 0xffff, PRP(4096), cqid=2) with pytest.warns(UserWarning, match="ERROR status: 01/02"): IOSQ(nvme0, 1, 1, PRP(4096), cqid=2) IOSQ(nvme0, 1, mqes - 2, PRP(4096), cqid=2).delete() IOSQ(nvme0, 1, mqes - 1, PRP(4096), cqid=2).delete() IOSQ(nvme0, 1, mqes, PRP(4096), cqid=2).delete() with pytest.warns(UserWarning, match="ERROR status: 01/02"): IOSQ(nvme0, 1, mqes + 1, PRP(4096), cqid=2) with pytest.warns(UserWarning, match="ERROR status: 01/02"): IOSQ(nvme0, 1, mqes + 2, PRP(4096), cqid=2) with pytest.warns(UserWarning, match="ERROR status: 01/02"): IOSQ(nvme0, 1, mqes + 0xff, PRP(4096), cqid=2) # empty queue with pytest.warns(UserWarning, match="ERROR status: 01/02"): IOSQ(nvme0, 1, 1, PRP(4096), cqid=2) with pytest.raises(AssertionError): IOSQ(nvme0, 1, 0, PRP(4096), cqid=2) IOSQ(nvme0, 1, 2, PRP(4096), cqid=2).delete() cq.delete()
def test_sq_overflow(nvme0): cq = IOCQ(nvme0, 1, 5, PRP()) sq = IOSQ(nvme0, 1, 2, PRP(), cqid=1) # send commands sq[0] = SQE(4<<16+0, 1); sq.tail = 1 sq[1] = SQE(3<<16+0, 1); sq.tail = 0 sq[0] = SQE(2<<16+0, 1); sq.tail = 0 with pytest.warns(UserWarning, match="AER notification is triggered: 0x10100"): nvme0.getfeatures(7).waitdone() # check cq time.sleep(0.1) assert cq[0][3] == 0x10004 assert cq[1][3] == 0x10003 assert cq[2][3] == 0 time.sleep(1) assert cq[2][3] == 0 assert cq[3][3] == 0 assert cq[4][3] == 0 logging.info(sq[0]) logging.info(cq[0]) sq.delete() cq.delete()
def test_delete_sq_with_invalid_id(nvme0, ncqa): def delete_sq(nvme0, qid): nvme0.send_cmd(0x00, cdw10=qid).waitdone() # pass case cq = IOCQ(nvme0, 1, 10, PRP(4096)) IOSQ(nvme0, 5, 10, PRP(4096), cqid=1) delete_sq(nvme0, 5) cq.delete() # sqid: 0 with pytest.warns(UserWarning, match="ERROR status: 01/01"): delete_sq(nvme0, 0) # sqid: 0xffff with pytest.warns(UserWarning, match="ERROR status: 01/01"): delete_sq(nvme0, 0xffff) # sqid: larger than supported number of queue with pytest.warns(UserWarning, match="ERROR status: 01/01"): delete_sq(nvme0, ncqa + 1) # sqid: duplicated cqid with pytest.warns(UserWarning, match="ERROR status: 01/01"): delete_sq(nvme0, ncqa + 0xff) # sqid: not existed with pytest.warns(UserWarning, match="ERROR status: 01/01"): delete_sq(nvme0, 5)
def test_sq_overflow(nvme0): cq = IOCQ(nvme0, 1, 5, PRP()) sq = IOSQ(nvme0, 1, 2, PRP(), cqid=1) # send commands sq[0] = SQE(4 << 16 + 0, 1) sq.tail = 1 time.sleep(0.1) sq[1] = SQE(3 << 16 + 0, 1) sq.tail = 0 time.sleep(0.1) # check cq assert cq[0][3] == 0x10004 assert cq[1][3] == 0x10003 assert cq[2][3] == 0 time.sleep(1) assert cq[2][3] == 0 assert cq[3][3] == 0 assert cq[4][3] == 0 logging.debug(sq[0]) logging.debug(cq[0]) sq.delete() cq.delete()
def test_create_sq_with_invalid_prp_offset(nvme0): prp = PRP(4096) cq = IOCQ(nvme0, 1, 10, prp) #Spec NVM-Express-1_4-2019.06.10-Ratified #Figure 153: In both cases, the PRP Entry shall have an offset of 0h. prp.offset = 0 IOSQ(nvme0, 1, 10, prp, cqid=1).delete() prp.offset = 2048 with pytest.warns(UserWarning, match="ERROR status: 00/13"): IOSQ(nvme0, 1, 10, prp, cqid=1).delete() prp.offset = 2050 with pytest.warns(UserWarning, match="ERROR status: 00/13"): IOSQ(nvme0, 1, 10, prp, cqid=1).delete() prp.offset = 4095 with pytest.warns(UserWarning, match="ERROR status: 00/13"): IOSQ(nvme0, 2, 10, prp, cqid=1).delete() prp.offset = 255 with pytest.warns(UserWarning, match="ERROR status: 00/13"): IOSQ(nvme0, 2, 10, prp, cqid=1).delete() cq.delete()
def test_default_round_robin(nvme0): # 1 admin, 8 io queue sq_list = [] cq = IOCQ(nvme0, 1, 1024, PRP(1024*64)) for i in range(8): sq_list.append(IOSQ(nvme0, i+1, 128, PRP(128*64), cqid=1)) # fill 100 flush commands in each queue for sq in sq_list: for i in range(100): sq[i] = SQE(i<<16+0, 1) # fire all sq, low prio first for sq in sq_list: sq.tail = 100 # check the latency of admin command start = time.time() nvme0.getfeatures(7).waitdone() logging.info("admin latency when IO busy: %f" % (time.time()-start)) # check sqid of the whole cq time.sleep(1) logging.debug([cq[i][2]>>16 for i in range(100*8)]) # assert all urgent IO completed first last_sqid = {cq[i][2]>>16 for i in range(700, 800)} assert len(last_sqid) >= 7 # delete all queues for sq in sq_list: sq.delete() cq.delete()
def test_sq_doorbell(nvme0): cq = IOCQ(nvme0, 1, 5, PRP()) sq = IOSQ(nvme0, 1, 2, PRP(), cqid=1) sq.tail = 1 time.sleep(0.1) sq.delete() cq.delete()
def test_create_sq_invalid_queue_address_offset(nvme0): cq = IOCQ(nvme0, 3, 10, PRP(4096)) queue = PRP(4096) queue.offset = 1 with pytest.warns(UserWarning, match="ERROR status: 00/13"): IOSQ(nvme0, 1, 10, queue, cqid=3) cq.delete()
def test_create_sq_physically_contiguous(nvme0): if not nvme0.cap & 0x10000: pytest.skip("pc is not required") cq = IOCQ(nvme0, 2, 10, PRP(4096)) with pytest.warns(UserWarning, match="ERROR status: 00/02"): IOSQ(nvme0, 1, 2, PRP(4096), pc=False, cqid=2) IOSQ(nvme0, 1, 2, PRP(4096), pc=True, cqid=2).delete() cq.delete()
def test_cid_conflict(nvme0): mdts_lba = nvme0.mdts // 512 cq = IOCQ(nvme0, 1, 20, PRP()) sq = IOSQ(nvme0, 1, 20, PRP(), cqid=1) # prp for the long buffer write_buf_1 = PRP(ptype=32, pvalue=0xaaaaaaaa) pages = mdts_lba // 8 pages -= 1 prp_list = PRPList() prp_list_head = prp_list while pages: logging.info(pages) for i in range(63): if pages: prp_list[i] = PRP() pages -= 1 logging.debug(pages) if pages > 1: tmp = PRPList() prp_list[63] = tmp prp_list = tmp logging.debug("prp_list") elif pages == 1: prp_list[63] = PRP() pages -= 1 logging.debug(pages) #send first cmd w1 = SQE((1 << 16) + 1, 1) w1.prp1 = write_buf_1 w1.prp2 = prp_list_head w1[12] = mdts_lba - 1 # 0based, nlba sq[0] = w1 sq[1] = w1 logging.info(sq[0]) logging.info(sq[1]) assert sq[0][0] >> 16 == 1 assert sq[1][0] >> 16 == 1 sq.tail = 2 time.sleep(1) logging.info(cq[0]) logging.info(cq[1]) cqe = CQE(cq[0]) assert cqe.p == 1 status = (cqe[3] >> 17) & 0x3ff assert status == 0 or status == 0x0003 cqe = CQE(cq[1]) assert cqe.p == 1 status = (cqe[3] >> 17) & 0x3ff assert status == 0 or status == 0x0003 cq.head = 2 sq.delete() cq.delete()
def test_sq_doorbell_invalid(nvme0, tail): cq = IOCQ(nvme0, 1, 5, PRP()) sq = IOSQ(nvme0, 1, 2, PRP(), cqid=1) sq.tail = tail time.sleep(0.1) #Invalid Doorbell Write Value with pytest.warns(UserWarning, match="AER notification is triggered: 0x10100"): nvme0.getfeatures(7).waitdone() sq.delete() cq.delete()
def test_sq_reserved(nvme0): cq = IOCQ(nvme0, 1, 3, PRP()) sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1) # Reserved field is non-zero. sq[0] = SQE((1<<16) + (7<<10) + 0, 1); sq.tail = 1; time.sleep(0.1) # check cq time.sleep(0.1) assert cq[0][3] == 0x10001 sq.delete() cq.delete()
def test_sq_fuse_is_zero(nvme0): cq = IOCQ(nvme0, 1, 3, PRP()) sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1) # FUSE field is zero. sq[0] = SQE((1<<16) + (0<<8), 1); sq.tail = 1; time.sleep(0.1) # check cq time.sleep(0.1) assert cq[0][3] == 0x10001 sq.delete() cq.delete()
def test_sq_fuse_is_reserved(nvme0): cq = IOCQ(nvme0, 1, 3, PRP()) sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1) # FUSE field is 0x3(Reserved). sq[0] = SQE((1<<16) + (3<<8), 1); sq.tail = 1; time.sleep(0.1) # check cq time.sleep(0.1) #sct=0,sc=2(Invalid Field in Command) assert cq[0][3]>>17 == 0x0002 sq.delete() cq.delete()
def test_cq_sqhd(nvme0): cq = IOCQ(nvme0, 1, 3, PRP()) sq = IOSQ(nvme0, 1, 2, PRP(), cqid=1) # send commands, and check cqe sq[0] = SQE(4 << 16 + 0, 1) sq.tail = 1 time.sleep(0.1) assert cq[0][2] == 0x10001 assert cq[0][3] == 0x10004 assert cq[1][2] == 0 assert cq[2][2] == 0 # send commands, and check cqe sq[1] = SQE(3 << 16 + 0, 1) sq.tail = 0 time.sleep(0.1) assert cq[0][2] == 0x10001 assert cq[0][3] == 0x10004 assert cq[1][2] == 0x10000 assert cq[1][3] == 0x10003 assert cq[2][2] == 0 # send commands, and check cqe sq[0] = SQE(2 << 16 + 0, 1) sq.tail = 1 time.sleep(0.1) assert cq[0][2] == 0x10001 assert cq[0][3] == 0x10004 assert cq[1][2] == 0x10000 assert cq[1][3] == 0x10003 assert cq[2][2] == 0 # free one cqe before get 3rd cqe cq.head = 1 time.sleep(0.1) assert cq[2][2] == 0x10001 assert cq[2][3] == 0x10002 # send commands, and check cqe sq[1] = SQE(1 << 16 + 0, 1) sq.tail = 0 time.sleep(0.1) cq.head = 2 time.sleep(0.1) assert cq[0][2] == 0x10000 assert cq[0][3] == 0x00001 assert cq[1][2] == 0x10000 assert cq[1][3] == 0x10003 assert cq[2][2] == 0x10001 assert cq[2][3] == 0x10002
def test_sq_cid1(nvme0): cq = IOCQ(nvme0, 1, 3, PRP()) sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1) # send discontinuous cid commands sq[0] = SQE(4<<16+0, 1); sq.tail = 1; time.sleep(0.1) sq[1] = SQE(1<<16+0, 1); sq.tail = 2; time.sleep(0.1) # check cq time.sleep(0.1) assert cq[0][3] == 0x10004 assert cq[1][3] == 0x10001 sq.delete() cq.delete()
def test_controller_cap_mqes(nvme0): mqes = 1+(nvme0.cap&0xffff) logging.info(mqes) assert mqes >= 2 if mqes == 64*1024: pytest.skip("mqes is maximum") with pytest.warns(UserWarning, match="ERROR status: 01/02"): cq = IOCQ(nvme0, 1, mqes+1, PRP()) cq = IOCQ(nvme0, 1, mqes, PRP()) with pytest.warns(UserWarning, match="ERROR status: 01/02"): sq = IOSQ(nvme0, 1, mqes+1, PRP(), cqid=1)
def test_sq_opc_invalid_nvm_cmd(nvme0,opc_id): cq = IOCQ(nvme0, 1, 3, PRP()) sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1) # OPC field is invalid. sq[0] = SQE((1<<16) + opc_id, 1); sq.tail = 1; time.sleep(0.1) # check cq time.sleep(0.1) #sct=0,sc=1(Invalid Command Opcode) assert (cq[0][3]>>17)&0x3ff == 0x0001 sq.delete() cq.delete()
def test_sq_ns_invalid(nvme0,ns_id): cq = IOCQ(nvme0, 1, 3, PRP()) sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1) # ns field is invalid. sq[0] = SQE(2, ns_id); sq.tail = 1; time.sleep(0.1) # check cq time.sleep(0.1) #sct=0,sc=0x0b(Invalid Namespace or Format) assert (cq[0][3]>>17)&0x3ff == 0x000b sq.delete() cq.delete()
def test_sq_cid2(nvme0): cq = IOCQ(nvme0, 1, 3, PRP()) sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1) # send max/min cid commands sq[0] = SQE(0xFFFF<<16+0, 1); sq[1] = SQE(0<<16+0, 1); sq.tail = 2; time.sleep(0.1) # check cq time.sleep(0.1) assert cq[0][3] == 0x1FFFF assert cq[1][3] == 0x10000 sq.delete() cq.delete()
def test_write_mdts(nvme0, mdts): cq = IOCQ(nvme0, 1, 2, PRP()) sq = IOSQ(nvme0, 1, 2, PRP(), cqid=1) # prp for the long buffer write_buf_1 = PRP(ptype=32, pvalue=0xaaaaaaaa) pages = mdts // 8 pages -= 1 prp_list = PRPList() prp_list_head = prp_list while pages: for i in range(511): if pages: prp_list[i] = PRP() pages -= 1 logging.debug(pages) if pages > 1: tmp = PRPList() prp_list[511] = tmp prp_list = tmp logging.debug("prp_list") elif pages == 1: prp_list[511] = PRP() pages -= 1 logging.debug(pages) w1 = SQE(1, 1) w1.prp1 = write_buf_1 w1.prp2 = prp_list_head w1[12] = mdts - 1 # 0based, nlba w1.cid = 0x123 sq[0] = w1 sq.tail = 1 time.sleep(1) cqe = CQE(cq[0]) logging.info(cqe) assert cqe.p == 1 assert cqe.cid == 0x123 assert cqe.sqhd == 1 logging.info("cqe status is {}".format(cqe.status)) assert cqe.status == 0 or cqe.status == 2 cq.head = 1 sq.delete() cq.delete()
def test_weighed_round_robin(nvme0): if (nvme0.cap >> 17) & 0x1 == 0: pytest.skip("WRR is not supported") assert nvme0[0x14] == 0x00460801 nvme0.setfeatures(1, cdw11=0x07030103).waitdone() cdw0 = nvme0.getfeatures(1).waitdone() assert cdw0 == 0x07030103 start = time.time() nvme0.getfeatures(7).waitdone() logging.info("admin latency: %f" % (time.time() - start)) # create the senario of Figure 138 in NVMe spec v1.4 # 1 admin, 2 urgent, 2 high, 2 medium, 2 low sq_list = [] cq = IOCQ(nvme0, 1, 1024, PRP(1024 * 64)) for i in range(8): sq_list.append( IOSQ(nvme0, i + 1, 128, PRP(128 * 64), cqid=1, qprio=i // 2)) # fill 100 flush commands in each queue for sq in sq_list: for i in range(100): sq[i] = SQE(i << 16 + 0, 1) # fire all sq, low prio first for sq in sq_list[::-1]: sq.tail = 100 # check the latency of admin command start = time.time() nvme0.getfeatures(7).waitdone() logging.info("admin latency when IO busy: %f" % (time.time() - start)) # check sqid of the whole cq time.sleep(3) logging.info([cq[i][2] >> 16 for i in range(100 * 8)]) # assert all urgent IO completed first last_sqid = {cq[i][2] >> 16 for i in range(300, 800)} logging.debug(last_sqid) assert 1 not in last_sqid assert 2 not in last_sqid # delete all queues for sq in sq_list: sq.delete() cq.delete()
def _test_cq_sqhd_aer(nvme0, buf): #Create cq and sq a = () cq = IOCQ(nvme0, 1, 5, PRP()) sq = IOSQ(nvme0, 1, 5, PRP(), cqid=1) #Trigger aer cmd response by invaild doorbell write value sq.tail = 5 time.sleep(0.1) #Invalid Doorbell Write Value with pytest.warns(UserWarning, match="AER notification is triggered: 0x10100"): nvme0.waitdone() sq.delete() cq.delete() def call_back_cpl(cpl): nonlocal a a = cpl #Check normal cmd cqe sqhd value nvme0.getlogpage(1, buf, cb=call_back_cpl).waitdone() sqhd1 = a[2] & 0xffff logging.info(sqhd1) nvme0.aer(cb=call_back_cpl) nvme0.getlogpage(1, buf, cb=call_back_cpl).waitdone() sqhd2 = a[2] & 0xffff logging.info(sqhd2) assert sqhd2 == sqhd1 + 2 #Trigger aer cmd response by invaild doorbell write value cq = IOCQ(nvme0, 1, 5, PRP()) sq = IOSQ(nvme0, 1, 5, PRP(), cqid=1) sq.tail = 5 time.sleep(0.1) #Invalid Doorbell Write Value with pytest.warns(UserWarning, match="AER notification is triggered: 0x10100"): nvme0.waitdone() #verify aer cmd cqe sqhd sqhd_aer = a[2] & 0xffff sqhd_aer = sqhd2 + 2 logging.info("aer sqhd is {}".format(sqhd_aer)) sq.delete() cq.delete() #verify the following cmd cqe sqhd nvme0.getlogpage(1, buf, cb=call_back_cpl).waitdone() sqhd3 = a[2] & 0xffff assert sqhd3 == sqhd_aer + 3 logging.info(sqhd3)
def test_pcie_link_control_aspm(nvme0, pcie, aspm): #1:0 linkctrl_addr = pcie.cap_offset(0x10) + 16 linkctrl = pcie.register(linkctrl_addr, 2) logging.info("link control register [0x%x]= 0x%x" % (linkctrl_addr, linkctrl)) # set ASPM control pcie[linkctrl_addr] = (linkctrl & 0xfc) | aspm linkctrl = pcie.register(linkctrl_addr, 2) logging.info("link control register [0x%x]= 0x%x" % (linkctrl_addr, linkctrl)) # IO queue for read commands cq = IOCQ(nvme0, 1, 16, PRP()) sq = IOSQ(nvme0, 1, 16, PRP(), cqid=1) # read lba 0 for 1000 times, interleaved with delays read_cmd = SQE(2, 1) read_cmd.prp1 = PRPList() pbit = 1 for i in range(100): logging.debug(i) slot = i % 16 if slot == 0: pbit = not pbit next_slot = slot + 1 if next_slot == 16: next_slot = 0 sq[slot] = read_cmd sq.tail = next_slot while cq[slot].p == pbit: pass cq.head = next_slot # delay to trigger ASPM time.sleep(0.01) sq.delete() cq.delete() time.sleep(1) #return ASPM L0 pcie[linkctrl_addr] = (linkctrl & 0xfc) | 0
def test_sq_cq_another_sq(nvme0): cq = IOCQ(nvme0, 1, 3, PRP()) # send commands in sq1 sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1) sq[0] = SQE(4 << 16 + 0, 1) sq[1] = SQE(3 << 16 + 0, 1) sq.tail = 2 sq2 = IOSQ(nvme0, 2, 3, PRP(), cqid=1) sq2[0] = SQE(2 << 16 + 0, 1) sq2[1] = SQE(1 << 16 + 0, 1) sq2.tail = 2 # check cq time.sleep(0.1) assert cq[0][3] == 0x10004 assert cq[1][3] == 0x10003 assert cq[2][3] == 0 cq.head = 1 time.sleep(0.1) assert cq[2][3] == 0x10002 assert cq[0][3] == 0x10004 cq.head = 2 time.sleep(0.1) assert cq[0][3] == 0x00001 sq.delete() sq2.delete() cq.delete()
def test_sq_cq_around(nvme0): cq = IOCQ(nvme0, 1, 3, PRP()) sq = IOSQ(nvme0, 1, 2, PRP(), cqid=1) # send commands sq[0] = SQE(4<<16+0, 1); sq.tail = 1 sq[1] = SQE(3<<16+0, 1); sq.tail = 0 sq[0] = SQE(2<<16+0, 1); sq.tail = 1 sq[1] = SQE(1<<16+0, 1); sq.tail = 0 # check cq time.sleep(0.1) assert cq[0][3] == 0x10004 assert cq[1][3] == 0x10003 assert cq[2][3] == 0 cq.head = 1 assert cq[0][3] == 0x10004 assert cq[2][3] == 0x10002 cq.head = 2 assert cq[2][3] == 0x10002 assert cq[1][3] == 0x10003 assert cq[0][3] == 0x00001 sq.delete() cq.delete()
def test_controller_cc_en(nvme0): en=nvme0[0x14]&0x1 logging.info("en:{}".format(en)) logging.info("cc:{}".format(nvme0[0x14])) assert nvme0[0x14] == 0x00460001 cq = IOCQ(nvme0, 1, 3, PRP()) sq = IOSQ(nvme0, 1, 3, PRP(), cqid=1) sq[0] = SQE(2, 1); sq.tail = 1; time.sleep(0.1) # check cq time.sleep(0.1) assert (cq[0][3]>>17)&0x3ff == 0x0000 sq.delete() cq.delete() #change cc.en from '1' to '0' nvme0[0x14] = 0 #wait csts.rdy change from '1' to '0' while not (nvme0[0x1c]&0x1)==0: pass nvme0.aer() try: nvme0.waitdone() except Exception as e: logging.warning(e) if 0 != nvme0.init_adminq(): raise NvmeEnumerateError("fail to init admin queue") #change cc.en from '0' to '1' nvme0[0x14] = 0x00460001 #wait csts.rdy change from '0' to '1' while not (nvme0[0x1c]&0x1)==1: pass assert nvme0[0x14] ==0x00460001
def test_invalid_offset_prp_in_list(nvme0): cq = IOCQ(nvme0, 1, 10, PRP()) sq = IOSQ(nvme0, 1, 10, PRP(), cqid=1) buf = PRP(ptype=32, pvalue=0xffffffff) buf.offset = 0x10 prp_list = PRPList() prp_list.offset = 0x20 for i in range(8): tmp = PRP(ptype=32, pvalue=0xffffffff) tmp.offset = 0x10 prp_list[i] = tmp logging.info(prp_list.dump(64)) print(buf.dump(32)) for i in range(8): print(prp_list[i].dump(32)) cmd = SQE(2, 1) cmd.prp1 = buf cmd.prp2 = prp_list cmd[12] = 0x4000001f sq[0] = cmd logging.info(sq[0]) sq.tail = 1 while CQE(cq[0]).p == 0: pass cq.head = 1 logging.info(cq[0]) logging.info(hex(cq[0][3] >> 17)) print(buf.dump(32)) for i in range(8): print(prp_list[i].dump(32)) status = (cq[0][3] >> 17) & 0x3ff assert status == 0x0013 or status == 0 sq.delete() cq.delete()
def test_create_cq_invalid_interrupt_vector(nvme0, pcie): msicap_addr = pcie.cap_offset(0x05) msicap = pcie.register(msicap_addr, 4) logging.info("MSI Enable: %d" % ((msicap >> 16) & 0x1)) logging.info("Multiple Message Capable: %d" % ((msicap >> 17) & 0x7)) logging.info("Multiple Message Enable: %d" % ((msicap >> 20) & 0x7)) if ((msicap >> 20) & 0x7): invalid_iv = ((msicap >> 17) & 0x7) + 2 logging.info("invalid_iv: %d" % invalid_iv) msixcap_addr = pcie.cap_offset(0x11) msixcap = pcie.register(msixcap_addr, 4) logging.info("Table Size: %d" % ((msixcap >> 16) & 0x3ff)) logging.info("MSI-X Enable: %d" % ((msixcap >> 31) & 0x1)) if ((msixcap >> 31) & 0x1): invalid_iv = ((msixcap >> 16) & 0x3ff) + 2 logging.info("invalid_iv: %d" % invalid_iv) with pytest.warns(UserWarning, match="ERROR status: 01/08"): IOCQ(nvme0, 1, 10, PRP(4096), iv=invalid_iv, ien=True) with pytest.warns(UserWarning, match="ERROR status: 01/08"): IOCQ(nvme0, 1, 10, PRP(4096), iv=2047, ien=True)