Commit fcb4bd93 authored by Andrey Filippov's avatar Andrey Filippov

This version tested with AHCI controller

parent 035f9e57
...@@ -52,87 +52,87 @@ ...@@ -52,87 +52,87 @@
<link> <link>
<name>vivado_logs/VivadoBitstream.log</name> <name>vivado_logs/VivadoBitstream.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160229185157261.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160304130042850.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOpt.log</name> <name>vivado_logs/VivadoOpt.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160229185157261.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160304130042850.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOptPhys.log</name> <name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160229185157261.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160304130042850.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOptPower.log</name> <name>vivado_logs/VivadoOptPower.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160229185157261.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160304130042850.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoPlace.log</name> <name>vivado_logs/VivadoPlace.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160229185157261.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160304130042850.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoRoute.log</name> <name>vivado_logs/VivadoRoute.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160229185157261.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160304130042850.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoSynthesis.log</name> <name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160229184939748.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160304125744608.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name> <name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160229185157261.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160304130042850.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name> <name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160229184939748.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160304125744608.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimingReportImplemented.log</name> <name>vivado_logs/VivadoTimingReportImplemented.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160229185157261.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160304130042850.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name> <name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160229184939748.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160304125744608.log</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-opt-phys.dcp</name> <name>vivado_state/x393_sata-opt-phys.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160229185157261.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160304130042850.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-opt-power.dcp</name> <name>vivado_state/x393_sata-opt-power.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160229185157261.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160304130042850.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-opt.dcp</name> <name>vivado_state/x393_sata-opt.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160229185157261.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160304130042850.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-place.dcp</name> <name>vivado_state/x393_sata-place.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160229185157261.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160304130042850.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-route.dcp</name> <name>vivado_state/x393_sata-route.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160229185157261.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160304130042850.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-synth.dcp</name> <name>vivado_state/x393_sata-synth.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160229184939748.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160304125744608.dcp</location>
</link> </link>
</linkedResources> </linkedResources>
</projectDescription> </projectDescription>
...@@ -342,7 +342,7 @@ localparam DATA_TYPE_ERR = 3; ...@@ -342,7 +342,7 @@ localparam DATA_TYPE_ERR = 3;
if (reg_we_w) reg_data <= hba_data_in; if (reg_we_w) reg_data <= hba_data_in;
else if (update_err_sts_r) reg_data <= {16'b0,tf_err_sts}; else if (update_err_sts_r) reg_data <= {16'b0,tf_err_sts};
else if (update_sig_r) reg_data <= sig_r; else if (update_sig_r) reg_data <= sig_r;
else if (update_prdbc_r) reg_data <= {xfer_cntr_r[31:2],2'b0}; else if (update_prdbc_r) reg_data <= {prdbc_r[31:2],2'b0}; // xfer_cntr_r[31:2],2'b0};
if (store_sig[1]) sig_r[31:8] <= hba_data_in[23:0]; if (store_sig[1]) sig_r[31:8] <= hba_data_in[23:0];
if (store_sig[3]) sig_r[ 7:0] <= hba_data_in[ 7:0]; if (store_sig[3]) sig_r[ 7:0] <= hba_data_in[ 7:0];
......
...@@ -1295,9 +1295,9 @@ debug_dma_h2d ...@@ -1295,9 +1295,9 @@ debug_dma_h2d
debug_in_link[23], debug_in_link[23],
datascope_id[2:0], {12-ADDRESS_BITS{1'b0}}, datascope_waddr_r}); datascope_id[2:0], {12-ADDRESS_BITS{1'b0}}, datascope_waddr_r});
always @(posedge mclk) begin always @(posedge mclk) begin
if (fsnd_cfis_xmit) datascope_waddr_r <= DATASCOPE_CFIS_START; // start from command FIS if (fsnd_cfis_xmit) datascope_waddr_r <= DATASCOPE_CFIS_START; // start from command FIS
/// if (mrst) datascope_waddr_r <= DATASCOPE_CFIS_START; /// if (mrst) datascope_waddr_r <= DATASCOPE_CFIS_START;
else if (datascope_we) datascope_waddr_r <= datascope_waddr_r + 1; else if (datascope_we && !(&datascope_waddr_r)) datascope_waddr_r <= datascope_waddr_r + 1;
end end
`else `else
......
...@@ -850,6 +850,19 @@ task send_identify_data; // @SuppressThisWarning VEditor - Used in testbench ...@@ -850,6 +850,19 @@ task send_identify_data; // @SuppressThisWarning VEditor - Used in testbench
end end
endtask endtask
task send_incrementing_data; // @SuppressThisWarning VEditor - Used in testbench
input integer id;
input integer len;
output integer status;
integer i;
begin
transmit_data[0] = FIS_DATA;
for (i=0;i<len;i=i+1) begin
transmit_data[i+1] = i;
end
linkTransmitFIS(id, 129, 0, status);
end
endtask
......
/******************************************************************************* /*******************************************************************************
* Module: action_decoder * Module: action_decoder
* Date:2016-02-29 * Date:2016-03-03
* Author: auto-generated file, see ahci_fsm_sequence.py * Author: auto-generated file, see ahci_fsm_sequence.py
* Description: Decode sequencer code to 1-hot actions * Description: Decode sequencer code to 1-hot actions
*******************************************************************************/ *******************************************************************************/
......
/******************************************************************************* /*******************************************************************************
* Module: condition_mux * Module: condition_mux
* Date:2016-02-29 * Date:2016-03-03
* Author: auto-generated file, see ahci_fsm_sequence.py * Author: auto-generated file, see ahci_fsm_sequence.py
* Description: Select condition * Description: Select condition
*******************************************************************************/ *******************************************************************************/
......
...@@ -57,6 +57,14 @@ class x393_vsc3304(object): ...@@ -57,6 +57,14 @@ class x393_vsc3304(object):
"SSD_B": "F", "SSD_B": "F",
"ZYNQ_A": "G", "ZYNQ_A": "G",
"ZYNQ_B": "H"}, "ZYNQ_B": "H"},
"10389S": { #testing with the wrong adapter
"INVERTED_PORTS": ("C","E","G","H"),
"ESATA_A": "C",
"ESATA_B": "A",
"SSD_A": "E",
"SSD_B": "F",
"ZYNQ_A": "G",
"ZYNQ_B": "H"},
} }
PORT_NUM = {"A":{"OUT": 8,"IN":12}, # I/O port numbers for each port name PORT_NUM = {"A":{"OUT": 8,"IN":12}, # I/O port numbers for each port name
"B":{"OUT": 9,"IN":13}, "B":{"OUT": 9,"IN":13},
...@@ -77,6 +85,9 @@ class x393_vsc3304(object): ...@@ -77,6 +85,9 @@ class x393_vsc3304(object):
"ZYNQ<->ESATA":[{"FROM": "ZYNQ_A", "TO": "ESATA_A" }, "ZYNQ<->ESATA":[{"FROM": "ZYNQ_A", "TO": "ESATA_A" },
{"FROM": "ESATA_B", "TO": "ZYNQ_B"}], {"FROM": "ESATA_B", "TO": "ZYNQ_B"}],
#Temporarily, testing with wrong adapter (swapped ESATA_A and ESATA_B)
"ZYNQ<->SSATA":[{"FROM": "ZYNQ_A", "TO": "ESATA_B" },
{"FROM": "ESATA_A", "TO": "ZYNQ_B"}],
"DEBUG_SSD": [{"FROM": "ZYNQ_A", "TO": "SSD_A" }, "DEBUG_SSD": [{"FROM": "ZYNQ_A", "TO": "SSD_A" },
{"FROM": "SSD_B", "TO": "ZYNQ_B"}, {"FROM": "SSD_B", "TO": "ZYNQ_B"},
...@@ -188,6 +199,9 @@ class x393_vsc3304(object): ...@@ -188,6 +199,9 @@ class x393_vsc3304(object):
def connect_zynq_esata(self): def connect_zynq_esata(self):
self.connect("ZYNQ<->ESATA") self.connect("ZYNQ<->ESATA")
def connect_zynq_ssata(self):
self.connect("ZYNQ<->SSATA")
def connect_debug(self): def connect_debug(self):
self.connect("DEBUG_SSD") self.connect("DEBUG_SSD")
......
...@@ -85,6 +85,7 @@ COMMAND_HEADER0_OFFS = 0x800 # offset of the command header 0 in MAXI1 space ...@@ -85,6 +85,7 @@ COMMAND_HEADER0_OFFS = 0x800 # offset of the command header 0 in MAXI1 space
COMMAND_BUFFER_OFFSET = 0x10 # Simulating offset in the AHCI driver COMMAND_BUFFER_OFFSET = 0x10 # Simulating offset in the AHCI driver
COMMAND_BUFFER_SIZE = 0x100 # 256 bytes - 128 before PRDT, 128+ - PRDTs (16 bytes each) COMMAND_BUFFER_SIZE = 0x100 # 256 bytes - 128 before PRDT, 128+ - PRDTs (16 bytes each)
PRD_OFFSET = 0x80 # Start of the PRD table PRD_OFFSET = 0x80 # Start of the PRD table
PRD_SIZE = 0x10 # PRD entry size
FB_OFFS = 0xc00 # Needs 0x100 bytes FB_OFFS = 0xc00 # Needs 0x100 bytes
DRP_OFFS = 0xfec # Read/Write DRP data [31] - write/ready, [30:16] - address/0, [15:0] - data to/data from DRP_OFFS = 0xfec # Read/Write DRP data [31] - write/ready, [30:16] - address/0, [15:0] - data to/data from
DBG_OFFS = 0xff0 # and 3 next DWORDS DBG_OFFS = 0xff0 # and 3 next DWORDS
...@@ -144,8 +145,11 @@ ATA_WDMA = 0xca # Write to device in DMA mode ...@@ -144,8 +145,11 @@ ATA_WDMA = 0xca # Write to device in DMA mode
ATA_WBUF_PIO = 0xe8 # Write 512 bytes to device buffer in PIO mode ATA_WBUF_PIO = 0xe8 # Write 512 bytes to device buffer in PIO mode
ATA_WBUF_DMA = 0xeb # Write 512 bytes to device buffer in DMA mode ATA_WBUF_DMA = 0xeb # Write 512 bytes to device buffer in DMA mode
ATA_RDMA = 0xc8 # Read from device in DMA mode ATA_RDMA = 0xc8 # Read from device in DMA mode
ATA_RDMA_EXT = 0x25 # Read DMA devices that support 48-bit Addressing
ATA_RBUF_PIO = 0xe4 # Read 512 bytes from device buffer in PIO mode ATA_RBUF_PIO = 0xe4 # Read 512 bytes from device buffer in PIO mode
ATA_RBUF_DMA = 0xe9 # Read 512 bytes from device buffer in DMA mode ATA_RBUF_DMA = 0xe9 # Read 512 bytes from device buffer in DMA mode
ATA_READ_LOG_EXT = 0x2f
class x393sata(object): class x393sata(object):
DRY_MODE= True # True DRY_MODE= True # True
...@@ -683,6 +687,269 @@ class x393sata(object): ...@@ -683,6 +687,269 @@ class x393sata(object):
self.sync_for_cpu('D2H',DATAIN_ADDRESS + IDENTIFY_BUF, 512) self.sync_for_cpu('D2H',DATAIN_ADDRESS + IDENTIFY_BUF, 512)
print("_=mem.mem_dump (0x%x, 0x100, 2)"%(DATAIN_ADDRESS + IDENTIFY_BUF)) print("_=mem.mem_dump (0x%x, 0x100, 2)"%(DATAIN_ADDRESS + IDENTIFY_BUF))
self.x393_mem.mem_dump (DATAIN_ADDRESS + IDENTIFY_BUF, 0x100,2) self.x393_mem.mem_dump (DATAIN_ADDRESS + IDENTIFY_BUF, 0x100,2)
def read_log_ext(self, lba, count = 1, cntrl = 0, do_not_start = False, prd_irqs = None): #TODO: Add multi-PRD testing
"""
run 'read log ext' command, as driver was doing it
@param lba - lba parameter
@param count - number of blocks to read
@param cntrl - cntrl parameter (was sending 0xa0 - all obsolete bits)
@param do_not_start - do not actually launch the command by writing 1 to command_issue (CI) bit in PxCI register
@param prd_irqs - None or a tuple/list with per-PRD interrupts
"""
if lba > (1 << 24):
raise ValueError ("This program supports only 24-bit LBA")
if count > 256:
raise ValueError ("This program supports only 8 bit count")
# Clear interrupt register
self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxIS'), 0xffffffff)
# clear system memory for the command
self.sync_for_cpu('H2D',COMMAND_ADDRESS, 256) # command and PRD table
for a in range(64):
self.x393_mem.write_mem(COMMAND_ADDRESS + 4*a, 0)
#Setup command table in system memory
self.x393_mem.write_mem(COMMAND_ADDRESS + 0,
FIS_H2DR | # FIS type - H2D register (0x27)
(0x80 << 8) | # set C = 1
(ATA_READ_LOG_EXT << 16) | # Command = 0x27EC (IDFY)
( 0 << 24)) # features = 0 ?
"""
0x80000800:0001 PRDTL==1
0005 CFISL = 5
00000000 2e200010 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x2e200010:00
2f Command
80 (Bit 15: `: Command register - 0 Device control register)
27 RFIS H2D
a0 Device?
00
0830 LBA 15:0
00000000
08 CONTROL = 8
000001 COUNT = 1
00000000
00000005 00000006 00000007 00000008 00000009 0000000a 0000000b
0x2e200040:0000000c 0000000d 0000000e 0000000f 00000010 00000011 00000012 00000013 00000014 00000015 00000016 00000017 00000018 00000019 0000001a 0000001b
0x2e200080:0000001c 0000001d 0000001e 0000001f
+0x80: 24d7e680 00000000 00000022 000001ff
"""
self.x393_mem.write_mem(COMMAND_ADDRESS + 4, lba | (0xa0 << 24)) # LBA 24 bits and device (how driver sent it)
self.x393_mem.write_mem(COMMAND_ADDRESS + 12, count & 0xff | (cntrl << 24)) # count field (0 means 256 blocks)
# Other DWORDs are reserved/0 for this command
# Set PRDT (single item) TODO: later check multiple small ones
self.x393_mem.write_mem(COMMAND_ADDRESS + PRD_OFFSET + (0 << 2), DATAIN_ADDRESS)
prdt_int = 0
if prd_irqs:
prdt_int = (0,1)[prd_irqs[0]]
self.x393_mem.write_mem(COMMAND_ADDRESS + PRD_OFFSET + (3 << 2), (prdt_int << 31) | ((count * 512) -1)) # count * 512 bytes in this PRDT)
# Setup command header
self.x393_mem.write_mem(MAXI1_ADDR + COMMAND_HEADER0_OFFS + (0 << 2),
(5 << 0) | # 'CFL' - number of DWORDs in this CFIS
(0 << 5) | # 'A' Not ATAPI
(0 << 6) | # 'W' Not write to device
(0 << 7) | # 'P' Prefetchable = 1
(0 << 8) | # 'R' Not a Reset
(0 << 9) | # 'B' Not a BIST
(0 << 10) | # 'C' Do clear BSY/CI after transmitting this command
(1 << 16)) # 'PRDTL' - number of PRDT entries (just one)
self.x393_mem.write_mem(MAXI1_ADDR + COMMAND_HEADER0_OFFS + (2 << 2),
(COMMAND_ADDRESS)) # 'CTBA' - Command table base address
# (COMMAND_ADDRESS) & 0xffffffc0) # 'CTBA' - Command table base address
self.sync_for_device('H2D',COMMAND_ADDRESS, 256) # command and PRD table
self.sync_for_device('D2H',DATAIN_ADDRESS , count * 512)
# Make it flush (dumb way - write each cache line (32 bytes) something?
# for i in range (4096):
# self.x393_mem.write_mem(COMMAND_ADDRESS + 32 * i, self.x393_mem.read_mem(COMMAND_ADDRESS + 32 * i))
# print("Running flush_mem()")
# self.flush_mem() # Did not worked, caused error
#mem.write_mem(0x80000118,0x11)
# Set PxCMD.ST bit (it may already be set)
self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxCMD'), 0x11) # .ST and .FRE bits (FRE is readonly 1 anyway)
# Set Command Issued
if do_not_start:
print ('Run the following command to start the comand:')
print("mem.write_mem(sata.get_reg_address('HBA_PORT__PxCI'), 1)")
else:
self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxCI'), 1)
print("Command table data:")
print("_=mem.mem_dump (0x%x, 0x10,4)"%(COMMAND_ADDRESS))
self.x393_mem.mem_dump (COMMAND_ADDRESS, 0x20,4)
#Wait interrupt
for r in range(10):
istat = self.x393_mem.read_mem(self.get_reg_address('HBA_PORT__PxIS'))
if istat:
self.parse_register(group_range = ['HBA_PORT__PxIS'],
skip0 = True,
dword = None)
if (istat & 2) != 2: #DHRS interrupt (for DMA - 1)
print ("\n ======================Got wrong interrupt ============================")
self.reg_status()
print("_=mem.mem_dump (0x%x, 0x4,4)"%(MAXI1_ADDR + DBG_OFFS))
self.x393_mem.mem_dump (MAXI1_ADDR + DBG_OFFS, 0x4,4)
print("Datascope (debug) data:")
print("_=mem.mem_dump (0x%x, 0x20,4)"%(DATASCOPE_ADDR))
self.x393_mem.mem_dump (DATASCOPE_ADDR, 0xa0,4)
dd =0
for a in range(0x80001000,0x80001014,4):
dd |= self.x393_mem.read_mem(a)
if dd == 0:
print ("*** Probably got cache/write buffer problem, continuing ***")
break
raise Exception("Failed to get interrupt")
break
sleep(0.1)
else:
print ("\n ====================== Failed to get interrupt ============================")
self.reg_status()
print("_=mem.mem_dump (0x%x, 0x4,4)"%(MAXI1_ADDR + DBG_OFFS))
self.x393_mem.mem_dump (MAXI1_ADDR + DBG_OFFS, 0x4,4)
print("Datascope (debug) data:")
print("_=mem.mem_dump (0x%x, 0x100,4)"%(DATASCOPE_ADDR))
self.x393_mem.mem_dump (DATASCOPE_ADDR, 0x200,4)
raise Exception("Failed to get interrupt")
print("Datascope (debug) data:")
print("_=mem.mem_dump (0x%x, 0x200,4)"%(DATASCOPE_ADDR))
self.x393_mem.mem_dump (DATASCOPE_ADDR, 0x200,4)
print("Memory read data:")
self.sync_for_cpu('D2H',DATAIN_ADDRESS, count * 512)
print("_=mem.mem_dump (0x%x, 0x%x, 1)"%(DATAIN_ADDRESS, count * 0x200))
self.x393_mem.mem_dump (DATAIN_ADDRESS, count * 0x200, 1)
#ATA_RDMA_EXT = 0x25 # Read DMA devices that support 48-bit Addressing
#Reproducing multi-block command that failed from the driver
def dd_read_dma_ext(self, lba, chunk_size= 4096, xfer_size= 0x30000, do_not_start = False, prd_irqs = None):
"""
Read device to memory, use multi PRD table
@param lba - start block number
@param chunk_size - Size of each memory chunk pointed by a single PRD entry
@param xfer_size - Total data size to be read
@param do_not_start - do not actually launch the command by writing 1 to command_issue (CI) bit in PxCI register
@param prd_irqs - None or a tuple/list with per-PRD interrupts
"""
features = 0
device = 0xe0
control = 0x08
icc = 0
aux = 0
# Round up the xfer size to integer number of logical sectors
lbs = 512 #logical block size)
count = -(-xfer_size // lbs)
xfer_size = count * lbs
nprds = -(-xfer_size // chunk_size) # last chunk may be partial
cmd_size = PRD_OFFSET + PRD_SIZE * nprds;
print("count = 0x%08x"%(count))
print("xfer_size = 0x%08x"%(xfer_size))
# Clear interrupt register
self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxIS'), 0xffffffff)
# sync system memory for the command
self.sync_for_cpu('H2D',COMMAND_ADDRESS, cmd_size) # command and PRD table
for a in range(cmd_size//4):
self.x393_mem.write_mem(COMMAND_ADDRESS + 4*a, 0)
#Setup command table in system memory
self.x393_mem.write_mem(COMMAND_ADDRESS + 0,
FIS_H2DR | # FIS type - H2D register (0x27)
(0x80 << 8) | # set C = 1
(ATA_RDMA_EXT << 16) | # Command = 0x25
((features & 0xff) << 24)) # features = 0
self.x393_mem.write_mem(COMMAND_ADDRESS + 4, (lba & 0xffffff) | (device << 24)) # LBA 24 low bits
self.x393_mem.write_mem(COMMAND_ADDRESS + 8, ((lba >> 24) & 0xffffff) | (((features>>8) & 0xff) << 24)) # LBA 24 high bits
self.x393_mem.write_mem(COMMAND_ADDRESS + 12, (count & 0xffff) | (icc << 16) | (control << 24)) # count
self.x393_mem.write_mem(COMMAND_ADDRESS + 16, aux & 0xffff) # count field (0 means 65536 logical blocks)
# Set PRDT entries
left = xfer_size
n = 0
while left > 0:
self.x393_mem.write_mem(COMMAND_ADDRESS + PRD_OFFSET + PRD_SIZE * n + (0 << 2), DATAIN_ADDRESS + chunk_size * n)
self.x393_mem.write_mem(COMMAND_ADDRESS + PRD_OFFSET + PRD_SIZE * n + (1 << 2), 0) # data chunk address , bits[63:32]
this_size = min(chunk_size, left)
prdt_int = 0
if prd_irqs and (len(prd_irqs) > n):
prdt_int = (0,1)[prd_irqs[n]]
self.x393_mem.write_mem(COMMAND_ADDRESS + PRD_OFFSET + PRD_SIZE * n + (3 << 2), (prdt_int << 31) | (this_size - 1))
left -= this_size
n += 1
# Setup command header
self.x393_mem.write_mem(MAXI1_ADDR + COMMAND_HEADER0_OFFS + (0 << 2),
(5 << 0) | # 'CFL' - number of DWORDs in this CFIS
(0 << 5) | # 'A' Not ATAPI
(0 << 6) | # 'W' Not write to device
(0 << 7) | # 'P' Prefetchable = 1
(0 << 8) | # 'R' Not a Reset
(0 << 9) | # 'B' Not a BIST
(0 << 10) | # 'C' Do clear BSY/CI after transmitting this command
(nprds << 16)) # 'PRDTL' - number of PRDT entries
self.x393_mem.write_mem(MAXI1_ADDR + COMMAND_HEADER0_OFFS + (2 << 2), (COMMAND_ADDRESS)) # 'CTBA' - Command table base address
self.sync_for_device('H2D',COMMAND_ADDRESS, cmd_size) # command and PRD table
self.sync_for_device('D2H',DATAIN_ADDRESS , xfer_size)
# Set PxCMD.ST bit (it may already be set)
self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxCMD'), 0x11) # .ST and .FRE bits (FRE is readonly 1 anyway)
# Set Command Issued
if do_not_start:
print ('Run the following command to start the comand:')
print("mem.write_mem(sata.get_reg_address('HBA_PORT__PxCI'), 1)")
else:
self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxCI'), 1)
print("Command table data:")
print("_=mem.mem_dump (0x%x, 0x10,4)"%(COMMAND_ADDRESS))
self.x393_mem.mem_dump (COMMAND_ADDRESS, 0x20,4)
#Wait interrupt
for r in range(10):
istat = self.x393_mem.read_mem(self.get_reg_address('HBA_PORT__PxIS'))
if istat:
self.parse_register(group_range = ['HBA_PORT__PxIS'],
skip0 = True,
dword = None)
if (istat & 1) != 1: #DHRS interrupt (for PIO - 2)
print ("\n ======================Got wrong interrupt ============================")
self.reg_status()
print("_=mem.mem_dump (0x%x, 0x4,4)"%(MAXI1_ADDR + DBG_OFFS))
self.x393_mem.mem_dump (MAXI1_ADDR + DBG_OFFS, 0x4,4)
print("Datascope (debug) data:")
print("_=mem.mem_dump (0x%x, 0x20,4)"%(DATASCOPE_ADDR))
self.x393_mem.mem_dump (DATASCOPE_ADDR, 0xa0,4)
dd =0
for a in range(0x80001000,0x80001014,4):
dd |= self.x393_mem.read_mem(a)
if dd == 0:
print ("*** Probably got cache/write buffer problem, continuing ***")
break
raise Exception("Failed to get interrupt")
break
sleep(0.1)
else:
print ("\n ====================== Failed to get interrupt ============================")
self.reg_status()
print("_=mem.mem_dump (0x%x, 0x4,4)"%(MAXI1_ADDR + DBG_OFFS))
self.x393_mem.mem_dump (MAXI1_ADDR + DBG_OFFS, 0x4,4)
print("Datascope (debug) data:")
print("_=mem.mem_dump (0x%x, 0x100,4)"%(DATASCOPE_ADDR))
self.x393_mem.mem_dump (DATASCOPE_ADDR, 0x200,4)
raise Exception("Failed to get interrupt")
print("Datascope (debug) data:")
print("_=mem.mem_dump (0x%x, 0x200,4)"%(DATASCOPE_ADDR))
self.x393_mem.mem_dump (DATASCOPE_ADDR, 0x200,4)
print("Memory read data:")
self.sync_for_cpu('D2H',DATAIN_ADDRESS, count * 512)
print("_=mem.mem_dump (0x%x, 0x%x, 1)"%(DATAIN_ADDRESS, count * 0x200))
mcount=min(count,2)
self.x393_mem.mem_dump (DATAIN_ADDRESS, mcount * 0x200, 1)
if (mcount<count):
print("------------------------- truncated -------------------------")
def dd_read_dma(self, skip, count = 1, do_not_start = False, prd_irqs = None): #TODO: Add multi-PRD testing def dd_read_dma(self, skip, count = 1, do_not_start = False, prd_irqs = None): #TODO: Add multi-PRD testing
""" """
...@@ -794,6 +1061,8 @@ class x393sata(object): ...@@ -794,6 +1061,8 @@ class x393sata(object):
self.sync_for_cpu('D2H',DATAIN_ADDRESS, count * 512) self.sync_for_cpu('D2H',DATAIN_ADDRESS, count * 512)
print("_=mem.mem_dump (0x%x, 0x%x, 1)"%(DATAIN_ADDRESS, count * 0x200)) print("_=mem.mem_dump (0x%x, 0x%x, 1)"%(DATAIN_ADDRESS, count * 0x200))
self.x393_mem.mem_dump (DATAIN_ADDRESS, count * 0x200, 1) self.x393_mem.mem_dump (DATAIN_ADDRESS, count * 0x200, 1)
def dd_write_dma(self, skip, count = 1, use_read_buffer = False, do_not_start = False, prd_irqs = None): #TODO: Add multi-PRD testing def dd_write_dma(self, skip, count = 1, use_read_buffer = False, do_not_start = False, prd_irqs = None): #TODO: Add multi-PRD testing
""" """
Write device from memory, use single PRD table Write device from memory, use single PRD table
...@@ -1227,7 +1496,7 @@ hex(mem.read_mem(0x80000fec)) ...@@ -1227,7 +1496,7 @@ hex(mem.read_mem(0x80000fec))
sata.drp_write(0x20b,1) #disable wait for auto align sata.drp_write(0x20b,1) #disable wait for auto align
sata.reset_device() sata.reset_device()
_=mem.mem_dump (0x80000ff0, 4,4) _=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status( sata.reg_status()
sata.reset_ie(), sata.reg_status() sata.reset_ie(), sata.reg_status()
sata.read_sipo_meas(0xfffff,0x7ffe) sata.read_sipo_meas(0xfffff,0x7ffe)
...@@ -1276,11 +1545,76 @@ sata.reg_status(),sata.reset_ie(),sata.err_count() ...@@ -1276,11 +1545,76 @@ sata.reg_status(),sata.reset_ie(),sata.err_count()
_=mem.mem_dump (0x80000ff0, 4,4) _=mem.mem_dump (0x80000ff0, 4,4)
_=mem.mem_dump (0x80001000, 0x120,4) _=mem.mem_dump (0x80001000, 0x120,4)
hex(sata.get_reg_address('HBA_PORT__PxSCTL')) hex(sata.get_reg_address('HBA_PORT__PxSCTL'))
mem.write_mem(0x8000012c,1) mem.write_mem(0x8000012c,1)
mem.write_mem(0x8000012c,0) mem.write_mem(0x8000012c,0)
hex(mem.read_mem(0x8000012c)) hex(mem.read_mem(0x8000012c))
mem.write_mem(0x80000118,0x10)
0x80001000:002f8027 a0000830 00000000 08000001 00000000
0x2e200010:00
2f Command
80 (Bit 15: `: Command register - 0 Device control register)
27 RFIS H2D
a0 Device?
00
0830 LBA 15:0
00000000
08 CONTROL = 8
000001 COUNT = 1
00000000
00000005 00000006 00000007 00000008 00000009 0000000a 0000000b
0x2e200040:0000000c 0000000d 0000000e 0000000f 00000010 00000011 00000012 00000013 00000014 00000015 00000016 00000017 00000018 00000019 0000001a 0000001b
0x2e200080:0000001c 0000001d 0000001e 0000001f
+0x80: 24d7e680 00000000 00000022 000001ff
00000024 00000025 00000026 00000027 00000028 00000029 0000002a 0000002b
0x2e2000c0:0000002c 0000002d 0000002e 0000002f 00000030 00000031 00000032 00000033 00000034 00000035 00000036 00000037 00000038 00000039 0000003a 0000003b
0x2e200100:0000003c 0000003d 0000003e 0000003f
0x24d7e680:00080001 80000000 06da4a87 80000000 00000102 80000000 00000000 00000000 00000000 00000000 ffff0000 00000000 00003200 80000000 00000000 00000000
0x24d7e6c0:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x24d7e700:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x24d7e740:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x24d7e780:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x24d7e7c0:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x24d7e800:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x24d7e840:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
----------------------
>>> _=mem.mem_dump (0x80000ff0, 4,4)
0x80000ff0:a0004109 9d010f00 adac0f00 021b890c
0x80000800:00300005 00000000 2e200010 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x2e200010:00258027 e0000080 00000000 08000180 00000000 00000005 00000006 00000007 00000008 00000009 0000000a 0000000b
0x2e200040:0000000c 0000000d 0000000e 0000000f 00000010 00000011 00000012 00000013 00000014 00000015 00000016 00000017 00000018 00000019 0000001a 0000001b
0x2e200080:0000001c 0000001d 0000001e 0000001f 29406000 00000000 00000022 00000fff 252fc000 00000000 00000026 00000fff 2488e000 00000000 0000002a 00000fff
0x2e2000c0:246c4000 00000000 0000002e 00000fff 246d1000 00000000 00000032 00000fff 2e952000 00000000 00000036 00000fff 246c7000 00000000 0000003a 00000fff
0x2e200100:246e6000 00000000 0000003e 00000fff 29b4c000 00000000 00000042 00000fff 246de000 00000000 00000046 00000fff 26667000 00000000 0000004a 00000fff
0x2e200140:26bbc000 00000000 0000004e 00000fff 26b7e000 00000000 00000052 00000fff 26a0a000 00000000 00000056 00000fff 2471b000 00000000 0000005a 00000fff
0x2e200180:2471d000 00000000 0000005e 00000fff 27a4c000 00000000 00000062 00000fff 27992000 00000000 00000066 00000fff 27954000 00000000 0000006a 00000fff
0x2e2001c0:2781e000 00000000 0000006e 00000fff 27cba000 00000000 00000072 00000fff 27fa2000 00000000 00000076 00000fff 27f64000 00000000 0000007a 00000fff
0x2e200200:27e6d000 00000000 0000007e 00000fff 27d74000 00000000 00000082 00000fff 261ca000 00000000 00000086 00000fff 282cb000 00000000 0000008a 00000fff
0x2e200240:2824f000 00000000 0000008e 00000fff 28194000 00000000 00000092 00000fff 281d3000 00000000 00000096 00000fff 25cf0000 00000000 0000009a 00000fff
0x2e200280:2618c000 00000000 0000009e 00000fff 26110000 00000000 000000a2 00000fff 26057000 00000000 000000a6 00000fff 26019000 00000000 000000aa 00000fff
0x2e2002c0:259c8000 00000000 000000ae 00000fff 25c37000 00000000 000000b2 00000fff 263bb000 00000000 000000b6 00000fff 262c2000 00000000 000000ba 00000fff
0x2e200300:26284000 00000000 000000be 00000fff 256df000 00000000 000000c2 00000fff 25f9b000 00000000 000000c6 00000fff 25de8000 00000000 000000ca 00000fff
0x2e200340:25e27000 00000000 000000ce 00000fff 25d6c000 00000000 000000d2 00000fff 250ce000 00000000 000000d6 00000fff 25663000 00000000 000000da 00000fff
0x2e200380:2556b000 00000000 000000de 00000fff 000000e0 000000e1 000000e2 000000e3 000000e4 000000e5 000000e6 000000e7 000000e8 000000e9 000000ea 000000eb
for block in range (1,1024): for block in range (1,1024):
...@@ -1304,7 +1638,10 @@ _=mem.mem_dump(0x3813fff8,0x2,4) ...@@ -1304,7 +1638,10 @@ _=mem.mem_dump(0x3813fff8,0x2,4)
mem.mem_save('/mnt/mmc/data/regs_dump_04',0x80000000,0x3000) mem.mem_save('/mnt/mmc/data/regs_dump_04',0x80000000,0x3000)
mem.mem_save('/mnt/mmc/data/mem0x3000_dump_04',0x38140000,0x13e000) mem.mem_save('/mnt/mmc/data/mem0x3000_dump_04',0x38140000,0x13e000)
0x3813fff8:0000018b 00003000
'0x4a1000'
mem.mem_save('/mnt/mmc/data/regs_dump_05',0x80000000,0x3000)
mem.mem_save('/mnt/mmc/data/mem0x3000_dump_05',0x38140000,0x4a1000)
############# #############
......
...@@ -817,6 +817,7 @@ localparam ATA_WBUF_DMA = 'heb; // Write 512 bytes to device buffer in DMA mode ...@@ -817,6 +817,7 @@ localparam ATA_WBUF_DMA = 'heb; // Write 512 bytes to device buffer in DMA mode
localparam ATA_RDMA = 'hc8; // Read from device in DMA mode @SuppressThisWarning VEditor - not yet used localparam ATA_RDMA = 'hc8; // Read from device in DMA mode @SuppressThisWarning VEditor - not yet used
localparam ATA_RBUF_PIO = 'he4; // Read 512 bytes from device buffer in PIO mode @SuppressThisWarning VEditor - not yet used localparam ATA_RBUF_PIO = 'he4; // Read 512 bytes from device buffer in PIO mode @SuppressThisWarning VEditor - not yet used
localparam ATA_RBUF_DMA = 'he9; // Read 512 bytes from device buffer in DMA mode @SuppressThisWarning VEditor - not yet used localparam ATA_RBUF_DMA = 'he9; // Read 512 bytes from device buffer in DMA mode @SuppressThisWarning VEditor - not yet used
localparam ATA_RDMA_EXT = 'h25; // Read DMA devices that support 48-bit Addressing
reg [31:0] sysmem[0:4095]; reg [31:0] sysmem[0:4095];
...@@ -996,6 +997,60 @@ localparam ATA_RBUF_DMA = 'he9; // Read 512 bytes from device buffer in DMA mod ...@@ -996,6 +997,60 @@ localparam ATA_RBUF_DMA = 'he9; // Read 512 bytes from device buffer in DMA mod
end end
endtask endtask
task setup_dma_read_ext_command_multi4;
input integer prd_int; // [0] - first prd interrupt, ... [31] - 31-st
input integer nw1; // first segment lengtth (in words)
input integer nw2; // second segment lengtth (in words)
input integer nw3; // third segment lengtth (in words)
integer nw4;
integer i;
begin
nw4 = 256 - nw1 - nw2 - nw3; // total 512 bytes, 256 words
// clear system memory for command
for (i = 0; i < 64; i = i+1) sysmem[(COMMAND_TABLE >> 2) + i] = 0;
// fill ATA command
sysmem[(COMMAND_TABLE >> 2) + 0] = FIS_H2DR | // FIS type - H2D register (0x27)
('h80 << 8) | // set C = 1
(ATA_RDMA_EXT << 16) | // Command = 0x25 (READ_DMA_EXT)
( 0 << 24); // features = 0 ?
// All other 4 DWORDs are 0 for this command
// Set PRDT (four items)
// PRDT #1
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 0] = SYS_MEM_START + IDENTIFY_BUF; // not shifted
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 3] = (prd_int[0] << 31) | (2 * nw1 - 1); // 2 * nw1 bytes
// PRDT #2
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 4] = SYS_MEM_START + IDENTIFY_BUF + (2 * nw1);
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 7] = (prd_int[0] << 31) | (2 * nw2 - 1); // 2 * nw2 bytes
// PRDT #3
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 8] = SYS_MEM_START + IDENTIFY_BUF + (2 * nw1) + (2 * nw2);
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 11] = (prd_int[0] << 31) | (2 * nw3 - 1); // 2 * nw3 bytes
// PRDT #4
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 12] = SYS_MEM_START + IDENTIFY_BUF + (2 * nw1) + (2 * nw2) + (2 * nw3);
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 15] = (prd_int[0] << 31) | (2 * nw4 - 1); // 2 * nw4 bytes
// Setup command header
maxigp1_writep ((CLB_OFFS32 + 0) << 2, (5 << 0) | // 'CFL' - number of DWORDs in the CFIS
(0 << 5) | // 'A' Not ATAPI
(0 << 6) | // 'W' Not write to device
// (1 << 7) | // 'P' Prefetchable = 1
(0 << 7) | // 'P' Prefetchable = 1
(0 << 8) | // 'R' Not a Reset
(0 << 9) | // 'B' Not a BIST
(0 << 10) | // 'C' Do not clear BSY/CI after transmitting this command
// (1 << 10) | // 'C' Do clear BSY/CI after transmitting this command
(4 << 16)); // 'PRDTL' - number of PRDT entries (4)
/// maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE) & 32'hffffffc0); // 'CTBA' - Command table base address
maxigp1_writep ((CLB_OFFS32 +2 ) << 2, (SYS_MEM_START + COMMAND_TABLE)); // 'CTBA' - Command table base address
// Set Command Issued
maxigp1_writep (HBA_PORT__PxCI__CI__ADDR << 2, 1); // 'PxCI' - Set 'Command issue' for slot 0 (the only one)
// relax and enjoy
end
endtask
task setup_dma_write_identify_command_multi4; // Write DMA, use data received during read identify task setup_dma_write_identify_command_multi4; // Write DMA, use data received during read identify
input integer lba; input integer lba;
input integer prd_int; // [0] - first prd interrupt, ... [31] - 31-st input integer prd_int; // [0] - first prd interrupt, ... [31] - 31-st
...@@ -1205,9 +1260,13 @@ initial begin //Host ...@@ -1205,9 +1260,13 @@ initial begin //Host
maxigp1_print (HBA_PORT__PxSSTS__DET__ADDR << 2,"HBA_PORT__PxSSTS__DET__ADDR"); maxigp1_print (HBA_PORT__PxSSTS__DET__ADDR << 2,"HBA_PORT__PxSSTS__DET__ADDR");
// setup_pio_read_identify_command_simple(512,1); // prdt interrupt for entry 0 // setup_pio_read_identify_command_simple(512,1); // prdt interrupt for entry 0
setup_pio_read_identify_command_simple(2560,1); // intentionally too long
//// setup_pio_read_identify_command_simple(2560,1); // intentionally too long
/// setup_pio_read_identify_command_shifted(1); // prdt interrupt for entry 0 /// setup_pio_read_identify_command_shifted(1); // prdt interrupt for entry 0
/// setup_pio_read_identify_command_multi4(1,27,71,83); // prdt interrupt for entry 0
/// setup_pio_read_identify_command_multi4(0,27,71,83); // No prdt interrupts
setup_dma_read_ext_command_multi4(0,64,64,64); // No prdt interrupts, 4 64-word chunks
/// setup_pio_read_identify_command_multi4(1,27,64,83); // prdt interrupt for entry 0 /// setup_pio_read_identify_command_multi4(1,27,64,83); // prdt interrupt for entry 0
/// setup_pio_read_identify_command_multi4(1,64,63,64); // prdt interrupt for entry 0 // last used /// setup_pio_read_identify_command_multi4(1,64,63,64); // prdt interrupt for entry 0 // last used
maxigp1_print (HBA_PORT__PxCI__CI__ADDR << 2,"HBA_PORT__PxCI__CI__ADDR"); maxigp1_print (HBA_PORT__PxCI__CI__ADDR << 2,"HBA_PORT__PxCI__CI__ADDR");
...@@ -1323,6 +1382,13 @@ initial begin //Host ...@@ -1323,6 +1382,13 @@ initial begin //Host
//HBA_PORT__PxIE__DHRE__MASK = 'h1; //HBA_PORT__PxIE__DHRE__MASK = 'h1;
end end
function func_is_dev_read_dma_ext;
input [31:0] dw;
begin
func_is_dev_read_dma_ext = ((dw & 'hff) == FIS_H2DR ) && (((dw >> 16) & 'hff) == ATA_RDMA_EXT);
end
endfunction
function func_is_dev_identify; function func_is_dev_identify;
input [31:0] dw; input [31:0] dw;
begin begin
...@@ -1390,13 +1456,32 @@ initial begin //Device ...@@ -1390,13 +1456,32 @@ initial begin //Device
dev.send_dma_activate (69, // input integer id; dev.send_dma_activate (69, // input integer id;
status); // output integer status; status); // output integer status;
end else if (func_is_dev_read_dma_ext(dev.receive_data[0])) begin
dev.send_incrementing_data(70, // input integer id;
128, // number of dwords to send, later decode count field
status); // output integer status;
DEVICE_TITLE = "Device sent Data FIS (READ DMA EXT)";
$display("[Dev-TB]: %s, status = 0x%x @%t", DEVICE_TITLE, status, $time);
// Send multiple FISes if needed, when done:
dev.send_D2HR(70,
1, // irq,
8'h0, // status
0, // error
0, // device
0, // lba_low
0, // lba_high
0, // count
status); // output: result status
DEVICE_TITLE = "Device sent D2H FIS (DMA D2H over)";
$display("[Dev-TB]: %s, status = 0x%x @%t", DEVICE_TITLE, status, $time);
end else if (func_is_h2d_data(dev.receive_data[0])) begin end else if (func_is_h2d_data(dev.receive_data[0])) begin
DEVICE_TITLE = "Got H2D data"; DEVICE_TITLE = "Got H2D data";
$display("[Dev-TB]: %s @%t", DEVICE_TITLE, $time); $display("[Dev-TB]: %s @%t", DEVICE_TITLE, $time);
$display("[Dev-TB]: %hh payload DWORDs got (%d bytes) @%t", dev.received_size, dev.received_size << 2, $time); $display("[Dev-TB]: %hh payload DWORDs got (%d bytes) @%t", dev.received_size, dev.received_size << 2, $time);
// Assuming device got what it needed, otherwise send DMA Activate again // Assuming device got what it needed, otherwise send DMA Activate again
dev.send_D2HR(70, dev.send_D2HR(71,
1, // irq, 1, // irq,
8'h0, // status 8'h0, // status
0, // error 0, // error
......
[*] [*]
[*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI [*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI
[*] Tue Mar 1 01:47:21 2016 [*] Fri Mar 4 19:49:47 2016
[*] [*]
[dumpfile] "/home/andrey/git/x393_sata/simulation/tb_ahci-20160229184025832.fst" [dumpfile] "/home/andrey/git/x393_sata/simulation/tb_ahci-20160304124651260.fst"
[dumpfile_mtime] "Tue Mar 1 01:42:30 2016" [dumpfile_mtime] "Fri Mar 4 19:48:48 2016"
[dumpfile_size] 15004446 [dumpfile_size] 13922108
[savefile] "/home/andrey/git/x393_sata/tb_ahci_01.sav" [savefile] "/home/andrey/git/x393_sata/tb_ahci_01.sav"
[timestart] 47816000 [timestart] 34498000
[size] 1823 1180 [size] 1823 1180
[pos] 0 42 [pos] 0 42
*-18.256386 48747934 62346574 72998842 74025406 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 *-19.415150 37229086 62346574 72998842 74025406 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] tb_ahci. [treeopen] tb_ahci.
[treeopen] tb_ahci.axi_read_addr. [treeopen] tb_ahci.axi_read_addr.
[treeopen] tb_ahci.dev.
[treeopen] tb_ahci.dev.linkMonitorFIS. [treeopen] tb_ahci.dev.linkMonitorFIS.
[treeopen] tb_ahci.dev.phy. [treeopen] tb_ahci.dev.phy.
[treeopen] tb_ahci.dev.phy.gtx_wrapper. [treeopen] tb_ahci.dev.phy.gtx_wrapper.
[treeopen] tb_ahci.dev.phy.gtx_wrapper.gtx_gpl. [treeopen] tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.
[treeopen] tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel. [treeopen] tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.
[treeopen] tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.rx.
[treeopen] tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.rx.dataiface.
[treeopen] tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.tx. [treeopen] tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.tx.
[treeopen] tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.tx.ser. [treeopen] tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.tx.ser.
[treeopen] tb_ahci.dev.phy.oob_dev. [treeopen] tb_ahci.dev.phy.oob_dev.
...@@ -56,8 +59,8 @@ ...@@ -56,8 +59,8 @@
[treeopen] tb_ahci.simul_axi_hp_wr_i.waddr_i. [treeopen] tb_ahci.simul_axi_hp_wr_i.waddr_i.
[treeopen] tb_ahci.simul_axi_hp_wr_i.wdata_i. [treeopen] tb_ahci.simul_axi_hp_wr_i.wdata_i.
[treeopen] tb_ahci.simul_axi_read_i. [treeopen] tb_ahci.simul_axi_read_i.
[sst_width] 368 [sst_width] 325
[signals_width] 409 [signals_width] 338
[sst_expanded] 1 [sst_expanded] 1
[sst_vpaned_height] 573 [sst_vpaned_height] 573
@820 @820
...@@ -1702,7 +1705,7 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtxe2_channel_wrapper.gtx_g ...@@ -1702,7 +1705,7 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.phy.gtx_wrap.gtxe2_channel_wrapper.gtx_g
-drp -drp
@1401200 @1401200
-axi_ahci_regs -axi_ahci_regs
@c00200 @800200
-ahci_fsm -ahci_fsm
@28 @28
tb_ahci.dut.sata_top.ahci_top_i.hba_arst tb_ahci.dut.sata_top.ahci_top_i.hba_arst
...@@ -1837,6 +1840,7 @@ tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.sirq_PC ...@@ -1837,6 +1840,7 @@ tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.sirq_PC
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.get_rfis tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.get_rfis
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.update_sig tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.update_sig
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.update_err_sts tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.update_err_sts
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.update_prdbc
@1000200 @1000200
-actions -actions
@c00200 @c00200
...@@ -1976,7 +1980,7 @@ tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.async_pend_r[1:0] ...@@ -1976,7 +1980,7 @@ tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.async_pend_r[1:0]
@28 @28
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.async_ackn tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.async_ackn
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.async_from_st tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.async_from_st
@1401200 @1000200
-ahci_fsm -ahci_fsm
@c00200 @c00200
-ahci_fis_receive -ahci_fis_receive
...@@ -2533,16 +2537,38 @@ tb_ahci.simul_axi_hp_wr_i.wdata_i.fill[7:0] ...@@ -2533,16 +2537,38 @@ tb_ahci.simul_axi_hp_wr_i.wdata_i.fill[7:0]
- -
@800200 @800200
-debug_non_prefetchable -debug_non_prefetchable
@29
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.condition_mux_i.XFER0
@28
tb_ahci.dut.sata_top.ahci_top_i.dma_cmd_busy
tb_ahci.dut.sata_top.ahci_top_i.dma_cmd_done
tb_ahci.dut.sata_top.ahci_top_i.ahci_fis_receive_i.dma_prds_done
tb_ahci.dut.sata_top.ahci_top_i.ahci_fis_receive_i.dwords_over
@22
tb_ahci.dut.sata_top.ahci_top_i.ahci_fis_receive_i.data_in_dwords_r[11:0]
tb_ahci.dut.sata_top.ahci_top_i.ahci_fis_receive_i.prdbc_r[31:2]
@28
tb_ahci.dut.sata_top.ahci_top_i.ahci_fis_receive_i.get_data_fis
tb_ahci.dut.sata_top.ahci_top_i.frcv_update_prdbc
tb_ahci.dut.sata_top.ahci_top_i.ahci_fis_receive_i.update_prdbc
tb_ahci.dut.sata_top.ahci_top_i.ahci_fis_receive_i.update_prdbc_r
@22
tb_ahci.dut.sata_top.ahci_top_i.xfer_cntr[31:2]
tb_ahci.dut.sata_top.ahci_top_i.ahci_fis_receive_i.xfer_cntr_r[31:2]
tb_ahci.dut.sata_top.ahci_top_i.ahci_fis_receive_i.reg_data[31:0]
tb_ahci.dut.sata_top.ahci_top_i.ahci_fis_receive_i.reg_addr[9:0]
@28
tb_ahci.dut.sata_top.ahci_top_i.ahci_fis_receive_i.reg_we
@200
-
@28 @28
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.update_pio tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.update_pio
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.update_err_sts tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.update_err_sts
(1)tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.fsm_transitions[1:0] (1)tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.fsm_transitions[1:0]
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.fsm_transitions_w tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.fsm_transitions_w
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.tfd_bsy tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.tfd_bsy
@29
[color] 3 [color] 3
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.conditions_ce tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.conditions_ce
@28
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.tfd_drq tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.tfd_drq
@22 @22
tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.tfd_sts[7:0] tb_ahci.dut.sata_top.ahci_top_i.ahci_fsm_i.tfd_sts[7:0]
...@@ -2802,7 +2828,7 @@ tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.qwcount[22:1] ...@@ -2802,7 +2828,7 @@ tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.qwcount[22:1]
tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.data_len[3:0] tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.data_len[3:0]
@28 @28
tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.axi_set_addr_data_w tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.axi_set_addr_data_w
@800200 @c00200
-fifo_h2d -fifo_h2d
@22 @22
tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.ahci_dma_rd_fifo_i.din[63:0] tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.ahci_dma_rd_fifo_i.din[63:0]
...@@ -3175,7 +3201,7 @@ tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.ahci_dma_rd_fifo_i.ahci_dma_rd_stuff_ ...@@ -3175,7 +3201,7 @@ tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.ahci_dma_rd_fifo_i.ahci_dma_rd_stuff_
@28 @28
tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.ahci_dma_rd_fifo_i.ahci_dma_rd_stuff_i.slow_down tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.ahci_dma_rd_fifo_i.ahci_dma_rd_stuff_i.slow_down
tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.ahci_dma_rd_fifo_i.ahci_dma_rd_stuff_i.last_DW tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.ahci_dma_rd_fifo_i.ahci_dma_rd_stuff_i.last_DW
@800200 @c00200
-debug -debug
@200 @200
- -
...@@ -3223,10 +3249,12 @@ tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.ahci_dma_rd_fifo_i.ahci_dma_rd_stuff_ ...@@ -3223,10 +3249,12 @@ tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.ahci_dma_rd_fifo_i.ahci_dma_rd_stuff_
tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.ahci_dma_rd_fifo_i.ahci_dma_rd_stuff_i.last_dw_sent tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.ahci_dma_rd_fifo_i.ahci_dma_rd_stuff_i.last_dw_sent
@1001200 @1001200
-group_end -group_end
@1000200 @1401200
-debug -debug
@1000200
-h2d_stuff -h2d_stuff
-mclk_domain -mclk_domain
@1401200
-fifo_h2d -fifo_h2d
@28 @28
tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.cmd_busy tb_ahci.dut.sata_top.ahci_top_i.ahci_dma_i.cmd_busy
...@@ -4221,6 +4249,20 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.link.crc.crc_bit[31:0] ...@@ -4221,6 +4249,20 @@ tb_ahci.dut.sata_top.ahci_sata_layers_i.link.crc.crc_bit[31:0]
@1000200 @1000200
-crc -crc
@800200 @800200
-dev_dbg
@28
tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.rx.dataiface.reset
tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.rx.dataiface.full_wr
tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.rx.dataiface.val_wr
tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.rx.dataiface.val_rd
tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.rx.des.need_reset
@22
tb_ahci.dev.phy.gtx_wrapper.gtx_gpl.channel.rx.des.bitcounter[31:0]
@200
-
@1000200
-dev_dbg
@800200
-dev_crc -dev_crc
@22 @22
tb_ahci.dev.phy.ll_data_out[31:0] tb_ahci.dev.phy.ll_data_out[31:0]
...@@ -5238,7 +5280,7 @@ tb_ahci.dut.sata_top.ahci_top_i.h2d_valid ...@@ -5238,7 +5280,7 @@ tb_ahci.dut.sata_top.ahci_top_i.h2d_valid
tb_ahci.dut.sata_top.ahci_top_i.data_out_dwords[11:0] tb_ahci.dut.sata_top.ahci_top_i.data_out_dwords[11:0]
@28 @28
tb_ahci.dut.sata_top.ahci_top_i.datascope_clk tb_ahci.dut.sata_top.ahci_top_i.datascope_clk
@800022 @c00022
tb_ahci.dut.sata_top.ahci_top_i.datascope_di[31:0] tb_ahci.dut.sata_top.ahci_top_i.datascope_di[31:0]
@28 @28
(0)tb_ahci.dut.sata_top.ahci_top_i.datascope_di[31:0] (0)tb_ahci.dut.sata_top.ahci_top_i.datascope_di[31:0]
...@@ -5273,7 +5315,7 @@ tb_ahci.dut.sata_top.ahci_top_i.datascope_di[31:0] ...@@ -5273,7 +5315,7 @@ tb_ahci.dut.sata_top.ahci_top_i.datascope_di[31:0]
(29)tb_ahci.dut.sata_top.ahci_top_i.datascope_di[31:0] (29)tb_ahci.dut.sata_top.ahci_top_i.datascope_di[31:0]
(30)tb_ahci.dut.sata_top.ahci_top_i.datascope_di[31:0] (30)tb_ahci.dut.sata_top.ahci_top_i.datascope_di[31:0]
(31)tb_ahci.dut.sata_top.ahci_top_i.datascope_di[31:0] (31)tb_ahci.dut.sata_top.ahci_top_i.datascope_di[31:0]
@1001200 @1401200
-group_end -group_end
@800022 @800022
tb_ahci.dut.sata_top.ahci_top_i.datascope_run[1:0] tb_ahci.dut.sata_top.ahci_top_i.datascope_run[1:0]
......
...@@ -1282,7 +1282,7 @@ assign val_wr = ~full_wr & bitcounter == (width - 1); ...@@ -1282,7 +1282,7 @@ assign val_wr = ~full_wr & bitcounter == (width - 1);
always @ (posedge inclk) begin always @ (posedge inclk) begin
if (reset) need_reset <= 0; if (reset) need_reset <= 0;
else if (full_wr && !need_reset) begin else if (full_wr && !need_reset) begin
$display("FIFO in %m is full, that is not an appropriate behaviour - needs reset @%time", $time); $display("1:FIFO in %m is full, that is not an appropriate behaviour - needs reset @%time", $time);
bitcounter <= 'bx; bitcounter <= 'bx;
need_reset <= 1'b1; need_reset <= 1'b1;
// $finish; // $finish;
...@@ -1811,6 +1811,7 @@ wire full_wr; ...@@ -1811,6 +1811,7 @@ wire full_wr;
wire val_wr; wire val_wr;
wire val_rd; wire val_rd;
wire almost_empty_rd; wire almost_empty_rd;
reg need_reset = 1;
always @ (posedge usrclk) always @ (posedge usrclk)
wordcounter <= reset ? 32'h0 : realign & ~(div == 0) ? 32'd1 : wordcounter == (div - 1) ? 32'h0 : wordcounter + 1'b1; wordcounter <= reset ? 32'h0 : realign & ~(div == 0) ? 32'd1 : wordcounter == (div - 1) ? 32'h0 : wordcounter + 1'b1;
...@@ -1835,10 +1836,11 @@ assign val_rd = ~empty_rd & ~almost_empty_rd; ...@@ -1835,10 +1836,11 @@ assign val_rd = ~empty_rd & ~almost_empty_rd;
assign val_wr = ~full_wr & wordcounter == (div - 1); assign val_wr = ~full_wr & wordcounter == (div - 1);
always @ (posedge usrclk) always @ (posedge usrclk)
if (full_wr) if (reset) need_reset <= 0;
begin else if (full_wr && !need_reset) begin
$display("FIFO in %m is full, that is not an appropriate behaviour, needs reset"); $display("2:FIFO in %m is full, that is not an appropriate behaviour, needs reset @%time", $time);
wordcounter = 'bx; wordcounter = 'bx;
need_reset <= 1;
// $finish; // $finish;
end end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment