1
0
mirror of synced 2026-01-18 00:42:34 +00:00

DMA busmaster AES-128-CBC

This commit is contained in:
Romain Dolbeau 2020-12-22 05:14:27 -05:00
parent 7992fd2b94
commit 2eba35f890
3 changed files with 229 additions and 42 deletions

View File

@ -93,6 +93,23 @@ static int rdfpga_wait_aes_ready(struct rdfpga_softc *sc) {
return 0;
}
static int rdfpga_wait_dma_ready(struct rdfpga_softc *sc, const int count) {
u_int32_t ctrl;
int ctr;
ctr = 0;
while (((ctrl = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_REG_DMA_CTRL)) != 0) &&
(ctr < count)) {
delay(1);
ctr ++;
}
if (ctrl)
return EBUSY;
return 0;
}
extern struct cfdriver rdfpga_cd;
@ -283,7 +300,7 @@ rdfpga_write(dev_t dev, struct uio *uio, int flags)
/* aprint_normal_dev(sc->sc_dev, "dma: synced\n"); */
ctrl = ((uint64_t)(RDFPGA_MASK_DMA_CTRL_START | ((nblock-1) & RDFPGA_MASK_DMA_CTRL_BLKCNT))) | ((uint64_t)(uint32_t)(sc->sc_dmamap->dm_segs[0].ds_addr)) << 32;
ctrl = ((uint64_t)(RDFPGA_MASK_DMA_CTRL_START | RDFPGA_MASK_DMA_CTRL_GCM | ((nblock-1) & RDFPGA_MASK_DMA_CTRL_BLKCNT))) | ((uint64_t)(uint32_t)(sc->sc_dmamap->dm_segs[0].ds_addr)) << 32;
/* aprint_normal_dev(sc->sc_dev, "trying 0x%016llx\n", ctrl); */
@ -629,15 +646,12 @@ rdfpga_rijndael128_encrypt(void *key, u_int8_t *blk)
}
}
#if 0
static int
rdfpga_rijndael128_writeivforcbc(void *key, u_int8_t *blk)
{
u_int32_t ctrl;
int ctr;
u_int64_t data[2];
u_int64_t *ptr;
int i;
int i, res;
rdfpga_rijndael_ctx* ctx;
struct rdfpga_softc *sc;
@ -660,7 +674,6 @@ rdfpga_rijndael128_writeivforcbc(void *key, u_int8_t *blk)
return 0;
}
#endif
static void
rdfpga_rijndael128_decrypt(void *key, u_int8_t *blk)
@ -998,6 +1011,73 @@ rdfpga_encdec_aes128cbc(struct rdfpga_softc *sw, struct cryptodesc *crd, void *b
*/
idat = ((char *)uio->uio_iov[ind].iov_base) + k;
if (!ctx->cbc) {
if (rdfpga_rijndael128_writeivforcbc(sw->sw_kschedule, ivp)) {
aprint_error_dev(sw->sc_dev, "rdfpga_rijndael128_crypt: stuck\n");
} else {
ctx->cbc = 1;
}
}
/* ********************************************************************************** */
if ((crd->crd_flags & CRD_F_ENCRYPT) && ctx->cbc && ((uio->uio_iov[ind].iov_len - k) >= 32)) {
bus_dma_segment_t segs;
int rsegs;
size_t tocopy = uio->uio_iov[ind].iov_len - k;
uint64_t ctrl;
/* int error; */
tocopy &= ~(size_t)0x0F;
if (tocopy > RDFPGA_VAL_DMA_MAX_SZ)
tocopy = RDFPGA_VAL_DMA_MAX_SZ;
/* aprint_normal_dev(sw->sc_dev, "AES DMA: %zd @ %p (%d) [from %d]\n", tocopy, idat, ind, k); */
if (bus_dmamem_alloc(sw->sc_dmatag, RDFPGA_VAL_DMA_MAX_SZ, 64, 64, &segs, 1, &rsegs, BUS_DMA_NOWAIT | BUS_DMA_STREAMING)) {
aprint_error_dev(sw->sc_dev, "cannot allocate DVMA memory");
goto afterdma;
}
void* kvap;
if (bus_dmamem_map(sw->sc_dmatag, &segs, 1, RDFPGA_VAL_DMA_MAX_SZ, &kvap, BUS_DMA_NOWAIT)) {
aprint_error_dev(sw->sc_dev, "cannot allocate DVMA address");
bus_dmamem_free(sw->sc_dmatag, &segs, 1);
goto afterdma;
}
if (bus_dmamap_load(sw->sc_dmatag, sw->sc_dmamap, kvap, RDFPGA_VAL_DMA_MAX_SZ, /* kernel space */ NULL,
BUS_DMA_NOWAIT | BUS_DMA_STREAMING | BUS_DMA_WRITE | BUS_DMA_READ)) {
aprint_error_dev(sw->sc_dev, "cannot load dma map");
bus_dmamem_unmap(sw->sc_dmatag, kvap, RDFPGA_VAL_DMA_MAX_SZ);
bus_dmamem_free(sw->sc_dmatag, &segs, 1);
goto afterdma;
}
/* if ((error = uiomove(kvap, tocopy, uio)) != 0) { */
/* aprint_error_dev(sw->sc_dev, "cannot copy from uio space"); */
/* bus_dmamap_unload(sw->sc_dmatag, sw->sc_dmamap); */
/* bus_dmamem_unmap(sw->sc_dmatag, kvap, RDFPGA_VAL_DMA_MAX_SZ); */
/* bus_dmamem_free(sw->sc_dmatag, &segs, 1); */
/* goto afterdma; */
/* } */
memcpy(kvap, idat, tocopy);
bus_dmamap_sync(sw->sc_dmatag, sw->sc_dmamap, 0, tocopy, BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
ctrl = ((uint64_t)(RDFPGA_MASK_DMA_CTRL_START | RDFPGA_MASK_DMA_CTRL_AES | ((tocopy/16)-1))) | ((uint64_t)(uint32_t)(sw->sc_dmamap->dm_segs[0].ds_addr)) << 32;
bus_space_write_8(sw->sc_bustag, sw->sc_bhregs, (RDFPGA_REG_DMA_ADDR), ctrl);
rdfpga_wait_dma_ready(sw, 50000);
bus_dmamap_sync(sw->sc_dmatag, sw->sc_dmamap, 0, tocopy, BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
memcpy(idat, kvap, tocopy);
bus_dmamap_unload(sw->sc_dmatag, sw->sc_dmamap);
bus_dmamem_unmap(sw->sc_dmatag, kvap, RDFPGA_VAL_DMA_MAX_SZ);
bus_dmamem_free(sw->sc_dmatag, &segs, 1);
idat += tocopy;
count += tocopy;
k += tocopy;
i -= tocopy;
}
afterdma:
/* ********************************************************************************** */
while (uio->uio_iov[ind].iov_len >= k + blks &&
i > 0) {
if (crd->crd_flags & CRD_F_ENCRYPT) {

View File

@ -69,7 +69,9 @@ struct rdfpga_softc {
#define RDFPGA_MASK_DMA_CTRL_START 0x80000000
#define RDFPGA_MASK_DMA_CTRL_BUSY 0x40000000 /* unused */
#define RDFPGA_MASK_DMA_CTRL_ERR 0x20000000
/* #define RDFPGA_MASK_DMA_CTRL_RW 0x10000000 */
#define RDFPGA_MASK_DMA_CTRL_WRITE 0x10000000 /* for AES only */
#define RDFPGA_MASK_DMA_CTRL_GCM 0x08000000
#define RDFPGA_MASK_DMA_CTRL_AES 0x04000000
#define RDFPGA_MASK_DMA_CTRL_BLKCNT 0x00000FFF
#define RDFPGA_VAL_DMA_MAX_BLKCNT 4096
/* #define RDFPGA_MASK_DMA_CTRL_SIZ 0x00000F00 */
@ -83,6 +85,7 @@ struct rdfpga_softc {
#define RDFPGA_REG_AES128_OUT (RDFPGA_REG_AES128_BASE + 0x20) /* 4 regs */
#define RDFPGA_REG_AES128_CTRL (RDFPGA_REG_AES128_BASE + 0x30)
/* AES128_CTRL */
#define RDFPGA_MASK_AES128_START 0x80000000
#define RDFPGA_MASK_AES128_BUSY 0x40000000
#define RDFPGA_MASK_AES128_ERR 0x20000000

View File

@ -108,6 +108,9 @@ ENTITY SBusFSM is
CONSTANT REG_INDEX_AES128_OUT3 : integer := 58;
CONSTANT REG_INDEX_AES128_OUT4 : integer := 59;
CONSTANT REG_INDEX_AES128_CTRL : integer := 60;
CONSTANT REG_INDEX_AES128_CTRL2 : integer := 61; -- placeholder
CONSTANT REG_INDEX_AES128_CTRL3 : integer := 62; -- placeholder
CONSTANT REG_INDEX_AES128_CTRL4 : integer := 63; -- placeholder
-- OFFSET to REGS; (8 downto 0) so 9 bits
CONSTANT REG_OFFSET_LED : std_logic_vector(8 downto 0) := conv_std_logic_vector(REG_INDEX_LED *4, 9);
@ -145,6 +148,9 @@ ENTITY SBusFSM is
CONSTANT REG_OFFSET_AES128_OUT3 : std_logic_vector(8 downto 0) := conv_std_logic_vector(REG_INDEX_AES128_OUT3*4, 9);
CONSTANT REG_OFFSET_AES128_OUT4 : std_logic_vector(8 downto 0) := conv_std_logic_vector(REG_INDEX_AES128_OUT4*4, 9);
CONSTANT REG_OFFSET_AES128_CTRL : std_logic_vector(8 downto 0) := conv_std_logic_vector(REG_INDEX_AES128_CTRL*4, 9);
CONSTANT REG_OFFSET_AES128_CTRL2 : std_logic_vector(8 downto 0) := conv_std_logic_vector(REG_INDEX_AES128_CTRL2*4, 9);
CONSTANT REG_OFFSET_AES128_CTRL3 : std_logic_vector(8 downto 0) := conv_std_logic_vector(REG_INDEX_AES128_CTRL3*4, 9);
CONSTANT REG_OFFSET_AES128_CTRL4 : std_logic_vector(8 downto 0) := conv_std_logic_vector(REG_INDEX_AES128_CTRL4*4, 9);
constant c_CLKS_PER_BIT : integer := 417; -- 48M/115200
-- constant c_CLKS_PER_BIT : integer := 50; -- 5.76M/115200
@ -204,7 +210,9 @@ ARCHITECTURE RTL OF SBusFSM IS
SBus_Master_Translation,
SBus_Master_Read,
SBus_Master_Read_Ack,
SBus_Master_Read_Finish
SBus_Master_Read_Finish,
SBus_Master_Write,
SBus_Master_Write_Final
);
TYPE Uart_States IS ( UART_IDLE, UART_WAITING );
TYPE AES_States IS ( AES_IDLE, AES_STARTED, AES_BUSY );
@ -255,7 +263,7 @@ ARCHITECTURE RTL OF SBusFSM IS
-- this means a need to probe-sbus from the PROM to find the board (or warm reset)
SIGNAL OE_COUNTER : natural range 0 to 960000000 := 960000000;
-- 16 registers for GCM (12 used), 4 for DMA (2 used ATM)
-- 16 registers for GCM (12 used), 4 for DMA (2 used ATM), 16 for AES (13 used ATM)
type REGISTERS_TYPE is array(0 to 64) of std_logic_vector(31 downto 0);
SIGNAL REGISTERS : REGISTERS_TYPE;
@ -721,24 +729,39 @@ BEGIN
State <= SBus_Slave_Error;
END IF;
-- _MASTER_
ELSIF (SBUS_3V3_BGs='1' AND REGISTERS(REG_INDEX_DMA_CTRL)(31)='1' AND REGISTERS(REG_INDEX_DMA_CTRL)(30)='0' and REGISTERS(REG_INDEX_DMA_CTRL)(29)='0') then
ELSIF (SBUS_3V3_BGs='1' AND
(REGISTERS(REG_INDEX_DMA_CTRL)(31)='1' AND REGISTERS(REG_INDEX_DMA_CTRL)(30)='0' and REGISTERS(REG_INDEX_DMA_CTRL)(29)='0')
) then
-- we have a DMA request pending and not been granted the bus
IF ((REGISTERS(REG_INDEX_DMA_CTRL)(27) = '1') OR
((REGISTERS(REG_INDEX_DMA_CTRL)(26) = '1') AND (REGISTERS(REG_INDEX_AES128_CTRL) = 0))) THEN
fifo_wr_en <= '1'; fifo_din <= x"61"; -- "a"
-- GCM is always available (1 cycle)
-- for AES don't request the bus unless the AES block is free
-- there could be a race condition for AES if someone write the register before we get the bus...
SBUS_3V3_BRs <= '0'; -- request the bus
ELSE
fifo_wr_en <= '1'; fifo_din <= x"7a"; -- "z"
END IF;
ELSIF (SBUS_3V3_BGs='0') THEN
fifo_wr_en <= '1'; fifo_din <= x"62"; -- "b"
-- we were granted the bus
-- we were granted the bus for DMA
SBUS_3V3_BRs <= '1'; -- relinquish the request (required)
DATA_T <= '0'; -- set data buffer as output
SM_T <= '0'; -- PPRD, SIZ becomes output (master mode)
SMs_T <= '1';
BUF_DATA_O <= REGISTERS(REG_INDEX_DMA_ADDR); -- virt address
BUF_PPRD_O <= '1'; -- reading from slave
IF (REGISTERS(REG_INDEX_DMA_CTRL)(28) = '0') THEN
BUF_PPRD_O <= '1'; -- reading from slave
ELSE
BUF_PPRD_O <= '0'; -- writing to slave
END IF;
-- IF (conv_integer(REGISTERS(REG_INDEX_DMA_CTRL)(11 downto 0)) >= 3) THEN
-- BUF_SIZ_O <= SIZ_BURST16;
-- BURST_LIMIT := 16;
-- ELS
IF (conv_integer(REGISTERS(REG_INDEX_DMA_CTRL)(11 downto 0)) >= 1) THEN
IF ((REGISTERS(REG_INDEX_DMA_CTRL)(27) = '1') AND conv_integer(REGISTERS(REG_INDEX_DMA_CTRL)(11 downto 0)) >= 1) THEN
-- 32 bytes burst only for GCM ATM (bit 27)
BUF_SIZ_O <= SIZ_BURST8;
BURST_LIMIT := 8;
ELSE
@ -915,16 +938,32 @@ BEGIN
-- _MASTER_
when SBus_Master_Translation =>
fifo_wr_en <= '1'; fifo_din <= x"63"; -- "c"
DATA_T <= '1'; -- set buffer back to input
IF ((SBUS_3V3_BGs='0') and (SBUS_3V3_ASs = '0')) THEN
State <= SBus_Master_Read;
ELSIF (BUF_ACKs_I = ACK_ERR) THEN
IF (REGISTERS(REG_INDEX_DMA_CTRL)(28) = '0') THEN
DATA_T <= '1'; -- set buffer back to input
ELSE
DATA_T <= '0';
BUF_DATA_O <= REGISTERS(REG_INDEX_AES128_OUT1);
END IF;
IF (BUF_ACKs_I = ACK_ERR) THEN
fifo_din <= x"2F"; -- "/"
REGISTERS(REG_INDEX_DMA_CTRL)(29) <= '1';
SBus_Set_Default(SBUS_3V3_INT1s, SBUS_3V3_INT7s,
SBUS_DATA_OE_LED, SBUS_DATA_OE_LED_2,
p_addr, DATA_T, SM_T, SMs_T, LED_RESET);
State <= SBus_Idle;
ELSIF (BUF_ACKs_I = ACK_RERUN) THEN
fifo_din <= x"5c"; -- "\"
SBus_Set_Default(SBUS_3V3_INT1s, SBUS_3V3_INT7s,
SBUS_DATA_OE_LED, SBUS_DATA_OE_LED_2,
p_addr, DATA_T, SM_T, SMs_T, LED_RESET);
State <= SBus_Idle;
ELSIF (BUF_ACKs_I = ACK_IDLE) THEN
IF (REGISTERS(REG_INDEX_DMA_CTRL)(28) = '0') THEN
State <= SBus_Master_Read;
ELSE
BURST_COUNTER := BURST_COUNTER + 1; -- should happen only once
State <= SBus_Master_Write;
END IF;
ELSIF (SBUS_3V3_BGs='1') THEN
-- oups, we lost our bus access without error ?!?
fifo_din <= x"21"; -- "!"
@ -937,7 +976,7 @@ BEGIN
when SBus_Master_Read =>
fifo_wr_en <= '1'; fifo_din <= x"64"; -- "d"
if (BUF_ACKs_I = ACK_WORD) THEN
State <= SBus_Master_Read_Ack;
State <= SBus_Master_Read_Ack;
elsif (BUF_ACKS_I = ACK_IDLE) then
State <= SBus_Master_Read;
elsif (BUF_ACKS_I = ACK_RERUN) THEN
@ -961,25 +1000,33 @@ BEGIN
when SBus_Master_Read_Ack =>
fifo_wr_en <= '1'; fifo_din <= x"65"; -- "e"
REGISTERS(REG_INDEX_GCM_INPUT1 + (BURST_COUNTER mod 4)) <= BUF_DATA_I;
BURST_COUNTER := BURST_COUNTER + 1;
IF (finish_gcm) THEN
finish_gcm := false;
REGISTERS(REG_INDEX_GCM_C1) <= reverse_bit_in_byte(mas_c(31 downto 0));
REGISTERS(REG_INDEX_GCM_C2) <= reverse_bit_in_byte(mas_c(63 downto 32));
REGISTERS(REG_INDEX_GCM_C3) <= reverse_bit_in_byte(mas_c(95 downto 64));
REGISTERS(REG_INDEX_GCM_C4) <= reverse_bit_in_byte(mas_c(127 downto 96));
ELSIF (BURST_COUNTER mod 4 = 0) THEN
mas_a(31 downto 0) <= reverse_bit_in_byte(REGISTERS(REG_INDEX_GCM_INPUT1) xor REGISTERS(REG_INDEX_GCM_C1));
mas_a(63 downto 32) <= reverse_bit_in_byte(REGISTERS(REG_INDEX_GCM_INPUT2) xor REGISTERS(REG_INDEX_GCM_C2));
mas_a(95 downto 64) <= reverse_bit_in_byte(REGISTERS(REG_INDEX_GCM_INPUT3) xor REGISTERS(REG_INDEX_GCM_C3));
mas_a(127 downto 96) <= reverse_bit_in_byte(BUF_DATA_I xor REGISTERS(REG_INDEX_GCM_C4)); -- INPUT4 will only be valid next cycle
mas_b(31 downto 0) <= reverse_bit_in_byte(REGISTERS(REG_INDEX_GCM_H1));
mas_b(63 downto 32) <= reverse_bit_in_byte(REGISTERS(REG_INDEX_GCM_H2));
mas_b(95 downto 64) <= reverse_bit_in_byte(REGISTERS(REG_INDEX_GCM_H3));
mas_b(127 downto 96) <= reverse_bit_in_byte(REGISTERS(REG_INDEX_GCM_H4));
finish_gcm := true;
END IF;
IF (REGISTERS(REG_INDEX_DMA_CTRL)(27) = '1') THEN
REGISTERS(REG_INDEX_GCM_INPUT1 + (BURST_COUNTER mod 4)) <= BUF_DATA_I;
BURST_COUNTER := BURST_COUNTER + 1;
IF (finish_gcm) THEN
finish_gcm := false;
REGISTERS(REG_INDEX_GCM_C1) <= reverse_bit_in_byte(mas_c(31 downto 0));
REGISTERS(REG_INDEX_GCM_C2) <= reverse_bit_in_byte(mas_c(63 downto 32));
REGISTERS(REG_INDEX_GCM_C3) <= reverse_bit_in_byte(mas_c(95 downto 64));
REGISTERS(REG_INDEX_GCM_C4) <= reverse_bit_in_byte(mas_c(127 downto 96));
ELSIF (BURST_COUNTER mod 4 = 0) THEN
mas_a(31 downto 0) <= reverse_bit_in_byte(REGISTERS(REG_INDEX_GCM_INPUT1) xor REGISTERS(REG_INDEX_GCM_C1));
mas_a(63 downto 32) <= reverse_bit_in_byte(REGISTERS(REG_INDEX_GCM_INPUT2) xor REGISTERS(REG_INDEX_GCM_C2));
mas_a(95 downto 64) <= reverse_bit_in_byte(REGISTERS(REG_INDEX_GCM_INPUT3) xor REGISTERS(REG_INDEX_GCM_C3));
mas_a(127 downto 96) <= reverse_bit_in_byte(BUF_DATA_I xor REGISTERS(REG_INDEX_GCM_C4)); -- INPUT4 will only be valid next cycle
mas_b(31 downto 0) <= reverse_bit_in_byte(REGISTERS(REG_INDEX_GCM_H1));
mas_b(63 downto 32) <= reverse_bit_in_byte(REGISTERS(REG_INDEX_GCM_H2));
mas_b(95 downto 64) <= reverse_bit_in_byte(REGISTERS(REG_INDEX_GCM_H3));
mas_b(127 downto 96) <= reverse_bit_in_byte(REGISTERS(REG_INDEX_GCM_H4));
finish_gcm := true;
END IF;
ELSIF (REGISTERS(REG_INDEX_DMA_CTRL)(26) = '1') THEN
REGISTERS(REG_INDEX_AES128_DATA1 + (BURST_COUNTER mod 4)) <= BUF_DATA_I;
BURST_COUNTER := BURST_COUNTER + 1;
IF (BURST_COUNTER mod 4 = 0) THEN
REGISTERS(REG_INDEX_AES128_CTRL) <= x"88000000"; -- request to start a CBC block
END IF;
END IF; -- GCM | AES
if (BURST_COUNTER = BURST_LIMIT) THEN
State <= SBus_Master_Read_Finish;
ELSIF (BUF_ACKs_I = ACK_WORD) THEN
@ -1006,6 +1053,7 @@ BEGIN
end IF;
when SBus_Master_Read_Finish =>
-- missing the handling of late error
fifo_wr_en <= '1'; fifo_din <= x"66"; -- "f"
IF (finish_gcm) THEN
finish_gcm := false;
@ -1014,17 +1062,73 @@ BEGIN
REGISTERS(REG_INDEX_GCM_C3) <= reverse_bit_in_byte(mas_c(95 downto 64));
REGISTERS(REG_INDEX_GCM_C4) <= reverse_bit_in_byte(mas_c(127 downto 96));
END IF;
if (REGISTERS(REG_INDEX_DMA_CTRL)(11 downto 0) = ((BURST_LIMIT/4)-1)) THEN
REGISTERS(REG_INDEX_DMA_CTRL) <= (others => '0');
else
REGISTERS(REG_INDEX_DMA_CTRL)(11 downto 0) <= REGISTERS(REG_INDEX_DMA_CTRL)(11 downto 0) - (BURST_LIMIT/4);
REGISTERS(REG_INDEX_DMA_ADDR) <= REGISTERS(REG_INDEX_DMA_ADDR) + (BURST_LIMIT*4);
IF (REGISTERS(REG_INDEX_DMA_CTRL)(27) = '1') THEN
-- GCM just chains read
IF (REGISTERS(REG_INDEX_DMA_CTRL)(11 downto 0) = ((BURST_LIMIT/4)-1)) THEN
-- finished, stop the DMA engine
REGISTERS(REG_INDEX_DMA_CTRL) <= (others => '0');
ELSE
-- move to next block
REGISTERS(REG_INDEX_DMA_CTRL)(11 downto 0) <= REGISTERS(REG_INDEX_DMA_CTRL)(11 downto 0) - (BURST_LIMIT/4);
REGISTERS(REG_INDEX_DMA_ADDR) <= REGISTERS(REG_INDEX_DMA_ADDR) + (BURST_LIMIT*4);
END IF;
ELSIF (REGISTERS(REG_INDEX_DMA_CTRL)(26) = '1') THEN
-- AES must writeback first
REGISTERS(REG_INDEX_DMA_CTRL)(28) <= '1';
END IF;
SBus_Set_Default(SBUS_3V3_INT1s, SBUS_3V3_INT7s,
SBUS_DATA_OE_LED, SBUS_DATA_OE_LED_2,
p_addr, DATA_T, SM_T, SMs_T, LED_RESET);
State <= SBus_Idle;
when SBus_Master_Write =>
fifo_wr_en <= '1'; fifo_din <= x"67"; -- "g"
IF (BUF_ACKs_I = ACK_IDLE) THEN
-- wait some more
ELSIF (BUF_ACKs_I = ACK_WORD) THEN
IF (BURST_COUNTER = BURST_LIMIT) THEN
State <= SBus_Master_Write_Final;
ELSE
BUF_DATA_O <= REGISTERS(REG_INDEX_AES128_OUT1 + (BURST_COUNTER mod 4));
BURST_COUNTER := BURST_COUNTER + 1;
END IF;
elsif (BUF_ACKS_I = ACK_RERUN) THEN
fifo_din <= x"2b"; -- "+"
-- TODO FIXME
-- fall back to idle without changing CTRL
SBus_Set_Default(SBUS_3V3_INT1s, SBUS_3V3_INT7s,
SBUS_DATA_OE_LED, SBUS_DATA_OE_LED_2,
p_addr, DATA_T, SM_T, SMs_T, LED_RESET);
State <= SBus_Idle;
else -- (BUF_ACKS_I = ACK_ERR) or other
fifo_din <= x"27"; -- "'"
-- TODO FIXME
-- fall back to idle while setting error
SBus_Set_Default(SBUS_3V3_INT1s, SBUS_3V3_INT7s,
SBUS_DATA_OE_LED, SBUS_DATA_OE_LED_2,
p_addr, DATA_T, SM_T, SMs_T, LED_RESET);
REGISTERS(REG_INDEX_DMA_CTRL)(29) <= '1';
State <= SBus_Idle;
END IF;
when SBus_Master_Write_Final =>
-- missing the handling of late error
fifo_wr_en <= '1'; fifo_din <= x"68"; -- "h"
IF (REGISTERS(REG_INDEX_DMA_CTRL)(26) = '1') THEN -- should always be true ATM
IF (REGISTERS(REG_INDEX_DMA_CTRL)(11 downto 0) = ((BURST_LIMIT/4)-1)) THEN
-- finished, stop the DMA engine
REGISTERS(REG_INDEX_DMA_CTRL) <= (others => '0');
ELSE
-- move to next block in read mode
REGISTERS(REG_INDEX_DMA_CTRL)(11 downto 0) <= REGISTERS(REG_INDEX_DMA_CTRL)(11 downto 0) - (BURST_LIMIT/4);
REGISTERS(REG_INDEX_DMA_ADDR) <= REGISTERS(REG_INDEX_DMA_ADDR) + (BURST_LIMIT*4);
REGISTERS(REG_INDEX_DMA_CTRL)(28) <= '0';
END IF;
END IF;
SBus_Set_Default(SBUS_3V3_INT1s, SBUS_3V3_INT7s,
SBUS_DATA_OE_LED, SBUS_DATA_OE_LED_2,
p_addr, DATA_T, SM_T, SMs_T, LED_RESET);
State <= SBus_Idle;
-- FALLBACK
WHEN OTHERS => -- include SBus_Start
-- SBUS_OE <= '0'; -- enable all signals -- moved to COUNTER48 timer