transport: code SATATransportLayerTX (untested)

This commit is contained in:
Florent Kermarrec 2014-12-11 20:19:14 +01:00
parent e4c0b4a11f
commit 1aab9a449e
3 changed files with 163 additions and 17 deletions

View File

@ -48,13 +48,48 @@ def link_layout(dw):
] ]
return EndpointDescription(layout, packetized=True) return EndpointDescription(layout, packetized=True)
def transport_tx_layout(dw): def transport_cmd_tx_layout():
layout = [ layout = [
("d", dw) ("type", 8),
("pm_port", 4),
("a", 1),
("c", 1),
("d", 1),
("i", 1),
("command", 8),
("features", 16),
("lba", 48),
("device", 8),
("count", 16),
("icc", 8),
("control", 8),
("dma_buffer_id", 64),
("dma_buffer_offset", 32),
("dma_transfer_count", 32),
] ]
return EndpointDescription(layout, packetized=True) return EndpointDescription(layout, packetized=True)
def transport_rx_layout(dw): def transport_cmd_rx_layout():
layout = [
("type", 8),
("pm_port", 4),
("a", 1),
("d", 1),
("i", 1),
("status", 8),
("error", 8),
("lba", 48),
("device", 8),
("count", 16),
("e_status", 8),
("transfer_count", 16),
("dma_buffer_id", 64),
("dma_buffer_offset", 32),
("dma_transfer_count", 32)
]
return EndpointDescription(layout, packetized=True)
def transport_data_layout(dw):
layout = [ layout = [
("d", dw) ("d", dw)
] ]

View File

@ -1,15 +1,125 @@
from lib.sata.std import * from lib.sata.std import *
from lib.sata.transport.std import * from lib.sata.transport.std import *
def _encode_cmd(obj, layout, signal):
r = []
for k, v in sorted(layout.items()):
start = v.word*32 + v.offset
end = start + v.width
r.append(signal[start:end].eq(getattr(obj, k)))
return r
class SATATransportLayerTX(Module): class SATATransportLayerTX(Module):
def __init__(self): def __init__(self, link):
self.sink = Sink(transport_layout(32)) self.cmd = cmd = Sink(transport_cmd_tx_layout())
self.data = data = Sink(transport_data_layout(32))
###
cmd_ndwords = max(fis_reg_h2d_cmd_len, fis_dma_setup_cmd_len, fis_data_cmd_len)
encoded_cmd = Signal(cmd_ndwords*32)
cnt = Signal(max=cmd_ndwords+1)
clr_cnt = Signal()
inc_cnt = Signal()
cmd_len = Signal(flen(cnt))
cmd_with_data = Signal()
cmd_send = Signal()
data_send = Signal()
cmd_done = Signal()
data_done = Signal()
fsm = FSM(reset_state="IDLE")
self.submodules += fsm
# FSM
fsm.act("IDLE",
clr_cnt.eq(1),
If(cmd.stb,
If(cmd.type == fis_types["REG_H2D"],
NextState("SEND_REG_H2D_CMD")
).Elif(cmd.type == "DMA_SETUP_CMD",
NextState("SEND_DMA_SETUP")
).Elif(cmd.type == "DATA_CMD"),
NextState("SEND_DATA")
).Else(
# XXX: Generate error to command layer?
cmd.ack.eq(1)
)
)
)
fsm.act("SEND_REG_H2D_CMD",
_encode_cmd(self.cmd, fis_reg_h2d_layout, encoded_cmd),
cmd_len.eq(fis_reg_h2d_cmd_len),
cmd_send.eq(1)
If(ack_cmd,
NextState.eq("ACK")
)
)
fsm.act("SEND_DMA_SETUP_CMD",
_encode_cmd(self.cmd, fis_dma_setup_layout, encoded_cmd),
cmd_len.eq(fis_dma_setup_cmd_len),
cmd_send.eq(1),
If(ack_cmd,
NextState.eq("ACK")
)
)
fsm.act("SEND_DATA_CMD",
_encode_cmd(self.cmd, fis_data_layout, encoded_cmd),
cmd_len.eq(fis_send_data_cmd_len),
cmd_width_data.eq(1),
cmd_send.eq(1),
If(cmd_done,
NextState.eq("SEND_DATA")
)
)
fsm.act("SEND_DATA",
data_send.eq(1),
If(data_done,
NextState.eq("ACK")
)
)
fsm.act("ACK",
cmd.ack.eq(1),
NextState.eq("IDLE")
)
cmd_cases = {}
for i in range(cmd_ndwords):
cmd_cases[i] = [link.sink.d.eq(encoded_cmd[32*i:32*(i+1)])]
self.comb += \
If(cmd_send,
link.sink.stb.eq(1),
link.sink.sop.eq(cnt==0),
link.sink.eop.eq((cnt==cmd_len) & ~cmd_with_data),
Case(cnt, cmd_cases),
inc_cnt.eq(link.sink.ack),
cmd_done.eq(cnt==cmd_len)
).Elif(data_send,
link.sink.stb.eq(data.stb),
link.sink.sop.eq(0),
link.sink.eop.eq(data.eop),
link.sink.d.eq(data.d),
data.ack.eq(link.sink.ack),
data_done.eq(data.eop & data.ack)
)
self.sync += \
If(clr_cnt,
cnt.eq(0)
).Elif(inc_cnt,
cnt.eq(cnt+1)
)
class SATATransportLayerRX(Module): class SATATransportLayerRX(Module):
def __init__(self): def __init__(self, link):
self.sink = Sink(transport_layout(32)) self.cmd = Source(transport_cmd_rx_layout())
self.data = Source(transport_data_layout(32))
class SATATransportLayer(Module): class SATATransportLayer(Module):
def __init__(self): def __init__(self, link):
self.submodules.tx = SATATransportLayerTX() self.submodules.tx = SATATransportLayerTX(link)
self.submodules.rx = SATATransportLayerRX() self.submodules.rx = SATATransportLayerRX(link)

