class Test (unittest.TestCase): def setUp(self): self.s = Status() plat = ["", None, None] pscanner = PlatformScanner() platform_dict = pscanner.get_platforms() platform_names = platform_dict.keys() if "sim" in platform_names: #If sim is in the platforms, move it to the end platform_names.remove("sim") platform_names.append("sim") urn = None for platform_name in platform_names: if plat[1] is not None: break self.s.Debug("Platform: %s" % str(platform_name)) platform_instance = platform_dict[platform_name](self.s) #self.s.Verbose("Platform Instance: %s" % str(platform_instance)) instances_dict = platform_instance.scan() for name in instances_dict: #s.Verbose("Found Platform Item: %s" % str(platform_item)) n = instances_dict[name] plat = ["", None, None] if n is not None: self.s.Important("Found a nysa instance: %s" % name) n.read_sdb() #import pdb; pdb.set_trace() if n.is_device_in_platform(DRIVER): plat = [platform_name, name, n] break continue #self.s.Verbose("\t%s" % psi) if plat[1] is None: self.sata_drv = None return n = plat[2] self.n = n sata_urn = n.find_device(DRIVER)[0] dma_urn = n.find_device(DMA)[0] self.memory_urn = self.n.find_device(Memory)[0] self.sata_drv = DRIVER(n, sata_urn) self.dma = DMA(n, dma_urn) self.s.set_level("verbose") self.s.Info("Using Platform: %s" % plat[0]) self.s.Info("Instantiated a SATA Device: %s" % sata_urn) self.s.Info("Instantiated a DMA Device: %s" % dma_urn) def test_dma_sata(self): if self.sata_drv is None: self.s.Fatal("Cannot Run Test when no device is found!") return self.s.Info("Reseting Hard Drive...") self.sata_drv.enable_sata_reset(True) time.sleep(0.5) self.sata_drv.enable_sata_reset(False) time.sleep(0.75) self.s.Info("Reset Complete") if self.sata_drv.is_linkup(): self.s.Important("Linked up with Hard Drive!") self.s.Info("\tInitial Status of hard drive (Status): 0x%02X" % self.sata_drv.get_d2h_status()) if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Warning("\tReceived 0 for status of hard drive, sending reset!") self.s.Warning ("Sending reset command to hard drive") self.sata_drv.send_hard_drive_command(0x08) if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Warning("Still Received 0x00 after reset, send a sequence of identify commands to get hard drive into known state") for i in range (32): self.sata_drv.send_hard_drive_command(0xEC) if (self.sata_drv.get_d2h_status() & 0x040) > 0: print "Found!" break if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Warning("Did not get a normal status response from the hard drive attempting soft reset") time.sleep(0.1) self.sata_drv.enable_sata_command_layer_reset(True) time.sleep(0.1) self.sata_drv.enable_sata_command_layer_reset(False) self.sata_drv.send_hard_drive_command(0x00) if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Error("After Soft Reset Still Did not get a good response") sys.exit(1) self.sata_drv.identify_hard_drive() config = self.sata_drv.get_config() self.s.Verbose("Hard Drive Serial Number: %s" % config.serial_number()) max_user_lba = config.max_user_sectors() self.s.Verbose("Max User Sectors: %d" % config.max_user_sectors()) self.s.Verbose("Max User Size (GB): %f" % ((config.max_user_sectors() * 512.0) * 0.000000001)) #Clear out a block of memory values = Array('B') clear_values = Array('B') for i in range (2048 * 4): values.append(i % 256) clear_values.append(0) self.sata_drv.set_local_buffer_write_size(128) self.sata_drv.write_local_buffer(clear_values) self.sata_drv.load_local_buffer() self.sata_drv.hard_drive_write(0x0000, 1) print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status() print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count() print "\tSATA Current Address: 0x%08X" % self.sata_drv.get_hard_drive_lba() self.sata_drv.hard_drive_read(0x0000, 1) data = self.sata_drv.read_local_buffer() #self.s.Verbose("Data from Hard Drive Before DMA Transfer (Should be all zeros):") #print str(data[0:128]) self.sata_drv.enable_dma_control(True) self.s.Info("Setup DMA") self.dma.setup() self.dma.enable_dma(True) #DMA Configuration CHANNEL_ADDR = 2 SINK_ADDR = 0 INST_ADDR = 0 DDR3_ADDRESS = 0x0000000000000000 SATA_ADDRESS = 0x0000000000000000 #WORD_TRANSFER_COUNT = 0x1000 #WORD_TRANSFER_COUNT = 0x800 #WORD_TRANSFER_COUNT = 2048 #Rarely Failed: #WORD_TRANSFER_COUNT = 0x2000 #WORD_TRANSFER_COUNT = 0x16000 WORD_TRANSFER_COUNT = 0x0A00000 #WORD_TRANSFER_COUNT = 0x100000 #WORD_TRANSFER_COUNT = 0xF00000 #WORD_TRANSFER_COUNT = 0x800000 #WORD_TRANSFER_COUNT = 0x900000 #WORD_TRANSFER_COUNT = 0xB00000 MEGABYTES = (WORD_TRANSFER_COUNT * 4.0) / 1000000.0 self.s.Info ("Transfer Size: 0x%08X" % WORD_TRANSFER_COUNT) #Clear SATA self.clear_memory() #Fill Memory With Data self.s.Important("Fill memory with zeros") self.s.Important("Configure DMA to transfer %f MB from DDR3 to Hard Drive" % MEGABYTES) #self.fill_memory_with_pattern() self.dma.enable_channel (CHANNEL_ADDR, False ) #Configure DMA to transfer 100MB of data from DDR3 to hard drive self.dma.set_channel_sink_addr (CHANNEL_ADDR, SINK_ADDR ) self.dma.set_channel_instruction_pointer (CHANNEL_ADDR, INST_ADDR ) self.dma.enable_source_address_increment (CHANNEL_ADDR, True ) self.dma.enable_dest_address_increment (SINK_ADDR, True ) self.dma.enable_dest_respect_quantum (SINK_ADDR, True ) self.dma.set_instruction_source_address (INST_ADDR, DDR3_ADDRESS ) self.dma.set_instruction_dest_address (INST_ADDR, SATA_ADDRESS ) self.dma.set_instruction_data_count (INST_ADDR, WORD_TRANSFER_COUNT ) #This is only needed if we are going to another instruction after this self.dma.set_instruction_next_instruction (INST_ADDR, INST_ADDR ) self.dma.enable_instruction_continue (INST_ADDR, False ) #Initate DMA Transaction self.s.Important("Intiate a DMA Transaction") self.dma.enable_interrupt_when_command_finished(True) self.dma.enable_channel (CHANNEL_ADDR, True ) #Transaction Complete self.s.Important("DMA Transaction is complete") #self.dma.wait_for_interrupts(wait_time = 10) self.s.Info ("Wait for transaction to finish") fail = False timeout = time.time() + TIMEOUT self.sata_drv.hard_drive_read(0x0000, 1) data = self.sata_drv.read_local_buffer() self.s.Verbose("Data from first sector of hard drive (Should be all zeros):") print str(data[0:128]) self.sata_drv.enable_dma_control(True) print ("") #Fill Memory With Data self.s.Important("Fill memory with pattern") self.s.Important("Configure DMA to transfer %f MB from DDR3 to Hard Drive" % MEGABYTES) self.fill_memory_with_pattern() self.dma.enable_channel (CHANNEL_ADDR, False ) #Configure DMA to transfer 100MB of data from DDR3 to hard drive self.dma.set_channel_sink_addr (CHANNEL_ADDR, SINK_ADDR ) self.dma.set_channel_instruction_pointer (CHANNEL_ADDR, INST_ADDR ) self.dma.enable_source_address_increment (CHANNEL_ADDR, True ) self.dma.enable_dest_address_increment (SINK_ADDR, True ) self.dma.enable_dest_respect_quantum (SINK_ADDR, True ) self.dma.set_instruction_source_address (INST_ADDR, DDR3_ADDRESS ) self.dma.set_instruction_dest_address (INST_ADDR, SATA_ADDRESS ) self.dma.set_instruction_data_count (INST_ADDR, WORD_TRANSFER_COUNT ) #This is only needed if we are going to another instruction after this self.dma.set_instruction_next_instruction (INST_ADDR, INST_ADDR ) self.dma.enable_instruction_continue (INST_ADDR, False ) #Initate DMA Transaction self.s.Important("Intiate a DMA Transaction") self.dma.enable_interrupt_when_command_finished(True) self.dma.enable_channel (CHANNEL_ADDR, True ) #Transaction Complete self.s.Important("DMA Transaction is complete") #self.dma.wait_for_interrupts(wait_time = 10) self.s.Info ("Wait for transaction to finish") fail = False timeout = time.time() + TIMEOUT ''' self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) print "\tCurrent SATA DMA Address: 0x%08X" % self.dma.get_current_sink_address(SINK_ADDR) print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status() print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count() status = self.dma.get_channel_status(CHANNEL_ADDR) print "\tFinished: %s" % str(((status & 0x04) > 0)) print "\tStatus: 0x%08X" % status ''' while not self.dma.is_channel_finished(CHANNEL_ADDR): #while (self.dma.get_current_sink_address(SINK_ADDR) - SATA_ADDRESS) >= WORD_TRANSFER_COUNT: print ".", if time.time() > timeout: print "" self.s.Error("Timeout Occured!") fail = True break if fail: self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) return self.s.Info ("Transaction Finished!") print "\tCurrent SATA DMA Address: 0x%08X" % self.dma.get_current_sink_address(SINK_ADDR) print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status() print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count() #self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) self.dma.enable_channel (CHANNEL_ADDR, False ) self.sata_drv.enable_dma_control (False) self.sata_drv.hard_drive_read(0x0000, 1) data = self.sata_drv.read_local_buffer() self.s.Verbose("Data from first sector of the hard drive (Should be incrementing number patter):") print str(data[0:128]) self.sata_drv.enable_dma_control(True) #Clear DDR3 Memory self.s.Important("Clear DDR3 Memory") self.clear_memory() data = self.n.read_memory(0x00, 128) self.s.Verbose("Data read from memory after clear (Should be all zeros):") print str(data[0:128]) #Configure DMA to transfer 100MB of data from hard drive to DDR3 CHANNEL_ADDR = 0 SINK_ADDR = 2 self.s.Important("Configure DMA to transfer %f MB from Hard Drive to DDR3" % MEGABYTES) self.dma.set_channel_sink_addr (CHANNEL_ADDR, SINK_ADDR ) self.dma.set_channel_instruction_pointer (CHANNEL_ADDR, INST_ADDR ) self.dma.enable_source_address_increment (CHANNEL_ADDR, True ) self.dma.enable_dest_address_increment (SINK_ADDR, True ) #self.dma.enable_dest_respect_quantum (SINK_ADDR, True ) self.dma.enable_dest_respect_quantum (SINK_ADDR, False ) self.dma.set_instruction_source_address (INST_ADDR, SATA_ADDRESS ) self.dma.set_instruction_dest_address (INST_ADDR, SATA_ADDRESS ) self.dma.set_instruction_data_count (INST_ADDR, WORD_TRANSFER_COUNT ) #This is only needed if we are going to another instruction after this self.dma.set_instruction_next_instruction (INST_ADDR, INST_ADDR ) self.dma.enable_instruction_continue (INST_ADDR, False ) #Initate DMA Transaction self.s.Important("Intiate a DMA Transaction") self.dma.enable_interrupt_when_command_finished(True) self.dma.enable_channel (CHANNEL_ADDR, True ) #Transaction Complete self.s.Important("DMA Transaction is complete") #self.dma.wait_for_interrupts(wait_time = 10) self.s.Info ("Wait for transaction to finish (Timeout: %d)" % TIMEOUT) timeout = time.time() + TIMEOUT fail = False while not self.dma.is_channel_finished(CHANNEL_ADDR): print ".", if time.time() > timeout: print "" self.s.Error("Timeout Occured!") fail = True break if fail: self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) return self.s.Info ("Transaction Finished!") print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count() #Transaction Complete self.s.Important("DMA Transaction is complete") #Verify values of memory are correct self.s.Important("Verify values of DDR3 are correct") data = self.n.read_memory(0x00, 128) self.s.Verbose("Data read from memory after clear (Should be all incrementing number pattern):") print str(data[0:128]) #self.verify_memory_pattern() self.s.Verbose("Put Hard Drive to Sleep") self.sata_drv.hard_drive_sleep() def fail_analysis(self, channel, sink, instruction_addr): status = self.dma.get_channel_status(channel) source_ready = ((status & 0x200) >> 9) source_activate = ((status & 0x100) >> 8) sink_ready = ((status & 0xC0) >> 6) sink_activate = ((status & 0x30) >> 4) if channel == 0: self.s.Warning("Hard Drive -> DDR3") if ((source_ready == 0) and (source_activate == 0)): self.s.Error("*** HARD DRIVE STALL! ****") elif ((sink_ready == 0) and (sink_activate == 0)): self.s.Error("***DMA STALL! *****") elif channel == 2: self.s.Warning("DDR3 -> Hard Drive") if ((source_ready == 0) and (source_activate == 0)): self.s.Error("***DMA STALL! *****") elif ((sink_ready == 0) and (sink_activate == 0)): self.s.Error("*** HARD DRIVE STALL! ****") print "Channel Status: 0x%08X" % status print "\tDMA Enabled: %s" % str(((status & 0x01) > 0)) print "\tBusy: %s" % str(((status & 0x02) > 0)) print "\tFinished: %s" % str(((status & 0x04) > 0)) print "\tSink Error Conflict: %s" % str(((status & 0x08) > 0)) print "\tSink Activate: 0x%02X" % sink_activate print "\tSink Ready: 0x%02X" % sink_ready print "\tSource Activate: 0x%02X" % source_activate print "\tSource Ready: 0x%02X" % source_ready print "\tInstruction Count: 0x%08X" % self.dma.get_instruction_data_count(instruction_addr) print "\tInstruction Dest Addr 0x%016X" % self.dma.get_instruction_dest_address(instruction_addr) print "\tInstruction Source Addr0x%016X" % self.dma.get_instruction_source_address(instruction_addr) print"" print "\tDMA Request Ingress Address: 0x%08X" % self.dma.get_channel_sink_addr(channel) print "\tSATA Current Address: 0x%08X" % self.sata_drv.get_hard_drive_lba() print "\tDMA Request Egress Address: 0x%08X" % self.dma.get_instruction_dest_address(instruction_addr) print "\tCurrent SATA DMA Address: 0x%08X" % self.dma.get_current_sink_address(sink) print "" print "\tSATA Command Layer Write State: %d" % self.sata_drv.get_cmd_wr_state() print "\tSATA Transport State: %d" % self.sata_drv.get_transport_state() print "\tSATA Link Layer State: %d" % self.sata_drv.get_link_layer_write_state() print "" print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status() print "\tSATA Current Address: 0x%08X" % self.sata_drv.get_hard_drive_lba() print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count() print "\tDMA Channel State: %s" % self.dma.get_debug_channel_state(channel) def fill_memory_with_pattern(self): position = 0 #self.clear_memory() total_size = self.n.get_device_size(self.memory_urn) size = 0 if total_size > MAX_LONG_SIZE: self.s.Verbose("Memory Size: 0x%08X is larger than write size" % total_size) self.s.Verbose("\tBreaking transaction into 0x%08X chunks" % MAX_LONG_SIZE) size = MAX_LONG_SIZE else: size = total_size #Write Data Out data_out = Array('B') for i in range (0, size): data_out.append((i % 0x100)) while position < total_size: self.n.write_memory(position, data_out) #Increment the position prev_pos = position if position + size > total_size: size = total_size - position position += size self.s.Verbose("Wrote: 0x%08X - 0x%08X" % (prev_pos, position)) def verify_memory_pattern(self): #Read status = "Passed" fail = False fail_count = 0 total_size = self.n.get_device_size(self.memory_urn) position = 0 size = 0 data_out = Array('B') for i in range (0, size): data_out.append((i % 0x100)) if total_size > MAX_LONG_SIZE: self.s.Verbose("Memory Size: 0x%08X is larger than write size" % total_size) self.s.Verbose("\tBreaking transaction into 0x%08X chunks" % MAX_LONG_SIZE) size = MAX_LONG_SIZE else: size = total_size while (position < total_size) and fail_count < 257: data_in = self.n.read_memory(position, size / 4) if size != len(data_in): self.s.Error("Data in length not equal to data_out length") self.s.Error("\toutgoing: %d" % size) self.s.Error("\tincomming: %d" % len(data_in)) dout = data_out.tolist() din = data_in.tolist() for i in range(len(data_out)): out_val = dout[i] in_val = din[i] if out_val != in_val: fail = True status = "Failed" self.s.Error("Mismatch @ 0x%08X: Write: (Hex): 0x%08X Read (Hex): 0x%08X" % (position + i, data_out[i], data_in[i])) if fail_count >= 16: break fail_count += 1 prev_pos = position if (position + size) > total_size: size = total_size - position position += size self.s.Verbose("Read: 0x%08X - 0x%08X" % (prev_pos, position)) return status def clear_memory(self): total_size = self.n.get_device_size(self.memory_urn) position = 0 size = 0 self.s.Verbose("Clearing Memory") self.s.Verbose("Memory Size: 0x%08X" % size) if total_size > MAX_LONG_SIZE: self.s.Verbose("Memory Size: 0x%08X is larger than read/write size" % total_size) self.s.Verbose("\tBreaking transaction into 0x%08X chunks" % MAX_LONG_SIZE) size = MAX_LONG_SIZE else: size = total_size while position < total_size: data_out = Array('B') for i in range(0, ((size / 4) - 1)): num = 0x00 data_out.append(num) self.n.write_memory(position, data_out) #Increment the position prev_pos = position if position + size > total_size: size = total_size - position position += size self.s.Verbose ("Cleared: 0x%08X - 0x%08X" % (prev_pos, position))
class Test(unittest.TestCase): def setUp(self): self.s = Status() plat = ["", None, None] pscanner = PlatformScanner() platform_dict = pscanner.get_platforms() platform_names = platform_dict.keys() if "sim" in platform_names: #If sim is in the platforms, move it to the end platform_names.remove("sim") platform_names.append("sim") urn = None for platform_name in platform_names: if plat[1] is not None: break self.s.Debug("Platform: %s" % str(platform_name)) platform_instance = platform_dict[platform_name](self.s) #self.s.Verbose("Platform Instance: %s" % str(platform_instance)) instances_dict = platform_instance.scan() for name in instances_dict: #s.Verbose("Found Platform Item: %s" % str(platform_item)) n = instances_dict[name] plat = ["", None, None] if n is not None: self.s.Important("Found a nysa instance: %s" % name) n.read_sdb() #import pdb; pdb.set_trace() if n.is_device_in_platform(DRIVER): plat = [platform_name, name, n] break continue #self.s.Verbose("\t%s" % psi) if plat[1] is None: self.sata_drv = None return n = plat[2] self.n = n sata_urn = n.find_device(DRIVER)[0] dma_urn = n.find_device(DMA)[0] self.memory_urn = self.n.find_device(Memory)[0] self.sata_drv = DRIVER(n, sata_urn) self.dma = DMA(n, dma_urn) self.s.set_level("verbose") self.s.Info("Using Platform: %s" % plat[0]) self.s.Info("Instantiated a SATA Device: %s" % sata_urn) self.s.Info("Instantiated a DMA Device: %s" % dma_urn) def test_dma_sata(self): if self.sata_drv is None: self.s.Fatal("Cannot Run Test when no device is found!") return self.s.Info("Reseting Hard Drive...") self.sata_drv.enable_sata_reset(True) time.sleep(0.5) self.sata_drv.enable_sata_reset(False) time.sleep(0.75) self.s.Info("Reset Complete") if self.sata_drv.is_linkup(): self.s.Important("Linked up with Hard Drive!") self.s.Info("\tInitial Status of hard drive (Status): 0x%02X" % self.sata_drv.get_d2h_status()) if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Warning( "\tReceived 0 for status of hard drive, sending reset!") self.s.Warning("Sending reset command to hard drive") self.sata_drv.send_hard_drive_command(0x08) if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Warning( "Still Received 0x00 after reset, send a sequence of identify commands to get hard drive into known state" ) for i in range(32): self.sata_drv.send_hard_drive_command(0xEC) if (self.sata_drv.get_d2h_status() & 0x040) > 0: print "Found!" break if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Warning( "Did not get a normal status response from the hard drive attempting soft reset" ) time.sleep(0.1) self.sata_drv.enable_sata_command_layer_reset(True) time.sleep(0.1) self.sata_drv.enable_sata_command_layer_reset(False) self.sata_drv.send_hard_drive_command(0x00) if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Error( "After Soft Reset Still Did not get a good response" ) sys.exit(1) self.sata_drv.identify_hard_drive() config = self.sata_drv.get_config() self.s.Verbose("Hard Drive Serial Number: %s" % config.serial_number()) max_user_lba = config.max_user_sectors() self.s.Verbose("Max User Sectors: %d" % config.max_user_sectors()) self.s.Verbose("Max User Size (GB): %f" % ((config.max_user_sectors() * 512.0) * 0.000000001)) #Clear out a block of memory values = Array('B') clear_values = Array('B') for i in range(2048 * 4): values.append(i % 256) clear_values.append(0) self.sata_drv.set_local_buffer_write_size(128) self.sata_drv.write_local_buffer(clear_values) self.sata_drv.load_local_buffer() self.sata_drv.hard_drive_write(0x0000, 1) print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status( ) print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count( ) print "\tSATA Current Address: 0x%08X" % self.sata_drv.get_hard_drive_lba( ) self.sata_drv.hard_drive_read(0x0000, 1) data = self.sata_drv.read_local_buffer() #self.s.Verbose("Data from Hard Drive Before DMA Transfer (Should be all zeros):") #print str(data[0:128]) self.sata_drv.enable_dma_control(True) self.s.Info("Setup DMA") self.dma.setup() self.dma.enable_dma(True) #DMA Configuration CHANNEL_ADDR = 2 SINK_ADDR = 0 INST_ADDR = 0 DDR3_ADDRESS = 0x0000000000000000 SATA_ADDRESS = 0x0000000000000000 #WORD_TRANSFER_COUNT = 0x1000 #WORD_TRANSFER_COUNT = 0x800 #WORD_TRANSFER_COUNT = 2048 #Rarely Failed: #WORD_TRANSFER_COUNT = 0x2000 #WORD_TRANSFER_COUNT = 0x16000 WORD_TRANSFER_COUNT = 0x0A00000 #WORD_TRANSFER_COUNT = 0x100000 #WORD_TRANSFER_COUNT = 0xF00000 #WORD_TRANSFER_COUNT = 0x800000 #WORD_TRANSFER_COUNT = 0x900000 #WORD_TRANSFER_COUNT = 0xB00000 MEGABYTES = (WORD_TRANSFER_COUNT * 4.0) / 1000000.0 self.s.Info("Transfer Size: 0x%08X" % WORD_TRANSFER_COUNT) #Clear SATA self.clear_memory() #Fill Memory With Data self.s.Important("Fill memory with zeros") self.s.Important( "Configure DMA to transfer %f MB from DDR3 to Hard Drive" % MEGABYTES) #self.fill_memory_with_pattern() self.dma.enable_channel(CHANNEL_ADDR, False) #Configure DMA to transfer 100MB of data from DDR3 to hard drive self.dma.set_channel_sink_addr(CHANNEL_ADDR, SINK_ADDR) self.dma.set_channel_instruction_pointer(CHANNEL_ADDR, INST_ADDR) self.dma.enable_source_address_increment(CHANNEL_ADDR, True) self.dma.enable_dest_address_increment(SINK_ADDR, True) self.dma.enable_dest_respect_quantum(SINK_ADDR, True) self.dma.set_instruction_source_address(INST_ADDR, DDR3_ADDRESS) self.dma.set_instruction_dest_address(INST_ADDR, SATA_ADDRESS) self.dma.set_instruction_data_count(INST_ADDR, WORD_TRANSFER_COUNT) #This is only needed if we are going to another instruction after this self.dma.set_instruction_next_instruction(INST_ADDR, INST_ADDR) self.dma.enable_instruction_continue(INST_ADDR, False) #Initate DMA Transaction self.s.Important("Intiate a DMA Transaction") self.dma.enable_interrupt_when_command_finished(True) self.dma.enable_channel(CHANNEL_ADDR, True) #Transaction Complete self.s.Important("DMA Transaction is complete") #self.dma.wait_for_interrupts(wait_time = 10) self.s.Info("Wait for transaction to finish") fail = False timeout = time.time() + TIMEOUT self.sata_drv.hard_drive_read(0x0000, 1) data = self.sata_drv.read_local_buffer() self.s.Verbose( "Data from first sector of hard drive (Should be all zeros):") print str(data[0:128]) self.sata_drv.enable_dma_control(True) print("") #Fill Memory With Data self.s.Important("Fill memory with pattern") self.s.Important( "Configure DMA to transfer %f MB from DDR3 to Hard Drive" % MEGABYTES) self.fill_memory_with_pattern() self.dma.enable_channel(CHANNEL_ADDR, False) #Configure DMA to transfer 100MB of data from DDR3 to hard drive self.dma.set_channel_sink_addr(CHANNEL_ADDR, SINK_ADDR) self.dma.set_channel_instruction_pointer(CHANNEL_ADDR, INST_ADDR) self.dma.enable_source_address_increment(CHANNEL_ADDR, True) self.dma.enable_dest_address_increment(SINK_ADDR, True) self.dma.enable_dest_respect_quantum(SINK_ADDR, True) self.dma.set_instruction_source_address(INST_ADDR, DDR3_ADDRESS) self.dma.set_instruction_dest_address(INST_ADDR, SATA_ADDRESS) self.dma.set_instruction_data_count(INST_ADDR, WORD_TRANSFER_COUNT) #This is only needed if we are going to another instruction after this self.dma.set_instruction_next_instruction(INST_ADDR, INST_ADDR) self.dma.enable_instruction_continue(INST_ADDR, False) #Initate DMA Transaction self.s.Important("Intiate a DMA Transaction") self.dma.enable_interrupt_when_command_finished(True) self.dma.enable_channel(CHANNEL_ADDR, True) #Transaction Complete self.s.Important("DMA Transaction is complete") #self.dma.wait_for_interrupts(wait_time = 10) self.s.Info("Wait for transaction to finish") fail = False timeout = time.time() + TIMEOUT ''' self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) print "\tCurrent SATA DMA Address: 0x%08X" % self.dma.get_current_sink_address(SINK_ADDR) print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status() print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count() status = self.dma.get_channel_status(CHANNEL_ADDR) print "\tFinished: %s" % str(((status & 0x04) > 0)) print "\tStatus: 0x%08X" % status ''' while not self.dma.is_channel_finished(CHANNEL_ADDR): #while (self.dma.get_current_sink_address(SINK_ADDR) - SATA_ADDRESS) >= WORD_TRANSFER_COUNT: print ".", if time.time() > timeout: print "" self.s.Error("Timeout Occured!") fail = True break if fail: self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) return self.s.Info("Transaction Finished!") print "\tCurrent SATA DMA Address: 0x%08X" % self.dma.get_current_sink_address( SINK_ADDR) print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status( ) print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count( ) #self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) self.dma.enable_channel(CHANNEL_ADDR, False) self.sata_drv.enable_dma_control(False) self.sata_drv.hard_drive_read(0x0000, 1) data = self.sata_drv.read_local_buffer() self.s.Verbose( "Data from first sector of the hard drive (Should be incrementing number patter):" ) print str(data[0:128]) self.sata_drv.enable_dma_control(True) #Clear DDR3 Memory self.s.Important("Clear DDR3 Memory") self.clear_memory() data = self.n.read_memory(0x00, 128) self.s.Verbose( "Data read from memory after clear (Should be all zeros):") print str(data[0:128]) #Configure DMA to transfer 100MB of data from hard drive to DDR3 CHANNEL_ADDR = 0 SINK_ADDR = 2 self.s.Important( "Configure DMA to transfer %f MB from Hard Drive to DDR3" % MEGABYTES) self.dma.set_channel_sink_addr(CHANNEL_ADDR, SINK_ADDR) self.dma.set_channel_instruction_pointer(CHANNEL_ADDR, INST_ADDR) self.dma.enable_source_address_increment(CHANNEL_ADDR, True) self.dma.enable_dest_address_increment(SINK_ADDR, True) #self.dma.enable_dest_respect_quantum (SINK_ADDR, True ) self.dma.enable_dest_respect_quantum(SINK_ADDR, False) self.dma.set_instruction_source_address(INST_ADDR, SATA_ADDRESS) self.dma.set_instruction_dest_address(INST_ADDR, SATA_ADDRESS) self.dma.set_instruction_data_count(INST_ADDR, WORD_TRANSFER_COUNT) #This is only needed if we are going to another instruction after this self.dma.set_instruction_next_instruction(INST_ADDR, INST_ADDR) self.dma.enable_instruction_continue(INST_ADDR, False) #Initate DMA Transaction self.s.Important("Intiate a DMA Transaction") self.dma.enable_interrupt_when_command_finished(True) self.dma.enable_channel(CHANNEL_ADDR, True) #Transaction Complete self.s.Important("DMA Transaction is complete") #self.dma.wait_for_interrupts(wait_time = 10) self.s.Info("Wait for transaction to finish (Timeout: %d)" % TIMEOUT) timeout = time.time() + TIMEOUT fail = False while not self.dma.is_channel_finished(CHANNEL_ADDR): print ".", if time.time() > timeout: print "" self.s.Error("Timeout Occured!") fail = True break if fail: self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) return self.s.Info("Transaction Finished!") print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count( ) #Transaction Complete self.s.Important("DMA Transaction is complete") #Verify values of memory are correct self.s.Important("Verify values of DDR3 are correct") data = self.n.read_memory(0x00, 128) self.s.Verbose( "Data read from memory after clear (Should be all incrementing number pattern):" ) print str(data[0:128]) #self.verify_memory_pattern() self.s.Verbose("Put Hard Drive to Sleep") self.sata_drv.hard_drive_sleep() def fail_analysis(self, channel, sink, instruction_addr): status = self.dma.get_channel_status(channel) source_ready = ((status & 0x200) >> 9) source_activate = ((status & 0x100) >> 8) sink_ready = ((status & 0xC0) >> 6) sink_activate = ((status & 0x30) >> 4) if channel == 0: self.s.Warning("Hard Drive -> DDR3") if ((source_ready == 0) and (source_activate == 0)): self.s.Error("*** HARD DRIVE STALL! ****") elif ((sink_ready == 0) and (sink_activate == 0)): self.s.Error("***DMA STALL! *****") elif channel == 2: self.s.Warning("DDR3 -> Hard Drive") if ((source_ready == 0) and (source_activate == 0)): self.s.Error("***DMA STALL! *****") elif ((sink_ready == 0) and (sink_activate == 0)): self.s.Error("*** HARD DRIVE STALL! ****") print "Channel Status: 0x%08X" % status print "\tDMA Enabled: %s" % str(((status & 0x01) > 0)) print "\tBusy: %s" % str(((status & 0x02) > 0)) print "\tFinished: %s" % str(((status & 0x04) > 0)) print "\tSink Error Conflict: %s" % str(((status & 0x08) > 0)) print "\tSink Activate: 0x%02X" % sink_activate print "\tSink Ready: 0x%02X" % sink_ready print "\tSource Activate: 0x%02X" % source_activate print "\tSource Ready: 0x%02X" % source_ready print "\tInstruction Count: 0x%08X" % self.dma.get_instruction_data_count( instruction_addr) print "\tInstruction Dest Addr 0x%016X" % self.dma.get_instruction_dest_address( instruction_addr) print "\tInstruction Source Addr0x%016X" % self.dma.get_instruction_source_address( instruction_addr) print "" print "\tDMA Request Ingress Address: 0x%08X" % self.dma.get_channel_sink_addr( channel) print "\tSATA Current Address: 0x%08X" % self.sata_drv.get_hard_drive_lba( ) print "\tDMA Request Egress Address: 0x%08X" % self.dma.get_instruction_dest_address( instruction_addr) print "\tCurrent SATA DMA Address: 0x%08X" % self.dma.get_current_sink_address( sink) print "" print "\tSATA Command Layer Write State: %d" % self.sata_drv.get_cmd_wr_state( ) print "\tSATA Transport State: %d" % self.sata_drv.get_transport_state( ) print "\tSATA Link Layer State: %d" % self.sata_drv.get_link_layer_write_state( ) print "" print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status( ) print "\tSATA Current Address: 0x%08X" % self.sata_drv.get_hard_drive_lba( ) print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count( ) print "\tDMA Channel State: %s" % self.dma.get_debug_channel_state( channel) def fill_memory_with_pattern(self): position = 0 #self.clear_memory() total_size = self.n.get_device_size(self.memory_urn) size = 0 if total_size > MAX_LONG_SIZE: self.s.Verbose("Memory Size: 0x%08X is larger than write size" % total_size) self.s.Verbose("\tBreaking transaction into 0x%08X chunks" % MAX_LONG_SIZE) size = MAX_LONG_SIZE else: size = total_size #Write Data Out data_out = Array('B') for i in range(0, size): data_out.append((i % 0x100)) while position < total_size: self.n.write_memory(position, data_out) #Increment the position prev_pos = position if position + size > total_size: size = total_size - position position += size self.s.Verbose("Wrote: 0x%08X - 0x%08X" % (prev_pos, position)) def verify_memory_pattern(self): #Read status = "Passed" fail = False fail_count = 0 total_size = self.n.get_device_size(self.memory_urn) position = 0 size = 0 data_out = Array('B') for i in range(0, size): data_out.append((i % 0x100)) if total_size > MAX_LONG_SIZE: self.s.Verbose("Memory Size: 0x%08X is larger than write size" % total_size) self.s.Verbose("\tBreaking transaction into 0x%08X chunks" % MAX_LONG_SIZE) size = MAX_LONG_SIZE else: size = total_size while (position < total_size) and fail_count < 257: data_in = self.n.read_memory(position, size / 4) if size != len(data_in): self.s.Error("Data in length not equal to data_out length") self.s.Error("\toutgoing: %d" % size) self.s.Error("\tincomming: %d" % len(data_in)) dout = data_out.tolist() din = data_in.tolist() for i in range(len(data_out)): out_val = dout[i] in_val = din[i] if out_val != in_val: fail = True status = "Failed" self.s.Error( "Mismatch @ 0x%08X: Write: (Hex): 0x%08X Read (Hex): 0x%08X" % (position + i, data_out[i], data_in[i])) if fail_count >= 16: break fail_count += 1 prev_pos = position if (position + size) > total_size: size = total_size - position position += size self.s.Verbose("Read: 0x%08X - 0x%08X" % (prev_pos, position)) return status def clear_memory(self): total_size = self.n.get_device_size(self.memory_urn) position = 0 size = 0 self.s.Verbose("Clearing Memory") self.s.Verbose("Memory Size: 0x%08X" % size) if total_size > MAX_LONG_SIZE: self.s.Verbose( "Memory Size: 0x%08X is larger than read/write size" % total_size) self.s.Verbose("\tBreaking transaction into 0x%08X chunks" % MAX_LONG_SIZE) size = MAX_LONG_SIZE else: size = total_size while position < total_size: data_out = Array('B') for i in range(0, ((size / 4) - 1)): num = 0x00 data_out.append(num) self.n.write_memory(position, data_out) #Increment the position prev_pos = position if position + size > total_size: size = total_size - position position += size self.s.Verbose("Cleared: 0x%08X - 0x%08X" % (prev_pos, position))