From 2eba35f890f3d0522d395eee332cc35f39e3e1e1 Mon Sep 17 00:00:00 2001 From: Romain Dolbeau Date: Tue, 22 Dec 2020 05:14:27 -0500 Subject: [PATCH] DMA busmaster AES-128-CBC --- NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.c | 92 +++++++++++- NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.h | 5 +- sbus-to-ztex-gateware/sbus_fsm.vhd | 174 ++++++++++++++++++----- 3 files changed, 229 insertions(+), 42 deletions(-) diff --git a/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.c b/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.c index e8ac689..f7d392a 100644 --- a/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.c +++ b/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.c @@ -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) { diff --git a/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.h b/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.h index 31445ec..da1fa96 100644 --- a/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.h +++ b/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.h @@ -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 diff --git a/sbus-to-ztex-gateware/sbus_fsm.vhd b/sbus-to-ztex-gateware/sbus_fsm.vhd index d2961c5..984ae3f 100644 --- a/sbus-to-ztex-gateware/sbus_fsm.vhd +++ b/sbus-to-ztex-gateware/sbus_fsm.vhd @@ -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