View File

@ -13,7 +13,7 @@ class FISField():
self.offset = offset self.offset = offset
self.width = width self.width = width
fis_reg_h2d_len = 5 fis_reg_h2d_cmd_len = 5
fis_reg_h2d_layout = { fis_reg_h2d_layout = {
"type": FISField(0, 0, 8), "type": FISField(0, 0, 8),
"pm_port": FISField(0, 8, 4), "pm_port": FISField(0, 8, 4),
@ -22,7 +22,7 @@ fis_reg_h2d_layout = {
"features_lsb": FISField(0, 24, 8), "features_lsb": FISField(0, 24, 8),
"lba_lsb": FISField(1, 0, 24), "lba_lsb": FISField(1, 0, 24),
"device": FISField(1, 24, 0), "device": FISField(1, 24, 8),
"lba_msb": FISField(2, 0, 24), "lba_msb": FISField(2, 0, 24),
"features_msb": FISField(2, 24, 8), "features_msb": FISField(2, 24, 8),
@ -32,7 +32,7 @@ fis_reg_h2d_layout = {
"control": FISField(3, 24, 8) "control": FISField(3, 24, 8)
} }
fis_reg_d2h_len = 5 fis_reg_d2h_cmd_len = 5
fis_reg_d2h_layout = { fis_reg_d2h_layout = {
"type": FISField(0, 0, 8), "type": FISField(0, 0, 8),
"pm_port": FISField(0, 8, 4), "pm_port": FISField(0, 8, 4),
@ -41,20 +41,20 @@ fis_reg_d2h_layout = {
"error": FISField(0, 24, 8), "error": FISField(0, 24, 8),
"lba_lsb": FISField(1, 0, 24), "lba_lsb": FISField(1, 0, 24),
"device": FISField(1, 24, 0), "device": FISField(1, 24, 8),
"lba_msb": FISField(2, 0, 24), "lba_msb": FISField(2, 0, 24),
"count": FISField(3, 0, 16) "count": FISField(3, 0, 16)
} }
fis_dma_activate_d2h_len = 1 fis_dma_activate_d2h_cmd_len = 1
fis_dma_activate_d2h_layout = { fis_dma_activate_d2h_layout = {
"type": FISField(0, 0, 8), "type": FISField(0, 0, 8),
"pm_port": FISField(0, 8, 4) "pm_port": FISField(0, 8, 4)
} }
fis_dma_setup_len = 7 fis_dma_setup_cmd_len = 7
fis_dma_setup_layout = { fis_dma_setup_layout = {
"type": FISField(0, 0, 8), "type": FISField(0, 0, 8),
"pm_port": FISField(0, 8, 4), "pm_port": FISField(0, 8, 4),
@ -71,6 +71,7 @@ fis_dma_setup_layout = {
"dma_transfer_count": FISField(4, 0, 32) "dma_transfer_count": FISField(4, 0, 32)
} }
fis_data_cmd_len = 1
fis_data_layout = { fis_data_layout = {
"type": FISField(0, 0, 8) "type": FISField(0, 0, 8)
} }
@ -85,7 +86,7 @@ fis_pio_setup_d2h_layout = {
"error": FISField(0, 24, 8), "error": FISField(0, 24, 8),
"lba_lsb": FISField(1, 0, 24), "lba_lsb": FISField(1, 0, 24),
"device": FISField(1, 24, 0), "device": FISField(1, 24, 8),
"lba_msb": FISField(2, 0, 24), "lba_msb": FISField(2, 0, 24),