def Write(self): """ Writes the buffer to address "self.address" :return: """ if self.data: page_offset = self.offset data_begin = 0 assert (self.num_pages == len(self.slabs)) for i in range(self.num_pages): page_bytes = min(self.page_size, (self.size - data_begin)) - page_offset start_addr = self.slabs[i].address + page_offset page_offset = 0 mem_handle = objects.MemHandle( start_addr, resmgr.HostMemoryAllocator.v2p(start_addr)) resmgr.HostMemoryAllocator.write(mem_handle, (bytes( self.data))[data_begin:data_begin + page_bytes]) logger.info("Writing Buffer[%d] @0x%x = size: %d " % (i, start_addr, page_bytes)) data_begin += page_bytes else: logger.info( "Warning:!! buffer is not bound to an address, Write is ignored !!" )
def Read(self): """ Reads a Descriptor from "self.address" :return: """ self.phy_address = resmgr.HostMemoryAllocator.v2p(self.address) mem_handle = objects.MemHandle(self.address, self.phy_address) desc = NvmeCqDescriptor(resmgr.HostMemoryAllocator.read( mem_handle, 64)) logger.ShowScapyObject(desc)
def Init(self, spec): #self.LockAttributes() if (GlobalOptions.dryrun): return self.size = spec.fields.size if hasattr(spec.fields, 'size') else 0 self.offset = spec.fields.offset if hasattr(spec.fields, 'offset') else 0 self.address = spec.fields.slab.address if spec.fields.slab else 0 self.address += self.offset if self.address: self.mem_handle = objects.MemHandle( self.address, resmgr.HostMemoryAllocator.v2p(self.address)) logger.info("Creating Nvme Xfer @0x%x = size: %d offset: %d " % (self.address, self.size, self.offset))
def Read(self): """ Reads a Descriptor from "self.address" :return: """ if self.mem_handle: self.phy_address = resmgr.HostMemoryAllocator.v2p(self.address) mem_handle = objects.MemHandle(self.address, self.phy_address) desc = NvmeTcprqDescriptor( resmgr.HostMemoryAllocator.read(mem_handle, 64)) else: hbm_addr = self.address desc = NvmeTcprqDescriptor(model_wrap.read_mem(hbm_addr, 64)) logger.ShowScapyObject(desc)
def Post(self, descriptor, debug = True): #if not self.initialized: # self.queue.qstate.set_ring_base(self.address) # self.queue.qstate.set_ring_size(self.size) # Bind the descriptor to the ring if debug is True: logger.info('posting descriptor at pindex: %d..' %(self.queue.qstate.get_pindex(0))) descriptor.address = (self.address + (self.desc_size * self.queue.qstate.get_pindex(0))) # pass q_max_desc_size to the descriptor object so that it can check and assert to see # if generated descritptor size is within the limits of q_max_desc_size to avoid # memory overwrite descriptor.q_max_desc_size = self.desc_size if self.nic_resident: descriptor.mem_handle = None else: descriptor.mem_handle = objects.MemHandle(descriptor.address, resmgr.HostMemoryAllocator.v2p(descriptor.address)) descriptor.Write(self.qp_spec_en) logger.info('incrementing pindex..') self.queue.qstate.incr_pindex(0, self.size)
def Consume(self, descriptor, debug = True): if debug is True: logger.info("Consuming descriptor on Queue(%s) Ring at cindex: %d" % (self.queue.queue_type.purpose.upper(), self.queue.qstate.get_cindex(0))) if self.queue.queue_type.purpose.upper() == "LIF_QUEUE_PURPOSE_RDMA_RECV": descriptor.address = (self.address + (self.desc_size * self.queue.qstate.get_proxy_cindex())) elif self.queue.queue_type.purpose.upper() == "LIF_QUEUE_PURPOSE_RDMA_SEND": descriptor.address = (self.address + (self.desc_size * ((self.queue.qstate.get_cindex(0) - 1) & (self.size - 1)))) else: descriptor.address = (self.address + (self.desc_size * self.queue.qstate.get_cindex(0))) if (self.nic_resident): descriptor.mem_handle = None else: descriptor.mem_handle = objects.MemHandle(descriptor.address, resmgr.HostMemoryAllocator.v2p(descriptor.address)) descriptor.Read() self.queue.qstate.Read() # Increment consumer index for CQs and EQs if ((self.queue.queue_type.purpose.upper() == "LIF_QUEUE_PURPOSE_CQ") or (self.queue.queue_type.purpose.upper() == "LIF_QUEUE_PURPOSE_EQ")): logger.info('incrementing cindex..') self.queue.qstate.incr_cindex(0, self.size)
def Init(self, spec): #self.LockAttributes() super().Init(spec) if (GlobalOptions.dryrun): return self.buffer_type = spec.buffer_type if hasattr(spec, 'buffer_type') else 0 if self.buffer_type == 1: sq_buffer = RdmaQuerySqBuffer( rnr_timer=spec.fields.rnr_timer, retry_timeout=spec.fields.retry_timeout, access_perms_flags=0, access_perms_rsvd=0, qkey_dest_qpn=spec.fields.qkey_dest_qpn, rate_limit_kbps=0, pkey_id=0, rq_psn=spec.fields.rq_psn) rq_buffer = RdmaQueryRqBuffer(state=spec.fields.state, pmtu=spec.fields.pmtu, retry_cnt=spec.fields.retry_cnt, rnr_retry=spec.fields.rnr_retry, rrq_depth=spec.fields.rrq_depth, rsq_depth=spec.fields.rsq_depth, sq_psn=spec.fields.sq_psn, ah_id_len=spec.fields.ah_id_len) hdr_buffer = spec.fields.hdr_data buffer = sq_buffer / rq_buffer / hdr_buffer self.data = bytes(buffer) self.size = len(buffer) logger.info("Creating Rdma Query Buffer size: %d " % (self.size)) logger.ShowScapyObject(sq_buffer) logger.ShowScapyObject(rq_buffer) logger.ShowScapyObject(hdr_buffer) elif self.buffer_type == 2: hdr_buffer = spec.fields.hdr_data self.data = bytes(hdr_buffer) self.size = len(hdr_buffer) logger.info("Creating Rdma Query AH Buffer size: %d " % (self.size)) logger.ShowScapyObject(hdr_buffer) else: if hasattr(spec.fields, 'segments'): for segment in spec.fields.segments: skip_bytes = segment.skip if hasattr(segment, 'skip') else 0 offset = segment.offset if hasattr(segment, 'offset') else 0 self.size += (segment.size - skip_bytes) if hasattr( segment, 'size') else 0 self.data += segment.data[offset:len(segment.data) - skip_bytes] if ( hasattr(segment, 'data') and segment.data) else [] #handle segment.offset #self.size = spec.fields.size if hasattr(spec.fields, 'size') else 0 #self.data = spec.fields.data if hasattr(spec.fields, 'data') else [] # Offset of the data self.slab_id = spec.fields.slab self.offset = spec.fields.offset if hasattr(spec.fields, 'offset') else 0 self.address = spec.fields.slab.address if spec.fields.slab else 0 self.address += self.offset if self.address: self.mem_handle = objects.MemHandle( self.address, resmgr.HostMemoryAllocator.v2p(self.address)) self.phy_address = resmgr.HostMemoryAllocator.v2p(self.address) logger.info( "Creating Rdma Buffer @0x%x = phy_address: 0x%x size: %d offset: %d " % (self.address, self.phy_address, self.size, self.offset))
def Write(self): """ Creates a Descriptor at "self.address" :return: """ opc = self.spec.fields.opc if opc in (NVME_OPC_FLUSH, NVME_OPC_WRITE, NVME_OPC_READ, NVME_OPC_WRITE_UNC, NVME_OPC_WRITE_ZEROES): #requires data to be specified if hasattr(self.spec.fields, 'data'): data_buffer = self.spec.fields.data else: logger.error( "Error!! nvme buffer needs to be specified for the descriptor" ) return self.prp1 = data_buffer.phy_pages[0] num_pages = data_buffer.num_pages if num_pages == 2: self.prp2 = data_buffer.phy_pages[1] #prepare PRP list page elif num_pages > 2: if hasattr(self.spec.fields, "prp2_offset"): prp2_offset = self.spec.fields.prp2_offset assert prp2_offset < data_buffer.page_size - 8 else: prp2_offset = 0 prp2_entries = (data_buffer.page_size - prp2_offset) / 8 prp2_begin = 1 prp2_end = (int)(min(prp2_entries, num_pages - 1)) logger.info( "PRP2 begin: %d, PRP2 end: %d, PRP2 offset: %d, prp2_entries: %d" % (prp2_begin, prp2_end, prp2_offset, prp2_entries)) prp3_required = 0 #prp3 required if prp2_end < num_pages - 1: prp3_required = 1 prp2_end -= 1 prp3_begin = (int)(prp2_end + 1) prp3_entries = num_pages - prp2_end - 1 prp3_end = (int)(num_pages - 1) assert prp3_end > prp3_begin prp3_offset = 0 logger.info( "PRP3 begin: %d, PRP3 end: %d, PRP3 offset: %d, prp3_entries: %d" % (prp3_begin, prp3_end, prp3_offset, prp3_entries)) prp3_slab = self.nvme_session.lif.GetNextSlab() logger.info( "Slab with address 0x%x allocated for PRP3 list" % (prp3_slab.address)) self.prp3 = resmgr.HostMemoryAllocator.v2p( prp3_slab.address) data = [] for i in range(prp3_begin, prp3_end + 1): data += data_buffer.phy_pages[i].to_bytes(8, 'little') print("%s" % (data)) mem_handle = objects.MemHandle( prp3_slab.address + prp3_offset, resmgr.HostMemoryAllocator.v2p(prp3_slab.address + prp3_offset)) resmgr.HostMemoryAllocator.write(mem_handle, bytes(data)) prp2_slab = self.nvme_session.lif.GetNextSlab() logger.info("Slab with address 0x%x allocated for PRP2 list" % (prp2_slab.address)) self.prp2 = resmgr.HostMemoryAllocator.v2p(prp2_slab.address + prp2_offset) data = [] for i in range(prp2_begin, prp2_end + 1): data += data_buffer.phy_pages[i].to_bytes(8, 'little') print("%s" % (data)) if prp3_required: data += resmgr.HostMemoryAllocator.v2p( prp3_slab.address).to_bytes(8, "little") print("%s" % (data)) mem_handle = objects.MemHandle( prp2_slab.address + prp2_offset, resmgr.HostMemoryAllocator.v2p(prp2_slab.address + prp2_offset)) resmgr.HostMemoryAllocator.write(mem_handle, bytes(data)) desc = NvmeSqDescriptorBase(opc=self.spec.fields.opc, cid=self.spec.fields.cid, nsid=self.spec.fields.nsid, prp1=self.prp1, prp2=self.prp2) logger.ShowScapyObject(desc) self.desc = desc if hasattr(self.spec.fields, 'write'): slba = self.spec.fields.write.slba if hasattr( self.spec.fields.write, 'slba') else 0 nlb = self.spec.fields.write.nlb if hasattr( self.spec.fields.write, 'nlb') else 0 write = NvmeSqDescriptorWrite(slba=slba, nlb=nlb) self.desc = self.desc / write logger.ShowScapyObject(write) logger.info("desc_size = %d" % (len(self.desc))) resmgr.HostMemoryAllocator.write(self.mem_handle, bytes(self.desc))