From 533b26e915026843508d36f662dbbcfa64742065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Mon, 2 Feb 2015 21:10:00 +0100 Subject: Adding initial version of test code for sha256 core. --- sw/test-sha256/Makefile | 11 ++ sw/test-sha256/novena-eim.c | 406 ++++++++++++++++++++++++++++++++++++++++++++ sw/test-sha256/novena-eim.h | 297 ++++++++++++++++++++++++++++++++ sw/test-sha256/test-adder.c | 206 ++++++++++++++++++++++ 4 files changed, 920 insertions(+) create mode 100755 sw/test-sha256/Makefile create mode 100644 sw/test-sha256/novena-eim.c create mode 100644 sw/test-sha256/novena-eim.h create mode 100644 sw/test-sha256/test-adder.c (limited to 'sw') diff --git a/sw/test-sha256/Makefile b/sw/test-sha256/Makefile new file mode 100755 index 0000000..c513ed0 --- /dev/null +++ b/sw/test-sha256/Makefile @@ -0,0 +1,11 @@ +all: test-sha256 + +test-sha256 : test-sha256.o novena-eim.o + gcc -o test-sha256 test-sha256.o novena-eim.o + +test-sha256.o: test-sha256.c novena-eim.h novena-eim.c + gcc -c test-sha256.c + gcc -c novena-eim.c + +clean: + rm -f *.o test-sha256 diff --git a/sw/test-sha256/novena-eim.c b/sw/test-sha256/novena-eim.c new file mode 100644 index 0000000..9ea76ef --- /dev/null +++ b/sw/test-sha256/novena-eim.c @@ -0,0 +1,406 @@ +//------------------------------------------------------------------------------ +// novena-eim.c +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ +#include +#include +#include +#include +#include +#include +#include "novena-eim.h" + + +//------------------------------------------------------------------------------ +// Variables +//------------------------------------------------------------------------------ +static long mem_page_size = 0; +static int mem_dev_fd = -1; +static void * mem_map_ptr = MAP_FAILED; +static off_t mem_base_addr = 0; + + +//------------------------------------------------------------------------------ +int eim_setup() +//------------------------------------------------------------------------------ +{ + // register cleanup function + int ok = atexit(_eim_cleanup); + if (ok != 0) + { printf("ERROR: atexit() failed.\n"); + return -1; + } + + // determine memory page size to use in mmap() + mem_page_size = sysconf(_SC_PAGESIZE); + if (mem_page_size < 1) + { printf("ERROR: sysconf(_SC_PAGESIZE) == %l\n", mem_page_size); + return -1; + } + + // try to open memory device + mem_dev_fd = open(MEMORY_DEVICE, O_RDWR | O_SYNC); + if (mem_dev_fd == -1) + { printf("ERROR: open(%s) failed.\n", MEMORY_DEVICE); + return -1; + } + + /* Several blocks in the CPU have common pins, we can use I/O MUX Controller + * to configure what block will actually use I/O pins. We wait EIM module to be able + * to communicate with the on-board FPGA. Let's configure IOMUXC accordingly. + */ + _eim_setup_iomuxc(); + + /* We need to enable clocking of EIM block in order to be able to use it. + * Let's configure Clock Controller Module accordingly. + */ + _eim_setup_ccm(); + + /* We need to properly configure EIM mode and all the corresponding parameters. + * That's a lot of code, let's do it now. + */ + _eim_setup_eim(); + + + // done + return 1; +} + + +//------------------------------------------------------------------------------ +void _eim_cleanup() +//------------------------------------------------------------------------------ +{ + // unmap memory if needed + if (mem_map_ptr != MAP_FAILED) + { int ok = munmap(mem_map_ptr, mem_page_size); + if (ok != 0) printf("WARNING: munmap() failed.\n"); + } + + // close memory device if needed + if (mem_dev_fd != -1) + { int ok = close(mem_dev_fd); + if (ok != 0) printf("WARNING: close() failed.\n"); + } +} + + +//------------------------------------------------------------------------------ +void _eim_setup_iomuxc() +//------------------------------------------------------------------------------ +{ + // create structures + struct IOMUXC_SW_MUX_CTL_PAD_EIM reg_mux; // mux control register + struct IOMUXC_SW_PAD_CTL_PAD_EIM reg_pad; // pad control register + + // setup mux control register + reg_mux.mux_mode = IOMUXC_MUX_MODE_ALT0; // ALT0 mode must be used for EIM + reg_mux.sion = 0; // forced input not needed + reg_mux.reserved_3 = 0; // must be 0 + reg_mux.reserved_31_5 = 0; // must be 0 + + // setup pad control register + reg_pad.sre = IOMUXC_PAD_CTL_SRE_FAST; // fast slew rate + reg_pad.dse = IOMUXC_PAD_CTL_DSE_33_OHM; // highest drive strength + reg_pad.speed = IOMUXC_PAD_CTL_SPEED_MEDIUM_10; // medium speed + reg_pad.ode = IOMUXC_PAD_CTL_ODE_DISABLED; // open drain not needed + reg_pad.pke = IOMUXC_PAD_CTL_PKE_DISABLED; // neither pull nor keeper are needed + reg_pad.pue = IOMUXC_PAD_CTL_PUE_PULL; // doesn't matter actually, because PKE is disabled + reg_pad.pus = IOMUXC_PAD_CTL_PUS_100K_OHM_PU; // doesn't matter actually, because PKE is disabled + reg_pad.hys = IOMUXC_PAD_CTL_HYS_DISABLED; // use CMOS, not Schmitt trigger input + reg_pad.reserved_2_1 = 0; // must be 0 + reg_pad.reserved_10_8 = 0; // must be 0 + reg_pad.reserved_31_17 = 0; // must be 0 + + // all the pins must be configured to use the same ALT0 mode + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_RW, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD00, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD01, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD02, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD03, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD04, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD05, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD06, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD07, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD08, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD09, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD10, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD11, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD12, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD13, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD14, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD15, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK, (unsigned int *)®_mux); + + // we need to configure all the I/O pads too + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_RW, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD00, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD01, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD02, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD03, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD04, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD05, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD06, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD07, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD08, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD09, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD10, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD11, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD12, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD13, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD14, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD15, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK, (unsigned int *)®_pad); +} + + +//------------------------------------------------------------------------------ +void _eim_setup_ccm() +//------------------------------------------------------------------------------ +{ + // create structure + struct CCM_CCGR6 ccm_ccgr6; + + // read register + eim_read_32(CCM_CCGR6, (unsigned int *)&ccm_ccgr6); + + // modify register + ccm_ccgr6.cg0_usboh3 = CCM_CGR_ON_EXCEPT_STOP; + ccm_ccgr6.cg1_usdhc1 = CCM_CGR_OFF; + ccm_ccgr6.cg2_usdhc2 = CCM_CGR_ON_EXCEPT_STOP; + ccm_ccgr6.cg3_usdhc3 = CCM_CGR_ON_EXCEPT_STOP; + + ccm_ccgr6.cg3_usdhc4 = CCM_CGR_OFF; + ccm_ccgr6.cg5_eim_slow = CCM_CGR_ON_EXCEPT_STOP; + ccm_ccgr6.cg6_vdoaxiclk = CCM_CGR_OFF; + ccm_ccgr6.cg7_vpu = CCM_CGR_OFF; + + ccm_ccgr6.cg8_reserved = 0; + ccm_ccgr6.cg9_reserved = 0; + ccm_ccgr6.cg10_reserved = 0; + ccm_ccgr6.cg11_reserved = 0; + ccm_ccgr6.cg12_reserved = 0; + ccm_ccgr6.cg13_reserved = 0; + ccm_ccgr6.cg14_reserved = 0; + ccm_ccgr6.cg15_reserved = 0; + + // write register + eim_write_32(CCM_CCGR6, (unsigned int *)&ccm_ccgr6); +} + + +//------------------------------------------------------------------------------ +void _eim_setup_eim() +//------------------------------------------------------------------------------ +{ + // create structures + struct EIM_CS_GCR1 gcr1; + struct EIM_CS_GCR2 gcr2; + struct EIM_CS_RCR1 rcr1; + struct EIM_CS_RCR2 rcr2; + struct EIM_CS_WCR1 wcr1; + struct EIM_CS_WCR2 wcr2; + + struct EIM_WCR wcr; + struct EIM_WIAR wiar; + struct EIM_EAR ear; + + // read all the registers + eim_read_32(EIM_CS0GCR1, (unsigned int *)&gcr1); + eim_read_32(EIM_CS0GCR2, (unsigned int *)&gcr2); + eim_read_32(EIM_CS0RCR1, (unsigned int *)&rcr1); + eim_read_32(EIM_CS0RCR2, (unsigned int *)&rcr2); + eim_read_32(EIM_CS0WCR1, (unsigned int *)&wcr1); + eim_read_32(EIM_CS0WCR2, (unsigned int *)&wcr2); + + eim_read_32(EIM_WCR, (unsigned int *)&wcr); + eim_read_32(EIM_WIAR, (unsigned int *)&wiar); + eim_read_32(EIM_EAR, (unsigned int *)&ear); + + // manipulate registers as needed + gcr1.csen = 1; // chip select is enabled | + gcr1.swr = 1; // write is sync | + gcr1.srd = 1; // read is sync | + gcr1.mum = 1; // address and data are multiplexed | + gcr1.wfl = 0; // write latency is not fixed | + gcr1.rfl = 0; // read latency is not fixed | + gcr1.cre = 0; // CRE signal not needed | + //gcr1.crep = x; // don't care, CRE not used | + gcr1.bl = 4; // burst length | ? + gcr1.wc = 0; // write is not continuous | ? + gcr1.bcd = 3; // BCLK divisor is 3+1=4 | + gcr1.bcs = 1; // delay from ~CS to BCLK is 1 cycle | + gcr1.dsz = 1; // 16 bits per databeat at DATA[15:0] | + gcr1.sp = 0; // supervisor protection is disabled | + gcr1.csrec = 1; // ~CS recovery is 1 cycle | + gcr1.aus = 1; // address is not shifted | + gcr1.gbc = 1; // ~CS gap is 1 cycle | + gcr1.wp = 0; // write protection is not enabled | + //gcr1.psz = x; // don't care, page mode is not used | + + gcr2.adh = 0; // address hold duration is 1 cycle | + //gcr2.daps = x; // don't care, DTACK is not used | + gcr2.dae = 0; // DTACK is not used | + //gcr2.dap = x; // don't care, DTACK is not used | + gcr2.mux16_byp_grant = 1; // enable grant mechanism | ? + gcr2.reserved_3_2 = 0; // must be 0 | + gcr2.reserved_11_10 = 0; // must be 0 | + gcr2.reserved_31_13 = 0; // must be 0 | + + //rcr1.rcsn = x; // don't care in sync mode | + rcr1.rcsa = 0; // no delay for ~CS needed | + //rcr1.oen = x; // don't care in sync mode | + rcr1.oea = 0; // no delay for ~OE needed | + rcr1.radvn = 0; // no delay for ~LBA needed | + rcr1.ral = 0; // clear ~LBA when needed | + rcr1.radva = 0; // no delay for ~LBA needed | + rcr1.rwsc = 1; // one wait state | + rcr1.reserved_3 = 0; // must be 0 | + rcr1.reserved_7 = 0; // must be 0 | + rcr1.reserved_11 = 0; // must be 0 | + rcr1.reserved_15 = 0; // must be 0 | + rcr1.reserved_23 = 0; // must be 0 | + rcr1.reserved_31_30 = 0; // must be 0 | + + //rcr2.rben = x; // don't care in sync mode | + rcr2.rbe = 0; // BE is disabled | + //rcr2.rbea = x; // don't care when BE is not used | + rcr2.rl = 0; // read latency is 0 | ? + //rcr2.pat = x; // don't care when page read is not used | + rcr2.apr = 0; // page read mode is not used | + rcr2.reserved_7 = 0; // must be 0 | + rcr2.reserved_11_10 = 0; // must be 0 | + rcr2.reserved_31_16 = 0; // must be 0 | + + //wcr1.wcsn = x; // don't care in sync mode | + wcr1.wcsa = 0; // no delay for ~CS needed | + //wcr1.wen = x; // don't care in sync mode | + wcr1.wea = 0; // no delay for ~WR_N needed | + //wcr1.wben = x; // don't care in sync mode | + //wcr1.wbea = x; // don't care in sync mode | + wcr1.wadvn = 0; // no delay for ~LBA needed | + wcr1.wadva = 0; // no delay for ~LBA needed | + wcr1.wwsc = 1; // no wait state in needed | + wcr1.wbed = 1; // BE is disabled | + wcr1.wal = 0; // clear ~LBA when needed | + + wcr2.wbcdd = 0; // write clock division is not needed | + wcr2.reserved_31_1 = 0; // must be 0 | + + wcr.bcm = 0; // clock is only active during access | + //wcr.gbcd = x; // don't care when BCM=0 | + wcr.inten = 0; // interrupt is not used | + //wcr.intpol = x; // don't care when interrupt is not used | + wcr.wdog_en = 1; // watchdog is enabled | + wcr.wdog_limit = 00; // timeout is 128 BCLK cycles | + wcr.reserved_3 = 0; // must be 0 | + wcr.reserved_7_6 = 0; // must be 0 | + wcr.reserved_31_11 = 0; // must be 0 | + + wiar.ips_req = 0; // IPS not needed | + wiar.ips_ack = 0; // IPS not needed | + //wiar.irq = x; // don't touch | + //wiar.errst = x; // don't touch | + wiar.aclk_en = 1; // clock is enabled | + wiar.reserved_31_5 = 0; // must be 0 | + + //ear.error_addr = x; // read-only | + + // write modified registers + eim_write_32(EIM_CS0GCR1, (unsigned int *)&gcr1); + eim_write_32(EIM_CS0GCR2, (unsigned int *)&gcr2); + eim_write_32(EIM_CS0RCR1, (unsigned int *)&rcr1); + eim_write_32(EIM_CS0RCR2, (unsigned int *)&rcr2); + eim_write_32(EIM_CS0WCR1, (unsigned int *)&wcr1); + eim_write_32(EIM_CS0WCR2, (unsigned int *)&wcr2); + eim_write_32(EIM_WCR, (unsigned int *)&wcr); + eim_write_32(EIM_WIAR, (unsigned int *)&wiar);/* + eim_write_32(EIM_EAR, (unsigned int *)&ear);*/ +} + + +//------------------------------------------------------------------------------ +void eim_write_32(off_t offset, unsigned int *pvalue) +//------------------------------------------------------------------------------ +{ + // calculate memory offset + unsigned int *ptr = (unsigned int *)_eim_calc_offset(offset); + + // write data to memory + memcpy(ptr, pvalue, sizeof(unsigned int)); +} + +//------------------------------------------------------------------------------ +void eim_read_32(off_t offset, unsigned int *pvalue) +//------------------------------------------------------------------------------ +{ + // calculate memory offset + unsigned int *ptr = (unsigned int *)_eim_calc_offset(offset); + + // read data from memory + memcpy(pvalue, ptr, sizeof(unsigned int)); +} + + +//------------------------------------------------------------------------------ +off_t _eim_calc_offset(off_t offset) +//------------------------------------------------------------------------------ +{ + // make sure that memory is mapped + if (mem_map_ptr == MAP_FAILED) _eim_remap_mem(offset); + + // calculate starting and ending addresses of currently mapped page + off_t offset_low = mem_base_addr; + off_t offset_high = mem_base_addr + (mem_page_size - 1); + + // check that offset is in currently mapped page, remap new page otherwise + if ((offset < offset_low) || (offset > offset_high)) _eim_remap_mem(offset); + + // calculate pointer + return (off_t)mem_map_ptr + (offset - mem_base_addr); +} + + +//------------------------------------------------------------------------------ +void _eim_remap_mem(off_t offset) +//------------------------------------------------------------------------------ +{ + // unmap old memory page if needed + if (mem_map_ptr != MAP_FAILED) + { int ok = munmap(mem_map_ptr, mem_page_size); + if (ok != 0) + { printf("ERROR: munmap() failed.\n"); + exit(EXIT_FAILURE); + } + } + + // calculate starting address of new page + while (offset % mem_page_size) offset--; + + // try to map new memory page + mem_map_ptr = mmap(NULL, mem_page_size, PROT_READ | PROT_WRITE, MAP_SHARED, mem_dev_fd, offset); + if (mem_map_ptr == MAP_FAILED) + { printf("ERROR: mmap() failed.\n"); + exit(EXIT_FAILURE); + } + + // save last mapped page address + mem_base_addr = offset; +} + + +//------------------------------------------------------------------------------ +// End-of-File +//------------------------------------------------------------------------------ diff --git a/sw/test-sha256/novena-eim.h b/sw/test-sha256/novena-eim.h new file mode 100644 index 0000000..fdcf5a5 --- /dev/null +++ b/sw/test-sha256/novena-eim.h @@ -0,0 +1,297 @@ +//------------------------------------------------------------------------------ +// novena-eim.h +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Defined Values +//------------------------------------------------------------------------------ +#define MEMORY_DEVICE "/dev/mem" + + +//------------------------------------------------------------------------------ +// IOMUXC Values +//------------------------------------------------------------------------------ +#define IOMUXC_MUX_MODE_ALT0 0 // 000 + +#define IOMUXC_PAD_CTL_SRE_FAST 1 // 1 +#define IOMUXC_PAD_CTL_DSE_33_OHM 7 // 111 +#define IOMUXC_PAD_CTL_SPEED_MEDIUM_10 2 // 10 +#define IOMUXC_PAD_CTL_ODE_DISABLED 0 // 0 +#define IOMUXC_PAD_CTL_PKE_DISABLED 0 // 0 +#define IOMUXC_PAD_CTL_PUE_PULL 1 // 1 +#define IOMUXC_PAD_CTL_PUS_100K_OHM_PU 2 // 10 +#define IOMUXC_PAD_CTL_HYS_DISABLED 0 // 0 + +//------------------------------------------------------------------------------ +// CCM Values +//------------------------------------------------------------------------------ +#define CCM_CGR_OFF 0 // 00 +#define CCM_CGR_ON_EXCEPT_STOP 3 // 11 + + +//------------------------------------------------------------------------------ +// CPU Registers +//------------------------------------------------------------------------------ +enum IMX6DQ_REGISTER_OFFSET +{ + IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B = 0x020E00F8, + IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B = 0x020E0100, + IOMUXC_SW_MUX_CTL_PAD_EIM_RW = 0x020E0104, + IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B = 0x020E0108, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD00 = 0x020E0114, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD01 = 0x020E0118, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD02 = 0x020E011C, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD03 = 0x020E0120, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD04 = 0x020E0124, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD05 = 0x020E0128, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD06 = 0x020E012C, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD07 = 0x020E0130, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD08 = 0x020E0134, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD09 = 0x020E0138, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD10 = 0x020E013C, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD11 = 0x020E0140, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD12 = 0x020E0144, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD13 = 0x020E0148, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD14 = 0x020E014C, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD15 = 0x020E0150, + IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B = 0x020E0154, + IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK = 0x020E0158, + + IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B = 0x020E040C, + IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B = 0x020E0414, + IOMUXC_SW_PAD_CTL_PAD_EIM_RW = 0x020E0418, + IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B = 0x020E041C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD00 = 0x020E0428, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD01 = 0x020E042C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD02 = 0x020E0430, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD03 = 0x020E0434, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD04 = 0x020E0438, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD05 = 0x020E043C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD06 = 0x020E0440, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD07 = 0x020E0444, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD08 = 0x020E0448, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD09 = 0x020E044C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD10 = 0x020E0450, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD11 = 0x020E0454, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD12 = 0x020E0458, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD13 = 0x020E045C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD14 = 0x020E0460, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD15 = 0x020E0464, + IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B = 0x020E0468, + IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK = 0x020E046C, + + CCM_CCGR6 = 0x020C4080, + + EIM_CS0GCR1 = 0x021B8000, + EIM_CS0GCR2 = 0x021B8004, + EIM_CS0RCR1 = 0x021B8008, + EIM_CS0RCR2 = 0x021B800C, + EIM_CS0WCR1 = 0x021B8010, + EIM_CS0WCR2 = 0x021B8014, + + EIM_WCR = 0x021B8090, + EIM_WIAR = 0x021B8094, + EIM_EAR = 0x021B8098, + + EIM_BASE_ADDR = 0x08000000 +}; + + +//------------------------------------------------------------------------------ +struct IOMUXC_SW_MUX_CTL_PAD_EIM +//------------------------------------------------------------------------------ +{ + unsigned int mux_mode : 3; + unsigned int reserved_3 : 1; + unsigned int sion : 1; + unsigned int reserved_31_5 : 27; +}; +//------------------------------------------------------------------------------ +struct IOMUXC_SW_PAD_CTL_PAD_EIM +//------------------------------------------------------------------------------ +{ + unsigned int sre : 1; + unsigned int reserved_2_1 : 2; + unsigned int dse : 3; + unsigned int speed : 2; + unsigned int reserved_10_8 : 3; + unsigned int ode : 1; + unsigned int pke : 1; + unsigned int pue : 1; + unsigned int pus : 2; + unsigned int hys : 1; + unsigned int reserved_31_17 : 15; +}; + + +//------------------------------------------------------------------------------ +struct CCM_CCGR6 +//------------------------------------------------------------------------------ +{ + unsigned int cg0_usboh3 : 2; + unsigned int cg1_usdhc1 : 2; + unsigned int cg2_usdhc2 : 2; + unsigned int cg3_usdhc3 : 2; + + unsigned int cg3_usdhc4 : 2; + unsigned int cg5_eim_slow : 2; + unsigned int cg6_vdoaxiclk : 2; + unsigned int cg7_vpu : 2; + + unsigned int cg8_reserved : 2; + unsigned int cg9_reserved : 2; + unsigned int cg10_reserved : 2; + unsigned int cg11_reserved : 2; + + unsigned int cg12_reserved : 2; + unsigned int cg13_reserved : 2; + unsigned int cg14_reserved : 2; + unsigned int cg15_reserved : 2; +}; + + +//------------------------------------------------------------------------------ +struct EIM_CS_GCR1 +//------------------------------------------------------------------------------ +{ + unsigned int csen : 1; + unsigned int swr : 1; + unsigned int srd : 1; + unsigned int mum : 1; + unsigned int wfl : 1; + unsigned int rfl : 1; + unsigned int cre : 1; + unsigned int crep : 1; + unsigned int bl : 3; + unsigned int wc : 1; + unsigned int bcd : 2; + unsigned int bcs : 2; + unsigned int dsz : 3; + unsigned int sp : 1; + unsigned int csrec : 3; + unsigned int aus : 1; + unsigned int gbc : 3; + unsigned int wp : 1; + unsigned int psz : 4; +}; +//------------------------------------------------------------------------------ +struct EIM_CS_GCR2 +//------------------------------------------------------------------------------ +{ + unsigned int adh : 2; + unsigned int reserved_3_2 : 2; + unsigned int daps : 4; + unsigned int dae : 1; + unsigned int dap : 1; + unsigned int reserved_11_10 : 2; + unsigned int mux16_byp_grant : 1; + unsigned int reserved_31_13 : 19; +}; +//------------------------------------------------------------------------------ +struct EIM_CS_RCR1 +//------------------------------------------------------------------------------ +{ + unsigned int rcsn : 3; + unsigned int reserved_3 : 1; + unsigned int rcsa : 3; + unsigned int reserved_7 : 1; + unsigned int oen : 3; + unsigned int reserved_11 : 1; + unsigned int oea : 3; + unsigned int reserved_15 : 1; + unsigned int radvn : 3; + unsigned int ral : 1; + unsigned int radva : 3; + unsigned int reserved_23 : 1; + unsigned int rwsc : 6; + unsigned int reserved_31_30 : 2; +}; +//------------------------------------------------------------------------------ +struct EIM_CS_RCR2 +//------------------------------------------------------------------------------ +{ + unsigned int rben : 3; + unsigned int rbe : 1; + unsigned int rbea : 3; + unsigned int reserved_7 : 1; + unsigned int rl : 2; + unsigned int reserved_11_10 : 2; + unsigned int pat : 3; + unsigned int apr : 1; + unsigned int reserved_31_16 : 16; +}; +//------------------------------------------------------------------------------ +struct EIM_CS_WCR1 +//------------------------------------------------------------------------------ +{ + unsigned int wcsn : 3; + unsigned int wcsa : 3; + unsigned int wen : 3; + unsigned int wea : 3; + unsigned int wben : 3; + unsigned int wbea : 3; + unsigned int wadvn : 3; + unsigned int wadva : 3; + unsigned int wwsc : 6; + unsigned int wbed : 1; + unsigned int wal : 1; +}; +//------------------------------------------------------------------------------ +struct EIM_CS_WCR2 +//------------------------------------------------------------------------------ +{ + unsigned int wbcdd : 1; + unsigned int reserved_31_1 : 31; +}; +//------------------------------------------------------------------------------ +struct EIM_WCR +//------------------------------------------------------------------------------ +{ + unsigned int bcm : 1; + unsigned int gbcd : 2; + unsigned int reserved_3 : 1; + unsigned int inten : 1; + unsigned int intpol : 1; + unsigned int reserved_7_6 : 2; + unsigned int wdog_en : 1; + unsigned int wdog_limit : 2; + unsigned int reserved_31_11 : 21; +}; +//------------------------------------------------------------------------------ +struct EIM_WIAR +//------------------------------------------------------------------------------ +{ + unsigned int ips_req : 1; + unsigned int ips_ack : 1; + unsigned int irq : 1; + unsigned int errst : 1; + unsigned int aclk_en : 1; + unsigned int reserved_31_5 : 27; +}; +//------------------------------------------------------------------------------ +struct EIM_EAR +//------------------------------------------------------------------------------ +{ + unsigned int error_addr : 32; +}; + + +//------------------------------------------------------------------------------ +// Prototypes +//------------------------------------------------------------------------------ +int eim_setup (); +void eim_write_32 (off_t, unsigned int *); +void eim_read_32 (off_t, unsigned int *); + +void _eim_setup_iomuxc (); +void _eim_setup_ccm (); +void _eim_setup_eim (); +void _eim_cleanup (); +off_t _eim_calc_offset (off_t); +void _eim_remap_mem (off_t); + + +//------------------------------------------------------------------------------ +// End-of-File +//------------------------------------------------------------------------------ diff --git a/sw/test-sha256/test-adder.c b/sw/test-sha256/test-adder.c new file mode 100644 index 0000000..70415d8 --- /dev/null +++ b/sw/test-sha256/test-adder.c @@ -0,0 +1,206 @@ +//------------------------------------------------------------------------------ +// setup-eim.c +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ +#include +#include +#include "novena-eim.h" + + +//------------------------------------------------------------------------------ +// Demo Adder +//------------------------------------------------------------------------------ +#define DEMO_ADDER_BASE_ADDR (0x3210) +#define DEMO_ADDER_REG_X (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (0<<2)) +#define DEMO_ADDER_REG_Y (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (1<<2)) +#define DEMO_ADDER_REG_Z (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (2<<2)) +#define DEMO_ADDER_REG_SC (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (3<<2)) + + +//------------------------------------------------------------------------------ +// Prototypes +//------------------------------------------------------------------------------ +unsigned int demo_adder_test_round (unsigned int, unsigned int); +unsigned int lfsr_next_x (unsigned int); +unsigned int lfsr_next_y (unsigned int); + + +//------------------------------------------------------------------------------ +// Testing Parameters +//------------------------------------------------------------------------------ +const int NUM_TEST_ROUNDS = 10000; +const int PRINT_XYZ_VALUES = 1; + + +//------------------------------------------------------------------------------ +int main() +//------------------------------------------------------------------------------ +{ + // try to setup eim (return value should be 1) + printf("Configuring EIM .. "); + int ok = eim_setup(); + if (ok < 1) + { printf("ERROR\n"); + return EXIT_FAILURE; + } + else printf("OK\n"); + + // run test + int i; + unsigned int x = 0x12341234, y = 0xABCDABCD, zyx; + printf("Testing started.\n"); + for (i=0; i>= 16; + if (sts != ctl) + { printf("ERROR: Adder timeout!\n"); + exit(EXIT_FAILURE); + } + + // read z + unsigned int z; + eim_read_32(DEMO_ADDER_REG_Z, &z); + + // uncomment to trigger an error + /** + z++; + **/ + + // done + return z; +} + + +//------------------------------------------------------------------------------ +unsigned int lfsr_next_x(unsigned int value) +//------------------------------------------------------------------------------ +{ + // + // [32, 31, 29, 28, 27, 25, 24, 23, 21, 19, 17, 14, 10, 6, 4, 2] + // 0 1 3 4 5 7 8 9 11 13 15 18 22 24 28 30 + // + + unsigned int carry = 0; + + carry ^= (value >> 0); + carry ^= (value >> 1); + carry ^= (value >> 3); + carry ^= (value >> 4); + + carry ^= (value >> 5); + carry ^= (value >> 7); + carry ^= (value >> 8); + carry ^= (value >> 9); + + carry ^= (value >> 11); + carry ^= (value >> 13); + carry ^= (value >> 15); + carry ^= (value >> 18); + + carry ^= (value >> 22); + carry ^= (value >> 24); + carry ^= (value >> 28); + carry ^= (value >> 30); + + value >>= 1, value |= (carry << 31); + + return value; +} + + +//------------------------------------------------------------------------------ +unsigned int lfsr_next_y(unsigned int value) +//------------------------------------------------------------------------------ +{ + // + // [32, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 1] + // 0 15 16 17 18 19 20 21 22 23 24 25 26 27 28 31 + // + + unsigned int carry = 0; + + carry ^= (value >> 0); + carry ^= (value >> 15); + carry ^= (value >> 16); + carry ^= (value >> 17); + + carry ^= (value >> 18); + carry ^= (value >> 19); + carry ^= (value >> 20); + carry ^= (value >> 21); + + carry ^= (value >> 22); + carry ^= (value >> 23); + carry ^= (value >> 24); + carry ^= (value >> 25); + + carry ^= (value >> 26); + carry ^= (value >> 27); + carry ^= (value >> 28); + carry ^= (value >> 31); + + value >>= 1, value |= (carry << 31); + + return value; +} + + + +//------------------------------------------------------------------------------ +// End-of-File +//------------------------------------------------------------------------------ -- cgit v1.2.3 From 860671f0cd8d5f31ca93c5d93606e68e015ddb23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Mon, 2 Feb 2015 21:10:45 +0100 Subject: Fixed name. --- sw/test-sha256/test-adder.c | 206 ------------------------------------------- sw/test-sha256/test-sha256.c | 206 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+), 206 deletions(-) delete mode 100644 sw/test-sha256/test-adder.c create mode 100644 sw/test-sha256/test-sha256.c (limited to 'sw') diff --git a/sw/test-sha256/test-adder.c b/sw/test-sha256/test-adder.c deleted file mode 100644 index 70415d8..0000000 --- a/sw/test-sha256/test-adder.c +++ /dev/null @@ -1,206 +0,0 @@ -//------------------------------------------------------------------------------ -// setup-eim.c -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// Headers -//------------------------------------------------------------------------------ -#include -#include -#include "novena-eim.h" - - -//------------------------------------------------------------------------------ -// Demo Adder -//------------------------------------------------------------------------------ -#define DEMO_ADDER_BASE_ADDR (0x3210) -#define DEMO_ADDER_REG_X (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (0<<2)) -#define DEMO_ADDER_REG_Y (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (1<<2)) -#define DEMO_ADDER_REG_Z (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (2<<2)) -#define DEMO_ADDER_REG_SC (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (3<<2)) - - -//------------------------------------------------------------------------------ -// Prototypes -//------------------------------------------------------------------------------ -unsigned int demo_adder_test_round (unsigned int, unsigned int); -unsigned int lfsr_next_x (unsigned int); -unsigned int lfsr_next_y (unsigned int); - - -//------------------------------------------------------------------------------ -// Testing Parameters -//------------------------------------------------------------------------------ -const int NUM_TEST_ROUNDS = 10000; -const int PRINT_XYZ_VALUES = 1; - - -//------------------------------------------------------------------------------ -int main() -//------------------------------------------------------------------------------ -{ - // try to setup eim (return value should be 1) - printf("Configuring EIM .. "); - int ok = eim_setup(); - if (ok < 1) - { printf("ERROR\n"); - return EXIT_FAILURE; - } - else printf("OK\n"); - - // run test - int i; - unsigned int x = 0x12341234, y = 0xABCDABCD, zyx; - printf("Testing started.\n"); - for (i=0; i>= 16; - if (sts != ctl) - { printf("ERROR: Adder timeout!\n"); - exit(EXIT_FAILURE); - } - - // read z - unsigned int z; - eim_read_32(DEMO_ADDER_REG_Z, &z); - - // uncomment to trigger an error - /** - z++; - **/ - - // done - return z; -} - - -//------------------------------------------------------------------------------ -unsigned int lfsr_next_x(unsigned int value) -//------------------------------------------------------------------------------ -{ - // - // [32, 31, 29, 28, 27, 25, 24, 23, 21, 19, 17, 14, 10, 6, 4, 2] - // 0 1 3 4 5 7 8 9 11 13 15 18 22 24 28 30 - // - - unsigned int carry = 0; - - carry ^= (value >> 0); - carry ^= (value >> 1); - carry ^= (value >> 3); - carry ^= (value >> 4); - - carry ^= (value >> 5); - carry ^= (value >> 7); - carry ^= (value >> 8); - carry ^= (value >> 9); - - carry ^= (value >> 11); - carry ^= (value >> 13); - carry ^= (value >> 15); - carry ^= (value >> 18); - - carry ^= (value >> 22); - carry ^= (value >> 24); - carry ^= (value >> 28); - carry ^= (value >> 30); - - value >>= 1, value |= (carry << 31); - - return value; -} - - -//------------------------------------------------------------------------------ -unsigned int lfsr_next_y(unsigned int value) -//------------------------------------------------------------------------------ -{ - // - // [32, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 1] - // 0 15 16 17 18 19 20 21 22 23 24 25 26 27 28 31 - // - - unsigned int carry = 0; - - carry ^= (value >> 0); - carry ^= (value >> 15); - carry ^= (value >> 16); - carry ^= (value >> 17); - - carry ^= (value >> 18); - carry ^= (value >> 19); - carry ^= (value >> 20); - carry ^= (value >> 21); - - carry ^= (value >> 22); - carry ^= (value >> 23); - carry ^= (value >> 24); - carry ^= (value >> 25); - - carry ^= (value >> 26); - carry ^= (value >> 27); - carry ^= (value >> 28); - carry ^= (value >> 31); - - value >>= 1, value |= (carry << 31); - - return value; -} - - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/sw/test-sha256/test-sha256.c b/sw/test-sha256/test-sha256.c new file mode 100644 index 0000000..70415d8 --- /dev/null +++ b/sw/test-sha256/test-sha256.c @@ -0,0 +1,206 @@ +//------------------------------------------------------------------------------ +// setup-eim.c +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ +#include +#include +#include "novena-eim.h" + + +//------------------------------------------------------------------------------ +// Demo Adder +//------------------------------------------------------------------------------ +#define DEMO_ADDER_BASE_ADDR (0x3210) +#define DEMO_ADDER_REG_X (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (0<<2)) +#define DEMO_ADDER_REG_Y (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (1<<2)) +#define DEMO_ADDER_REG_Z (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (2<<2)) +#define DEMO_ADDER_REG_SC (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (3<<2)) + + +//------------------------------------------------------------------------------ +// Prototypes +//------------------------------------------------------------------------------ +unsigned int demo_adder_test_round (unsigned int, unsigned int); +unsigned int lfsr_next_x (unsigned int); +unsigned int lfsr_next_y (unsigned int); + + +//------------------------------------------------------------------------------ +// Testing Parameters +//------------------------------------------------------------------------------ +const int NUM_TEST_ROUNDS = 10000; +const int PRINT_XYZ_VALUES = 1; + + +//------------------------------------------------------------------------------ +int main() +//------------------------------------------------------------------------------ +{ + // try to setup eim (return value should be 1) + printf("Configuring EIM .. "); + int ok = eim_setup(); + if (ok < 1) + { printf("ERROR\n"); + return EXIT_FAILURE; + } + else printf("OK\n"); + + // run test + int i; + unsigned int x = 0x12341234, y = 0xABCDABCD, zyx; + printf("Testing started.\n"); + for (i=0; i>= 16; + if (sts != ctl) + { printf("ERROR: Adder timeout!\n"); + exit(EXIT_FAILURE); + } + + // read z + unsigned int z; + eim_read_32(DEMO_ADDER_REG_Z, &z); + + // uncomment to trigger an error + /** + z++; + **/ + + // done + return z; +} + + +//------------------------------------------------------------------------------ +unsigned int lfsr_next_x(unsigned int value) +//------------------------------------------------------------------------------ +{ + // + // [32, 31, 29, 28, 27, 25, 24, 23, 21, 19, 17, 14, 10, 6, 4, 2] + // 0 1 3 4 5 7 8 9 11 13 15 18 22 24 28 30 + // + + unsigned int carry = 0; + + carry ^= (value >> 0); + carry ^= (value >> 1); + carry ^= (value >> 3); + carry ^= (value >> 4); + + carry ^= (value >> 5); + carry ^= (value >> 7); + carry ^= (value >> 8); + carry ^= (value >> 9); + + carry ^= (value >> 11); + carry ^= (value >> 13); + carry ^= (value >> 15); + carry ^= (value >> 18); + + carry ^= (value >> 22); + carry ^= (value >> 24); + carry ^= (value >> 28); + carry ^= (value >> 30); + + value >>= 1, value |= (carry << 31); + + return value; +} + + +//------------------------------------------------------------------------------ +unsigned int lfsr_next_y(unsigned int value) +//------------------------------------------------------------------------------ +{ + // + // [32, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 1] + // 0 15 16 17 18 19 20 21 22 23 24 25 26 27 28 31 + // + + unsigned int carry = 0; + + carry ^= (value >> 0); + carry ^= (value >> 15); + carry ^= (value >> 16); + carry ^= (value >> 17); + + carry ^= (value >> 18); + carry ^= (value >> 19); + carry ^= (value >> 20); + carry ^= (value >> 21); + + carry ^= (value >> 22); + carry ^= (value >> 23); + carry ^= (value >> 24); + carry ^= (value >> 25); + + carry ^= (value >> 26); + carry ^= (value >> 27); + carry ^= (value >> 28); + carry ^= (value >> 31); + + value >>= 1, value |= (carry << 31); + + return value; +} + + + +//------------------------------------------------------------------------------ +// End-of-File +//------------------------------------------------------------------------------ -- cgit v1.2.3 From a4edc787e4d18b9bc5a6c0a5980b02b81e5cf217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Mon, 2 Feb 2015 21:23:06 +0100 Subject: Completed first test program for sha256 core. --- sw/test-sha256/test-sha256.c | 222 ++++++++----------------------------------- 1 file changed, 39 insertions(+), 183 deletions(-) (limited to 'sw') diff --git a/sw/test-sha256/test-sha256.c b/sw/test-sha256/test-sha256.c index 70415d8..25845d0 100644 --- a/sw/test-sha256/test-sha256.c +++ b/sw/test-sha256/test-sha256.c @@ -1,206 +1,62 @@ -//------------------------------------------------------------------------------ -// setup-eim.c -//------------------------------------------------------------------------------ - +//====================================================================== +// +// test-sha256.c +// ------------- +// test program for Cryptech Novena framwwork with EIM interface +// using the sha256 core. +// +//====================================================================== //------------------------------------------------------------------------------ // Headers //------------------------------------------------------------------------------ #include +#include #include #include "novena-eim.h" //------------------------------------------------------------------------------ -// Demo Adder +// Defines //------------------------------------------------------------------------------ -#define DEMO_ADDER_BASE_ADDR (0x3210) -#define DEMO_ADDER_REG_X (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (0<<2)) -#define DEMO_ADDER_REG_Y (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (1<<2)) -#define DEMO_ADDER_REG_Z (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (2<<2)) -#define DEMO_ADDER_REG_SC (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (3<<2)) - - -//------------------------------------------------------------------------------ -// Prototypes -//------------------------------------------------------------------------------ -unsigned int demo_adder_test_round (unsigned int, unsigned int); -unsigned int lfsr_next_x (unsigned int); -unsigned int lfsr_next_y (unsigned int); +#define SHA256_PREFIX (0x14) +#define SHA_BASE (EIM_BASE_ADDR + SHA256_PREFIX) //------------------------------------------------------------------------------ // Testing Parameters //------------------------------------------------------------------------------ -const int NUM_TEST_ROUNDS = 10000; -const int PRINT_XYZ_VALUES = 1; - - -//------------------------------------------------------------------------------ -int main() -//------------------------------------------------------------------------------ -{ - // try to setup eim (return value should be 1) - printf("Configuring EIM .. "); - int ok = eim_setup(); - if (ok < 1) - { printf("ERROR\n"); - return EXIT_FAILURE; - } - else printf("OK\n"); - - // run test - int i; - unsigned int x = 0x12341234, y = 0xABCDABCD, zyx; - printf("Testing started.\n"); - for (i=0; i>= 16; - if (sts != ctl) - { printf("ERROR: Adder timeout!\n"); - exit(EXIT_FAILURE); - } - - // read z - unsigned int z; - eim_read_32(DEMO_ADDER_REG_Z, &z); - - // uncomment to trigger an error - /** - z++; - **/ - - // done - return z; -} //------------------------------------------------------------------------------ -unsigned int lfsr_next_x(unsigned int value) +// main() //------------------------------------------------------------------------------ +int main() { - // - // [32, 31, 29, 28, 27, 25, 24, 23, 21, 19, 17, 14, 10, 6, 4, 2] - // 0 1 3 4 5 7 8 9 11 13 15 18 22 24 28 30 - // - - unsigned int carry = 0; - - carry ^= (value >> 0); - carry ^= (value >> 1); - carry ^= (value >> 3); - carry ^= (value >> 4); - - carry ^= (value >> 5); - carry ^= (value >> 7); - carry ^= (value >> 8); - carry ^= (value >> 9); - - carry ^= (value >> 11); - carry ^= (value >> 13); - carry ^= (value >> 15); - carry ^= (value >> 18); - - carry ^= (value >> 22); - carry ^= (value >> 24); - carry ^= (value >> 28); - carry ^= (value >> 30); - - value >>= 1, value |= (carry << 31); - - return value; + unsigned int read_addr; + unsigned int read_data; + + // try to setup eim (return value should be 1) + printf("Configuring EIM .. "); + int ok = eim_setup(); + if (ok < 1) { + printf("ERROR\n"); + return EXIT_FAILURE; + } + else { + printf("EIM Setup ok.\n"); + } + + // Dump register contents. See if we have the core. + for (unsigned int i = 0 ; i < 100 ; i += 3) { + read_addr = SHA_BASE + i; + eim_read_32(read_addr, &read_data); + printf("address 0x%08x = 0x%08x\n", read_addr, read_data); + } + + return 0; } - -//------------------------------------------------------------------------------ -unsigned int lfsr_next_y(unsigned int value) -//------------------------------------------------------------------------------ -{ - // - // [32, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 1] - // 0 15 16 17 18 19 20 21 22 23 24 25 26 27 28 31 - // - - unsigned int carry = 0; - - carry ^= (value >> 0); - carry ^= (value >> 15); - carry ^= (value >> 16); - carry ^= (value >> 17); - - carry ^= (value >> 18); - carry ^= (value >> 19); - carry ^= (value >> 20); - carry ^= (value >> 21); - - carry ^= (value >> 22); - carry ^= (value >> 23); - carry ^= (value >> 24); - carry ^= (value >> 25); - - carry ^= (value >> 26); - carry ^= (value >> 27); - carry ^= (value >> 28); - carry ^= (value >> 31); - - value >>= 1, value |= (carry << 31); - - return value; -} - - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ +//====================================================================== +// EOF test-sha256.c +//====================================================================== -- cgit v1.2.3 From f0ded923cc20dbc39336f3f2e8f083033dba6f9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Tue, 3 Feb 2015 21:45:24 +0100 Subject: (1) Updated core selector with logic to connect sha256. (2) Adding test sw that is able to talk to the sha256 core and perform a hash operation. --- sw/test-sha256/test-sha256.c | 107 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 97 insertions(+), 10 deletions(-) (limited to 'sw') diff --git a/sw/test-sha256/test-sha256.c b/sw/test-sha256/test-sha256.c index 25845d0..9f7b331 100644 --- a/sw/test-sha256/test-sha256.c +++ b/sw/test-sha256/test-sha256.c @@ -19,9 +19,13 @@ //------------------------------------------------------------------------------ // Defines //------------------------------------------------------------------------------ -#define SHA256_PREFIX (0x14) +#define SHA256_PREFIX (0x0000) #define SHA_BASE (EIM_BASE_ADDR + SHA256_PREFIX) +#define DEMO_ADDER_BASE_ADDR (EIM_BASE_ADDR + 0x0000) +#define DEMO_ADDER_X_REG (DEMO_ADDER_BASE_ADDR + 0) +#define DEMO_ADDER_Y_REG (DEMO_ADDER_BASE_ADDR + 4) + //------------------------------------------------------------------------------ // Testing Parameters @@ -29,16 +33,104 @@ //------------------------------------------------------------------------------ -// main() //------------------------------------------------------------------------------ -int main() +void test_regs() { unsigned int read_addr; unsigned int read_data; + unsigned int write_addr; + unsigned int write_data; + unsigned int i; + +// +// for (i = 0 ; i < 0x40000 ; i += 4) { +// read_addr = EIM_BASE_ADDR + i; +// eim_read_32(read_addr, &read_data); +// printf("address 0x%08x = 0x%08x\n", read_addr, read_data); +// } + + read_addr = DEMO_ADDER_X_REG; + eim_read_32(read_addr, &read_data); + printf("address 0x%08x = 0x%08x\n", read_addr, read_data); + + read_addr = DEMO_ADDER_Y_REG; + eim_read_32(read_addr, &read_data); + printf("address 0x%08x = 0x%08x\n", read_addr, read_data); + + write_addr = DEMO_ADDER_Y_REG; + write_data = 0xaa55aa55; + eim_write_32(write_addr, &write_data); + + read_addr = DEMO_ADDER_Y_REG; + eim_read_32(read_addr, &read_data); + printf("address 0x%08x = 0x%08x\n", read_addr, read_data); +} + + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +void test_sha256() +{ + unsigned int write_addr; + unsigned int write_data; + unsigned int read_addr; + unsigned int read_data; + int ok; + unsigned int i; + + // Dump register contents. See if we have the core. + for (i = 0 ; i < 200 ; i += 4) { + read_addr = SHA_BASE + i; + eim_read_32(read_addr, &read_data); + printf("address 0x%08x = 0x%08x\n", read_addr, read_data); + } + + // Try to iniate block processing and then dump + write_addr = SHA_BASE + 0x20; + write_data = 0x00000001; + eim_write_32(write_addr, &write_data); + + // Dump register contents. See if we have the core. + for (i = 0 ; i < 200 ; i += 4) { + read_addr = SHA_BASE + i; + eim_read_32(read_addr, &read_data); + printf("address 0x%08x = 0x%08x\n", read_addr, read_data); + } + + // Dump register contents. See if we have the core. + for (i = 0 ; i < 200 ; i += 4) { + read_addr = SHA_BASE + i; + eim_read_32(read_addr, &read_data); + printf("address 0x%08x = 0x%08x\n", read_addr, read_data); + } + + // Dump register contents. See if we have the core. + for (i = 0 ; i < 200 ; i += 4) { + read_addr = SHA_BASE + i; + eim_read_32(read_addr, &read_data); + printf("address 0x%08x = 0x%08x\n", read_addr, read_data); + } + + // Dump register contents. See if we have the core. + for (i = 0 ; i < 200 ; i += 4) { + read_addr = SHA_BASE + i; + eim_read_32(read_addr, &read_data); + printf("address 0x%08x = 0x%08x\n", read_addr, read_data); + } + +} + +//------------------------------------------------------------------------------ +// main() +//------------------------------------------------------------------------------ +int main() +{ + int ok; + unsigned int i; // try to setup eim (return value should be 1) printf("Configuring EIM .. "); - int ok = eim_setup(); + ok = eim_setup(); if (ok < 1) { printf("ERROR\n"); return EXIT_FAILURE; @@ -47,12 +139,7 @@ int main() printf("EIM Setup ok.\n"); } - // Dump register contents. See if we have the core. - for (unsigned int i = 0 ; i < 100 ; i += 3) { - read_addr = SHA_BASE + i; - eim_read_32(read_addr, &read_data); - printf("address 0x%08x = 0x%08x\n", read_addr, read_data); - } + test_sha256(); return 0; } -- cgit v1.2.3 From 39140593d239f5043a762334d8505af8c8de349b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Wed, 4 Feb 2015 17:54:42 +0100 Subject: (1) Adding symbols for all registers in the sha256 api. --- sw/test-sha256/test-sha256.c | 115 +++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 70 deletions(-) (limited to 'sw') diff --git a/sw/test-sha256/test-sha256.c b/sw/test-sha256/test-sha256.c index 9f7b331..9b0fa1d 100644 --- a/sw/test-sha256/test-sha256.c +++ b/sw/test-sha256/test-sha256.c @@ -18,53 +18,49 @@ //------------------------------------------------------------------------------ // Defines +// +// Symbolic names for the SHA256 core API. //------------------------------------------------------------------------------ #define SHA256_PREFIX (0x0000) -#define SHA_BASE (EIM_BASE_ADDR + SHA256_PREFIX) - -#define DEMO_ADDER_BASE_ADDR (EIM_BASE_ADDR + 0x0000) -#define DEMO_ADDER_X_REG (DEMO_ADDER_BASE_ADDR + 0) -#define DEMO_ADDER_Y_REG (DEMO_ADDER_BASE_ADDR + 4) - - -//------------------------------------------------------------------------------ -// Testing Parameters -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -void test_regs() -{ - unsigned int read_addr; - unsigned int read_data; - unsigned int write_addr; - unsigned int write_data; - unsigned int i; - -// -// for (i = 0 ; i < 0x40000 ; i += 4) { -// read_addr = EIM_BASE_ADDR + i; -// eim_read_32(read_addr, &read_data); -// printf("address 0x%08x = 0x%08x\n", read_addr, read_data); -// } - - read_addr = DEMO_ADDER_X_REG; - eim_read_32(read_addr, &read_data); - printf("address 0x%08x = 0x%08x\n", read_addr, read_data); - - read_addr = DEMO_ADDER_Y_REG; - eim_read_32(read_addr, &read_data); - printf("address 0x%08x = 0x%08x\n", read_addr, read_data); - - write_addr = DEMO_ADDER_Y_REG; - write_data = 0xaa55aa55; - eim_write_32(write_addr, &write_data); - - read_addr = DEMO_ADDER_Y_REG; - eim_read_32(read_addr, &read_data); - printf("address 0x%08x = 0x%08x\n", read_addr, read_data); -} +#define SHA256_BASE (EIM_BASE_ADDR + SHA256_PREFIX) + +#define ADDR_NAME0 (SHA256_BASE + (0x00 << 2)) +#define ADDR_NAME1 (SHA256_BASE + (0x01 << 2)) +#define ADDR_VERSION (SHA256_BASE + (0x02 << 2)) + +#define ADDR_CTRL (SHA256_BASE + (0x08 << 2)) +#define CTRL_INIT_BIT 0 +#define CTRL_NEXT_BIT 1 + +#define ADDR_STATUS (SHA256_BASE + (0x09 << 2)) +#define STATUS_READY_BIT 0 +#define STATUS_VALID_BIT 1 + +#define ADDR_BLOCK0 (SHA256_BASE + (0x10 << 2)) +#define ADDR_BLOCK1 (SHA256_BASE + (0x11 << 2)) +#define ADDR_BLOCK2 (SHA256_BASE + (0x12 << 2)) +#define ADDR_BLOCK3 (SHA256_BASE + (0x13 << 2)) +#define ADDR_BLOCK4 (SHA256_BASE + (0x14 << 2)) +#define ADDR_BLOCK5 (SHA256_BASE + (0x15 << 2)) +#define ADDR_BLOCK6 (SHA256_BASE + (0x16 << 2)) +#define ADDR_BLOCK7 (SHA256_BASE + (0x17 << 2)) +#define ADDR_BLOCK8 (SHA256_BASE + (0x18 << 2)) +#define ADDR_BLOCK9 (SHA256_BASE + (0x19 << 2)) +#define ADDR_BLOCK10 (SHA256_BASE + (0x1a << 2)) +#define ADDR_BLOCK11 (SHA256_BASE + (0x1b << 2)) +#define ADDR_BLOCK12 (SHA256_BASE + (0x1c << 2)) +#define ADDR_BLOCK13 (SHA256_BASE + (0x1d << 2)) +#define ADDR_BLOCK14 (SHA256_BASE + (0x1e << 2)) +#define ADDR_BLOCK15 (SHA256_BASE + (0x1f << 2)) + +#define ADDR_DIGEST0 (SHA256_BASE + (0x20 << 2)) +#define ADDR_DIGEST1 (SHA256_BASE + (0x21 << 2)) +#define ADDR_DIGEST2 (SHA256_BASE + (0x22 << 2)) +#define ADDR_DIGEST3 (SHA256_BASE + (0x23 << 2)) +#define ADDR_DIGEST4 (SHA256_BASE + (0x24 << 2)) +#define ADDR_DIGEST5 (SHA256_BASE + (0x25 << 2)) +#define ADDR_DIGEST6 (SHA256_BASE + (0x26 << 2)) +#define ADDR_DIGEST7 (SHA256_BASE + (0x27 << 2)) //------------------------------------------------------------------------------ @@ -80,40 +76,19 @@ void test_sha256() // Dump register contents. See if we have the core. for (i = 0 ; i < 200 ; i += 4) { - read_addr = SHA_BASE + i; + read_addr = SHA256_BASE + i; eim_read_32(read_addr, &read_data); printf("address 0x%08x = 0x%08x\n", read_addr, read_data); } - // Try to iniate block processing and then dump - write_addr = SHA_BASE + 0x20; + // Try to iniate block processing and then dump + write_addr = SHA256_BASE + 0x20; write_data = 0x00000001; eim_write_32(write_addr, &write_data); // Dump register contents. See if we have the core. for (i = 0 ; i < 200 ; i += 4) { - read_addr = SHA_BASE + i; - eim_read_32(read_addr, &read_data); - printf("address 0x%08x = 0x%08x\n", read_addr, read_data); - } - - // Dump register contents. See if we have the core. - for (i = 0 ; i < 200 ; i += 4) { - read_addr = SHA_BASE + i; - eim_read_32(read_addr, &read_data); - printf("address 0x%08x = 0x%08x\n", read_addr, read_data); - } - - // Dump register contents. See if we have the core. - for (i = 0 ; i < 200 ; i += 4) { - read_addr = SHA_BASE + i; - eim_read_32(read_addr, &read_data); - printf("address 0x%08x = 0x%08x\n", read_addr, read_data); - } - - // Dump register contents. See if we have the core. - for (i = 0 ; i < 200 ; i += 4) { - read_addr = SHA_BASE + i; + read_addr = SHA256_BASE + i; eim_read_32(read_addr, &read_data); printf("address 0x%08x = 0x%08x\n", read_addr, read_data); } -- cgit v1.2.3 From d9e90335c5ba49c63f3e86acc72d401ac5138de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Wed, 4 Feb 2015 17:58:51 +0100 Subject: Adding NIST test vectors for single and dual block sha256 tests. Adding function stubs for tests. --- sw/test-sha256/test-sha256.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'sw') diff --git a/sw/test-sha256/test-sha256.c b/sw/test-sha256/test-sha256.c index 9b0fa1d..d87a902 100644 --- a/sw/test-sha256/test-sha256.c +++ b/sw/test-sha256/test-sha256.c @@ -63,6 +63,31 @@ #define ADDR_DIGEST7 (SHA256_BASE + (0x27 << 2)) +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +void test_single_block() +{ + // Single block test vector as specified by NIST. + //tc0 = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018; + //res0 = 256'hBA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD; + + +} + + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +void test_dual_block() +{ + // Dual block test vectors as specified by NIST. + // tc1_0 = 512'h6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70718000000000000000; + // res1_0 = 256'h85E655D6417A17953363376A624CDE5C76E09589CAC5F811CC4B32C1F20E533A; + // tc1_1 = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0; + // res1_1 = 256'h248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1; + + +} + //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void test_sha256() -- cgit v1.2.3 From 34b329c19ca9b24c55cc399db252c7134c18b615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Wed, 4 Feb 2015 18:10:46 +0100 Subject: (1) Adding test code to do single block hash. (2) Adding helper function for reading data from FPGA registers. (3) Moving eim config to separate function. --- sw/test-sha256/test-sha256.c | 89 +++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 29 deletions(-) (limited to 'sw') diff --git a/sw/test-sha256/test-sha256.c b/sw/test-sha256/test-sha256.c index d87a902..bc3190c 100644 --- a/sw/test-sha256/test-sha256.c +++ b/sw/test-sha256/test-sha256.c @@ -63,14 +63,58 @@ #define ADDR_DIGEST7 (SHA256_BASE + (0x27 << 2)) +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +uint32_t get_w32(uint32_t addr) +{ + unsigned int read_addr; + unsigned int read_data; + eim_read_32(read_addr, &read_data); + + return read_data; +} + + //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void test_single_block() { - // Single block test vector as specified by NIST. - //tc0 = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018; - //res0 = 256'hBA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD; + uint32_t write_data; + + write_data = 0x61626380; + eim_write_32(ADDR_BLOCK0, &write_data); + write_data = 0x00000000; + eim_write_32(ADDR_BLOCK1, &write_data); + eim_write_32(ADDR_BLOCK2, &write_data); + eim_write_32(ADDR_BLOCK3, &write_data); + eim_write_32(ADDR_BLOCK4, &write_data); + eim_write_32(ADDR_BLOCK5, &write_data); + eim_write_32(ADDR_BLOCK6, &write_data); + eim_write_32(ADDR_BLOCK7, &write_data); + eim_write_32(ADDR_BLOCK8, &write_data); + eim_write_32(ADDR_BLOCK9, &write_data); + eim_write_32(ADDR_BLOCK10, &write_data); + eim_write_32(ADDR_BLOCK11, &write_data); + eim_write_32(ADDR_BLOCK12, &write_data); + eim_write_32(ADDR_BLOCK13, &write_data); + eim_write_32(ADDR_BLOCK14, &write_data); + write_data = 0x00000018; + eim_write_32(ADDR_BLOCK15, &write_data); + + write_data = 0x00000001; + eim_write_32(ADDR_CTRL, &write_data); + + printf("digest0 = 0x%08x\n", get_w32(ADDR_DIGEST0)); + printf("digest1 = 0x%08x\n", get_w32(ADDR_DIGEST1)); + printf("digest2 = 0x%08x\n", get_w32(ADDR_DIGEST2)); + printf("digest3 = 0x%08x\n", get_w32(ADDR_DIGEST3)); + printf("digest4 = 0x%08x\n", get_w32(ADDR_DIGEST4)); + printf("digest5 = 0x%08x\n", get_w32(ADDR_DIGEST5)); + printf("digest6 = 0x%08x\n", get_w32(ADDR_DIGEST6)); + printf("digest7 = 0x%08x\n", get_w32(ADDR_DIGEST7)); + // What we want to see: + // res0 = 256'hBA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD; } @@ -88,42 +132,21 @@ void test_dual_block() } + //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void test_sha256() { - unsigned int write_addr; - unsigned int write_data; - unsigned int read_addr; - unsigned int read_data; - int ok; - unsigned int i; - - // Dump register contents. See if we have the core. - for (i = 0 ; i < 200 ; i += 4) { - read_addr = SHA256_BASE + i; - eim_read_32(read_addr, &read_data); - printf("address 0x%08x = 0x%08x\n", read_addr, read_data); - } - - // Try to iniate block processing and then dump - write_addr = SHA256_BASE + 0x20; - write_data = 0x00000001; - eim_write_32(write_addr, &write_data); + uint32_t i; - // Dump register contents. See if we have the core. - for (i = 0 ; i < 200 ; i += 4) { - read_addr = SHA256_BASE + i; - eim_read_32(read_addr, &read_data); - printf("address 0x%08x = 0x%08x\n", read_addr, read_data); - } + test_single_block(); } + //------------------------------------------------------------------------------ -// main() //------------------------------------------------------------------------------ -int main() +int config_eim() { int ok; unsigned int i; @@ -139,6 +162,14 @@ int main() printf("EIM Setup ok.\n"); } +} + +//------------------------------------------------------------------------------ +// main() +//------------------------------------------------------------------------------ +int main() +{ + config_eim(); test_sha256(); return 0; -- cgit v1.2.3 From 01669dcd3d341e43e1f1a03f837d3d5aac880009 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Wed, 4 Feb 2015 13:58:27 -0500 Subject: change 'unsigned int' to the more explicit 'uint32_t' --- sw/test-sha256/novena-eim.c | 143 ++++++++++++++-------------- sw/test-sha256/novena-eim.h | 224 ++++++++++++++++++++++---------------------- 2 files changed, 184 insertions(+), 183 deletions(-) (limited to 'sw') diff --git a/sw/test-sha256/novena-eim.c b/sw/test-sha256/novena-eim.c index 9ea76ef..1effff1 100644 --- a/sw/test-sha256/novena-eim.c +++ b/sw/test-sha256/novena-eim.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "novena-eim.h" @@ -38,7 +39,7 @@ int eim_setup() // determine memory page size to use in mmap() mem_page_size = sysconf(_SC_PAGESIZE); if (mem_page_size < 1) - { printf("ERROR: sysconf(_SC_PAGESIZE) == %l\n", mem_page_size); + { printf("ERROR: sysconf(_SC_PAGESIZE) == %ld\n", mem_page_size); return -1; } @@ -117,52 +118,52 @@ void _eim_setup_iomuxc() reg_pad.reserved_31_17 = 0; // must be 0 // all the pins must be configured to use the same ALT0 mode - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_RW, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD00, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD01, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD02, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD03, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD04, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD05, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD06, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD07, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD08, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD09, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD10, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD11, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD12, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD13, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD14, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD15, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK, (unsigned int *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_RW, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD00, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD01, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD02, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD03, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD04, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD05, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD06, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD07, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD08, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD09, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD10, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD11, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD12, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD13, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD14, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD15, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK, (uint32_t *)®_mux); // we need to configure all the I/O pads too - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_RW, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD00, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD01, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD02, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD03, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD04, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD05, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD06, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD07, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD08, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD09, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD10, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD11, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD12, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD13, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD14, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD15, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK, (unsigned int *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_RW, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD00, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD01, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD02, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD03, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD04, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD05, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD06, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD07, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD08, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD09, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD10, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD11, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD12, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD13, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD14, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD15, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK, (uint32_t *)®_pad); } @@ -174,7 +175,7 @@ void _eim_setup_ccm() struct CCM_CCGR6 ccm_ccgr6; // read register - eim_read_32(CCM_CCGR6, (unsigned int *)&ccm_ccgr6); + eim_read_32(CCM_CCGR6, (uint32_t *)&ccm_ccgr6); // modify register ccm_ccgr6.cg0_usboh3 = CCM_CGR_ON_EXCEPT_STOP; @@ -197,7 +198,7 @@ void _eim_setup_ccm() ccm_ccgr6.cg15_reserved = 0; // write register - eim_write_32(CCM_CCGR6, (unsigned int *)&ccm_ccgr6); + eim_write_32(CCM_CCGR6, (uint32_t *)&ccm_ccgr6); } @@ -218,16 +219,16 @@ void _eim_setup_eim() struct EIM_EAR ear; // read all the registers - eim_read_32(EIM_CS0GCR1, (unsigned int *)&gcr1); - eim_read_32(EIM_CS0GCR2, (unsigned int *)&gcr2); - eim_read_32(EIM_CS0RCR1, (unsigned int *)&rcr1); - eim_read_32(EIM_CS0RCR2, (unsigned int *)&rcr2); - eim_read_32(EIM_CS0WCR1, (unsigned int *)&wcr1); - eim_read_32(EIM_CS0WCR2, (unsigned int *)&wcr2); + eim_read_32(EIM_CS0GCR1, (uint32_t *)&gcr1); + eim_read_32(EIM_CS0GCR2, (uint32_t *)&gcr2); + eim_read_32(EIM_CS0RCR1, (uint32_t *)&rcr1); + eim_read_32(EIM_CS0RCR2, (uint32_t *)&rcr2); + eim_read_32(EIM_CS0WCR1, (uint32_t *)&wcr1); + eim_read_32(EIM_CS0WCR2, (uint32_t *)&wcr2); - eim_read_32(EIM_WCR, (unsigned int *)&wcr); - eim_read_32(EIM_WIAR, (unsigned int *)&wiar); - eim_read_32(EIM_EAR, (unsigned int *)&ear); + eim_read_32(EIM_WCR, (uint32_t *)&wcr); + eim_read_32(EIM_WIAR, (uint32_t *)&wiar); + eim_read_32(EIM_EAR, (uint32_t *)&ear); // manipulate registers as needed gcr1.csen = 1; // chip select is enabled | @@ -319,38 +320,38 @@ void _eim_setup_eim() //ear.error_addr = x; // read-only | // write modified registers - eim_write_32(EIM_CS0GCR1, (unsigned int *)&gcr1); - eim_write_32(EIM_CS0GCR2, (unsigned int *)&gcr2); - eim_write_32(EIM_CS0RCR1, (unsigned int *)&rcr1); - eim_write_32(EIM_CS0RCR2, (unsigned int *)&rcr2); - eim_write_32(EIM_CS0WCR1, (unsigned int *)&wcr1); - eim_write_32(EIM_CS0WCR2, (unsigned int *)&wcr2); - eim_write_32(EIM_WCR, (unsigned int *)&wcr); - eim_write_32(EIM_WIAR, (unsigned int *)&wiar);/* - eim_write_32(EIM_EAR, (unsigned int *)&ear);*/ + eim_write_32(EIM_CS0GCR1, (uint32_t *)&gcr1); + eim_write_32(EIM_CS0GCR2, (uint32_t *)&gcr2); + eim_write_32(EIM_CS0RCR1, (uint32_t *)&rcr1); + eim_write_32(EIM_CS0RCR2, (uint32_t *)&rcr2); + eim_write_32(EIM_CS0WCR1, (uint32_t *)&wcr1); + eim_write_32(EIM_CS0WCR2, (uint32_t *)&wcr2); + eim_write_32(EIM_WCR, (uint32_t *)&wcr); + eim_write_32(EIM_WIAR, (uint32_t *)&wiar);/* + eim_write_32(EIM_EAR, (uint32_t *)&ear);*/ } //------------------------------------------------------------------------------ -void eim_write_32(off_t offset, unsigned int *pvalue) +void eim_write_32(off_t offset, uint32_t *pvalue) //------------------------------------------------------------------------------ { // calculate memory offset - unsigned int *ptr = (unsigned int *)_eim_calc_offset(offset); + uint32_t *ptr = (uint32_t *)_eim_calc_offset(offset); // write data to memory - memcpy(ptr, pvalue, sizeof(unsigned int)); + memcpy(ptr, pvalue, sizeof(uint32_t)); } //------------------------------------------------------------------------------ -void eim_read_32(off_t offset, unsigned int *pvalue) +void eim_read_32(off_t offset, uint32_t *pvalue) //------------------------------------------------------------------------------ { // calculate memory offset - unsigned int *ptr = (unsigned int *)_eim_calc_offset(offset); + uint32_t *ptr = (uint32_t *)_eim_calc_offset(offset); // read data from memory - memcpy(pvalue, ptr, sizeof(unsigned int)); + memcpy(pvalue, ptr, sizeof(uint32_t)); } diff --git a/sw/test-sha256/novena-eim.h b/sw/test-sha256/novena-eim.h index fdcf5a5..3d29f77 100644 --- a/sw/test-sha256/novena-eim.h +++ b/sw/test-sha256/novena-eim.h @@ -102,26 +102,26 @@ enum IMX6DQ_REGISTER_OFFSET struct IOMUXC_SW_MUX_CTL_PAD_EIM //------------------------------------------------------------------------------ { - unsigned int mux_mode : 3; - unsigned int reserved_3 : 1; - unsigned int sion : 1; - unsigned int reserved_31_5 : 27; + uint32_t mux_mode : 3; + uint32_t reserved_3 : 1; + uint32_t sion : 1; + uint32_t reserved_31_5 : 27; }; //------------------------------------------------------------------------------ struct IOMUXC_SW_PAD_CTL_PAD_EIM //------------------------------------------------------------------------------ { - unsigned int sre : 1; - unsigned int reserved_2_1 : 2; - unsigned int dse : 3; - unsigned int speed : 2; - unsigned int reserved_10_8 : 3; - unsigned int ode : 1; - unsigned int pke : 1; - unsigned int pue : 1; - unsigned int pus : 2; - unsigned int hys : 1; - unsigned int reserved_31_17 : 15; + uint32_t sre : 1; + uint32_t reserved_2_1 : 2; + uint32_t dse : 3; + uint32_t speed : 2; + uint32_t reserved_10_8 : 3; + uint32_t ode : 1; + uint32_t pke : 1; + uint32_t pue : 1; + uint32_t pus : 2; + uint32_t hys : 1; + uint32_t reserved_31_17 : 15; }; @@ -129,25 +129,25 @@ struct IOMUXC_SW_PAD_CTL_PAD_EIM struct CCM_CCGR6 //------------------------------------------------------------------------------ { - unsigned int cg0_usboh3 : 2; - unsigned int cg1_usdhc1 : 2; - unsigned int cg2_usdhc2 : 2; - unsigned int cg3_usdhc3 : 2; + uint32_t cg0_usboh3 : 2; + uint32_t cg1_usdhc1 : 2; + uint32_t cg2_usdhc2 : 2; + uint32_t cg3_usdhc3 : 2; - unsigned int cg3_usdhc4 : 2; - unsigned int cg5_eim_slow : 2; - unsigned int cg6_vdoaxiclk : 2; - unsigned int cg7_vpu : 2; + uint32_t cg3_usdhc4 : 2; + uint32_t cg5_eim_slow : 2; + uint32_t cg6_vdoaxiclk : 2; + uint32_t cg7_vpu : 2; - unsigned int cg8_reserved : 2; - unsigned int cg9_reserved : 2; - unsigned int cg10_reserved : 2; - unsigned int cg11_reserved : 2; + uint32_t cg8_reserved : 2; + uint32_t cg9_reserved : 2; + uint32_t cg10_reserved : 2; + uint32_t cg11_reserved : 2; - unsigned int cg12_reserved : 2; - unsigned int cg13_reserved : 2; - unsigned int cg14_reserved : 2; - unsigned int cg15_reserved : 2; + uint32_t cg12_reserved : 2; + uint32_t cg13_reserved : 2; + uint32_t cg14_reserved : 2; + uint32_t cg15_reserved : 2; }; @@ -155,125 +155,125 @@ struct CCM_CCGR6 struct EIM_CS_GCR1 //------------------------------------------------------------------------------ { - unsigned int csen : 1; - unsigned int swr : 1; - unsigned int srd : 1; - unsigned int mum : 1; - unsigned int wfl : 1; - unsigned int rfl : 1; - unsigned int cre : 1; - unsigned int crep : 1; - unsigned int bl : 3; - unsigned int wc : 1; - unsigned int bcd : 2; - unsigned int bcs : 2; - unsigned int dsz : 3; - unsigned int sp : 1; - unsigned int csrec : 3; - unsigned int aus : 1; - unsigned int gbc : 3; - unsigned int wp : 1; - unsigned int psz : 4; + uint32_t csen : 1; + uint32_t swr : 1; + uint32_t srd : 1; + uint32_t mum : 1; + uint32_t wfl : 1; + uint32_t rfl : 1; + uint32_t cre : 1; + uint32_t crep : 1; + uint32_t bl : 3; + uint32_t wc : 1; + uint32_t bcd : 2; + uint32_t bcs : 2; + uint32_t dsz : 3; + uint32_t sp : 1; + uint32_t csrec : 3; + uint32_t aus : 1; + uint32_t gbc : 3; + uint32_t wp : 1; + uint32_t psz : 4; }; //------------------------------------------------------------------------------ struct EIM_CS_GCR2 //------------------------------------------------------------------------------ { - unsigned int adh : 2; - unsigned int reserved_3_2 : 2; - unsigned int daps : 4; - unsigned int dae : 1; - unsigned int dap : 1; - unsigned int reserved_11_10 : 2; - unsigned int mux16_byp_grant : 1; - unsigned int reserved_31_13 : 19; + uint32_t adh : 2; + uint32_t reserved_3_2 : 2; + uint32_t daps : 4; + uint32_t dae : 1; + uint32_t dap : 1; + uint32_t reserved_11_10 : 2; + uint32_t mux16_byp_grant : 1; + uint32_t reserved_31_13 : 19; }; //------------------------------------------------------------------------------ struct EIM_CS_RCR1 //------------------------------------------------------------------------------ { - unsigned int rcsn : 3; - unsigned int reserved_3 : 1; - unsigned int rcsa : 3; - unsigned int reserved_7 : 1; - unsigned int oen : 3; - unsigned int reserved_11 : 1; - unsigned int oea : 3; - unsigned int reserved_15 : 1; - unsigned int radvn : 3; - unsigned int ral : 1; - unsigned int radva : 3; - unsigned int reserved_23 : 1; - unsigned int rwsc : 6; - unsigned int reserved_31_30 : 2; + uint32_t rcsn : 3; + uint32_t reserved_3 : 1; + uint32_t rcsa : 3; + uint32_t reserved_7 : 1; + uint32_t oen : 3; + uint32_t reserved_11 : 1; + uint32_t oea : 3; + uint32_t reserved_15 : 1; + uint32_t radvn : 3; + uint32_t ral : 1; + uint32_t radva : 3; + uint32_t reserved_23 : 1; + uint32_t rwsc : 6; + uint32_t reserved_31_30 : 2; }; //------------------------------------------------------------------------------ struct EIM_CS_RCR2 //------------------------------------------------------------------------------ { - unsigned int rben : 3; - unsigned int rbe : 1; - unsigned int rbea : 3; - unsigned int reserved_7 : 1; - unsigned int rl : 2; - unsigned int reserved_11_10 : 2; - unsigned int pat : 3; - unsigned int apr : 1; - unsigned int reserved_31_16 : 16; + uint32_t rben : 3; + uint32_t rbe : 1; + uint32_t rbea : 3; + uint32_t reserved_7 : 1; + uint32_t rl : 2; + uint32_t reserved_11_10 : 2; + uint32_t pat : 3; + uint32_t apr : 1; + uint32_t reserved_31_16 : 16; }; //------------------------------------------------------------------------------ struct EIM_CS_WCR1 //------------------------------------------------------------------------------ { - unsigned int wcsn : 3; - unsigned int wcsa : 3; - unsigned int wen : 3; - unsigned int wea : 3; - unsigned int wben : 3; - unsigned int wbea : 3; - unsigned int wadvn : 3; - unsigned int wadva : 3; - unsigned int wwsc : 6; - unsigned int wbed : 1; - unsigned int wal : 1; + uint32_t wcsn : 3; + uint32_t wcsa : 3; + uint32_t wen : 3; + uint32_t wea : 3; + uint32_t wben : 3; + uint32_t wbea : 3; + uint32_t wadvn : 3; + uint32_t wadva : 3; + uint32_t wwsc : 6; + uint32_t wbed : 1; + uint32_t wal : 1; }; //------------------------------------------------------------------------------ struct EIM_CS_WCR2 //------------------------------------------------------------------------------ { - unsigned int wbcdd : 1; - unsigned int reserved_31_1 : 31; + uint32_t wbcdd : 1; + uint32_t reserved_31_1 : 31; }; //------------------------------------------------------------------------------ struct EIM_WCR //------------------------------------------------------------------------------ { - unsigned int bcm : 1; - unsigned int gbcd : 2; - unsigned int reserved_3 : 1; - unsigned int inten : 1; - unsigned int intpol : 1; - unsigned int reserved_7_6 : 2; - unsigned int wdog_en : 1; - unsigned int wdog_limit : 2; - unsigned int reserved_31_11 : 21; + uint32_t bcm : 1; + uint32_t gbcd : 2; + uint32_t reserved_3 : 1; + uint32_t inten : 1; + uint32_t intpol : 1; + uint32_t reserved_7_6 : 2; + uint32_t wdog_en : 1; + uint32_t wdog_limit : 2; + uint32_t reserved_31_11 : 21; }; //------------------------------------------------------------------------------ struct EIM_WIAR //------------------------------------------------------------------------------ { - unsigned int ips_req : 1; - unsigned int ips_ack : 1; - unsigned int irq : 1; - unsigned int errst : 1; - unsigned int aclk_en : 1; - unsigned int reserved_31_5 : 27; + uint32_t ips_req : 1; + uint32_t ips_ack : 1; + uint32_t irq : 1; + uint32_t errst : 1; + uint32_t aclk_en : 1; + uint32_t reserved_31_5 : 27; }; //------------------------------------------------------------------------------ struct EIM_EAR //------------------------------------------------------------------------------ { - unsigned int error_addr : 32; + uint32_t error_addr : 32; }; @@ -281,8 +281,8 @@ struct EIM_EAR // Prototypes //------------------------------------------------------------------------------ int eim_setup (); -void eim_write_32 (off_t, unsigned int *); -void eim_read_32 (off_t, unsigned int *); +void eim_write_32 (off_t, uint32_t *); +void eim_read_32 (off_t, uint32_t *); void _eim_setup_iomuxc (); void _eim_setup_ccm (); -- cgit v1.2.3 From 1f8d768432dcc54331f569cf1c7e91645f336249 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Wed, 4 Feb 2015 13:59:55 -0500 Subject: port hash_tester to this version of novena_eim --- sw/test-sha256/Makefile | 18 +- sw/test-sha256/hash_tester.c | 541 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 554 insertions(+), 5 deletions(-) create mode 100644 sw/test-sha256/hash_tester.c (limited to 'sw') diff --git a/sw/test-sha256/Makefile b/sw/test-sha256/Makefile index c513ed0..ee8536e 100755 --- a/sw/test-sha256/Makefile +++ b/sw/test-sha256/Makefile @@ -1,11 +1,19 @@ -all: test-sha256 +all: test-sha256 hash_tester + +.c.o: + gcc -c -Wall -o $@ $< test-sha256 : test-sha256.o novena-eim.o gcc -o test-sha256 test-sha256.o novena-eim.o -test-sha256.o: test-sha256.c novena-eim.h novena-eim.c - gcc -c test-sha256.c - gcc -c novena-eim.c +test-sha256.o: test-sha256.c novena-eim.h + +hash_tester : hash_tester.o novena-eim.o + gcc -o hash_tester hash_tester.o novena-eim.o + +hash_tester.o: hash_tester.c novena-eim.h + +novena-eim.o: novena-eim.c novena-eim.h clean: - rm -f *.o test-sha256 + rm -f *.o test-adder test-sha256 hash_tester diff --git a/sw/test-sha256/hash_tester.c b/sw/test-sha256/hash_tester.c new file mode 100644 index 0000000..544e2c5 --- /dev/null +++ b/sw/test-sha256/hash_tester.c @@ -0,0 +1,541 @@ +/* + * hash_tester.c + * -------------- + * This program sends several commands to the coretest_hashes subsystem + * in order to verify the SHA-1, SHA-256 and SHA-512/x hash function + * cores. + * + * Note: This version of the program talks to the FPGA over an EIM bus. + * + * The single and dual block test cases are taken from the + * NIST KAT document: + * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf + * + * + * Authors: Joachim Strömbergson, Paul Selkirk + * Copyright (c) 2014, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "novena-eim.h" + +int debug = 0; +int quiet = 0; +int repeat = 0; + +/* addresses and codes common to all hash cores */ +#define ADDR_NAME0 0x00 +#define ADDR_NAME1 0x04 +#define ADDR_VERSION 0x08 +#define ADDR_CTRL 0x20 +#define CTRL_INIT_CMD 1 +#define CTRL_NEXT_CMD 2 +#define ADDR_STATUS 0x24 +#define STATUS_READY_BIT 1 +#define STATUS_VALID_BIT 2 +#define ADDR_BLOCK 0x40 +#define ADDR_DIGEST 0x80 + +/* addresses and codes for the specific hash cores */ +#define SHA256_PREFIX 0x0000 +#define SHA256_ADDR_BASE EIM_BASE_ADDR + SHA256_PREFIX +#define SHA256_ADDR_NAME0 SHA256_ADDR_BASE + ADDR_NAME0 +#define SHA256_ADDR_NAME1 SHA256_ADDR_BASE + ADDR_NAME1 +#define SHA256_ADDR_VERSION SHA256_ADDR_BASE + ADDR_VERSION +#define SHA256_ADDR_CTRL SHA256_ADDR_BASE + ADDR_CTRL +#define SHA256_ADDR_STATUS SHA256_ADDR_BASE + ADDR_STATUS +#define SHA256_ADDR_BLOCK SHA256_ADDR_BASE + ADDR_BLOCK +#define SHA256_ADDR_DIGEST SHA256_ADDR_BASE + ADDR_DIGEST +#define SHA256_BLOCK_LEN 512 / 8 +#define SHA256_DIGEST_LEN 256 / 8 + +/* SHA-1/SHA-256 One Block Message Sample + Input Message: "abc" */ +const uint8_t NIST_512_SINGLE[] = +{ 0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18 }; + +const uint8_t SHA256_SINGLE_DIGEST[] = +{ 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, + 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, + 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, + 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD }; + +/* SHA-1/SHA-256 Two Block Message Sample + Input Message: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" */ +const uint8_t NIST_512_DOUBLE0[] = +{ 0x61, 0x62, 0x63, 0x64, 0x62, 0x63, 0x64, 0x65, + 0x63, 0x64, 0x65, 0x66, 0x64, 0x65, 0x66, 0x67, + 0x65, 0x66, 0x67, 0x68, 0x66, 0x67, 0x68, 0x69, + 0x67, 0x68, 0x69, 0x6A, 0x68, 0x69, 0x6A, 0x6B, + 0x69, 0x6A, 0x6B, 0x6C, 0x6A, 0x6B, 0x6C, 0x6D, + 0x6B, 0x6C, 0x6D, 0x6E, 0x6C, 0x6D, 0x6E, 0x6F, + 0x6D, 0x6E, 0x6F, 0x70, 0x6E, 0x6F, 0x70, 0x71, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +const uint8_t NIST_512_DOUBLE1[] = +{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0 }; + +const uint8_t SHA256_DOUBLE_DIGEST[] = +{ 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, + 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, + 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, + 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }; + +/* ---------------- test-case low-level code ---------------- */ + +void dump(char *label, const uint8_t *buf, int len) +{ + if (debug) { + int i; + printf("%s [", label); + for (i = 0; i < len; ++i) + printf(" %02x", buf[i]); + printf(" ]\n"); + } +} + +int tc_write(off_t offset, const uint8_t *buf, int len) +{ + dump("write ", buf, len); + + for (; len > 0; offset += 4, buf += 4, len -= 4) { + uint32_t val; + val = htonl(*(uint32_t *)buf); + eim_write_32(offset, &val); + } + + return 0; +} + +int tc_read(off_t offset, uint8_t *buf, int len) +{ + uint8_t *rbuf = buf; + int rlen = len; + + for (; rlen > 0; offset += 4, rbuf += 4, rlen -= 4) { + uint32_t val; + eim_read_32(offset, &val); + *(uint32_t *)rbuf = ntohl(val); + } + + dump("read ", buf, len); + + return 0; +} + +int tc_expected(off_t offset, const uint8_t *expected, int len) +{ + uint8_t *buf; + int i; + + buf = malloc(len); + if (buf == NULL) { + perror("malloc"); + return 1; + } + dump("expect", expected, len); + + if (tc_read(offset, buf, len) != 0) + goto errout; + + for (i = 0; i < len; ++i) + if (buf[i] != expected[i]) { + fprintf(stderr, "response byte %d: expected 0x%02x, got 0x%02x\n", + i, expected[i], buf[i]); + goto errout; + } + + free(buf); + return 0; +errout: + free(buf); + return 1; +} + +int tc_init(off_t offset) +{ + uint8_t buf[4] = { 0, 0, 0, CTRL_INIT_CMD }; + + return tc_write(offset, buf, 4); +} + +int tc_next(off_t offset) +{ + uint8_t buf[4] = { 0, 0, 0, CTRL_NEXT_CMD }; + + return tc_write(offset, buf, 4); +} + +int tc_wait(off_t offset, uint8_t status) +{ + uint8_t buf[4]; + +#if 0 + do { + if (tc_read(offset, buf, 4) != 0) + return 1; + } while (!(buf[3] & status)); + + return 0; +#else + int i; + for (i = 0; i < 10; ++i) { + if (tc_read(offset, buf, 4) != 0) + return 1; + if (buf[3] & status) + return 0; + } + fprintf(stderr, "tc_wait timed out\n"); + return 1; +#endif +} + +int tc_wait_ready(off_t offset) +{ + return tc_wait(offset, STATUS_READY_BIT); +} + +int tc_wait_valid(off_t offset) +{ + return tc_wait(offset, STATUS_VALID_BIT); +} + +/* ---------------- SHA-1 test cases ---------------- */ + +/* TC1: Read name and version from SHA-1 core. */ +int TC1(void) +{ + return 0; +} + +/* TC2: SHA-1 Single block message test as specified by NIST. */ +int TC2(void) +{ + return 0; +} + +/* TC3: SHA-1 Double block message test as specified by NIST. */ +int TC3(void) +{ + return 0; +} + +/* ---------------- SHA-256 test cases ---------------- */ + +/* TC4: Read name and version from SHA-256 core. */ +int TC4(void) +{ + uint8_t name0[4] = { 0x73, 0x68, 0x61, 0x32 }; /* "sha2" */ + uint8_t name1[4] = { 0x2d, 0x32, 0x35, 0x36 }; /* "-256" */ + uint8_t version[4] = { 0x30, 0x2e, 0x38, 0x30 }; /* "0.80" */ + + if (!quiet) + printf("TC4: Reading name, type and version words from SHA-256 core.\n"); + + return + tc_expected(SHA256_ADDR_NAME0, name0, 4) || + tc_expected(SHA256_ADDR_NAME1, name1, 4) || + tc_expected(SHA256_ADDR_VERSION, version, 4); +} + +/* TC5: SHA-256 Single block message test as specified by NIST. */ +int TC5() +{ + const uint8_t *block = NIST_512_SINGLE; + const uint8_t *expected = SHA256_SINGLE_DIGEST; + + if (!quiet) + printf("TC5: Single block message test for SHA-256.\n"); + + return + /* Write block to SHA-256. */ + tc_write(SHA256_ADDR_BLOCK, block, SHA256_BLOCK_LEN) || + /* Start initial block hashing, wait and check status. */ + tc_init(SHA256_ADDR_CTRL) || + tc_wait_valid(SHA256_ADDR_STATUS) || + /* Extract the digest. */ + tc_expected(SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN); +} + +/* TC6: SHA-256 Double block message test as specified by NIST. */ +int TC6() +{ + const uint8_t *block[2] = { NIST_512_DOUBLE0, NIST_512_DOUBLE1 }; + static const uint8_t block0_expected[] = + { 0x85, 0xE6, 0x55, 0xD6, 0x41, 0x7A, 0x17, 0x95, + 0x33, 0x63, 0x37, 0x6A, 0x62, 0x4C, 0xDE, 0x5C, + 0x76, 0xE0, 0x95, 0x89, 0xCA, 0xC5, 0xF8, 0x11, + 0xCC, 0x4B, 0x32, 0xC1, 0xF2, 0x0E, 0x53, 0x3A }; + const uint8_t *expected = SHA256_DOUBLE_DIGEST; + + if (!quiet) + printf("TC6: Double block message test for SHA-256.\n"); + + return + /* Write first block to SHA-256. */ + tc_write(SHA256_ADDR_BLOCK, block[0], SHA256_BLOCK_LEN) || + /* Start initial block hashing, wait and check status. */ + tc_init(SHA256_ADDR_CTRL) || + tc_wait_valid(SHA256_ADDR_STATUS) || + /* Extract the first digest. */ + tc_expected(SHA256_ADDR_DIGEST, block0_expected, SHA256_DIGEST_LEN) || + /* Write second block to SHA-256. */ + tc_write(SHA256_ADDR_BLOCK, block[1], SHA256_BLOCK_LEN) || + /* Start next block hashing, wait and check status. */ + tc_next(SHA256_ADDR_CTRL) || + tc_wait_valid(SHA256_ADDR_STATUS) || + /* Extract the second digest. */ + tc_expected(SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN); +} + +/* TC7: SHA-256 Huge message test. */ +int TC7() +{ + static const uint8_t block[] = + { 0xaa, 0x55, 0xaa, 0x55, 0xde, 0xad, 0xbe, 0xef, + 0x55, 0xaa, 0x55, 0xaa, 0xf0, 0x0f, 0xf0, 0x0f, + 0xaa, 0x55, 0xaa, 0x55, 0xde, 0xad, 0xbe, 0xef, + 0x55, 0xaa, 0x55, 0xaa, 0xf0, 0x0f, 0xf0, 0x0f, + 0xaa, 0x55, 0xaa, 0x55, 0xde, 0xad, 0xbe, 0xef, + 0x55, 0xaa, 0x55, 0xaa, 0xf0, 0x0f, 0xf0, 0x0f, + 0xaa, 0x55, 0xaa, 0x55, 0xde, 0xad, 0xbe, 0xef, + 0x55, 0xaa, 0x55, 0xaa, 0xf0, 0x0f, 0xf0, 0x0f }; + + /* final digest after 1000 iterations */ + static const uint8_t expected[] = + { 0x76, 0x38, 0xf3, 0xbc, 0x50, 0x0d, 0xd1, 0xa6, + 0x58, 0x6d, 0xd4, 0xd0, 0x1a, 0x15, 0x51, 0xaf, + 0xd8, 0x21, 0xd2, 0x35, 0x2f, 0x91, 0x9e, 0x28, + 0xd5, 0x84, 0x2f, 0xab, 0x03, 0xa4, 0x0f, 0x2a }; + + int i, n = 1000; + + if (!quiet) + printf("TC7: Message with %d blocks test for SHA-256.\n", n); + + /* Write block data to SHA-256. */ + if (tc_write(SHA256_ADDR_BLOCK, block, SHA256_BLOCK_LEN)) + return 1; + + /* Start initial block hashing, wait and check status. */ + if (tc_init(SHA256_ADDR_CTRL) || + tc_wait_ready(SHA256_ADDR_STATUS)) + return 1; + + /* First block done. Do the rest. */ + for (i = 1; i < n; ++i) { + /* Start next block hashing, wait and check status. */ + if (tc_next(SHA256_ADDR_CTRL) || + tc_wait_ready(SHA256_ADDR_STATUS)) + return 1; + } + + /* XXX valid is probably set at the same time as ready */ + if (tc_wait_valid(SHA256_ADDR_STATUS)) + return 1; + /* Extract the final digest. */ + return tc_expected(SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN); +} + +/* ---------------- SHA-512 test cases ---------------- */ + +/* TC8: Read name and version from SHA-512 core. */ +int TC8() +{ + return 0; +} + +/* TC9: SHA-512 Single block message test as specified by NIST. + We do this for all modes. */ +int TC9() +{ + return 0; +} + +/* TC10: SHA-512 Double block message test as specified by NIST. + We do this for all modes. */ +int TC10() +{ + return 0; +} + +/* ---------------- main ---------------- */ + +unsigned long iter = 0; +struct timeval tv_start, tv_end; +void sighandler(int unused) +{ + double tv_diff; + + gettimeofday(&tv_end, NULL); + tv_diff = (double)(tv_end.tv_sec - tv_start.tv_sec) + + (double)(tv_end.tv_usec - tv_start.tv_usec)/1000000; + printf("\n%lu iterations in %.3f seconds (%.3f iterations/sec)\n", + iter, tv_diff, (double)iter/tv_diff); + exit(0); +} + +int main(int argc, char *argv[]) +{ + typedef int (*tcfp)(void); + tcfp sha1_tests[] = { TC1, TC2, TC3 }; + tcfp sha256_tests[] = { TC4, TC5, TC6, TC7 }; + tcfp sha512_tests[] = { TC8, TC9, TC10 }; + tcfp all_tests[] = { TC1, TC2, TC3, TC4, TC5, TC6, TC7, TC8, TC9, TC10 }; + + char *usage = "Usage: %s [-h] [-d] [-q] [-r] tc...\n"; + int i, j, opt; + + while ((opt = getopt(argc, argv, "h?dqr")) != -1) { + switch (opt) { + case 'h': + case '?': + printf(usage, argv[0]); + return 0; + case 'd': + debug = 1; + break; + case 'q': + quiet = 1; + break; + case 'r': + repeat = 1; + break; + default: + fprintf(stderr, usage, argv[0]); + return 1; + } + } + + // try to setup eim (return value should be 1) + printf("Configuring EIM .. "); + if (eim_setup() < 1) { + printf("ERROR\n"); + return EXIT_FAILURE; + } + else { + printf("EIM Setup ok.\n"); + } + + if (repeat) { + tcfp tc; + if (optind != argc - 1) { + fprintf(stderr, "only one test case can be repeated\n"); + return 1; + } + j = atoi(argv[optind]); + if (j <= 0 || j > sizeof(all_tests)/sizeof(all_tests[0])) { + fprintf(stderr, "invalid test number %s\n", argv[optind]); + return 1; + } + tc = (all_tests[j - 1]); + srand(time(NULL)); + signal(SIGINT, sighandler); + gettimeofday(&tv_start, NULL); + while (1) { + ++iter; + if ((iter & 0xffff) == 0) { + printf("."); + fflush(stdout); + } + if (tc() != 0) + sighandler(0); + } + return 0; /*NOTREACHED*/ + } + + /* no args == run all tests */ + if (optind >= argc) { + for (j = 0; j < sizeof(all_tests)/sizeof(all_tests[0]); ++j) + if (all_tests[j]() != 0) + return 1; + return 0; + } + + for (i = optind; i < argc; ++i) { + if (strcmp(argv[i], "sha1") == 0) { + for (j = 0; j < sizeof(sha1_tests)/sizeof(sha1_tests[0]); ++j) + if (sha1_tests[j]() != 0) + return 1; + } + else if (strcmp(argv[i], "sha256") == 0) { + for (j = 0; j < sizeof(sha256_tests)/sizeof(sha256_tests[0]); ++j) + if (sha256_tests[j]() != 0) + return 1; + } + else if (strcmp(argv[i], "sha512") == 0) { + for (j = 0; j < sizeof(sha512_tests)/sizeof(sha512_tests[0]); ++j) + if (sha512_tests[j]() != 0) + return 1; + } + else if (strcmp(argv[i], "all") == 0) { + for (j = 0; j < sizeof(all_tests)/sizeof(all_tests[0]); ++j) + if (all_tests[j]() != 0) + return 1; + } + else if (isdigit(argv[i][0]) && + (((j = atoi(argv[i])) > 0) && + (j <= sizeof(all_tests)/sizeof(all_tests[0])))) { + if (all_tests[j - 1]() != 0) + return 1; + } + else { + fprintf(stderr, "unknown test case %s\n", argv[i]); + return 1; + } + } + + return 0; +} -- cgit v1.2.3 From b4f9c86dd621bb75bebaac8cf7389b2d1d4985d2 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Wed, 4 Feb 2015 14:20:20 -0500 Subject: fix a few warnings and one error --- sw/test-sha256/test-sha256.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'sw') diff --git a/sw/test-sha256/test-sha256.c b/sw/test-sha256/test-sha256.c index bc3190c..0ea0d8c 100644 --- a/sw/test-sha256/test-sha256.c +++ b/sw/test-sha256/test-sha256.c @@ -67,9 +67,9 @@ //------------------------------------------------------------------------------ uint32_t get_w32(uint32_t addr) { - unsigned int read_addr; unsigned int read_data; - eim_read_32(read_addr, &read_data); + + eim_read_32(addr, &read_data); return read_data; } @@ -137,7 +137,6 @@ void test_dual_block() //------------------------------------------------------------------------------ void test_sha256() { - uint32_t i; test_single_block(); @@ -149,7 +148,6 @@ void test_sha256() int config_eim() { int ok; - unsigned int i; // try to setup eim (return value should be 1) printf("Configuring EIM .. "); @@ -162,6 +160,7 @@ int config_eim() printf("EIM Setup ok.\n"); } + return EXIT_SUCCESS; } //------------------------------------------------------------------------------ -- cgit v1.2.3 From 13b8166c8989b5e83b0c998279c60c17bf46e890 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Thu, 5 Feb 2015 15:31:33 -0500 Subject: add all SHA cores (hello coretest_hashes) --- sw/test-sha256/hash_tester.c | 299 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 292 insertions(+), 7 deletions(-) (limited to 'sw') diff --git a/sw/test-sha256/hash_tester.c b/sw/test-sha256/hash_tester.c index 544e2c5..978cb82 100644 --- a/sw/test-sha256/hash_tester.c +++ b/sw/test-sha256/hash_tester.c @@ -13,7 +13,7 @@ * * * Authors: Joachim Strömbergson, Paul Selkirk - * Copyright (c) 2014, NORDUnet A/S All rights reserved. + * Copyright (c) 2014-2015, NORDUnet A/S All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -76,8 +76,18 @@ int repeat = 0; #define ADDR_DIGEST 0x80 /* addresses and codes for the specific hash cores */ -#define SHA256_PREFIX 0x0000 -#define SHA256_ADDR_BASE EIM_BASE_ADDR + SHA256_PREFIX +#define SHA1_ADDR_BASE EIM_BASE_ADDR + 0x1000 +#define SHA1_ADDR_NAME0 SHA1_ADDR_BASE + ADDR_NAME0 +#define SHA1_ADDR_NAME1 SHA1_ADDR_BASE + ADDR_NAME1 +#define SHA1_ADDR_VERSION SHA1_ADDR_BASE + ADDR_VERSION +#define SHA1_ADDR_CTRL SHA1_ADDR_BASE + ADDR_CTRL +#define SHA1_ADDR_STATUS SHA1_ADDR_BASE + ADDR_STATUS +#define SHA1_ADDR_BLOCK SHA1_ADDR_BASE + ADDR_BLOCK +#define SHA1_ADDR_DIGEST SHA1_ADDR_BASE + ADDR_DIGEST +#define SHA1_BLOCK_LEN 512 / 8 +#define SHA1_DIGEST_LEN 160 / 8 + +#define SHA256_ADDR_BASE EIM_BASE_ADDR + 0x2000 #define SHA256_ADDR_NAME0 SHA256_ADDR_BASE + ADDR_NAME0 #define SHA256_ADDR_NAME1 SHA256_ADDR_BASE + ADDR_NAME1 #define SHA256_ADDR_VERSION SHA256_ADDR_BASE + ADDR_VERSION @@ -88,6 +98,24 @@ int repeat = 0; #define SHA256_BLOCK_LEN 512 / 8 #define SHA256_DIGEST_LEN 256 / 8 +#define SHA512_ADDR_BASE EIM_BASE_ADDR + 0x3000 +#define SHA512_ADDR_NAME0 SHA512_ADDR_BASE + ADDR_NAME0 +#define SHA512_ADDR_NAME1 SHA512_ADDR_BASE + ADDR_NAME1 +#define SHA512_ADDR_VERSION SHA512_ADDR_BASE + ADDR_VERSION +#define SHA512_ADDR_CTRL SHA512_ADDR_BASE + ADDR_CTRL +#define SHA512_ADDR_STATUS SHA512_ADDR_BASE + ADDR_STATUS +#define SHA512_ADDR_BLOCK SHA512_ADDR_BASE + ADDR_BLOCK +#define SHA512_ADDR_DIGEST SHA512_ADDR_BASE + 0x100 +#define SHA512_BLOCK_LEN 1024 / 8 +#define SHA512_224_DIGEST_LEN 224 / 8 +#define SHA512_256_DIGEST_LEN 256 / 8 +#define SHA384_DIGEST_LEN 384 / 8 +#define SHA512_DIGEST_LEN 512 / 8 +#define MODE_SHA_512_224 0 << 2 +#define MODE_SHA_512_256 1 << 2 +#define MODE_SHA_384 2 << 2 +#define MODE_SHA_512 3 << 2 + /* SHA-1/SHA-256 One Block Message Sample Input Message: "abc" */ const uint8_t NIST_512_SINGLE[] = @@ -100,6 +128,11 @@ const uint8_t NIST_512_SINGLE[] = 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18 }; +const uint8_t SHA1_SINGLE_DIGEST[] = +{ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, + 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, + 0x9c, 0xd0, 0xd8, 0x9d }; + const uint8_t SHA256_SINGLE_DIGEST[] = { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, @@ -127,12 +160,129 @@ const uint8_t NIST_512_DOUBLE1[] = 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0 }; +const uint8_t SHA1_DOUBLE_DIGEST[] = +{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, + 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, + 0xE5, 0x46, 0x70, 0xF1 }; + const uint8_t SHA256_DOUBLE_DIGEST[] = { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }; +/* SHA-512 One Block Message Sample + Input Message: "abc" */ +const uint8_t NIST_1024_SINGLE[] = +{ 0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18 }; + +const uint8_t SHA512_224_SINGLE_DIGEST[] = +{ 0x46, 0x34, 0x27, 0x0f, 0x70, 0x7b, 0x6a, 0x54, + 0xda, 0xae, 0x75, 0x30, 0x46, 0x08, 0x42, 0xe2, + 0x0e, 0x37, 0xed, 0x26, 0x5c, 0xee, 0xe9, 0xa4, + 0x3e, 0x89, 0x24, 0xaa }; +const uint8_t SHA512_256_SINGLE_DIGEST[] = +{ 0x53, 0x04, 0x8e, 0x26, 0x81, 0x94, 0x1e, 0xf9, + 0x9b, 0x2e, 0x29, 0xb7, 0x6b, 0x4c, 0x7d, 0xab, + 0xe4, 0xc2, 0xd0, 0xc6, 0x34, 0xfc, 0x6d, 0x46, + 0xe0, 0xe2, 0xf1, 0x31, 0x07, 0xe7, 0xaf, 0x23 }; +const uint8_t SHA384_SINGLE_DIGEST[] = +{ 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, + 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, + 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, + 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, + 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, + 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 }; +const uint8_t SHA512_SINGLE_DIGEST[] = +{ 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, + 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, + 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, + 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, + 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, + 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, + 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, + 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }; + +/* SHA-512 Two Block Message Sample + Input Message: "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" */ +const uint8_t NIST_1024_DOUBLE0[] = +{ 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, + 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, + 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, + 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, + 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, + 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, + 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +const uint8_t NIST_1024_DOUBLE1[] = +{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80 }; + +const uint8_t SHA512_224_DOUBLE_DIGEST[] = +{ 0x23, 0xfe, 0xc5, 0xbb, 0x94, 0xd6, 0x0b, 0x23, + 0x30, 0x81, 0x92, 0x64, 0x0b, 0x0c, 0x45, 0x33, + 0x35, 0xd6, 0x64, 0x73, 0x4f, 0xe4, 0x0e, 0x72, + 0x68, 0x67, 0x4a, 0xf9 }; +const uint8_t SHA512_256_DOUBLE_DIGEST[] = +{ 0x39, 0x28, 0xe1, 0x84, 0xfb, 0x86, 0x90, 0xf8, + 0x40, 0xda, 0x39, 0x88, 0x12, 0x1d, 0x31, 0xbe, + 0x65, 0xcb, 0x9d, 0x3e, 0xf8, 0x3e, 0xe6, 0x14, + 0x6f, 0xea, 0xc8, 0x61, 0xe1, 0x9b, 0x56, 0x3a }; +const uint8_t SHA384_DOUBLE_DIGEST[] = +{ 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, + 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, + 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, + 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, + 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, + 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 }; +const uint8_t SHA512_DOUBLE_DIGEST[] = +{ 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, + 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, + 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, + 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, + 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, + 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, + 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, + 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }; + /* ---------------- test-case low-level code ---------------- */ void dump(char *label, const uint8_t *buf, int len) @@ -257,19 +407,68 @@ int tc_wait_valid(off_t offset) /* TC1: Read name and version from SHA-1 core. */ int TC1(void) { - return 0; + uint8_t name0[4] = { 0x73, 0x68, 0x61, 0x31 }; /* "sha1" */ + uint8_t name1[4] = { 0x20, 0x20, 0x20, 0x20 }; /* " " */ + uint8_t version[4] = { 0x30, 0x2e, 0x35, 0x30 }; /* "0.50" */ + + if (!quiet) + printf("TC1: Reading name, type and version words from SHA-1 core.\n"); + + return + tc_expected(SHA1_ADDR_NAME0, name0, 4) || + tc_expected(SHA1_ADDR_NAME1, name1, 4) || + tc_expected(SHA1_ADDR_VERSION, version, 4); } /* TC2: SHA-1 Single block message test as specified by NIST. */ int TC2(void) { - return 0; + const uint8_t *block = NIST_512_SINGLE; + const uint8_t *expected = SHA1_SINGLE_DIGEST; + int ret; + + if (!quiet) + printf("TC2: Single block message test for SHA-1.\n"); + + /* Write block to SHA-1. */ + tc_write(SHA1_ADDR_BLOCK, block, SHA1_BLOCK_LEN); + /* Start initial block hashing, wait and check status. */ + tc_init(SHA1_ADDR_CTRL); + tc_wait_valid(SHA1_ADDR_STATUS); + /* Extract the digest. */ + ret = tc_expected(SHA1_ADDR_DIGEST, expected, SHA1_DIGEST_LEN); + return ret; } /* TC3: SHA-1 Double block message test as specified by NIST. */ int TC3(void) { - return 0; + const uint8_t *block[2] = { NIST_512_DOUBLE0, NIST_512_DOUBLE1 }; + static const uint8_t block0_expected[] = + { 0xF4, 0x28, 0x68, 0x18, 0xC3, 0x7B, 0x27, 0xAE, + 0x04, 0x08, 0xF5, 0x81, 0x84, 0x67, 0x71, 0x48, + 0x4A, 0x56, 0x65, 0x72 }; + const uint8_t *expected = SHA1_DOUBLE_DIGEST; + int ret; + + if (!quiet) + printf("TC3: Double block message test for SHA-1.\n"); + + /* Write first block to SHA-1. */ + tc_write(SHA1_ADDR_BLOCK, block[0], SHA1_BLOCK_LEN); + /* Start initial block hashing, wait and check status. */ + tc_init(SHA1_ADDR_CTRL); + tc_wait_valid(SHA1_ADDR_STATUS); + /* Extract the first digest. */ + tc_expected(SHA1_ADDR_DIGEST, block0_expected, SHA1_DIGEST_LEN); + /* Write second block to SHA-1. */ + tc_write(SHA1_ADDR_BLOCK, block[1], SHA1_BLOCK_LEN); + /* Start next block hashing, wait and check status. */ + tc_next(SHA1_ADDR_CTRL); + tc_wait_valid(SHA1_ADDR_STATUS); + /* Extract the second digest. */ + ret = tc_expected(SHA1_ADDR_DIGEST, expected, SHA1_DIGEST_LEN); + return ret; } /* ---------------- SHA-256 test cases ---------------- */ @@ -394,20 +593,106 @@ int TC7() /* TC8: Read name and version from SHA-512 core. */ int TC8() { - return 0; + uint8_t name0[4] = { 0x73, 0x68, 0x61, 0x32 }; /* "sha2" */ + uint8_t name1[4] = { 0x2d, 0x35, 0x31, 0x32 }; /* "-512" */ + uint8_t version[4] = { 0x30, 0x2e, 0x38, 0x30 }; /* "0.80" */ + + if (!quiet) + printf("TC8: Reading name, type and version words from SHA-512 core.\n"); + + return + tc_expected(SHA512_ADDR_NAME0, name0, 4) || + tc_expected(SHA512_ADDR_NAME1, name1, 4) || + tc_expected(SHA512_ADDR_VERSION, version, 4); } /* TC9: SHA-512 Single block message test as specified by NIST. We do this for all modes. */ +int tc9(int mode, const uint8_t *expected, int digest_len) +{ + const uint8_t *block = NIST_1024_SINGLE; + uint8_t init[4] = { 0, 0, 0, CTRL_INIT_CMD + mode }; + + return + /* Write block to SHA-512. */ + tc_write(SHA512_ADDR_BLOCK, block, SHA512_BLOCK_LEN) || + /* Start initial block hashing, wait and check status. */ + tc_write(SHA512_ADDR_CTRL, init, 4) || + tc_wait_valid(SHA512_ADDR_STATUS) || + /* Extract the digest. */ + tc_expected(SHA512_ADDR_DIGEST, expected, digest_len); +} + int TC9() { + if (!quiet) + printf("TC9-1: Single block message test for SHA-512/224.\n"); + if (tc9(MODE_SHA_512_224, SHA512_224_SINGLE_DIGEST, SHA512_224_DIGEST_LEN) != 0) + return 1; + + if (!quiet) + printf("TC9-2: Single block message test for SHA-512/256.\n"); + if (tc9(MODE_SHA_512_256, SHA512_256_SINGLE_DIGEST, SHA512_256_DIGEST_LEN) != 0) + return 1; + + if (!quiet) + printf("TC9-3: Single block message test for SHA-384.\n"); + if (tc9(MODE_SHA_384, SHA384_SINGLE_DIGEST, SHA384_DIGEST_LEN) != 0) + return 1; + + if (!quiet) + printf("TC9-4: Single block message test for SHA-512.\n"); + if (tc9(MODE_SHA_512, SHA512_SINGLE_DIGEST, SHA512_DIGEST_LEN) != 0) + return 1; + return 0; } /* TC10: SHA-512 Double block message test as specified by NIST. We do this for all modes. */ +int tc10(int mode, const uint8_t *expected, int digest_len) +{ + const uint8_t *block[2] = { NIST_1024_DOUBLE0, NIST_1024_DOUBLE1 }; + uint8_t init[4] = { 0, 0, 0, CTRL_INIT_CMD + mode }; + uint8_t next[4] = { 0, 0, 0, CTRL_NEXT_CMD + mode }; + + return + /* Write first block to SHA-512. */ + tc_write(SHA512_ADDR_BLOCK, block[0], SHA512_BLOCK_LEN) || + /* Start initial block hashing, wait and check status. */ + tc_write(SHA512_ADDR_CTRL, init, 4) || + tc_wait_ready(SHA512_ADDR_STATUS) || + /* Write second block to SHA-512. */ + tc_write(SHA512_ADDR_BLOCK, block[1], SHA512_BLOCK_LEN) || + /* Start next block hashing, wait and check status. */ + tc_write(SHA512_ADDR_CTRL, next, 4) || + tc_wait_valid(SHA512_ADDR_STATUS) || + /* Extract the digest. */ + tc_expected(SHA512_ADDR_DIGEST, expected, digest_len); +} + int TC10() { + if (!quiet) + printf("TC10-1: Double block message test for SHA-512/224.\n"); + if (tc10(MODE_SHA_512_224, SHA512_224_DOUBLE_DIGEST, SHA512_224_DIGEST_LEN) != 0) + return 1; + + if (!quiet) + printf("TC10-2: Double block message test for SHA-512/256.\n"); + if (tc10(MODE_SHA_512_256, SHA512_256_DOUBLE_DIGEST, SHA512_256_DIGEST_LEN) != 0) + return 1; + + if (!quiet) + printf("TC10-3: Double block message test for SHA-384.\n"); + if (tc10(MODE_SHA_384, SHA384_DOUBLE_DIGEST, SHA384_DIGEST_LEN) != 0) + return 1; + + if (!quiet) + printf("TC10-4: Double block message test for SHA-512.\n"); + if (tc10(MODE_SHA_512, SHA512_DOUBLE_DIGEST, SHA512_DIGEST_LEN) != 0) + return 1; + return 0; } -- cgit v1.2.3 From 560ebacb0c576b92d7b64d728423683ad974885e Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Tue, 10 Feb 2015 12:03:47 -0500 Subject: Updates from Pavel with new mux. 1. EIM arbiter was updated to take advantage of 3 additional address lines, that bunnie routed from the CPU to the FPGA. Now we have 19 address lines instead of 16, that means 19-2=17 effective bits when using 32-bit access. 2. In the doc directory there's a draft version of current EIM memory map. 3. I've figured out why you guys could not use read and write signals from the arbiter the way they were supposed to be used. I was wrong when I expected Joachim's cores to have registered outputs. They have a combinatorial output in fact. EIM arbiter's minimum latency is 1 cycle, so we have to register data coming out of cores. I've added these three lines to every core wrapper (sha1.v, sha256.v and sha512.v): reg [31 : 0] tmp_read_data_reg; always @(posedge clk) tmp_read_data_reg <= tmp_read_data; assign read_data = tmp_read_data_reg; 4. Joachim told me, that we are going to have different types of cores (HASH, RNG, CIPHER and so on), so I redesigned EIM multiplexor to have separate modules for every core type. RNG and CIPHER selectors right now are just templates with some dummy registers. Here is what was modified in the HASH multiplexor: 4a. Core number 0 was added. It is not an actual HASH core, but a set of global (board-level) registers. I've added three registers so far: board type, bitstream version and one writeable dummy general-purpose register. 4b. Core instantiation was made conditional to allow selecting of what cores to actually implement. We can have a project that offers a large number of cores, so people can disable unnecessary cores to speed up compile time and to save some slices for something else. 4c. I have disconnected .error() output from cores. As far as I understand it gets asserted when some non-existent register is being addressed. In most projects that I've seen writes to empty regions of memory are discarded and reads return zeroes. If you really need this kind of error checking, please re-connect this output as needed. 4d. core_selector.v has an instruction on how to add new HASH cores to our design. 5. TC11() was added to hash_tester.c to check that we can read global board-level registers and that we have access to segments other than HASH. The last check reads dummy registers from RNG and CIPHER segments (which are just templates now), this effectively tests the 3 new added address bits. --- sw/test-sha256/hash_tester.c | 58 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) (limited to 'sw') diff --git a/sw/test-sha256/hash_tester.c b/sw/test-sha256/hash_tester.c index 978cb82..4fbeaa3 100644 --- a/sw/test-sha256/hash_tester.c +++ b/sw/test-sha256/hash_tester.c @@ -62,6 +62,16 @@ int debug = 0; int quiet = 0; int repeat = 0; +/* instead of core number 0 we have a page of global registers */ +#define ADDR_GLOBAL_BOARD_TYPE EIM_BASE_ADDR + (0x00 << 2) +#define ADDR_GLOBAL_BITSTREAM_VER EIM_BASE_ADDR + (0x01 << 2) +#define ADDR_GLOBAL_DUMMY_REG EIM_BASE_ADDR + (0xFF << 2) + +#define SEGMENT_OFFSET_HASHES EIM_BASE_ADDR + 0x000000 +#define SEGMENT_OFFSET_RNGS EIM_BASE_ADDR + 0x010000 +#define SEGMENT_OFFSET_CIPHERS EIM_BASE_ADDR + 0x020000 + + /* addresses and codes common to all hash cores */ #define ADDR_NAME0 0x00 #define ADDR_NAME1 0x04 @@ -75,8 +85,10 @@ int repeat = 0; #define ADDR_BLOCK 0x40 #define ADDR_DIGEST 0x80 +#define HASH_CORE_SIZE 0x400 + /* addresses and codes for the specific hash cores */ -#define SHA1_ADDR_BASE EIM_BASE_ADDR + 0x1000 +#define SHA1_ADDR_BASE EIM_BASE_ADDR + (1*HASH_CORE_SIZE) #define SHA1_ADDR_NAME0 SHA1_ADDR_BASE + ADDR_NAME0 #define SHA1_ADDR_NAME1 SHA1_ADDR_BASE + ADDR_NAME1 #define SHA1_ADDR_VERSION SHA1_ADDR_BASE + ADDR_VERSION @@ -87,7 +99,7 @@ int repeat = 0; #define SHA1_BLOCK_LEN 512 / 8 #define SHA1_DIGEST_LEN 160 / 8 -#define SHA256_ADDR_BASE EIM_BASE_ADDR + 0x2000 +#define SHA256_ADDR_BASE EIM_BASE_ADDR + (2*HASH_CORE_SIZE) #define SHA256_ADDR_NAME0 SHA256_ADDR_BASE + ADDR_NAME0 #define SHA256_ADDR_NAME1 SHA256_ADDR_BASE + ADDR_NAME1 #define SHA256_ADDR_VERSION SHA256_ADDR_BASE + ADDR_VERSION @@ -98,7 +110,7 @@ int repeat = 0; #define SHA256_BLOCK_LEN 512 / 8 #define SHA256_DIGEST_LEN 256 / 8 -#define SHA512_ADDR_BASE EIM_BASE_ADDR + 0x3000 +#define SHA512_ADDR_BASE EIM_BASE_ADDR + (3*HASH_CORE_SIZE) #define SHA512_ADDR_NAME0 SHA512_ADDR_BASE + ADDR_NAME0 #define SHA512_ADDR_NAME1 SHA512_ADDR_BASE + ADDR_NAME1 #define SHA512_ADDR_VERSION SHA512_ADDR_BASE + ADDR_VERSION @@ -696,6 +708,44 @@ int TC10() return 0; } +int TC11() +{ + uint8_t board_type[4] = { 'P', 'V', 'T', '1'}; /* "PVT1" */ + uint8_t bitstream_ver[4] = { 0x00, 0x01, 0x00, 0x0B }; /* v0.1.0b */ + uint8_t t[4]; + + uint8_t seg_rngs_reg_first[4] = { 0xAA, 0xAA, 0xAA, 0xAA}; + uint8_t seg_rngs_reg_second[4] = { 0xBB, 0xBB, 0xBB, 0xBB}; + uint8_t seg_rngs_reg_third[4] = { 0xCC, 0xCC, 0xCC, 0xCC}; + + uint8_t seg_ciphers_reg_first[4] = { 0xDD, 0xDD, 0xDD, 0xDD}; + uint8_t seg_ciphers_reg_second[4] = { 0xEE, 0xEE, 0xEE, 0xEE}; + uint8_t seg_ciphers_reg_third[4] = { 0xFF, 0xFF, 0xFF, 0xFF}; + + // write current time into dummy register, then try to read it back + // to make sure that we can actually write something into eim + (void)time((time_t *)t); + tc_write(ADDR_GLOBAL_DUMMY_REG, (void *)&t, 4); + + if (!quiet) + printf("TC11: Reading board type, bitstream version and dummy register from global registers.\n"); + if (!quiet) + printf("TC11: Reading dummy registers from RNG and CIPHER memory segments.\n"); + + return + tc_expected(ADDR_GLOBAL_BOARD_TYPE, board_type, 4) || + tc_expected(ADDR_GLOBAL_BITSTREAM_VER, bitstream_ver, 4) || + tc_expected(ADDR_GLOBAL_DUMMY_REG, (void *)t, 4) || + + tc_expected(SEGMENT_OFFSET_RNGS + (0 << 2), seg_rngs_reg_first, 4) || + tc_expected(SEGMENT_OFFSET_RNGS + (1 << 2), seg_rngs_reg_second, 4) || + tc_expected(SEGMENT_OFFSET_RNGS + (2 << 2), seg_rngs_reg_third, 4) || + + tc_expected(SEGMENT_OFFSET_CIPHERS + (0 << 2), seg_ciphers_reg_first, 4) || + tc_expected(SEGMENT_OFFSET_CIPHERS + (1 << 2), seg_ciphers_reg_second, 4) || + tc_expected(SEGMENT_OFFSET_CIPHERS + (2 << 2), seg_ciphers_reg_third, 4); +} + /* ---------------- main ---------------- */ unsigned long iter = 0; @@ -718,7 +768,7 @@ int main(int argc, char *argv[]) tcfp sha1_tests[] = { TC1, TC2, TC3 }; tcfp sha256_tests[] = { TC4, TC5, TC6, TC7 }; tcfp sha512_tests[] = { TC8, TC9, TC10 }; - tcfp all_tests[] = { TC1, TC2, TC3, TC4, TC5, TC6, TC7, TC8, TC9, TC10 }; + tcfp all_tests[] = { TC1, TC2, TC3, TC4, TC5, TC6, TC7, TC8, TC9, TC10, TC11 }; char *usage = "Usage: %s [-h] [-d] [-q] [-r] tc...\n"; int i, j, opt; -- cgit v1.2.3 From 0e4e0b5d71b15e1f4edf31295fc95d45d4ae3890 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Tue, 10 Feb 2015 13:51:40 -0500 Subject: First stage of integration cleanup. Add local SHA core wrappers, due to the need for registered outputs. Remove unused demo-adder code, and reorganize sw directory. --- sw/Makefile | 14 + sw/hash_tester.c | 876 +++++++++++++++++++++++++++++++++++++++++++ sw/novena-eim.c | 407 ++++++++++++++++++++ sw/novena-eim.h | 297 +++++++++++++++ sw/test-adder/Makefile | 11 - sw/test-adder/novena-eim.c | 406 -------------------- sw/test-adder/novena-eim.h | 297 --------------- sw/test-adder/test-adder.c | 206 ---------- sw/test-sha256/Makefile | 19 - sw/test-sha256/hash_tester.c | 876 ------------------------------------------- sw/test-sha256/novena-eim.c | 407 -------------------- sw/test-sha256/novena-eim.h | 297 --------------- sw/test-sha256/test-sha256.c | 179 --------- 13 files changed, 1594 insertions(+), 2698 deletions(-) create mode 100755 sw/Makefile create mode 100644 sw/hash_tester.c create mode 100644 sw/novena-eim.c create mode 100644 sw/novena-eim.h delete mode 100755 sw/test-adder/Makefile delete mode 100644 sw/test-adder/novena-eim.c delete mode 100644 sw/test-adder/novena-eim.h delete mode 100644 sw/test-adder/test-adder.c delete mode 100755 sw/test-sha256/Makefile delete mode 100644 sw/test-sha256/hash_tester.c delete mode 100644 sw/test-sha256/novena-eim.c delete mode 100644 sw/test-sha256/novena-eim.h delete mode 100644 sw/test-sha256/test-sha256.c (limited to 'sw') diff --git a/sw/Makefile b/sw/Makefile new file mode 100755 index 0000000..b9fb6a2 --- /dev/null +++ b/sw/Makefile @@ -0,0 +1,14 @@ +all: hash_tester + +.c.o: + gcc -c -Wall -o $@ $< + +hash_tester : hash_tester.o novena-eim.o + gcc -o hash_tester hash_tester.o novena-eim.o + +hash_tester.o: hash_tester.c novena-eim.h + +novena-eim.o: novena-eim.c novena-eim.h + +clean: + rm -f *.o hash_tester diff --git a/sw/hash_tester.c b/sw/hash_tester.c new file mode 100644 index 0000000..4fbeaa3 --- /dev/null +++ b/sw/hash_tester.c @@ -0,0 +1,876 @@ +/* + * hash_tester.c + * -------------- + * This program sends several commands to the coretest_hashes subsystem + * in order to verify the SHA-1, SHA-256 and SHA-512/x hash function + * cores. + * + * Note: This version of the program talks to the FPGA over an EIM bus. + * + * The single and dual block test cases are taken from the + * NIST KAT document: + * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf + * + * + * Authors: Joachim Strömbergson, Paul Selkirk + * Copyright (c) 2014-2015, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "novena-eim.h" + +int debug = 0; +int quiet = 0; +int repeat = 0; + +/* instead of core number 0 we have a page of global registers */ +#define ADDR_GLOBAL_BOARD_TYPE EIM_BASE_ADDR + (0x00 << 2) +#define ADDR_GLOBAL_BITSTREAM_VER EIM_BASE_ADDR + (0x01 << 2) +#define ADDR_GLOBAL_DUMMY_REG EIM_BASE_ADDR + (0xFF << 2) + +#define SEGMENT_OFFSET_HASHES EIM_BASE_ADDR + 0x000000 +#define SEGMENT_OFFSET_RNGS EIM_BASE_ADDR + 0x010000 +#define SEGMENT_OFFSET_CIPHERS EIM_BASE_ADDR + 0x020000 + + +/* addresses and codes common to all hash cores */ +#define ADDR_NAME0 0x00 +#define ADDR_NAME1 0x04 +#define ADDR_VERSION 0x08 +#define ADDR_CTRL 0x20 +#define CTRL_INIT_CMD 1 +#define CTRL_NEXT_CMD 2 +#define ADDR_STATUS 0x24 +#define STATUS_READY_BIT 1 +#define STATUS_VALID_BIT 2 +#define ADDR_BLOCK 0x40 +#define ADDR_DIGEST 0x80 + +#define HASH_CORE_SIZE 0x400 + +/* addresses and codes for the specific hash cores */ +#define SHA1_ADDR_BASE EIM_BASE_ADDR + (1*HASH_CORE_SIZE) +#define SHA1_ADDR_NAME0 SHA1_ADDR_BASE + ADDR_NAME0 +#define SHA1_ADDR_NAME1 SHA1_ADDR_BASE + ADDR_NAME1 +#define SHA1_ADDR_VERSION SHA1_ADDR_BASE + ADDR_VERSION +#define SHA1_ADDR_CTRL SHA1_ADDR_BASE + ADDR_CTRL +#define SHA1_ADDR_STATUS SHA1_ADDR_BASE + ADDR_STATUS +#define SHA1_ADDR_BLOCK SHA1_ADDR_BASE + ADDR_BLOCK +#define SHA1_ADDR_DIGEST SHA1_ADDR_BASE + ADDR_DIGEST +#define SHA1_BLOCK_LEN 512 / 8 +#define SHA1_DIGEST_LEN 160 / 8 + +#define SHA256_ADDR_BASE EIM_BASE_ADDR + (2*HASH_CORE_SIZE) +#define SHA256_ADDR_NAME0 SHA256_ADDR_BASE + ADDR_NAME0 +#define SHA256_ADDR_NAME1 SHA256_ADDR_BASE + ADDR_NAME1 +#define SHA256_ADDR_VERSION SHA256_ADDR_BASE + ADDR_VERSION +#define SHA256_ADDR_CTRL SHA256_ADDR_BASE + ADDR_CTRL +#define SHA256_ADDR_STATUS SHA256_ADDR_BASE + ADDR_STATUS +#define SHA256_ADDR_BLOCK SHA256_ADDR_BASE + ADDR_BLOCK +#define SHA256_ADDR_DIGEST SHA256_ADDR_BASE + ADDR_DIGEST +#define SHA256_BLOCK_LEN 512 / 8 +#define SHA256_DIGEST_LEN 256 / 8 + +#define SHA512_ADDR_BASE EIM_BASE_ADDR + (3*HASH_CORE_SIZE) +#define SHA512_ADDR_NAME0 SHA512_ADDR_BASE + ADDR_NAME0 +#define SHA512_ADDR_NAME1 SHA512_ADDR_BASE + ADDR_NAME1 +#define SHA512_ADDR_VERSION SHA512_ADDR_BASE + ADDR_VERSION +#define SHA512_ADDR_CTRL SHA512_ADDR_BASE + ADDR_CTRL +#define SHA512_ADDR_STATUS SHA512_ADDR_BASE + ADDR_STATUS +#define SHA512_ADDR_BLOCK SHA512_ADDR_BASE + ADDR_BLOCK +#define SHA512_ADDR_DIGEST SHA512_ADDR_BASE + 0x100 +#define SHA512_BLOCK_LEN 1024 / 8 +#define SHA512_224_DIGEST_LEN 224 / 8 +#define SHA512_256_DIGEST_LEN 256 / 8 +#define SHA384_DIGEST_LEN 384 / 8 +#define SHA512_DIGEST_LEN 512 / 8 +#define MODE_SHA_512_224 0 << 2 +#define MODE_SHA_512_256 1 << 2 +#define MODE_SHA_384 2 << 2 +#define MODE_SHA_512 3 << 2 + +/* SHA-1/SHA-256 One Block Message Sample + Input Message: "abc" */ +const uint8_t NIST_512_SINGLE[] = +{ 0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18 }; + +const uint8_t SHA1_SINGLE_DIGEST[] = +{ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, + 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, + 0x9c, 0xd0, 0xd8, 0x9d }; + +const uint8_t SHA256_SINGLE_DIGEST[] = +{ 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, + 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, + 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, + 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD }; + +/* SHA-1/SHA-256 Two Block Message Sample + Input Message: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" */ +const uint8_t NIST_512_DOUBLE0[] = +{ 0x61, 0x62, 0x63, 0x64, 0x62, 0x63, 0x64, 0x65, + 0x63, 0x64, 0x65, 0x66, 0x64, 0x65, 0x66, 0x67, + 0x65, 0x66, 0x67, 0x68, 0x66, 0x67, 0x68, 0x69, + 0x67, 0x68, 0x69, 0x6A, 0x68, 0x69, 0x6A, 0x6B, + 0x69, 0x6A, 0x6B, 0x6C, 0x6A, 0x6B, 0x6C, 0x6D, + 0x6B, 0x6C, 0x6D, 0x6E, 0x6C, 0x6D, 0x6E, 0x6F, + 0x6D, 0x6E, 0x6F, 0x70, 0x6E, 0x6F, 0x70, 0x71, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +const uint8_t NIST_512_DOUBLE1[] = +{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0 }; + +const uint8_t SHA1_DOUBLE_DIGEST[] = +{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, + 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, + 0xE5, 0x46, 0x70, 0xF1 }; + +const uint8_t SHA256_DOUBLE_DIGEST[] = +{ 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, + 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, + 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, + 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }; + +/* SHA-512 One Block Message Sample + Input Message: "abc" */ +const uint8_t NIST_1024_SINGLE[] = +{ 0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18 }; + +const uint8_t SHA512_224_SINGLE_DIGEST[] = +{ 0x46, 0x34, 0x27, 0x0f, 0x70, 0x7b, 0x6a, 0x54, + 0xda, 0xae, 0x75, 0x30, 0x46, 0x08, 0x42, 0xe2, + 0x0e, 0x37, 0xed, 0x26, 0x5c, 0xee, 0xe9, 0xa4, + 0x3e, 0x89, 0x24, 0xaa }; +const uint8_t SHA512_256_SINGLE_DIGEST[] = +{ 0x53, 0x04, 0x8e, 0x26, 0x81, 0x94, 0x1e, 0xf9, + 0x9b, 0x2e, 0x29, 0xb7, 0x6b, 0x4c, 0x7d, 0xab, + 0xe4, 0xc2, 0xd0, 0xc6, 0x34, 0xfc, 0x6d, 0x46, + 0xe0, 0xe2, 0xf1, 0x31, 0x07, 0xe7, 0xaf, 0x23 }; +const uint8_t SHA384_SINGLE_DIGEST[] = +{ 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, + 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, + 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, + 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, + 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, + 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 }; +const uint8_t SHA512_SINGLE_DIGEST[] = +{ 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, + 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, + 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, + 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, + 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, + 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, + 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, + 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }; + +/* SHA-512 Two Block Message Sample + Input Message: "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" */ +const uint8_t NIST_1024_DOUBLE0[] = +{ 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, + 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, + 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, + 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, + 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, + 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, + 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +const uint8_t NIST_1024_DOUBLE1[] = +{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80 }; + +const uint8_t SHA512_224_DOUBLE_DIGEST[] = +{ 0x23, 0xfe, 0xc5, 0xbb, 0x94, 0xd6, 0x0b, 0x23, + 0x30, 0x81, 0x92, 0x64, 0x0b, 0x0c, 0x45, 0x33, + 0x35, 0xd6, 0x64, 0x73, 0x4f, 0xe4, 0x0e, 0x72, + 0x68, 0x67, 0x4a, 0xf9 }; +const uint8_t SHA512_256_DOUBLE_DIGEST[] = +{ 0x39, 0x28, 0xe1, 0x84, 0xfb, 0x86, 0x90, 0xf8, + 0x40, 0xda, 0x39, 0x88, 0x12, 0x1d, 0x31, 0xbe, + 0x65, 0xcb, 0x9d, 0x3e, 0xf8, 0x3e, 0xe6, 0x14, + 0x6f, 0xea, 0xc8, 0x61, 0xe1, 0x9b, 0x56, 0x3a }; +const uint8_t SHA384_DOUBLE_DIGEST[] = +{ 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, + 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, + 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, + 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, + 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, + 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 }; +const uint8_t SHA512_DOUBLE_DIGEST[] = +{ 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, + 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, + 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, + 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, + 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, + 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, + 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, + 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }; + +/* ---------------- test-case low-level code ---------------- */ + +void dump(char *label, const uint8_t *buf, int len) +{ + if (debug) { + int i; + printf("%s [", label); + for (i = 0; i < len; ++i) + printf(" %02x", buf[i]); + printf(" ]\n"); + } +} + +int tc_write(off_t offset, const uint8_t *buf, int len) +{ + dump("write ", buf, len); + + for (; len > 0; offset += 4, buf += 4, len -= 4) { + uint32_t val; + val = htonl(*(uint32_t *)buf); + eim_write_32(offset, &val); + } + + return 0; +} + +int tc_read(off_t offset, uint8_t *buf, int len) +{ + uint8_t *rbuf = buf; + int rlen = len; + + for (; rlen > 0; offset += 4, rbuf += 4, rlen -= 4) { + uint32_t val; + eim_read_32(offset, &val); + *(uint32_t *)rbuf = ntohl(val); + } + + dump("read ", buf, len); + + return 0; +} + +int tc_expected(off_t offset, const uint8_t *expected, int len) +{ + uint8_t *buf; + int i; + + buf = malloc(len); + if (buf == NULL) { + perror("malloc"); + return 1; + } + dump("expect", expected, len); + + if (tc_read(offset, buf, len) != 0) + goto errout; + + for (i = 0; i < len; ++i) + if (buf[i] != expected[i]) { + fprintf(stderr, "response byte %d: expected 0x%02x, got 0x%02x\n", + i, expected[i], buf[i]); + goto errout; + } + + free(buf); + return 0; +errout: + free(buf); + return 1; +} + +int tc_init(off_t offset) +{ + uint8_t buf[4] = { 0, 0, 0, CTRL_INIT_CMD }; + + return tc_write(offset, buf, 4); +} + +int tc_next(off_t offset) +{ + uint8_t buf[4] = { 0, 0, 0, CTRL_NEXT_CMD }; + + return tc_write(offset, buf, 4); +} + +int tc_wait(off_t offset, uint8_t status) +{ + uint8_t buf[4]; + +#if 0 + do { + if (tc_read(offset, buf, 4) != 0) + return 1; + } while (!(buf[3] & status)); + + return 0; +#else + int i; + for (i = 0; i < 10; ++i) { + if (tc_read(offset, buf, 4) != 0) + return 1; + if (buf[3] & status) + return 0; + } + fprintf(stderr, "tc_wait timed out\n"); + return 1; +#endif +} + +int tc_wait_ready(off_t offset) +{ + return tc_wait(offset, STATUS_READY_BIT); +} + +int tc_wait_valid(off_t offset) +{ + return tc_wait(offset, STATUS_VALID_BIT); +} + +/* ---------------- SHA-1 test cases ---------------- */ + +/* TC1: Read name and version from SHA-1 core. */ +int TC1(void) +{ + uint8_t name0[4] = { 0x73, 0x68, 0x61, 0x31 }; /* "sha1" */ + uint8_t name1[4] = { 0x20, 0x20, 0x20, 0x20 }; /* " " */ + uint8_t version[4] = { 0x30, 0x2e, 0x35, 0x30 }; /* "0.50" */ + + if (!quiet) + printf("TC1: Reading name, type and version words from SHA-1 core.\n"); + + return + tc_expected(SHA1_ADDR_NAME0, name0, 4) || + tc_expected(SHA1_ADDR_NAME1, name1, 4) || + tc_expected(SHA1_ADDR_VERSION, version, 4); +} + +/* TC2: SHA-1 Single block message test as specified by NIST. */ +int TC2(void) +{ + const uint8_t *block = NIST_512_SINGLE; + const uint8_t *expected = SHA1_SINGLE_DIGEST; + int ret; + + if (!quiet) + printf("TC2: Single block message test for SHA-1.\n"); + + /* Write block to SHA-1. */ + tc_write(SHA1_ADDR_BLOCK, block, SHA1_BLOCK_LEN); + /* Start initial block hashing, wait and check status. */ + tc_init(SHA1_ADDR_CTRL); + tc_wait_valid(SHA1_ADDR_STATUS); + /* Extract the digest. */ + ret = tc_expected(SHA1_ADDR_DIGEST, expected, SHA1_DIGEST_LEN); + return ret; +} + +/* TC3: SHA-1 Double block message test as specified by NIST. */ +int TC3(void) +{ + const uint8_t *block[2] = { NIST_512_DOUBLE0, NIST_512_DOUBLE1 }; + static const uint8_t block0_expected[] = + { 0xF4, 0x28, 0x68, 0x18, 0xC3, 0x7B, 0x27, 0xAE, + 0x04, 0x08, 0xF5, 0x81, 0x84, 0x67, 0x71, 0x48, + 0x4A, 0x56, 0x65, 0x72 }; + const uint8_t *expected = SHA1_DOUBLE_DIGEST; + int ret; + + if (!quiet) + printf("TC3: Double block message test for SHA-1.\n"); + + /* Write first block to SHA-1. */ + tc_write(SHA1_ADDR_BLOCK, block[0], SHA1_BLOCK_LEN); + /* Start initial block hashing, wait and check status. */ + tc_init(SHA1_ADDR_CTRL); + tc_wait_valid(SHA1_ADDR_STATUS); + /* Extract the first digest. */ + tc_expected(SHA1_ADDR_DIGEST, block0_expected, SHA1_DIGEST_LEN); + /* Write second block to SHA-1. */ + tc_write(SHA1_ADDR_BLOCK, block[1], SHA1_BLOCK_LEN); + /* Start next block hashing, wait and check status. */ + tc_next(SHA1_ADDR_CTRL); + tc_wait_valid(SHA1_ADDR_STATUS); + /* Extract the second digest. */ + ret = tc_expected(SHA1_ADDR_DIGEST, expected, SHA1_DIGEST_LEN); + return ret; +} + +/* ---------------- SHA-256 test cases ---------------- */ + +/* TC4: Read name and version from SHA-256 core. */ +int TC4(void) +{ + uint8_t name0[4] = { 0x73, 0x68, 0x61, 0x32 }; /* "sha2" */ + uint8_t name1[4] = { 0x2d, 0x32, 0x35, 0x36 }; /* "-256" */ + uint8_t version[4] = { 0x30, 0x2e, 0x38, 0x30 }; /* "0.80" */ + + if (!quiet) + printf("TC4: Reading name, type and version words from SHA-256 core.\n"); + + return + tc_expected(SHA256_ADDR_NAME0, name0, 4) || + tc_expected(SHA256_ADDR_NAME1, name1, 4) || + tc_expected(SHA256_ADDR_VERSION, version, 4); +} + +/* TC5: SHA-256 Single block message test as specified by NIST. */ +int TC5() +{ + const uint8_t *block = NIST_512_SINGLE; + const uint8_t *expected = SHA256_SINGLE_DIGEST; + + if (!quiet) + printf("TC5: Single block message test for SHA-256.\n"); + + return + /* Write block to SHA-256. */ + tc_write(SHA256_ADDR_BLOCK, block, SHA256_BLOCK_LEN) || + /* Start initial block hashing, wait and check status. */ + tc_init(SHA256_ADDR_CTRL) || + tc_wait_valid(SHA256_ADDR_STATUS) || + /* Extract the digest. */ + tc_expected(SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN); +} + +/* TC6: SHA-256 Double block message test as specified by NIST. */ +int TC6() +{ + const uint8_t *block[2] = { NIST_512_DOUBLE0, NIST_512_DOUBLE1 }; + static const uint8_t block0_expected[] = + { 0x85, 0xE6, 0x55, 0xD6, 0x41, 0x7A, 0x17, 0x95, + 0x33, 0x63, 0x37, 0x6A, 0x62, 0x4C, 0xDE, 0x5C, + 0x76, 0xE0, 0x95, 0x89, 0xCA, 0xC5, 0xF8, 0x11, + 0xCC, 0x4B, 0x32, 0xC1, 0xF2, 0x0E, 0x53, 0x3A }; + const uint8_t *expected = SHA256_DOUBLE_DIGEST; + + if (!quiet) + printf("TC6: Double block message test for SHA-256.\n"); + + return + /* Write first block to SHA-256. */ + tc_write(SHA256_ADDR_BLOCK, block[0], SHA256_BLOCK_LEN) || + /* Start initial block hashing, wait and check status. */ + tc_init(SHA256_ADDR_CTRL) || + tc_wait_valid(SHA256_ADDR_STATUS) || + /* Extract the first digest. */ + tc_expected(SHA256_ADDR_DIGEST, block0_expected, SHA256_DIGEST_LEN) || + /* Write second block to SHA-256. */ + tc_write(SHA256_ADDR_BLOCK, block[1], SHA256_BLOCK_LEN) || + /* Start next block hashing, wait and check status. */ + tc_next(SHA256_ADDR_CTRL) || + tc_wait_valid(SHA256_ADDR_STATUS) || + /* Extract the second digest. */ + tc_expected(SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN); +} + +/* TC7: SHA-256 Huge message test. */ +int TC7() +{ + static const uint8_t block[] = + { 0xaa, 0x55, 0xaa, 0x55, 0xde, 0xad, 0xbe, 0xef, + 0x55, 0xaa, 0x55, 0xaa, 0xf0, 0x0f, 0xf0, 0x0f, + 0xaa, 0x55, 0xaa, 0x55, 0xde, 0xad, 0xbe, 0xef, + 0x55, 0xaa, 0x55, 0xaa, 0xf0, 0x0f, 0xf0, 0x0f, + 0xaa, 0x55, 0xaa, 0x55, 0xde, 0xad, 0xbe, 0xef, + 0x55, 0xaa, 0x55, 0xaa, 0xf0, 0x0f, 0xf0, 0x0f, + 0xaa, 0x55, 0xaa, 0x55, 0xde, 0xad, 0xbe, 0xef, + 0x55, 0xaa, 0x55, 0xaa, 0xf0, 0x0f, 0xf0, 0x0f }; + + /* final digest after 1000 iterations */ + static const uint8_t expected[] = + { 0x76, 0x38, 0xf3, 0xbc, 0x50, 0x0d, 0xd1, 0xa6, + 0x58, 0x6d, 0xd4, 0xd0, 0x1a, 0x15, 0x51, 0xaf, + 0xd8, 0x21, 0xd2, 0x35, 0x2f, 0x91, 0x9e, 0x28, + 0xd5, 0x84, 0x2f, 0xab, 0x03, 0xa4, 0x0f, 0x2a }; + + int i, n = 1000; + + if (!quiet) + printf("TC7: Message with %d blocks test for SHA-256.\n", n); + + /* Write block data to SHA-256. */ + if (tc_write(SHA256_ADDR_BLOCK, block, SHA256_BLOCK_LEN)) + return 1; + + /* Start initial block hashing, wait and check status. */ + if (tc_init(SHA256_ADDR_CTRL) || + tc_wait_ready(SHA256_ADDR_STATUS)) + return 1; + + /* First block done. Do the rest. */ + for (i = 1; i < n; ++i) { + /* Start next block hashing, wait and check status. */ + if (tc_next(SHA256_ADDR_CTRL) || + tc_wait_ready(SHA256_ADDR_STATUS)) + return 1; + } + + /* XXX valid is probably set at the same time as ready */ + if (tc_wait_valid(SHA256_ADDR_STATUS)) + return 1; + /* Extract the final digest. */ + return tc_expected(SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN); +} + +/* ---------------- SHA-512 test cases ---------------- */ + +/* TC8: Read name and version from SHA-512 core. */ +int TC8() +{ + uint8_t name0[4] = { 0x73, 0x68, 0x61, 0x32 }; /* "sha2" */ + uint8_t name1[4] = { 0x2d, 0x35, 0x31, 0x32 }; /* "-512" */ + uint8_t version[4] = { 0x30, 0x2e, 0x38, 0x30 }; /* "0.80" */ + + if (!quiet) + printf("TC8: Reading name, type and version words from SHA-512 core.\n"); + + return + tc_expected(SHA512_ADDR_NAME0, name0, 4) || + tc_expected(SHA512_ADDR_NAME1, name1, 4) || + tc_expected(SHA512_ADDR_VERSION, version, 4); +} + +/* TC9: SHA-512 Single block message test as specified by NIST. + We do this for all modes. */ +int tc9(int mode, const uint8_t *expected, int digest_len) +{ + const uint8_t *block = NIST_1024_SINGLE; + uint8_t init[4] = { 0, 0, 0, CTRL_INIT_CMD + mode }; + + return + /* Write block to SHA-512. */ + tc_write(SHA512_ADDR_BLOCK, block, SHA512_BLOCK_LEN) || + /* Start initial block hashing, wait and check status. */ + tc_write(SHA512_ADDR_CTRL, init, 4) || + tc_wait_valid(SHA512_ADDR_STATUS) || + /* Extract the digest. */ + tc_expected(SHA512_ADDR_DIGEST, expected, digest_len); +} + +int TC9() +{ + if (!quiet) + printf("TC9-1: Single block message test for SHA-512/224.\n"); + if (tc9(MODE_SHA_512_224, SHA512_224_SINGLE_DIGEST, SHA512_224_DIGEST_LEN) != 0) + return 1; + + if (!quiet) + printf("TC9-2: Single block message test for SHA-512/256.\n"); + if (tc9(MODE_SHA_512_256, SHA512_256_SINGLE_DIGEST, SHA512_256_DIGEST_LEN) != 0) + return 1; + + if (!quiet) + printf("TC9-3: Single block message test for SHA-384.\n"); + if (tc9(MODE_SHA_384, SHA384_SINGLE_DIGEST, SHA384_DIGEST_LEN) != 0) + return 1; + + if (!quiet) + printf("TC9-4: Single block message test for SHA-512.\n"); + if (tc9(MODE_SHA_512, SHA512_SINGLE_DIGEST, SHA512_DIGEST_LEN) != 0) + return 1; + + return 0; +} + +/* TC10: SHA-512 Double block message test as specified by NIST. + We do this for all modes. */ +int tc10(int mode, const uint8_t *expected, int digest_len) +{ + const uint8_t *block[2] = { NIST_1024_DOUBLE0, NIST_1024_DOUBLE1 }; + uint8_t init[4] = { 0, 0, 0, CTRL_INIT_CMD + mode }; + uint8_t next[4] = { 0, 0, 0, CTRL_NEXT_CMD + mode }; + + return + /* Write first block to SHA-512. */ + tc_write(SHA512_ADDR_BLOCK, block[0], SHA512_BLOCK_LEN) || + /* Start initial block hashing, wait and check status. */ + tc_write(SHA512_ADDR_CTRL, init, 4) || + tc_wait_ready(SHA512_ADDR_STATUS) || + /* Write second block to SHA-512. */ + tc_write(SHA512_ADDR_BLOCK, block[1], SHA512_BLOCK_LEN) || + /* Start next block hashing, wait and check status. */ + tc_write(SHA512_ADDR_CTRL, next, 4) || + tc_wait_valid(SHA512_ADDR_STATUS) || + /* Extract the digest. */ + tc_expected(SHA512_ADDR_DIGEST, expected, digest_len); +} + +int TC10() +{ + if (!quiet) + printf("TC10-1: Double block message test for SHA-512/224.\n"); + if (tc10(MODE_SHA_512_224, SHA512_224_DOUBLE_DIGEST, SHA512_224_DIGEST_LEN) != 0) + return 1; + + if (!quiet) + printf("TC10-2: Double block message test for SHA-512/256.\n"); + if (tc10(MODE_SHA_512_256, SHA512_256_DOUBLE_DIGEST, SHA512_256_DIGEST_LEN) != 0) + return 1; + + if (!quiet) + printf("TC10-3: Double block message test for SHA-384.\n"); + if (tc10(MODE_SHA_384, SHA384_DOUBLE_DIGEST, SHA384_DIGEST_LEN) != 0) + return 1; + + if (!quiet) + printf("TC10-4: Double block message test for SHA-512.\n"); + if (tc10(MODE_SHA_512, SHA512_DOUBLE_DIGEST, SHA512_DIGEST_LEN) != 0) + return 1; + + return 0; +} + +int TC11() +{ + uint8_t board_type[4] = { 'P', 'V', 'T', '1'}; /* "PVT1" */ + uint8_t bitstream_ver[4] = { 0x00, 0x01, 0x00, 0x0B }; /* v0.1.0b */ + uint8_t t[4]; + + uint8_t seg_rngs_reg_first[4] = { 0xAA, 0xAA, 0xAA, 0xAA}; + uint8_t seg_rngs_reg_second[4] = { 0xBB, 0xBB, 0xBB, 0xBB}; + uint8_t seg_rngs_reg_third[4] = { 0xCC, 0xCC, 0xCC, 0xCC}; + + uint8_t seg_ciphers_reg_first[4] = { 0xDD, 0xDD, 0xDD, 0xDD}; + uint8_t seg_ciphers_reg_second[4] = { 0xEE, 0xEE, 0xEE, 0xEE}; + uint8_t seg_ciphers_reg_third[4] = { 0xFF, 0xFF, 0xFF, 0xFF}; + + // write current time into dummy register, then try to read it back + // to make sure that we can actually write something into eim + (void)time((time_t *)t); + tc_write(ADDR_GLOBAL_DUMMY_REG, (void *)&t, 4); + + if (!quiet) + printf("TC11: Reading board type, bitstream version and dummy register from global registers.\n"); + if (!quiet) + printf("TC11: Reading dummy registers from RNG and CIPHER memory segments.\n"); + + return + tc_expected(ADDR_GLOBAL_BOARD_TYPE, board_type, 4) || + tc_expected(ADDR_GLOBAL_BITSTREAM_VER, bitstream_ver, 4) || + tc_expected(ADDR_GLOBAL_DUMMY_REG, (void *)t, 4) || + + tc_expected(SEGMENT_OFFSET_RNGS + (0 << 2), seg_rngs_reg_first, 4) || + tc_expected(SEGMENT_OFFSET_RNGS + (1 << 2), seg_rngs_reg_second, 4) || + tc_expected(SEGMENT_OFFSET_RNGS + (2 << 2), seg_rngs_reg_third, 4) || + + tc_expected(SEGMENT_OFFSET_CIPHERS + (0 << 2), seg_ciphers_reg_first, 4) || + tc_expected(SEGMENT_OFFSET_CIPHERS + (1 << 2), seg_ciphers_reg_second, 4) || + tc_expected(SEGMENT_OFFSET_CIPHERS + (2 << 2), seg_ciphers_reg_third, 4); +} + +/* ---------------- main ---------------- */ + +unsigned long iter = 0; +struct timeval tv_start, tv_end; +void sighandler(int unused) +{ + double tv_diff; + + gettimeofday(&tv_end, NULL); + tv_diff = (double)(tv_end.tv_sec - tv_start.tv_sec) + + (double)(tv_end.tv_usec - tv_start.tv_usec)/1000000; + printf("\n%lu iterations in %.3f seconds (%.3f iterations/sec)\n", + iter, tv_diff, (double)iter/tv_diff); + exit(0); +} + +int main(int argc, char *argv[]) +{ + typedef int (*tcfp)(void); + tcfp sha1_tests[] = { TC1, TC2, TC3 }; + tcfp sha256_tests[] = { TC4, TC5, TC6, TC7 }; + tcfp sha512_tests[] = { TC8, TC9, TC10 }; + tcfp all_tests[] = { TC1, TC2, TC3, TC4, TC5, TC6, TC7, TC8, TC9, TC10, TC11 }; + + char *usage = "Usage: %s [-h] [-d] [-q] [-r] tc...\n"; + int i, j, opt; + + while ((opt = getopt(argc, argv, "h?dqr")) != -1) { + switch (opt) { + case 'h': + case '?': + printf(usage, argv[0]); + return 0; + case 'd': + debug = 1; + break; + case 'q': + quiet = 1; + break; + case 'r': + repeat = 1; + break; + default: + fprintf(stderr, usage, argv[0]); + return 1; + } + } + + // try to setup eim (return value should be 1) + printf("Configuring EIM .. "); + if (eim_setup() < 1) { + printf("ERROR\n"); + return EXIT_FAILURE; + } + else { + printf("EIM Setup ok.\n"); + } + + if (repeat) { + tcfp tc; + if (optind != argc - 1) { + fprintf(stderr, "only one test case can be repeated\n"); + return 1; + } + j = atoi(argv[optind]); + if (j <= 0 || j > sizeof(all_tests)/sizeof(all_tests[0])) { + fprintf(stderr, "invalid test number %s\n", argv[optind]); + return 1; + } + tc = (all_tests[j - 1]); + srand(time(NULL)); + signal(SIGINT, sighandler); + gettimeofday(&tv_start, NULL); + while (1) { + ++iter; + if ((iter & 0xffff) == 0) { + printf("."); + fflush(stdout); + } + if (tc() != 0) + sighandler(0); + } + return 0; /*NOTREACHED*/ + } + + /* no args == run all tests */ + if (optind >= argc) { + for (j = 0; j < sizeof(all_tests)/sizeof(all_tests[0]); ++j) + if (all_tests[j]() != 0) + return 1; + return 0; + } + + for (i = optind; i < argc; ++i) { + if (strcmp(argv[i], "sha1") == 0) { + for (j = 0; j < sizeof(sha1_tests)/sizeof(sha1_tests[0]); ++j) + if (sha1_tests[j]() != 0) + return 1; + } + else if (strcmp(argv[i], "sha256") == 0) { + for (j = 0; j < sizeof(sha256_tests)/sizeof(sha256_tests[0]); ++j) + if (sha256_tests[j]() != 0) + return 1; + } + else if (strcmp(argv[i], "sha512") == 0) { + for (j = 0; j < sizeof(sha512_tests)/sizeof(sha512_tests[0]); ++j) + if (sha512_tests[j]() != 0) + return 1; + } + else if (strcmp(argv[i], "all") == 0) { + for (j = 0; j < sizeof(all_tests)/sizeof(all_tests[0]); ++j) + if (all_tests[j]() != 0) + return 1; + } + else if (isdigit(argv[i][0]) && + (((j = atoi(argv[i])) > 0) && + (j <= sizeof(all_tests)/sizeof(all_tests[0])))) { + if (all_tests[j - 1]() != 0) + return 1; + } + else { + fprintf(stderr, "unknown test case %s\n", argv[i]); + return 1; + } + } + + return 0; +} diff --git a/sw/novena-eim.c b/sw/novena-eim.c new file mode 100644 index 0000000..1effff1 --- /dev/null +++ b/sw/novena-eim.c @@ -0,0 +1,407 @@ +//------------------------------------------------------------------------------ +// novena-eim.c +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ +#include +#include +#include +#include +#include +#include +#include +#include "novena-eim.h" + + +//------------------------------------------------------------------------------ +// Variables +//------------------------------------------------------------------------------ +static long mem_page_size = 0; +static int mem_dev_fd = -1; +static void * mem_map_ptr = MAP_FAILED; +static off_t mem_base_addr = 0; + + +//------------------------------------------------------------------------------ +int eim_setup() +//------------------------------------------------------------------------------ +{ + // register cleanup function + int ok = atexit(_eim_cleanup); + if (ok != 0) + { printf("ERROR: atexit() failed.\n"); + return -1; + } + + // determine memory page size to use in mmap() + mem_page_size = sysconf(_SC_PAGESIZE); + if (mem_page_size < 1) + { printf("ERROR: sysconf(_SC_PAGESIZE) == %ld\n", mem_page_size); + return -1; + } + + // try to open memory device + mem_dev_fd = open(MEMORY_DEVICE, O_RDWR | O_SYNC); + if (mem_dev_fd == -1) + { printf("ERROR: open(%s) failed.\n", MEMORY_DEVICE); + return -1; + } + + /* Several blocks in the CPU have common pins, we can use I/O MUX Controller + * to configure what block will actually use I/O pins. We wait EIM module to be able + * to communicate with the on-board FPGA. Let's configure IOMUXC accordingly. + */ + _eim_setup_iomuxc(); + + /* We need to enable clocking of EIM block in order to be able to use it. + * Let's configure Clock Controller Module accordingly. + */ + _eim_setup_ccm(); + + /* We need to properly configure EIM mode and all the corresponding parameters. + * That's a lot of code, let's do it now. + */ + _eim_setup_eim(); + + + // done + return 1; +} + + +//------------------------------------------------------------------------------ +void _eim_cleanup() +//------------------------------------------------------------------------------ +{ + // unmap memory if needed + if (mem_map_ptr != MAP_FAILED) + { int ok = munmap(mem_map_ptr, mem_page_size); + if (ok != 0) printf("WARNING: munmap() failed.\n"); + } + + // close memory device if needed + if (mem_dev_fd != -1) + { int ok = close(mem_dev_fd); + if (ok != 0) printf("WARNING: close() failed.\n"); + } +} + + +//------------------------------------------------------------------------------ +void _eim_setup_iomuxc() +//------------------------------------------------------------------------------ +{ + // create structures + struct IOMUXC_SW_MUX_CTL_PAD_EIM reg_mux; // mux control register + struct IOMUXC_SW_PAD_CTL_PAD_EIM reg_pad; // pad control register + + // setup mux control register + reg_mux.mux_mode = IOMUXC_MUX_MODE_ALT0; // ALT0 mode must be used for EIM + reg_mux.sion = 0; // forced input not needed + reg_mux.reserved_3 = 0; // must be 0 + reg_mux.reserved_31_5 = 0; // must be 0 + + // setup pad control register + reg_pad.sre = IOMUXC_PAD_CTL_SRE_FAST; // fast slew rate + reg_pad.dse = IOMUXC_PAD_CTL_DSE_33_OHM; // highest drive strength + reg_pad.speed = IOMUXC_PAD_CTL_SPEED_MEDIUM_10; // medium speed + reg_pad.ode = IOMUXC_PAD_CTL_ODE_DISABLED; // open drain not needed + reg_pad.pke = IOMUXC_PAD_CTL_PKE_DISABLED; // neither pull nor keeper are needed + reg_pad.pue = IOMUXC_PAD_CTL_PUE_PULL; // doesn't matter actually, because PKE is disabled + reg_pad.pus = IOMUXC_PAD_CTL_PUS_100K_OHM_PU; // doesn't matter actually, because PKE is disabled + reg_pad.hys = IOMUXC_PAD_CTL_HYS_DISABLED; // use CMOS, not Schmitt trigger input + reg_pad.reserved_2_1 = 0; // must be 0 + reg_pad.reserved_10_8 = 0; // must be 0 + reg_pad.reserved_31_17 = 0; // must be 0 + + // all the pins must be configured to use the same ALT0 mode + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_RW, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD00, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD01, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD02, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD03, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD04, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD05, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD06, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD07, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD08, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD09, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD10, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD11, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD12, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD13, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD14, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD15, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK, (uint32_t *)®_mux); + + // we need to configure all the I/O pads too + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_RW, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD00, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD01, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD02, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD03, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD04, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD05, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD06, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD07, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD08, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD09, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD10, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD11, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD12, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD13, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD14, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD15, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK, (uint32_t *)®_pad); +} + + +//------------------------------------------------------------------------------ +void _eim_setup_ccm() +//------------------------------------------------------------------------------ +{ + // create structure + struct CCM_CCGR6 ccm_ccgr6; + + // read register + eim_read_32(CCM_CCGR6, (uint32_t *)&ccm_ccgr6); + + // modify register + ccm_ccgr6.cg0_usboh3 = CCM_CGR_ON_EXCEPT_STOP; + ccm_ccgr6.cg1_usdhc1 = CCM_CGR_OFF; + ccm_ccgr6.cg2_usdhc2 = CCM_CGR_ON_EXCEPT_STOP; + ccm_ccgr6.cg3_usdhc3 = CCM_CGR_ON_EXCEPT_STOP; + + ccm_ccgr6.cg3_usdhc4 = CCM_CGR_OFF; + ccm_ccgr6.cg5_eim_slow = CCM_CGR_ON_EXCEPT_STOP; + ccm_ccgr6.cg6_vdoaxiclk = CCM_CGR_OFF; + ccm_ccgr6.cg7_vpu = CCM_CGR_OFF; + + ccm_ccgr6.cg8_reserved = 0; + ccm_ccgr6.cg9_reserved = 0; + ccm_ccgr6.cg10_reserved = 0; + ccm_ccgr6.cg11_reserved = 0; + ccm_ccgr6.cg12_reserved = 0; + ccm_ccgr6.cg13_reserved = 0; + ccm_ccgr6.cg14_reserved = 0; + ccm_ccgr6.cg15_reserved = 0; + + // write register + eim_write_32(CCM_CCGR6, (uint32_t *)&ccm_ccgr6); +} + + +//------------------------------------------------------------------------------ +void _eim_setup_eim() +//------------------------------------------------------------------------------ +{ + // create structures + struct EIM_CS_GCR1 gcr1; + struct EIM_CS_GCR2 gcr2; + struct EIM_CS_RCR1 rcr1; + struct EIM_CS_RCR2 rcr2; + struct EIM_CS_WCR1 wcr1; + struct EIM_CS_WCR2 wcr2; + + struct EIM_WCR wcr; + struct EIM_WIAR wiar; + struct EIM_EAR ear; + + // read all the registers + eim_read_32(EIM_CS0GCR1, (uint32_t *)&gcr1); + eim_read_32(EIM_CS0GCR2, (uint32_t *)&gcr2); + eim_read_32(EIM_CS0RCR1, (uint32_t *)&rcr1); + eim_read_32(EIM_CS0RCR2, (uint32_t *)&rcr2); + eim_read_32(EIM_CS0WCR1, (uint32_t *)&wcr1); + eim_read_32(EIM_CS0WCR2, (uint32_t *)&wcr2); + + eim_read_32(EIM_WCR, (uint32_t *)&wcr); + eim_read_32(EIM_WIAR, (uint32_t *)&wiar); + eim_read_32(EIM_EAR, (uint32_t *)&ear); + + // manipulate registers as needed + gcr1.csen = 1; // chip select is enabled | + gcr1.swr = 1; // write is sync | + gcr1.srd = 1; // read is sync | + gcr1.mum = 1; // address and data are multiplexed | + gcr1.wfl = 0; // write latency is not fixed | + gcr1.rfl = 0; // read latency is not fixed | + gcr1.cre = 0; // CRE signal not needed | + //gcr1.crep = x; // don't care, CRE not used | + gcr1.bl = 4; // burst length | ? + gcr1.wc = 0; // write is not continuous | ? + gcr1.bcd = 3; // BCLK divisor is 3+1=4 | + gcr1.bcs = 1; // delay from ~CS to BCLK is 1 cycle | + gcr1.dsz = 1; // 16 bits per databeat at DATA[15:0] | + gcr1.sp = 0; // supervisor protection is disabled | + gcr1.csrec = 1; // ~CS recovery is 1 cycle | + gcr1.aus = 1; // address is not shifted | + gcr1.gbc = 1; // ~CS gap is 1 cycle | + gcr1.wp = 0; // write protection is not enabled | + //gcr1.psz = x; // don't care, page mode is not used | + + gcr2.adh = 0; // address hold duration is 1 cycle | + //gcr2.daps = x; // don't care, DTACK is not used | + gcr2.dae = 0; // DTACK is not used | + //gcr2.dap = x; // don't care, DTACK is not used | + gcr2.mux16_byp_grant = 1; // enable grant mechanism | ? + gcr2.reserved_3_2 = 0; // must be 0 | + gcr2.reserved_11_10 = 0; // must be 0 | + gcr2.reserved_31_13 = 0; // must be 0 | + + //rcr1.rcsn = x; // don't care in sync mode | + rcr1.rcsa = 0; // no delay for ~CS needed | + //rcr1.oen = x; // don't care in sync mode | + rcr1.oea = 0; // no delay for ~OE needed | + rcr1.radvn = 0; // no delay for ~LBA needed | + rcr1.ral = 0; // clear ~LBA when needed | + rcr1.radva = 0; // no delay for ~LBA needed | + rcr1.rwsc = 1; // one wait state | + rcr1.reserved_3 = 0; // must be 0 | + rcr1.reserved_7 = 0; // must be 0 | + rcr1.reserved_11 = 0; // must be 0 | + rcr1.reserved_15 = 0; // must be 0 | + rcr1.reserved_23 = 0; // must be 0 | + rcr1.reserved_31_30 = 0; // must be 0 | + + //rcr2.rben = x; // don't care in sync mode | + rcr2.rbe = 0; // BE is disabled | + //rcr2.rbea = x; // don't care when BE is not used | + rcr2.rl = 0; // read latency is 0 | ? + //rcr2.pat = x; // don't care when page read is not used | + rcr2.apr = 0; // page read mode is not used | + rcr2.reserved_7 = 0; // must be 0 | + rcr2.reserved_11_10 = 0; // must be 0 | + rcr2.reserved_31_16 = 0; // must be 0 | + + //wcr1.wcsn = x; // don't care in sync mode | + wcr1.wcsa = 0; // no delay for ~CS needed | + //wcr1.wen = x; // don't care in sync mode | + wcr1.wea = 0; // no delay for ~WR_N needed | + //wcr1.wben = x; // don't care in sync mode | + //wcr1.wbea = x; // don't care in sync mode | + wcr1.wadvn = 0; // no delay for ~LBA needed | + wcr1.wadva = 0; // no delay for ~LBA needed | + wcr1.wwsc = 1; // no wait state in needed | + wcr1.wbed = 1; // BE is disabled | + wcr1.wal = 0; // clear ~LBA when needed | + + wcr2.wbcdd = 0; // write clock division is not needed | + wcr2.reserved_31_1 = 0; // must be 0 | + + wcr.bcm = 0; // clock is only active during access | + //wcr.gbcd = x; // don't care when BCM=0 | + wcr.inten = 0; // interrupt is not used | + //wcr.intpol = x; // don't care when interrupt is not used | + wcr.wdog_en = 1; // watchdog is enabled | + wcr.wdog_limit = 00; // timeout is 128 BCLK cycles | + wcr.reserved_3 = 0; // must be 0 | + wcr.reserved_7_6 = 0; // must be 0 | + wcr.reserved_31_11 = 0; // must be 0 | + + wiar.ips_req = 0; // IPS not needed | + wiar.ips_ack = 0; // IPS not needed | + //wiar.irq = x; // don't touch | + //wiar.errst = x; // don't touch | + wiar.aclk_en = 1; // clock is enabled | + wiar.reserved_31_5 = 0; // must be 0 | + + //ear.error_addr = x; // read-only | + + // write modified registers + eim_write_32(EIM_CS0GCR1, (uint32_t *)&gcr1); + eim_write_32(EIM_CS0GCR2, (uint32_t *)&gcr2); + eim_write_32(EIM_CS0RCR1, (uint32_t *)&rcr1); + eim_write_32(EIM_CS0RCR2, (uint32_t *)&rcr2); + eim_write_32(EIM_CS0WCR1, (uint32_t *)&wcr1); + eim_write_32(EIM_CS0WCR2, (uint32_t *)&wcr2); + eim_write_32(EIM_WCR, (uint32_t *)&wcr); + eim_write_32(EIM_WIAR, (uint32_t *)&wiar);/* + eim_write_32(EIM_EAR, (uint32_t *)&ear);*/ +} + + +//------------------------------------------------------------------------------ +void eim_write_32(off_t offset, uint32_t *pvalue) +//------------------------------------------------------------------------------ +{ + // calculate memory offset + uint32_t *ptr = (uint32_t *)_eim_calc_offset(offset); + + // write data to memory + memcpy(ptr, pvalue, sizeof(uint32_t)); +} + +//------------------------------------------------------------------------------ +void eim_read_32(off_t offset, uint32_t *pvalue) +//------------------------------------------------------------------------------ +{ + // calculate memory offset + uint32_t *ptr = (uint32_t *)_eim_calc_offset(offset); + + // read data from memory + memcpy(pvalue, ptr, sizeof(uint32_t)); +} + + +//------------------------------------------------------------------------------ +off_t _eim_calc_offset(off_t offset) +//------------------------------------------------------------------------------ +{ + // make sure that memory is mapped + if (mem_map_ptr == MAP_FAILED) _eim_remap_mem(offset); + + // calculate starting and ending addresses of currently mapped page + off_t offset_low = mem_base_addr; + off_t offset_high = mem_base_addr + (mem_page_size - 1); + + // check that offset is in currently mapped page, remap new page otherwise + if ((offset < offset_low) || (offset > offset_high)) _eim_remap_mem(offset); + + // calculate pointer + return (off_t)mem_map_ptr + (offset - mem_base_addr); +} + + +//------------------------------------------------------------------------------ +void _eim_remap_mem(off_t offset) +//------------------------------------------------------------------------------ +{ + // unmap old memory page if needed + if (mem_map_ptr != MAP_FAILED) + { int ok = munmap(mem_map_ptr, mem_page_size); + if (ok != 0) + { printf("ERROR: munmap() failed.\n"); + exit(EXIT_FAILURE); + } + } + + // calculate starting address of new page + while (offset % mem_page_size) offset--; + + // try to map new memory page + mem_map_ptr = mmap(NULL, mem_page_size, PROT_READ | PROT_WRITE, MAP_SHARED, mem_dev_fd, offset); + if (mem_map_ptr == MAP_FAILED) + { printf("ERROR: mmap() failed.\n"); + exit(EXIT_FAILURE); + } + + // save last mapped page address + mem_base_addr = offset; +} + + +//------------------------------------------------------------------------------ +// End-of-File +//------------------------------------------------------------------------------ diff --git a/sw/novena-eim.h b/sw/novena-eim.h new file mode 100644 index 0000000..3d29f77 --- /dev/null +++ b/sw/novena-eim.h @@ -0,0 +1,297 @@ +//------------------------------------------------------------------------------ +// novena-eim.h +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Defined Values +//------------------------------------------------------------------------------ +#define MEMORY_DEVICE "/dev/mem" + + +//------------------------------------------------------------------------------ +// IOMUXC Values +//------------------------------------------------------------------------------ +#define IOMUXC_MUX_MODE_ALT0 0 // 000 + +#define IOMUXC_PAD_CTL_SRE_FAST 1 // 1 +#define IOMUXC_PAD_CTL_DSE_33_OHM 7 // 111 +#define IOMUXC_PAD_CTL_SPEED_MEDIUM_10 2 // 10 +#define IOMUXC_PAD_CTL_ODE_DISABLED 0 // 0 +#define IOMUXC_PAD_CTL_PKE_DISABLED 0 // 0 +#define IOMUXC_PAD_CTL_PUE_PULL 1 // 1 +#define IOMUXC_PAD_CTL_PUS_100K_OHM_PU 2 // 10 +#define IOMUXC_PAD_CTL_HYS_DISABLED 0 // 0 + +//------------------------------------------------------------------------------ +// CCM Values +//------------------------------------------------------------------------------ +#define CCM_CGR_OFF 0 // 00 +#define CCM_CGR_ON_EXCEPT_STOP 3 // 11 + + +//------------------------------------------------------------------------------ +// CPU Registers +//------------------------------------------------------------------------------ +enum IMX6DQ_REGISTER_OFFSET +{ + IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B = 0x020E00F8, + IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B = 0x020E0100, + IOMUXC_SW_MUX_CTL_PAD_EIM_RW = 0x020E0104, + IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B = 0x020E0108, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD00 = 0x020E0114, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD01 = 0x020E0118, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD02 = 0x020E011C, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD03 = 0x020E0120, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD04 = 0x020E0124, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD05 = 0x020E0128, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD06 = 0x020E012C, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD07 = 0x020E0130, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD08 = 0x020E0134, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD09 = 0x020E0138, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD10 = 0x020E013C, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD11 = 0x020E0140, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD12 = 0x020E0144, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD13 = 0x020E0148, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD14 = 0x020E014C, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD15 = 0x020E0150, + IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B = 0x020E0154, + IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK = 0x020E0158, + + IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B = 0x020E040C, + IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B = 0x020E0414, + IOMUXC_SW_PAD_CTL_PAD_EIM_RW = 0x020E0418, + IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B = 0x020E041C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD00 = 0x020E0428, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD01 = 0x020E042C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD02 = 0x020E0430, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD03 = 0x020E0434, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD04 = 0x020E0438, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD05 = 0x020E043C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD06 = 0x020E0440, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD07 = 0x020E0444, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD08 = 0x020E0448, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD09 = 0x020E044C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD10 = 0x020E0450, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD11 = 0x020E0454, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD12 = 0x020E0458, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD13 = 0x020E045C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD14 = 0x020E0460, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD15 = 0x020E0464, + IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B = 0x020E0468, + IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK = 0x020E046C, + + CCM_CCGR6 = 0x020C4080, + + EIM_CS0GCR1 = 0x021B8000, + EIM_CS0GCR2 = 0x021B8004, + EIM_CS0RCR1 = 0x021B8008, + EIM_CS0RCR2 = 0x021B800C, + EIM_CS0WCR1 = 0x021B8010, + EIM_CS0WCR2 = 0x021B8014, + + EIM_WCR = 0x021B8090, + EIM_WIAR = 0x021B8094, + EIM_EAR = 0x021B8098, + + EIM_BASE_ADDR = 0x08000000 +}; + + +//------------------------------------------------------------------------------ +struct IOMUXC_SW_MUX_CTL_PAD_EIM +//------------------------------------------------------------------------------ +{ + uint32_t mux_mode : 3; + uint32_t reserved_3 : 1; + uint32_t sion : 1; + uint32_t reserved_31_5 : 27; +}; +//------------------------------------------------------------------------------ +struct IOMUXC_SW_PAD_CTL_PAD_EIM +//------------------------------------------------------------------------------ +{ + uint32_t sre : 1; + uint32_t reserved_2_1 : 2; + uint32_t dse : 3; + uint32_t speed : 2; + uint32_t reserved_10_8 : 3; + uint32_t ode : 1; + uint32_t pke : 1; + uint32_t pue : 1; + uint32_t pus : 2; + uint32_t hys : 1; + uint32_t reserved_31_17 : 15; +}; + + +//------------------------------------------------------------------------------ +struct CCM_CCGR6 +//------------------------------------------------------------------------------ +{ + uint32_t cg0_usboh3 : 2; + uint32_t cg1_usdhc1 : 2; + uint32_t cg2_usdhc2 : 2; + uint32_t cg3_usdhc3 : 2; + + uint32_t cg3_usdhc4 : 2; + uint32_t cg5_eim_slow : 2; + uint32_t cg6_vdoaxiclk : 2; + uint32_t cg7_vpu : 2; + + uint32_t cg8_reserved : 2; + uint32_t cg9_reserved : 2; + uint32_t cg10_reserved : 2; + uint32_t cg11_reserved : 2; + + uint32_t cg12_reserved : 2; + uint32_t cg13_reserved : 2; + uint32_t cg14_reserved : 2; + uint32_t cg15_reserved : 2; +}; + + +//------------------------------------------------------------------------------ +struct EIM_CS_GCR1 +//------------------------------------------------------------------------------ +{ + uint32_t csen : 1; + uint32_t swr : 1; + uint32_t srd : 1; + uint32_t mum : 1; + uint32_t wfl : 1; + uint32_t rfl : 1; + uint32_t cre : 1; + uint32_t crep : 1; + uint32_t bl : 3; + uint32_t wc : 1; + uint32_t bcd : 2; + uint32_t bcs : 2; + uint32_t dsz : 3; + uint32_t sp : 1; + uint32_t csrec : 3; + uint32_t aus : 1; + uint32_t gbc : 3; + uint32_t wp : 1; + uint32_t psz : 4; +}; +//------------------------------------------------------------------------------ +struct EIM_CS_GCR2 +//------------------------------------------------------------------------------ +{ + uint32_t adh : 2; + uint32_t reserved_3_2 : 2; + uint32_t daps : 4; + uint32_t dae : 1; + uint32_t dap : 1; + uint32_t reserved_11_10 : 2; + uint32_t mux16_byp_grant : 1; + uint32_t reserved_31_13 : 19; +}; +//------------------------------------------------------------------------------ +struct EIM_CS_RCR1 +//------------------------------------------------------------------------------ +{ + uint32_t rcsn : 3; + uint32_t reserved_3 : 1; + uint32_t rcsa : 3; + uint32_t reserved_7 : 1; + uint32_t oen : 3; + uint32_t reserved_11 : 1; + uint32_t oea : 3; + uint32_t reserved_15 : 1; + uint32_t radvn : 3; + uint32_t ral : 1; + uint32_t radva : 3; + uint32_t reserved_23 : 1; + uint32_t rwsc : 6; + uint32_t reserved_31_30 : 2; +}; +//------------------------------------------------------------------------------ +struct EIM_CS_RCR2 +//------------------------------------------------------------------------------ +{ + uint32_t rben : 3; + uint32_t rbe : 1; + uint32_t rbea : 3; + uint32_t reserved_7 : 1; + uint32_t rl : 2; + uint32_t reserved_11_10 : 2; + uint32_t pat : 3; + uint32_t apr : 1; + uint32_t reserved_31_16 : 16; +}; +//------------------------------------------------------------------------------ +struct EIM_CS_WCR1 +//------------------------------------------------------------------------------ +{ + uint32_t wcsn : 3; + uint32_t wcsa : 3; + uint32_t wen : 3; + uint32_t wea : 3; + uint32_t wben : 3; + uint32_t wbea : 3; + uint32_t wadvn : 3; + uint32_t wadva : 3; + uint32_t wwsc : 6; + uint32_t wbed : 1; + uint32_t wal : 1; +}; +//------------------------------------------------------------------------------ +struct EIM_CS_WCR2 +//------------------------------------------------------------------------------ +{ + uint32_t wbcdd : 1; + uint32_t reserved_31_1 : 31; +}; +//------------------------------------------------------------------------------ +struct EIM_WCR +//------------------------------------------------------------------------------ +{ + uint32_t bcm : 1; + uint32_t gbcd : 2; + uint32_t reserved_3 : 1; + uint32_t inten : 1; + uint32_t intpol : 1; + uint32_t reserved_7_6 : 2; + uint32_t wdog_en : 1; + uint32_t wdog_limit : 2; + uint32_t reserved_31_11 : 21; +}; +//------------------------------------------------------------------------------ +struct EIM_WIAR +//------------------------------------------------------------------------------ +{ + uint32_t ips_req : 1; + uint32_t ips_ack : 1; + uint32_t irq : 1; + uint32_t errst : 1; + uint32_t aclk_en : 1; + uint32_t reserved_31_5 : 27; +}; +//------------------------------------------------------------------------------ +struct EIM_EAR +//------------------------------------------------------------------------------ +{ + uint32_t error_addr : 32; +}; + + +//------------------------------------------------------------------------------ +// Prototypes +//------------------------------------------------------------------------------ +int eim_setup (); +void eim_write_32 (off_t, uint32_t *); +void eim_read_32 (off_t, uint32_t *); + +void _eim_setup_iomuxc (); +void _eim_setup_ccm (); +void _eim_setup_eim (); +void _eim_cleanup (); +off_t _eim_calc_offset (off_t); +void _eim_remap_mem (off_t); + + +//------------------------------------------------------------------------------ +// End-of-File +//------------------------------------------------------------------------------ diff --git a/sw/test-adder/Makefile b/sw/test-adder/Makefile deleted file mode 100755 index 5271b70..0000000 --- a/sw/test-adder/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -all: test-adder - -test-adder : test-adder.o novena-eim.o - gcc -o test-adder test-adder.o novena-eim.o - -test-adder.o: test-adder.c novena-eim.h novena-eim.c - gcc -c test-adder.c - gcc -c novena-eim.c - -clean: - rm -f *.o test-adder diff --git a/sw/test-adder/novena-eim.c b/sw/test-adder/novena-eim.c deleted file mode 100644 index 9ea76ef..0000000 --- a/sw/test-adder/novena-eim.c +++ /dev/null @@ -1,406 +0,0 @@ -//------------------------------------------------------------------------------ -// novena-eim.c -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// Headers -//------------------------------------------------------------------------------ -#include -#include -#include -#include -#include -#include -#include "novena-eim.h" - - -//------------------------------------------------------------------------------ -// Variables -//------------------------------------------------------------------------------ -static long mem_page_size = 0; -static int mem_dev_fd = -1; -static void * mem_map_ptr = MAP_FAILED; -static off_t mem_base_addr = 0; - - -//------------------------------------------------------------------------------ -int eim_setup() -//------------------------------------------------------------------------------ -{ - // register cleanup function - int ok = atexit(_eim_cleanup); - if (ok != 0) - { printf("ERROR: atexit() failed.\n"); - return -1; - } - - // determine memory page size to use in mmap() - mem_page_size = sysconf(_SC_PAGESIZE); - if (mem_page_size < 1) - { printf("ERROR: sysconf(_SC_PAGESIZE) == %l\n", mem_page_size); - return -1; - } - - // try to open memory device - mem_dev_fd = open(MEMORY_DEVICE, O_RDWR | O_SYNC); - if (mem_dev_fd == -1) - { printf("ERROR: open(%s) failed.\n", MEMORY_DEVICE); - return -1; - } - - /* Several blocks in the CPU have common pins, we can use I/O MUX Controller - * to configure what block will actually use I/O pins. We wait EIM module to be able - * to communicate with the on-board FPGA. Let's configure IOMUXC accordingly. - */ - _eim_setup_iomuxc(); - - /* We need to enable clocking of EIM block in order to be able to use it. - * Let's configure Clock Controller Module accordingly. - */ - _eim_setup_ccm(); - - /* We need to properly configure EIM mode and all the corresponding parameters. - * That's a lot of code, let's do it now. - */ - _eim_setup_eim(); - - - // done - return 1; -} - - -//------------------------------------------------------------------------------ -void _eim_cleanup() -//------------------------------------------------------------------------------ -{ - // unmap memory if needed - if (mem_map_ptr != MAP_FAILED) - { int ok = munmap(mem_map_ptr, mem_page_size); - if (ok != 0) printf("WARNING: munmap() failed.\n"); - } - - // close memory device if needed - if (mem_dev_fd != -1) - { int ok = close(mem_dev_fd); - if (ok != 0) printf("WARNING: close() failed.\n"); - } -} - - -//------------------------------------------------------------------------------ -void _eim_setup_iomuxc() -//------------------------------------------------------------------------------ -{ - // create structures - struct IOMUXC_SW_MUX_CTL_PAD_EIM reg_mux; // mux control register - struct IOMUXC_SW_PAD_CTL_PAD_EIM reg_pad; // pad control register - - // setup mux control register - reg_mux.mux_mode = IOMUXC_MUX_MODE_ALT0; // ALT0 mode must be used for EIM - reg_mux.sion = 0; // forced input not needed - reg_mux.reserved_3 = 0; // must be 0 - reg_mux.reserved_31_5 = 0; // must be 0 - - // setup pad control register - reg_pad.sre = IOMUXC_PAD_CTL_SRE_FAST; // fast slew rate - reg_pad.dse = IOMUXC_PAD_CTL_DSE_33_OHM; // highest drive strength - reg_pad.speed = IOMUXC_PAD_CTL_SPEED_MEDIUM_10; // medium speed - reg_pad.ode = IOMUXC_PAD_CTL_ODE_DISABLED; // open drain not needed - reg_pad.pke = IOMUXC_PAD_CTL_PKE_DISABLED; // neither pull nor keeper are needed - reg_pad.pue = IOMUXC_PAD_CTL_PUE_PULL; // doesn't matter actually, because PKE is disabled - reg_pad.pus = IOMUXC_PAD_CTL_PUS_100K_OHM_PU; // doesn't matter actually, because PKE is disabled - reg_pad.hys = IOMUXC_PAD_CTL_HYS_DISABLED; // use CMOS, not Schmitt trigger input - reg_pad.reserved_2_1 = 0; // must be 0 - reg_pad.reserved_10_8 = 0; // must be 0 - reg_pad.reserved_31_17 = 0; // must be 0 - - // all the pins must be configured to use the same ALT0 mode - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_RW, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD00, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD01, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD02, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD03, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD04, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD05, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD06, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD07, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD08, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD09, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD10, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD11, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD12, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD13, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD14, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD15, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B, (unsigned int *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK, (unsigned int *)®_mux); - - // we need to configure all the I/O pads too - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_RW, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD00, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD01, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD02, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD03, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD04, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD05, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD06, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD07, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD08, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD09, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD10, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD11, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD12, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD13, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD14, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD15, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B, (unsigned int *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK, (unsigned int *)®_pad); -} - - -//------------------------------------------------------------------------------ -void _eim_setup_ccm() -//------------------------------------------------------------------------------ -{ - // create structure - struct CCM_CCGR6 ccm_ccgr6; - - // read register - eim_read_32(CCM_CCGR6, (unsigned int *)&ccm_ccgr6); - - // modify register - ccm_ccgr6.cg0_usboh3 = CCM_CGR_ON_EXCEPT_STOP; - ccm_ccgr6.cg1_usdhc1 = CCM_CGR_OFF; - ccm_ccgr6.cg2_usdhc2 = CCM_CGR_ON_EXCEPT_STOP; - ccm_ccgr6.cg3_usdhc3 = CCM_CGR_ON_EXCEPT_STOP; - - ccm_ccgr6.cg3_usdhc4 = CCM_CGR_OFF; - ccm_ccgr6.cg5_eim_slow = CCM_CGR_ON_EXCEPT_STOP; - ccm_ccgr6.cg6_vdoaxiclk = CCM_CGR_OFF; - ccm_ccgr6.cg7_vpu = CCM_CGR_OFF; - - ccm_ccgr6.cg8_reserved = 0; - ccm_ccgr6.cg9_reserved = 0; - ccm_ccgr6.cg10_reserved = 0; - ccm_ccgr6.cg11_reserved = 0; - ccm_ccgr6.cg12_reserved = 0; - ccm_ccgr6.cg13_reserved = 0; - ccm_ccgr6.cg14_reserved = 0; - ccm_ccgr6.cg15_reserved = 0; - - // write register - eim_write_32(CCM_CCGR6, (unsigned int *)&ccm_ccgr6); -} - - -//------------------------------------------------------------------------------ -void _eim_setup_eim() -//------------------------------------------------------------------------------ -{ - // create structures - struct EIM_CS_GCR1 gcr1; - struct EIM_CS_GCR2 gcr2; - struct EIM_CS_RCR1 rcr1; - struct EIM_CS_RCR2 rcr2; - struct EIM_CS_WCR1 wcr1; - struct EIM_CS_WCR2 wcr2; - - struct EIM_WCR wcr; - struct EIM_WIAR wiar; - struct EIM_EAR ear; - - // read all the registers - eim_read_32(EIM_CS0GCR1, (unsigned int *)&gcr1); - eim_read_32(EIM_CS0GCR2, (unsigned int *)&gcr2); - eim_read_32(EIM_CS0RCR1, (unsigned int *)&rcr1); - eim_read_32(EIM_CS0RCR2, (unsigned int *)&rcr2); - eim_read_32(EIM_CS0WCR1, (unsigned int *)&wcr1); - eim_read_32(EIM_CS0WCR2, (unsigned int *)&wcr2); - - eim_read_32(EIM_WCR, (unsigned int *)&wcr); - eim_read_32(EIM_WIAR, (unsigned int *)&wiar); - eim_read_32(EIM_EAR, (unsigned int *)&ear); - - // manipulate registers as needed - gcr1.csen = 1; // chip select is enabled | - gcr1.swr = 1; // write is sync | - gcr1.srd = 1; // read is sync | - gcr1.mum = 1; // address and data are multiplexed | - gcr1.wfl = 0; // write latency is not fixed | - gcr1.rfl = 0; // read latency is not fixed | - gcr1.cre = 0; // CRE signal not needed | - //gcr1.crep = x; // don't care, CRE not used | - gcr1.bl = 4; // burst length | ? - gcr1.wc = 0; // write is not continuous | ? - gcr1.bcd = 3; // BCLK divisor is 3+1=4 | - gcr1.bcs = 1; // delay from ~CS to BCLK is 1 cycle | - gcr1.dsz = 1; // 16 bits per databeat at DATA[15:0] | - gcr1.sp = 0; // supervisor protection is disabled | - gcr1.csrec = 1; // ~CS recovery is 1 cycle | - gcr1.aus = 1; // address is not shifted | - gcr1.gbc = 1; // ~CS gap is 1 cycle | - gcr1.wp = 0; // write protection is not enabled | - //gcr1.psz = x; // don't care, page mode is not used | - - gcr2.adh = 0; // address hold duration is 1 cycle | - //gcr2.daps = x; // don't care, DTACK is not used | - gcr2.dae = 0; // DTACK is not used | - //gcr2.dap = x; // don't care, DTACK is not used | - gcr2.mux16_byp_grant = 1; // enable grant mechanism | ? - gcr2.reserved_3_2 = 0; // must be 0 | - gcr2.reserved_11_10 = 0; // must be 0 | - gcr2.reserved_31_13 = 0; // must be 0 | - - //rcr1.rcsn = x; // don't care in sync mode | - rcr1.rcsa = 0; // no delay for ~CS needed | - //rcr1.oen = x; // don't care in sync mode | - rcr1.oea = 0; // no delay for ~OE needed | - rcr1.radvn = 0; // no delay for ~LBA needed | - rcr1.ral = 0; // clear ~LBA when needed | - rcr1.radva = 0; // no delay for ~LBA needed | - rcr1.rwsc = 1; // one wait state | - rcr1.reserved_3 = 0; // must be 0 | - rcr1.reserved_7 = 0; // must be 0 | - rcr1.reserved_11 = 0; // must be 0 | - rcr1.reserved_15 = 0; // must be 0 | - rcr1.reserved_23 = 0; // must be 0 | - rcr1.reserved_31_30 = 0; // must be 0 | - - //rcr2.rben = x; // don't care in sync mode | - rcr2.rbe = 0; // BE is disabled | - //rcr2.rbea = x; // don't care when BE is not used | - rcr2.rl = 0; // read latency is 0 | ? - //rcr2.pat = x; // don't care when page read is not used | - rcr2.apr = 0; // page read mode is not used | - rcr2.reserved_7 = 0; // must be 0 | - rcr2.reserved_11_10 = 0; // must be 0 | - rcr2.reserved_31_16 = 0; // must be 0 | - - //wcr1.wcsn = x; // don't care in sync mode | - wcr1.wcsa = 0; // no delay for ~CS needed | - //wcr1.wen = x; // don't care in sync mode | - wcr1.wea = 0; // no delay for ~WR_N needed | - //wcr1.wben = x; // don't care in sync mode | - //wcr1.wbea = x; // don't care in sync mode | - wcr1.wadvn = 0; // no delay for ~LBA needed | - wcr1.wadva = 0; // no delay for ~LBA needed | - wcr1.wwsc = 1; // no wait state in needed | - wcr1.wbed = 1; // BE is disabled | - wcr1.wal = 0; // clear ~LBA when needed | - - wcr2.wbcdd = 0; // write clock division is not needed | - wcr2.reserved_31_1 = 0; // must be 0 | - - wcr.bcm = 0; // clock is only active during access | - //wcr.gbcd = x; // don't care when BCM=0 | - wcr.inten = 0; // interrupt is not used | - //wcr.intpol = x; // don't care when interrupt is not used | - wcr.wdog_en = 1; // watchdog is enabled | - wcr.wdog_limit = 00; // timeout is 128 BCLK cycles | - wcr.reserved_3 = 0; // must be 0 | - wcr.reserved_7_6 = 0; // must be 0 | - wcr.reserved_31_11 = 0; // must be 0 | - - wiar.ips_req = 0; // IPS not needed | - wiar.ips_ack = 0; // IPS not needed | - //wiar.irq = x; // don't touch | - //wiar.errst = x; // don't touch | - wiar.aclk_en = 1; // clock is enabled | - wiar.reserved_31_5 = 0; // must be 0 | - - //ear.error_addr = x; // read-only | - - // write modified registers - eim_write_32(EIM_CS0GCR1, (unsigned int *)&gcr1); - eim_write_32(EIM_CS0GCR2, (unsigned int *)&gcr2); - eim_write_32(EIM_CS0RCR1, (unsigned int *)&rcr1); - eim_write_32(EIM_CS0RCR2, (unsigned int *)&rcr2); - eim_write_32(EIM_CS0WCR1, (unsigned int *)&wcr1); - eim_write_32(EIM_CS0WCR2, (unsigned int *)&wcr2); - eim_write_32(EIM_WCR, (unsigned int *)&wcr); - eim_write_32(EIM_WIAR, (unsigned int *)&wiar);/* - eim_write_32(EIM_EAR, (unsigned int *)&ear);*/ -} - - -//------------------------------------------------------------------------------ -void eim_write_32(off_t offset, unsigned int *pvalue) -//------------------------------------------------------------------------------ -{ - // calculate memory offset - unsigned int *ptr = (unsigned int *)_eim_calc_offset(offset); - - // write data to memory - memcpy(ptr, pvalue, sizeof(unsigned int)); -} - -//------------------------------------------------------------------------------ -void eim_read_32(off_t offset, unsigned int *pvalue) -//------------------------------------------------------------------------------ -{ - // calculate memory offset - unsigned int *ptr = (unsigned int *)_eim_calc_offset(offset); - - // read data from memory - memcpy(pvalue, ptr, sizeof(unsigned int)); -} - - -//------------------------------------------------------------------------------ -off_t _eim_calc_offset(off_t offset) -//------------------------------------------------------------------------------ -{ - // make sure that memory is mapped - if (mem_map_ptr == MAP_FAILED) _eim_remap_mem(offset); - - // calculate starting and ending addresses of currently mapped page - off_t offset_low = mem_base_addr; - off_t offset_high = mem_base_addr + (mem_page_size - 1); - - // check that offset is in currently mapped page, remap new page otherwise - if ((offset < offset_low) || (offset > offset_high)) _eim_remap_mem(offset); - - // calculate pointer - return (off_t)mem_map_ptr + (offset - mem_base_addr); -} - - -//------------------------------------------------------------------------------ -void _eim_remap_mem(off_t offset) -//------------------------------------------------------------------------------ -{ - // unmap old memory page if needed - if (mem_map_ptr != MAP_FAILED) - { int ok = munmap(mem_map_ptr, mem_page_size); - if (ok != 0) - { printf("ERROR: munmap() failed.\n"); - exit(EXIT_FAILURE); - } - } - - // calculate starting address of new page - while (offset % mem_page_size) offset--; - - // try to map new memory page - mem_map_ptr = mmap(NULL, mem_page_size, PROT_READ | PROT_WRITE, MAP_SHARED, mem_dev_fd, offset); - if (mem_map_ptr == MAP_FAILED) - { printf("ERROR: mmap() failed.\n"); - exit(EXIT_FAILURE); - } - - // save last mapped page address - mem_base_addr = offset; -} - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/sw/test-adder/novena-eim.h b/sw/test-adder/novena-eim.h deleted file mode 100644 index fdcf5a5..0000000 --- a/sw/test-adder/novena-eim.h +++ /dev/null @@ -1,297 +0,0 @@ -//------------------------------------------------------------------------------ -// novena-eim.h -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// Defined Values -//------------------------------------------------------------------------------ -#define MEMORY_DEVICE "/dev/mem" - - -//------------------------------------------------------------------------------ -// IOMUXC Values -//------------------------------------------------------------------------------ -#define IOMUXC_MUX_MODE_ALT0 0 // 000 - -#define IOMUXC_PAD_CTL_SRE_FAST 1 // 1 -#define IOMUXC_PAD_CTL_DSE_33_OHM 7 // 111 -#define IOMUXC_PAD_CTL_SPEED_MEDIUM_10 2 // 10 -#define IOMUXC_PAD_CTL_ODE_DISABLED 0 // 0 -#define IOMUXC_PAD_CTL_PKE_DISABLED 0 // 0 -#define IOMUXC_PAD_CTL_PUE_PULL 1 // 1 -#define IOMUXC_PAD_CTL_PUS_100K_OHM_PU 2 // 10 -#define IOMUXC_PAD_CTL_HYS_DISABLED 0 // 0 - -//------------------------------------------------------------------------------ -// CCM Values -//------------------------------------------------------------------------------ -#define CCM_CGR_OFF 0 // 00 -#define CCM_CGR_ON_EXCEPT_STOP 3 // 11 - - -//------------------------------------------------------------------------------ -// CPU Registers -//------------------------------------------------------------------------------ -enum IMX6DQ_REGISTER_OFFSET -{ - IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B = 0x020E00F8, - IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B = 0x020E0100, - IOMUXC_SW_MUX_CTL_PAD_EIM_RW = 0x020E0104, - IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B = 0x020E0108, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD00 = 0x020E0114, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD01 = 0x020E0118, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD02 = 0x020E011C, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD03 = 0x020E0120, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD04 = 0x020E0124, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD05 = 0x020E0128, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD06 = 0x020E012C, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD07 = 0x020E0130, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD08 = 0x020E0134, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD09 = 0x020E0138, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD10 = 0x020E013C, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD11 = 0x020E0140, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD12 = 0x020E0144, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD13 = 0x020E0148, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD14 = 0x020E014C, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD15 = 0x020E0150, - IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B = 0x020E0154, - IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK = 0x020E0158, - - IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B = 0x020E040C, - IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B = 0x020E0414, - IOMUXC_SW_PAD_CTL_PAD_EIM_RW = 0x020E0418, - IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B = 0x020E041C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD00 = 0x020E0428, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD01 = 0x020E042C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD02 = 0x020E0430, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD03 = 0x020E0434, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD04 = 0x020E0438, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD05 = 0x020E043C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD06 = 0x020E0440, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD07 = 0x020E0444, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD08 = 0x020E0448, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD09 = 0x020E044C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD10 = 0x020E0450, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD11 = 0x020E0454, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD12 = 0x020E0458, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD13 = 0x020E045C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD14 = 0x020E0460, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD15 = 0x020E0464, - IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B = 0x020E0468, - IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK = 0x020E046C, - - CCM_CCGR6 = 0x020C4080, - - EIM_CS0GCR1 = 0x021B8000, - EIM_CS0GCR2 = 0x021B8004, - EIM_CS0RCR1 = 0x021B8008, - EIM_CS0RCR2 = 0x021B800C, - EIM_CS0WCR1 = 0x021B8010, - EIM_CS0WCR2 = 0x021B8014, - - EIM_WCR = 0x021B8090, - EIM_WIAR = 0x021B8094, - EIM_EAR = 0x021B8098, - - EIM_BASE_ADDR = 0x08000000 -}; - - -//------------------------------------------------------------------------------ -struct IOMUXC_SW_MUX_CTL_PAD_EIM -//------------------------------------------------------------------------------ -{ - unsigned int mux_mode : 3; - unsigned int reserved_3 : 1; - unsigned int sion : 1; - unsigned int reserved_31_5 : 27; -}; -//------------------------------------------------------------------------------ -struct IOMUXC_SW_PAD_CTL_PAD_EIM -//------------------------------------------------------------------------------ -{ - unsigned int sre : 1; - unsigned int reserved_2_1 : 2; - unsigned int dse : 3; - unsigned int speed : 2; - unsigned int reserved_10_8 : 3; - unsigned int ode : 1; - unsigned int pke : 1; - unsigned int pue : 1; - unsigned int pus : 2; - unsigned int hys : 1; - unsigned int reserved_31_17 : 15; -}; - - -//------------------------------------------------------------------------------ -struct CCM_CCGR6 -//------------------------------------------------------------------------------ -{ - unsigned int cg0_usboh3 : 2; - unsigned int cg1_usdhc1 : 2; - unsigned int cg2_usdhc2 : 2; - unsigned int cg3_usdhc3 : 2; - - unsigned int cg3_usdhc4 : 2; - unsigned int cg5_eim_slow : 2; - unsigned int cg6_vdoaxiclk : 2; - unsigned int cg7_vpu : 2; - - unsigned int cg8_reserved : 2; - unsigned int cg9_reserved : 2; - unsigned int cg10_reserved : 2; - unsigned int cg11_reserved : 2; - - unsigned int cg12_reserved : 2; - unsigned int cg13_reserved : 2; - unsigned int cg14_reserved : 2; - unsigned int cg15_reserved : 2; -}; - - -//------------------------------------------------------------------------------ -struct EIM_CS_GCR1 -//------------------------------------------------------------------------------ -{ - unsigned int csen : 1; - unsigned int swr : 1; - unsigned int srd : 1; - unsigned int mum : 1; - unsigned int wfl : 1; - unsigned int rfl : 1; - unsigned int cre : 1; - unsigned int crep : 1; - unsigned int bl : 3; - unsigned int wc : 1; - unsigned int bcd : 2; - unsigned int bcs : 2; - unsigned int dsz : 3; - unsigned int sp : 1; - unsigned int csrec : 3; - unsigned int aus : 1; - unsigned int gbc : 3; - unsigned int wp : 1; - unsigned int psz : 4; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_GCR2 -//------------------------------------------------------------------------------ -{ - unsigned int adh : 2; - unsigned int reserved_3_2 : 2; - unsigned int daps : 4; - unsigned int dae : 1; - unsigned int dap : 1; - unsigned int reserved_11_10 : 2; - unsigned int mux16_byp_grant : 1; - unsigned int reserved_31_13 : 19; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_RCR1 -//------------------------------------------------------------------------------ -{ - unsigned int rcsn : 3; - unsigned int reserved_3 : 1; - unsigned int rcsa : 3; - unsigned int reserved_7 : 1; - unsigned int oen : 3; - unsigned int reserved_11 : 1; - unsigned int oea : 3; - unsigned int reserved_15 : 1; - unsigned int radvn : 3; - unsigned int ral : 1; - unsigned int radva : 3; - unsigned int reserved_23 : 1; - unsigned int rwsc : 6; - unsigned int reserved_31_30 : 2; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_RCR2 -//------------------------------------------------------------------------------ -{ - unsigned int rben : 3; - unsigned int rbe : 1; - unsigned int rbea : 3; - unsigned int reserved_7 : 1; - unsigned int rl : 2; - unsigned int reserved_11_10 : 2; - unsigned int pat : 3; - unsigned int apr : 1; - unsigned int reserved_31_16 : 16; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_WCR1 -//------------------------------------------------------------------------------ -{ - unsigned int wcsn : 3; - unsigned int wcsa : 3; - unsigned int wen : 3; - unsigned int wea : 3; - unsigned int wben : 3; - unsigned int wbea : 3; - unsigned int wadvn : 3; - unsigned int wadva : 3; - unsigned int wwsc : 6; - unsigned int wbed : 1; - unsigned int wal : 1; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_WCR2 -//------------------------------------------------------------------------------ -{ - unsigned int wbcdd : 1; - unsigned int reserved_31_1 : 31; -}; -//------------------------------------------------------------------------------ -struct EIM_WCR -//------------------------------------------------------------------------------ -{ - unsigned int bcm : 1; - unsigned int gbcd : 2; - unsigned int reserved_3 : 1; - unsigned int inten : 1; - unsigned int intpol : 1; - unsigned int reserved_7_6 : 2; - unsigned int wdog_en : 1; - unsigned int wdog_limit : 2; - unsigned int reserved_31_11 : 21; -}; -//------------------------------------------------------------------------------ -struct EIM_WIAR -//------------------------------------------------------------------------------ -{ - unsigned int ips_req : 1; - unsigned int ips_ack : 1; - unsigned int irq : 1; - unsigned int errst : 1; - unsigned int aclk_en : 1; - unsigned int reserved_31_5 : 27; -}; -//------------------------------------------------------------------------------ -struct EIM_EAR -//------------------------------------------------------------------------------ -{ - unsigned int error_addr : 32; -}; - - -//------------------------------------------------------------------------------ -// Prototypes -//------------------------------------------------------------------------------ -int eim_setup (); -void eim_write_32 (off_t, unsigned int *); -void eim_read_32 (off_t, unsigned int *); - -void _eim_setup_iomuxc (); -void _eim_setup_ccm (); -void _eim_setup_eim (); -void _eim_cleanup (); -off_t _eim_calc_offset (off_t); -void _eim_remap_mem (off_t); - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/sw/test-adder/test-adder.c b/sw/test-adder/test-adder.c deleted file mode 100644 index 70415d8..0000000 --- a/sw/test-adder/test-adder.c +++ /dev/null @@ -1,206 +0,0 @@ -//------------------------------------------------------------------------------ -// setup-eim.c -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// Headers -//------------------------------------------------------------------------------ -#include -#include -#include "novena-eim.h" - - -//------------------------------------------------------------------------------ -// Demo Adder -//------------------------------------------------------------------------------ -#define DEMO_ADDER_BASE_ADDR (0x3210) -#define DEMO_ADDER_REG_X (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (0<<2)) -#define DEMO_ADDER_REG_Y (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (1<<2)) -#define DEMO_ADDER_REG_Z (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (2<<2)) -#define DEMO_ADDER_REG_SC (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (3<<2)) - - -//------------------------------------------------------------------------------ -// Prototypes -//------------------------------------------------------------------------------ -unsigned int demo_adder_test_round (unsigned int, unsigned int); -unsigned int lfsr_next_x (unsigned int); -unsigned int lfsr_next_y (unsigned int); - - -//------------------------------------------------------------------------------ -// Testing Parameters -//------------------------------------------------------------------------------ -const int NUM_TEST_ROUNDS = 10000; -const int PRINT_XYZ_VALUES = 1; - - -//------------------------------------------------------------------------------ -int main() -//------------------------------------------------------------------------------ -{ - // try to setup eim (return value should be 1) - printf("Configuring EIM .. "); - int ok = eim_setup(); - if (ok < 1) - { printf("ERROR\n"); - return EXIT_FAILURE; - } - else printf("OK\n"); - - // run test - int i; - unsigned int x = 0x12341234, y = 0xABCDABCD, zyx; - printf("Testing started.\n"); - for (i=0; i>= 16; - if (sts != ctl) - { printf("ERROR: Adder timeout!\n"); - exit(EXIT_FAILURE); - } - - // read z - unsigned int z; - eim_read_32(DEMO_ADDER_REG_Z, &z); - - // uncomment to trigger an error - /** - z++; - **/ - - // done - return z; -} - - -//------------------------------------------------------------------------------ -unsigned int lfsr_next_x(unsigned int value) -//------------------------------------------------------------------------------ -{ - // - // [32, 31, 29, 28, 27, 25, 24, 23, 21, 19, 17, 14, 10, 6, 4, 2] - // 0 1 3 4 5 7 8 9 11 13 15 18 22 24 28 30 - // - - unsigned int carry = 0; - - carry ^= (value >> 0); - carry ^= (value >> 1); - carry ^= (value >> 3); - carry ^= (value >> 4); - - carry ^= (value >> 5); - carry ^= (value >> 7); - carry ^= (value >> 8); - carry ^= (value >> 9); - - carry ^= (value >> 11); - carry ^= (value >> 13); - carry ^= (value >> 15); - carry ^= (value >> 18); - - carry ^= (value >> 22); - carry ^= (value >> 24); - carry ^= (value >> 28); - carry ^= (value >> 30); - - value >>= 1, value |= (carry << 31); - - return value; -} - - -//------------------------------------------------------------------------------ -unsigned int lfsr_next_y(unsigned int value) -//------------------------------------------------------------------------------ -{ - // - // [32, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 1] - // 0 15 16 17 18 19 20 21 22 23 24 25 26 27 28 31 - // - - unsigned int carry = 0; - - carry ^= (value >> 0); - carry ^= (value >> 15); - carry ^= (value >> 16); - carry ^= (value >> 17); - - carry ^= (value >> 18); - carry ^= (value >> 19); - carry ^= (value >> 20); - carry ^= (value >> 21); - - carry ^= (value >> 22); - carry ^= (value >> 23); - carry ^= (value >> 24); - carry ^= (value >> 25); - - carry ^= (value >> 26); - carry ^= (value >> 27); - carry ^= (value >> 28); - carry ^= (value >> 31); - - value >>= 1, value |= (carry << 31); - - return value; -} - - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/sw/test-sha256/Makefile b/sw/test-sha256/Makefile deleted file mode 100755 index ee8536e..0000000 --- a/sw/test-sha256/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -all: test-sha256 hash_tester - -.c.o: - gcc -c -Wall -o $@ $< - -test-sha256 : test-sha256.o novena-eim.o - gcc -o test-sha256 test-sha256.o novena-eim.o - -test-sha256.o: test-sha256.c novena-eim.h - -hash_tester : hash_tester.o novena-eim.o - gcc -o hash_tester hash_tester.o novena-eim.o - -hash_tester.o: hash_tester.c novena-eim.h - -novena-eim.o: novena-eim.c novena-eim.h - -clean: - rm -f *.o test-adder test-sha256 hash_tester diff --git a/sw/test-sha256/hash_tester.c b/sw/test-sha256/hash_tester.c deleted file mode 100644 index 4fbeaa3..0000000 --- a/sw/test-sha256/hash_tester.c +++ /dev/null @@ -1,876 +0,0 @@ -/* - * hash_tester.c - * -------------- - * This program sends several commands to the coretest_hashes subsystem - * in order to verify the SHA-1, SHA-256 and SHA-512/x hash function - * cores. - * - * Note: This version of the program talks to the FPGA over an EIM bus. - * - * The single and dual block test cases are taken from the - * NIST KAT document: - * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf - * - * - * Authors: Joachim Strömbergson, Paul Selkirk - * Copyright (c) 2014-2015, NORDUnet A/S All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the NORDUnet nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "novena-eim.h" - -int debug = 0; -int quiet = 0; -int repeat = 0; - -/* instead of core number 0 we have a page of global registers */ -#define ADDR_GLOBAL_BOARD_TYPE EIM_BASE_ADDR + (0x00 << 2) -#define ADDR_GLOBAL_BITSTREAM_VER EIM_BASE_ADDR + (0x01 << 2) -#define ADDR_GLOBAL_DUMMY_REG EIM_BASE_ADDR + (0xFF << 2) - -#define SEGMENT_OFFSET_HASHES EIM_BASE_ADDR + 0x000000 -#define SEGMENT_OFFSET_RNGS EIM_BASE_ADDR + 0x010000 -#define SEGMENT_OFFSET_CIPHERS EIM_BASE_ADDR + 0x020000 - - -/* addresses and codes common to all hash cores */ -#define ADDR_NAME0 0x00 -#define ADDR_NAME1 0x04 -#define ADDR_VERSION 0x08 -#define ADDR_CTRL 0x20 -#define CTRL_INIT_CMD 1 -#define CTRL_NEXT_CMD 2 -#define ADDR_STATUS 0x24 -#define STATUS_READY_BIT 1 -#define STATUS_VALID_BIT 2 -#define ADDR_BLOCK 0x40 -#define ADDR_DIGEST 0x80 - -#define HASH_CORE_SIZE 0x400 - -/* addresses and codes for the specific hash cores */ -#define SHA1_ADDR_BASE EIM_BASE_ADDR + (1*HASH_CORE_SIZE) -#define SHA1_ADDR_NAME0 SHA1_ADDR_BASE + ADDR_NAME0 -#define SHA1_ADDR_NAME1 SHA1_ADDR_BASE + ADDR_NAME1 -#define SHA1_ADDR_VERSION SHA1_ADDR_BASE + ADDR_VERSION -#define SHA1_ADDR_CTRL SHA1_ADDR_BASE + ADDR_CTRL -#define SHA1_ADDR_STATUS SHA1_ADDR_BASE + ADDR_STATUS -#define SHA1_ADDR_BLOCK SHA1_ADDR_BASE + ADDR_BLOCK -#define SHA1_ADDR_DIGEST SHA1_ADDR_BASE + ADDR_DIGEST -#define SHA1_BLOCK_LEN 512 / 8 -#define SHA1_DIGEST_LEN 160 / 8 - -#define SHA256_ADDR_BASE EIM_BASE_ADDR + (2*HASH_CORE_SIZE) -#define SHA256_ADDR_NAME0 SHA256_ADDR_BASE + ADDR_NAME0 -#define SHA256_ADDR_NAME1 SHA256_ADDR_BASE + ADDR_NAME1 -#define SHA256_ADDR_VERSION SHA256_ADDR_BASE + ADDR_VERSION -#define SHA256_ADDR_CTRL SHA256_ADDR_BASE + ADDR_CTRL -#define SHA256_ADDR_STATUS SHA256_ADDR_BASE + ADDR_STATUS -#define SHA256_ADDR_BLOCK SHA256_ADDR_BASE + ADDR_BLOCK -#define SHA256_ADDR_DIGEST SHA256_ADDR_BASE + ADDR_DIGEST -#define SHA256_BLOCK_LEN 512 / 8 -#define SHA256_DIGEST_LEN 256 / 8 - -#define SHA512_ADDR_BASE EIM_BASE_ADDR + (3*HASH_CORE_SIZE) -#define SHA512_ADDR_NAME0 SHA512_ADDR_BASE + ADDR_NAME0 -#define SHA512_ADDR_NAME1 SHA512_ADDR_BASE + ADDR_NAME1 -#define SHA512_ADDR_VERSION SHA512_ADDR_BASE + ADDR_VERSION -#define SHA512_ADDR_CTRL SHA512_ADDR_BASE + ADDR_CTRL -#define SHA512_ADDR_STATUS SHA512_ADDR_BASE + ADDR_STATUS -#define SHA512_ADDR_BLOCK SHA512_ADDR_BASE + ADDR_BLOCK -#define SHA512_ADDR_DIGEST SHA512_ADDR_BASE + 0x100 -#define SHA512_BLOCK_LEN 1024 / 8 -#define SHA512_224_DIGEST_LEN 224 / 8 -#define SHA512_256_DIGEST_LEN 256 / 8 -#define SHA384_DIGEST_LEN 384 / 8 -#define SHA512_DIGEST_LEN 512 / 8 -#define MODE_SHA_512_224 0 << 2 -#define MODE_SHA_512_256 1 << 2 -#define MODE_SHA_384 2 << 2 -#define MODE_SHA_512 3 << 2 - -/* SHA-1/SHA-256 One Block Message Sample - Input Message: "abc" */ -const uint8_t NIST_512_SINGLE[] = -{ 0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18 }; - -const uint8_t SHA1_SINGLE_DIGEST[] = -{ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, - 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, - 0x9c, 0xd0, 0xd8, 0x9d }; - -const uint8_t SHA256_SINGLE_DIGEST[] = -{ 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, - 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, - 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, - 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD }; - -/* SHA-1/SHA-256 Two Block Message Sample - Input Message: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" */ -const uint8_t NIST_512_DOUBLE0[] = -{ 0x61, 0x62, 0x63, 0x64, 0x62, 0x63, 0x64, 0x65, - 0x63, 0x64, 0x65, 0x66, 0x64, 0x65, 0x66, 0x67, - 0x65, 0x66, 0x67, 0x68, 0x66, 0x67, 0x68, 0x69, - 0x67, 0x68, 0x69, 0x6A, 0x68, 0x69, 0x6A, 0x6B, - 0x69, 0x6A, 0x6B, 0x6C, 0x6A, 0x6B, 0x6C, 0x6D, - 0x6B, 0x6C, 0x6D, 0x6E, 0x6C, 0x6D, 0x6E, 0x6F, - 0x6D, 0x6E, 0x6F, 0x70, 0x6E, 0x6F, 0x70, 0x71, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -const uint8_t NIST_512_DOUBLE1[] = -{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0 }; - -const uint8_t SHA1_DOUBLE_DIGEST[] = -{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, - 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, - 0xE5, 0x46, 0x70, 0xF1 }; - -const uint8_t SHA256_DOUBLE_DIGEST[] = -{ 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, - 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, - 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, - 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }; - -/* SHA-512 One Block Message Sample - Input Message: "abc" */ -const uint8_t NIST_1024_SINGLE[] = -{ 0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18 }; - -const uint8_t SHA512_224_SINGLE_DIGEST[] = -{ 0x46, 0x34, 0x27, 0x0f, 0x70, 0x7b, 0x6a, 0x54, - 0xda, 0xae, 0x75, 0x30, 0x46, 0x08, 0x42, 0xe2, - 0x0e, 0x37, 0xed, 0x26, 0x5c, 0xee, 0xe9, 0xa4, - 0x3e, 0x89, 0x24, 0xaa }; -const uint8_t SHA512_256_SINGLE_DIGEST[] = -{ 0x53, 0x04, 0x8e, 0x26, 0x81, 0x94, 0x1e, 0xf9, - 0x9b, 0x2e, 0x29, 0xb7, 0x6b, 0x4c, 0x7d, 0xab, - 0xe4, 0xc2, 0xd0, 0xc6, 0x34, 0xfc, 0x6d, 0x46, - 0xe0, 0xe2, 0xf1, 0x31, 0x07, 0xe7, 0xaf, 0x23 }; -const uint8_t SHA384_SINGLE_DIGEST[] = -{ 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, - 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, - 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, - 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, - 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, - 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 }; -const uint8_t SHA512_SINGLE_DIGEST[] = -{ 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, - 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, - 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, - 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, - 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, - 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, - 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, - 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }; - -/* SHA-512 Two Block Message Sample - Input Message: "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" - "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" */ -const uint8_t NIST_1024_DOUBLE0[] = -{ 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, - 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, - 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, - 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, - 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, - 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, - 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, - 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, - 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, - 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -const uint8_t NIST_1024_DOUBLE1[] = -{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80 }; - -const uint8_t SHA512_224_DOUBLE_DIGEST[] = -{ 0x23, 0xfe, 0xc5, 0xbb, 0x94, 0xd6, 0x0b, 0x23, - 0x30, 0x81, 0x92, 0x64, 0x0b, 0x0c, 0x45, 0x33, - 0x35, 0xd6, 0x64, 0x73, 0x4f, 0xe4, 0x0e, 0x72, - 0x68, 0x67, 0x4a, 0xf9 }; -const uint8_t SHA512_256_DOUBLE_DIGEST[] = -{ 0x39, 0x28, 0xe1, 0x84, 0xfb, 0x86, 0x90, 0xf8, - 0x40, 0xda, 0x39, 0x88, 0x12, 0x1d, 0x31, 0xbe, - 0x65, 0xcb, 0x9d, 0x3e, 0xf8, 0x3e, 0xe6, 0x14, - 0x6f, 0xea, 0xc8, 0x61, 0xe1, 0x9b, 0x56, 0x3a }; -const uint8_t SHA384_DOUBLE_DIGEST[] = -{ 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, - 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, - 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, - 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, - 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, - 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 }; -const uint8_t SHA512_DOUBLE_DIGEST[] = -{ 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, - 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, - 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, - 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, - 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, - 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, - 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, - 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }; - -/* ---------------- test-case low-level code ---------------- */ - -void dump(char *label, const uint8_t *buf, int len) -{ - if (debug) { - int i; - printf("%s [", label); - for (i = 0; i < len; ++i) - printf(" %02x", buf[i]); - printf(" ]\n"); - } -} - -int tc_write(off_t offset, const uint8_t *buf, int len) -{ - dump("write ", buf, len); - - for (; len > 0; offset += 4, buf += 4, len -= 4) { - uint32_t val; - val = htonl(*(uint32_t *)buf); - eim_write_32(offset, &val); - } - - return 0; -} - -int tc_read(off_t offset, uint8_t *buf, int len) -{ - uint8_t *rbuf = buf; - int rlen = len; - - for (; rlen > 0; offset += 4, rbuf += 4, rlen -= 4) { - uint32_t val; - eim_read_32(offset, &val); - *(uint32_t *)rbuf = ntohl(val); - } - - dump("read ", buf, len); - - return 0; -} - -int tc_expected(off_t offset, const uint8_t *expected, int len) -{ - uint8_t *buf; - int i; - - buf = malloc(len); - if (buf == NULL) { - perror("malloc"); - return 1; - } - dump("expect", expected, len); - - if (tc_read(offset, buf, len) != 0) - goto errout; - - for (i = 0; i < len; ++i) - if (buf[i] != expected[i]) { - fprintf(stderr, "response byte %d: expected 0x%02x, got 0x%02x\n", - i, expected[i], buf[i]); - goto errout; - } - - free(buf); - return 0; -errout: - free(buf); - return 1; -} - -int tc_init(off_t offset) -{ - uint8_t buf[4] = { 0, 0, 0, CTRL_INIT_CMD }; - - return tc_write(offset, buf, 4); -} - -int tc_next(off_t offset) -{ - uint8_t buf[4] = { 0, 0, 0, CTRL_NEXT_CMD }; - - return tc_write(offset, buf, 4); -} - -int tc_wait(off_t offset, uint8_t status) -{ - uint8_t buf[4]; - -#if 0 - do { - if (tc_read(offset, buf, 4) != 0) - return 1; - } while (!(buf[3] & status)); - - return 0; -#else - int i; - for (i = 0; i < 10; ++i) { - if (tc_read(offset, buf, 4) != 0) - return 1; - if (buf[3] & status) - return 0; - } - fprintf(stderr, "tc_wait timed out\n"); - return 1; -#endif -} - -int tc_wait_ready(off_t offset) -{ - return tc_wait(offset, STATUS_READY_BIT); -} - -int tc_wait_valid(off_t offset) -{ - return tc_wait(offset, STATUS_VALID_BIT); -} - -/* ---------------- SHA-1 test cases ---------------- */ - -/* TC1: Read name and version from SHA-1 core. */ -int TC1(void) -{ - uint8_t name0[4] = { 0x73, 0x68, 0x61, 0x31 }; /* "sha1" */ - uint8_t name1[4] = { 0x20, 0x20, 0x20, 0x20 }; /* " " */ - uint8_t version[4] = { 0x30, 0x2e, 0x35, 0x30 }; /* "0.50" */ - - if (!quiet) - printf("TC1: Reading name, type and version words from SHA-1 core.\n"); - - return - tc_expected(SHA1_ADDR_NAME0, name0, 4) || - tc_expected(SHA1_ADDR_NAME1, name1, 4) || - tc_expected(SHA1_ADDR_VERSION, version, 4); -} - -/* TC2: SHA-1 Single block message test as specified by NIST. */ -int TC2(void) -{ - const uint8_t *block = NIST_512_SINGLE; - const uint8_t *expected = SHA1_SINGLE_DIGEST; - int ret; - - if (!quiet) - printf("TC2: Single block message test for SHA-1.\n"); - - /* Write block to SHA-1. */ - tc_write(SHA1_ADDR_BLOCK, block, SHA1_BLOCK_LEN); - /* Start initial block hashing, wait and check status. */ - tc_init(SHA1_ADDR_CTRL); - tc_wait_valid(SHA1_ADDR_STATUS); - /* Extract the digest. */ - ret = tc_expected(SHA1_ADDR_DIGEST, expected, SHA1_DIGEST_LEN); - return ret; -} - -/* TC3: SHA-1 Double block message test as specified by NIST. */ -int TC3(void) -{ - const uint8_t *block[2] = { NIST_512_DOUBLE0, NIST_512_DOUBLE1 }; - static const uint8_t block0_expected[] = - { 0xF4, 0x28, 0x68, 0x18, 0xC3, 0x7B, 0x27, 0xAE, - 0x04, 0x08, 0xF5, 0x81, 0x84, 0x67, 0x71, 0x48, - 0x4A, 0x56, 0x65, 0x72 }; - const uint8_t *expected = SHA1_DOUBLE_DIGEST; - int ret; - - if (!quiet) - printf("TC3: Double block message test for SHA-1.\n"); - - /* Write first block to SHA-1. */ - tc_write(SHA1_ADDR_BLOCK, block[0], SHA1_BLOCK_LEN); - /* Start initial block hashing, wait and check status. */ - tc_init(SHA1_ADDR_CTRL); - tc_wait_valid(SHA1_ADDR_STATUS); - /* Extract the first digest. */ - tc_expected(SHA1_ADDR_DIGEST, block0_expected, SHA1_DIGEST_LEN); - /* Write second block to SHA-1. */ - tc_write(SHA1_ADDR_BLOCK, block[1], SHA1_BLOCK_LEN); - /* Start next block hashing, wait and check status. */ - tc_next(SHA1_ADDR_CTRL); - tc_wait_valid(SHA1_ADDR_STATUS); - /* Extract the second digest. */ - ret = tc_expected(SHA1_ADDR_DIGEST, expected, SHA1_DIGEST_LEN); - return ret; -} - -/* ---------------- SHA-256 test cases ---------------- */ - -/* TC4: Read name and version from SHA-256 core. */ -int TC4(void) -{ - uint8_t name0[4] = { 0x73, 0x68, 0x61, 0x32 }; /* "sha2" */ - uint8_t name1[4] = { 0x2d, 0x32, 0x35, 0x36 }; /* "-256" */ - uint8_t version[4] = { 0x30, 0x2e, 0x38, 0x30 }; /* "0.80" */ - - if (!quiet) - printf("TC4: Reading name, type and version words from SHA-256 core.\n"); - - return - tc_expected(SHA256_ADDR_NAME0, name0, 4) || - tc_expected(SHA256_ADDR_NAME1, name1, 4) || - tc_expected(SHA256_ADDR_VERSION, version, 4); -} - -/* TC5: SHA-256 Single block message test as specified by NIST. */ -int TC5() -{ - const uint8_t *block = NIST_512_SINGLE; - const uint8_t *expected = SHA256_SINGLE_DIGEST; - - if (!quiet) - printf("TC5: Single block message test for SHA-256.\n"); - - return - /* Write block to SHA-256. */ - tc_write(SHA256_ADDR_BLOCK, block, SHA256_BLOCK_LEN) || - /* Start initial block hashing, wait and check status. */ - tc_init(SHA256_ADDR_CTRL) || - tc_wait_valid(SHA256_ADDR_STATUS) || - /* Extract the digest. */ - tc_expected(SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN); -} - -/* TC6: SHA-256 Double block message test as specified by NIST. */ -int TC6() -{ - const uint8_t *block[2] = { NIST_512_DOUBLE0, NIST_512_DOUBLE1 }; - static const uint8_t block0_expected[] = - { 0x85, 0xE6, 0x55, 0xD6, 0x41, 0x7A, 0x17, 0x95, - 0x33, 0x63, 0x37, 0x6A, 0x62, 0x4C, 0xDE, 0x5C, - 0x76, 0xE0, 0x95, 0x89, 0xCA, 0xC5, 0xF8, 0x11, - 0xCC, 0x4B, 0x32, 0xC1, 0xF2, 0x0E, 0x53, 0x3A }; - const uint8_t *expected = SHA256_DOUBLE_DIGEST; - - if (!quiet) - printf("TC6: Double block message test for SHA-256.\n"); - - return - /* Write first block to SHA-256. */ - tc_write(SHA256_ADDR_BLOCK, block[0], SHA256_BLOCK_LEN) || - /* Start initial block hashing, wait and check status. */ - tc_init(SHA256_ADDR_CTRL) || - tc_wait_valid(SHA256_ADDR_STATUS) || - /* Extract the first digest. */ - tc_expected(SHA256_ADDR_DIGEST, block0_expected, SHA256_DIGEST_LEN) || - /* Write second block to SHA-256. */ - tc_write(SHA256_ADDR_BLOCK, block[1], SHA256_BLOCK_LEN) || - /* Start next block hashing, wait and check status. */ - tc_next(SHA256_ADDR_CTRL) || - tc_wait_valid(SHA256_ADDR_STATUS) || - /* Extract the second digest. */ - tc_expected(SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN); -} - -/* TC7: SHA-256 Huge message test. */ -int TC7() -{ - static const uint8_t block[] = - { 0xaa, 0x55, 0xaa, 0x55, 0xde, 0xad, 0xbe, 0xef, - 0x55, 0xaa, 0x55, 0xaa, 0xf0, 0x0f, 0xf0, 0x0f, - 0xaa, 0x55, 0xaa, 0x55, 0xde, 0xad, 0xbe, 0xef, - 0x55, 0xaa, 0x55, 0xaa, 0xf0, 0x0f, 0xf0, 0x0f, - 0xaa, 0x55, 0xaa, 0x55, 0xde, 0xad, 0xbe, 0xef, - 0x55, 0xaa, 0x55, 0xaa, 0xf0, 0x0f, 0xf0, 0x0f, - 0xaa, 0x55, 0xaa, 0x55, 0xde, 0xad, 0xbe, 0xef, - 0x55, 0xaa, 0x55, 0xaa, 0xf0, 0x0f, 0xf0, 0x0f }; - - /* final digest after 1000 iterations */ - static const uint8_t expected[] = - { 0x76, 0x38, 0xf3, 0xbc, 0x50, 0x0d, 0xd1, 0xa6, - 0x58, 0x6d, 0xd4, 0xd0, 0x1a, 0x15, 0x51, 0xaf, - 0xd8, 0x21, 0xd2, 0x35, 0x2f, 0x91, 0x9e, 0x28, - 0xd5, 0x84, 0x2f, 0xab, 0x03, 0xa4, 0x0f, 0x2a }; - - int i, n = 1000; - - if (!quiet) - printf("TC7: Message with %d blocks test for SHA-256.\n", n); - - /* Write block data to SHA-256. */ - if (tc_write(SHA256_ADDR_BLOCK, block, SHA256_BLOCK_LEN)) - return 1; - - /* Start initial block hashing, wait and check status. */ - if (tc_init(SHA256_ADDR_CTRL) || - tc_wait_ready(SHA256_ADDR_STATUS)) - return 1; - - /* First block done. Do the rest. */ - for (i = 1; i < n; ++i) { - /* Start next block hashing, wait and check status. */ - if (tc_next(SHA256_ADDR_CTRL) || - tc_wait_ready(SHA256_ADDR_STATUS)) - return 1; - } - - /* XXX valid is probably set at the same time as ready */ - if (tc_wait_valid(SHA256_ADDR_STATUS)) - return 1; - /* Extract the final digest. */ - return tc_expected(SHA256_ADDR_DIGEST, expected, SHA256_DIGEST_LEN); -} - -/* ---------------- SHA-512 test cases ---------------- */ - -/* TC8: Read name and version from SHA-512 core. */ -int TC8() -{ - uint8_t name0[4] = { 0x73, 0x68, 0x61, 0x32 }; /* "sha2" */ - uint8_t name1[4] = { 0x2d, 0x35, 0x31, 0x32 }; /* "-512" */ - uint8_t version[4] = { 0x30, 0x2e, 0x38, 0x30 }; /* "0.80" */ - - if (!quiet) - printf("TC8: Reading name, type and version words from SHA-512 core.\n"); - - return - tc_expected(SHA512_ADDR_NAME0, name0, 4) || - tc_expected(SHA512_ADDR_NAME1, name1, 4) || - tc_expected(SHA512_ADDR_VERSION, version, 4); -} - -/* TC9: SHA-512 Single block message test as specified by NIST. - We do this for all modes. */ -int tc9(int mode, const uint8_t *expected, int digest_len) -{ - const uint8_t *block = NIST_1024_SINGLE; - uint8_t init[4] = { 0, 0, 0, CTRL_INIT_CMD + mode }; - - return - /* Write block to SHA-512. */ - tc_write(SHA512_ADDR_BLOCK, block, SHA512_BLOCK_LEN) || - /* Start initial block hashing, wait and check status. */ - tc_write(SHA512_ADDR_CTRL, init, 4) || - tc_wait_valid(SHA512_ADDR_STATUS) || - /* Extract the digest. */ - tc_expected(SHA512_ADDR_DIGEST, expected, digest_len); -} - -int TC9() -{ - if (!quiet) - printf("TC9-1: Single block message test for SHA-512/224.\n"); - if (tc9(MODE_SHA_512_224, SHA512_224_SINGLE_DIGEST, SHA512_224_DIGEST_LEN) != 0) - return 1; - - if (!quiet) - printf("TC9-2: Single block message test for SHA-512/256.\n"); - if (tc9(MODE_SHA_512_256, SHA512_256_SINGLE_DIGEST, SHA512_256_DIGEST_LEN) != 0) - return 1; - - if (!quiet) - printf("TC9-3: Single block message test for SHA-384.\n"); - if (tc9(MODE_SHA_384, SHA384_SINGLE_DIGEST, SHA384_DIGEST_LEN) != 0) - return 1; - - if (!quiet) - printf("TC9-4: Single block message test for SHA-512.\n"); - if (tc9(MODE_SHA_512, SHA512_SINGLE_DIGEST, SHA512_DIGEST_LEN) != 0) - return 1; - - return 0; -} - -/* TC10: SHA-512 Double block message test as specified by NIST. - We do this for all modes. */ -int tc10(int mode, const uint8_t *expected, int digest_len) -{ - const uint8_t *block[2] = { NIST_1024_DOUBLE0, NIST_1024_DOUBLE1 }; - uint8_t init[4] = { 0, 0, 0, CTRL_INIT_CMD + mode }; - uint8_t next[4] = { 0, 0, 0, CTRL_NEXT_CMD + mode }; - - return - /* Write first block to SHA-512. */ - tc_write(SHA512_ADDR_BLOCK, block[0], SHA512_BLOCK_LEN) || - /* Start initial block hashing, wait and check status. */ - tc_write(SHA512_ADDR_CTRL, init, 4) || - tc_wait_ready(SHA512_ADDR_STATUS) || - /* Write second block to SHA-512. */ - tc_write(SHA512_ADDR_BLOCK, block[1], SHA512_BLOCK_LEN) || - /* Start next block hashing, wait and check status. */ - tc_write(SHA512_ADDR_CTRL, next, 4) || - tc_wait_valid(SHA512_ADDR_STATUS) || - /* Extract the digest. */ - tc_expected(SHA512_ADDR_DIGEST, expected, digest_len); -} - -int TC10() -{ - if (!quiet) - printf("TC10-1: Double block message test for SHA-512/224.\n"); - if (tc10(MODE_SHA_512_224, SHA512_224_DOUBLE_DIGEST, SHA512_224_DIGEST_LEN) != 0) - return 1; - - if (!quiet) - printf("TC10-2: Double block message test for SHA-512/256.\n"); - if (tc10(MODE_SHA_512_256, SHA512_256_DOUBLE_DIGEST, SHA512_256_DIGEST_LEN) != 0) - return 1; - - if (!quiet) - printf("TC10-3: Double block message test for SHA-384.\n"); - if (tc10(MODE_SHA_384, SHA384_DOUBLE_DIGEST, SHA384_DIGEST_LEN) != 0) - return 1; - - if (!quiet) - printf("TC10-4: Double block message test for SHA-512.\n"); - if (tc10(MODE_SHA_512, SHA512_DOUBLE_DIGEST, SHA512_DIGEST_LEN) != 0) - return 1; - - return 0; -} - -int TC11() -{ - uint8_t board_type[4] = { 'P', 'V', 'T', '1'}; /* "PVT1" */ - uint8_t bitstream_ver[4] = { 0x00, 0x01, 0x00, 0x0B }; /* v0.1.0b */ - uint8_t t[4]; - - uint8_t seg_rngs_reg_first[4] = { 0xAA, 0xAA, 0xAA, 0xAA}; - uint8_t seg_rngs_reg_second[4] = { 0xBB, 0xBB, 0xBB, 0xBB}; - uint8_t seg_rngs_reg_third[4] = { 0xCC, 0xCC, 0xCC, 0xCC}; - - uint8_t seg_ciphers_reg_first[4] = { 0xDD, 0xDD, 0xDD, 0xDD}; - uint8_t seg_ciphers_reg_second[4] = { 0xEE, 0xEE, 0xEE, 0xEE}; - uint8_t seg_ciphers_reg_third[4] = { 0xFF, 0xFF, 0xFF, 0xFF}; - - // write current time into dummy register, then try to read it back - // to make sure that we can actually write something into eim - (void)time((time_t *)t); - tc_write(ADDR_GLOBAL_DUMMY_REG, (void *)&t, 4); - - if (!quiet) - printf("TC11: Reading board type, bitstream version and dummy register from global registers.\n"); - if (!quiet) - printf("TC11: Reading dummy registers from RNG and CIPHER memory segments.\n"); - - return - tc_expected(ADDR_GLOBAL_BOARD_TYPE, board_type, 4) || - tc_expected(ADDR_GLOBAL_BITSTREAM_VER, bitstream_ver, 4) || - tc_expected(ADDR_GLOBAL_DUMMY_REG, (void *)t, 4) || - - tc_expected(SEGMENT_OFFSET_RNGS + (0 << 2), seg_rngs_reg_first, 4) || - tc_expected(SEGMENT_OFFSET_RNGS + (1 << 2), seg_rngs_reg_second, 4) || - tc_expected(SEGMENT_OFFSET_RNGS + (2 << 2), seg_rngs_reg_third, 4) || - - tc_expected(SEGMENT_OFFSET_CIPHERS + (0 << 2), seg_ciphers_reg_first, 4) || - tc_expected(SEGMENT_OFFSET_CIPHERS + (1 << 2), seg_ciphers_reg_second, 4) || - tc_expected(SEGMENT_OFFSET_CIPHERS + (2 << 2), seg_ciphers_reg_third, 4); -} - -/* ---------------- main ---------------- */ - -unsigned long iter = 0; -struct timeval tv_start, tv_end; -void sighandler(int unused) -{ - double tv_diff; - - gettimeofday(&tv_end, NULL); - tv_diff = (double)(tv_end.tv_sec - tv_start.tv_sec) + - (double)(tv_end.tv_usec - tv_start.tv_usec)/1000000; - printf("\n%lu iterations in %.3f seconds (%.3f iterations/sec)\n", - iter, tv_diff, (double)iter/tv_diff); - exit(0); -} - -int main(int argc, char *argv[]) -{ - typedef int (*tcfp)(void); - tcfp sha1_tests[] = { TC1, TC2, TC3 }; - tcfp sha256_tests[] = { TC4, TC5, TC6, TC7 }; - tcfp sha512_tests[] = { TC8, TC9, TC10 }; - tcfp all_tests[] = { TC1, TC2, TC3, TC4, TC5, TC6, TC7, TC8, TC9, TC10, TC11 }; - - char *usage = "Usage: %s [-h] [-d] [-q] [-r] tc...\n"; - int i, j, opt; - - while ((opt = getopt(argc, argv, "h?dqr")) != -1) { - switch (opt) { - case 'h': - case '?': - printf(usage, argv[0]); - return 0; - case 'd': - debug = 1; - break; - case 'q': - quiet = 1; - break; - case 'r': - repeat = 1; - break; - default: - fprintf(stderr, usage, argv[0]); - return 1; - } - } - - // try to setup eim (return value should be 1) - printf("Configuring EIM .. "); - if (eim_setup() < 1) { - printf("ERROR\n"); - return EXIT_FAILURE; - } - else { - printf("EIM Setup ok.\n"); - } - - if (repeat) { - tcfp tc; - if (optind != argc - 1) { - fprintf(stderr, "only one test case can be repeated\n"); - return 1; - } - j = atoi(argv[optind]); - if (j <= 0 || j > sizeof(all_tests)/sizeof(all_tests[0])) { - fprintf(stderr, "invalid test number %s\n", argv[optind]); - return 1; - } - tc = (all_tests[j - 1]); - srand(time(NULL)); - signal(SIGINT, sighandler); - gettimeofday(&tv_start, NULL); - while (1) { - ++iter; - if ((iter & 0xffff) == 0) { - printf("."); - fflush(stdout); - } - if (tc() != 0) - sighandler(0); - } - return 0; /*NOTREACHED*/ - } - - /* no args == run all tests */ - if (optind >= argc) { - for (j = 0; j < sizeof(all_tests)/sizeof(all_tests[0]); ++j) - if (all_tests[j]() != 0) - return 1; - return 0; - } - - for (i = optind; i < argc; ++i) { - if (strcmp(argv[i], "sha1") == 0) { - for (j = 0; j < sizeof(sha1_tests)/sizeof(sha1_tests[0]); ++j) - if (sha1_tests[j]() != 0) - return 1; - } - else if (strcmp(argv[i], "sha256") == 0) { - for (j = 0; j < sizeof(sha256_tests)/sizeof(sha256_tests[0]); ++j) - if (sha256_tests[j]() != 0) - return 1; - } - else if (strcmp(argv[i], "sha512") == 0) { - for (j = 0; j < sizeof(sha512_tests)/sizeof(sha512_tests[0]); ++j) - if (sha512_tests[j]() != 0) - return 1; - } - else if (strcmp(argv[i], "all") == 0) { - for (j = 0; j < sizeof(all_tests)/sizeof(all_tests[0]); ++j) - if (all_tests[j]() != 0) - return 1; - } - else if (isdigit(argv[i][0]) && - (((j = atoi(argv[i])) > 0) && - (j <= sizeof(all_tests)/sizeof(all_tests[0])))) { - if (all_tests[j - 1]() != 0) - return 1; - } - else { - fprintf(stderr, "unknown test case %s\n", argv[i]); - return 1; - } - } - - return 0; -} diff --git a/sw/test-sha256/novena-eim.c b/sw/test-sha256/novena-eim.c deleted file mode 100644 index 1effff1..0000000 --- a/sw/test-sha256/novena-eim.c +++ /dev/null @@ -1,407 +0,0 @@ -//------------------------------------------------------------------------------ -// novena-eim.c -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// Headers -//------------------------------------------------------------------------------ -#include -#include -#include -#include -#include -#include -#include -#include "novena-eim.h" - - -//------------------------------------------------------------------------------ -// Variables -//------------------------------------------------------------------------------ -static long mem_page_size = 0; -static int mem_dev_fd = -1; -static void * mem_map_ptr = MAP_FAILED; -static off_t mem_base_addr = 0; - - -//------------------------------------------------------------------------------ -int eim_setup() -//------------------------------------------------------------------------------ -{ - // register cleanup function - int ok = atexit(_eim_cleanup); - if (ok != 0) - { printf("ERROR: atexit() failed.\n"); - return -1; - } - - // determine memory page size to use in mmap() - mem_page_size = sysconf(_SC_PAGESIZE); - if (mem_page_size < 1) - { printf("ERROR: sysconf(_SC_PAGESIZE) == %ld\n", mem_page_size); - return -1; - } - - // try to open memory device - mem_dev_fd = open(MEMORY_DEVICE, O_RDWR | O_SYNC); - if (mem_dev_fd == -1) - { printf("ERROR: open(%s) failed.\n", MEMORY_DEVICE); - return -1; - } - - /* Several blocks in the CPU have common pins, we can use I/O MUX Controller - * to configure what block will actually use I/O pins. We wait EIM module to be able - * to communicate with the on-board FPGA. Let's configure IOMUXC accordingly. - */ - _eim_setup_iomuxc(); - - /* We need to enable clocking of EIM block in order to be able to use it. - * Let's configure Clock Controller Module accordingly. - */ - _eim_setup_ccm(); - - /* We need to properly configure EIM mode and all the corresponding parameters. - * That's a lot of code, let's do it now. - */ - _eim_setup_eim(); - - - // done - return 1; -} - - -//------------------------------------------------------------------------------ -void _eim_cleanup() -//------------------------------------------------------------------------------ -{ - // unmap memory if needed - if (mem_map_ptr != MAP_FAILED) - { int ok = munmap(mem_map_ptr, mem_page_size); - if (ok != 0) printf("WARNING: munmap() failed.\n"); - } - - // close memory device if needed - if (mem_dev_fd != -1) - { int ok = close(mem_dev_fd); - if (ok != 0) printf("WARNING: close() failed.\n"); - } -} - - -//------------------------------------------------------------------------------ -void _eim_setup_iomuxc() -//------------------------------------------------------------------------------ -{ - // create structures - struct IOMUXC_SW_MUX_CTL_PAD_EIM reg_mux; // mux control register - struct IOMUXC_SW_PAD_CTL_PAD_EIM reg_pad; // pad control register - - // setup mux control register - reg_mux.mux_mode = IOMUXC_MUX_MODE_ALT0; // ALT0 mode must be used for EIM - reg_mux.sion = 0; // forced input not needed - reg_mux.reserved_3 = 0; // must be 0 - reg_mux.reserved_31_5 = 0; // must be 0 - - // setup pad control register - reg_pad.sre = IOMUXC_PAD_CTL_SRE_FAST; // fast slew rate - reg_pad.dse = IOMUXC_PAD_CTL_DSE_33_OHM; // highest drive strength - reg_pad.speed = IOMUXC_PAD_CTL_SPEED_MEDIUM_10; // medium speed - reg_pad.ode = IOMUXC_PAD_CTL_ODE_DISABLED; // open drain not needed - reg_pad.pke = IOMUXC_PAD_CTL_PKE_DISABLED; // neither pull nor keeper are needed - reg_pad.pue = IOMUXC_PAD_CTL_PUE_PULL; // doesn't matter actually, because PKE is disabled - reg_pad.pus = IOMUXC_PAD_CTL_PUS_100K_OHM_PU; // doesn't matter actually, because PKE is disabled - reg_pad.hys = IOMUXC_PAD_CTL_HYS_DISABLED; // use CMOS, not Schmitt trigger input - reg_pad.reserved_2_1 = 0; // must be 0 - reg_pad.reserved_10_8 = 0; // must be 0 - reg_pad.reserved_31_17 = 0; // must be 0 - - // all the pins must be configured to use the same ALT0 mode - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_RW, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD00, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD01, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD02, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD03, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD04, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD05, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD06, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD07, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD08, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD09, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD10, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD11, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD12, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD13, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD14, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD15, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK, (uint32_t *)®_mux); - - // we need to configure all the I/O pads too - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_RW, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD00, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD01, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD02, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD03, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD04, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD05, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD06, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD07, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD08, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD09, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD10, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD11, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD12, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD13, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD14, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD15, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK, (uint32_t *)®_pad); -} - - -//------------------------------------------------------------------------------ -void _eim_setup_ccm() -//------------------------------------------------------------------------------ -{ - // create structure - struct CCM_CCGR6 ccm_ccgr6; - - // read register - eim_read_32(CCM_CCGR6, (uint32_t *)&ccm_ccgr6); - - // modify register - ccm_ccgr6.cg0_usboh3 = CCM_CGR_ON_EXCEPT_STOP; - ccm_ccgr6.cg1_usdhc1 = CCM_CGR_OFF; - ccm_ccgr6.cg2_usdhc2 = CCM_CGR_ON_EXCEPT_STOP; - ccm_ccgr6.cg3_usdhc3 = CCM_CGR_ON_EXCEPT_STOP; - - ccm_ccgr6.cg3_usdhc4 = CCM_CGR_OFF; - ccm_ccgr6.cg5_eim_slow = CCM_CGR_ON_EXCEPT_STOP; - ccm_ccgr6.cg6_vdoaxiclk = CCM_CGR_OFF; - ccm_ccgr6.cg7_vpu = CCM_CGR_OFF; - - ccm_ccgr6.cg8_reserved = 0; - ccm_ccgr6.cg9_reserved = 0; - ccm_ccgr6.cg10_reserved = 0; - ccm_ccgr6.cg11_reserved = 0; - ccm_ccgr6.cg12_reserved = 0; - ccm_ccgr6.cg13_reserved = 0; - ccm_ccgr6.cg14_reserved = 0; - ccm_ccgr6.cg15_reserved = 0; - - // write register - eim_write_32(CCM_CCGR6, (uint32_t *)&ccm_ccgr6); -} - - -//------------------------------------------------------------------------------ -void _eim_setup_eim() -//------------------------------------------------------------------------------ -{ - // create structures - struct EIM_CS_GCR1 gcr1; - struct EIM_CS_GCR2 gcr2; - struct EIM_CS_RCR1 rcr1; - struct EIM_CS_RCR2 rcr2; - struct EIM_CS_WCR1 wcr1; - struct EIM_CS_WCR2 wcr2; - - struct EIM_WCR wcr; - struct EIM_WIAR wiar; - struct EIM_EAR ear; - - // read all the registers - eim_read_32(EIM_CS0GCR1, (uint32_t *)&gcr1); - eim_read_32(EIM_CS0GCR2, (uint32_t *)&gcr2); - eim_read_32(EIM_CS0RCR1, (uint32_t *)&rcr1); - eim_read_32(EIM_CS0RCR2, (uint32_t *)&rcr2); - eim_read_32(EIM_CS0WCR1, (uint32_t *)&wcr1); - eim_read_32(EIM_CS0WCR2, (uint32_t *)&wcr2); - - eim_read_32(EIM_WCR, (uint32_t *)&wcr); - eim_read_32(EIM_WIAR, (uint32_t *)&wiar); - eim_read_32(EIM_EAR, (uint32_t *)&ear); - - // manipulate registers as needed - gcr1.csen = 1; // chip select is enabled | - gcr1.swr = 1; // write is sync | - gcr1.srd = 1; // read is sync | - gcr1.mum = 1; // address and data are multiplexed | - gcr1.wfl = 0; // write latency is not fixed | - gcr1.rfl = 0; // read latency is not fixed | - gcr1.cre = 0; // CRE signal not needed | - //gcr1.crep = x; // don't care, CRE not used | - gcr1.bl = 4; // burst length | ? - gcr1.wc = 0; // write is not continuous | ? - gcr1.bcd = 3; // BCLK divisor is 3+1=4 | - gcr1.bcs = 1; // delay from ~CS to BCLK is 1 cycle | - gcr1.dsz = 1; // 16 bits per databeat at DATA[15:0] | - gcr1.sp = 0; // supervisor protection is disabled | - gcr1.csrec = 1; // ~CS recovery is 1 cycle | - gcr1.aus = 1; // address is not shifted | - gcr1.gbc = 1; // ~CS gap is 1 cycle | - gcr1.wp = 0; // write protection is not enabled | - //gcr1.psz = x; // don't care, page mode is not used | - - gcr2.adh = 0; // address hold duration is 1 cycle | - //gcr2.daps = x; // don't care, DTACK is not used | - gcr2.dae = 0; // DTACK is not used | - //gcr2.dap = x; // don't care, DTACK is not used | - gcr2.mux16_byp_grant = 1; // enable grant mechanism | ? - gcr2.reserved_3_2 = 0; // must be 0 | - gcr2.reserved_11_10 = 0; // must be 0 | - gcr2.reserved_31_13 = 0; // must be 0 | - - //rcr1.rcsn = x; // don't care in sync mode | - rcr1.rcsa = 0; // no delay for ~CS needed | - //rcr1.oen = x; // don't care in sync mode | - rcr1.oea = 0; // no delay for ~OE needed | - rcr1.radvn = 0; // no delay for ~LBA needed | - rcr1.ral = 0; // clear ~LBA when needed | - rcr1.radva = 0; // no delay for ~LBA needed | - rcr1.rwsc = 1; // one wait state | - rcr1.reserved_3 = 0; // must be 0 | - rcr1.reserved_7 = 0; // must be 0 | - rcr1.reserved_11 = 0; // must be 0 | - rcr1.reserved_15 = 0; // must be 0 | - rcr1.reserved_23 = 0; // must be 0 | - rcr1.reserved_31_30 = 0; // must be 0 | - - //rcr2.rben = x; // don't care in sync mode | - rcr2.rbe = 0; // BE is disabled | - //rcr2.rbea = x; // don't care when BE is not used | - rcr2.rl = 0; // read latency is 0 | ? - //rcr2.pat = x; // don't care when page read is not used | - rcr2.apr = 0; // page read mode is not used | - rcr2.reserved_7 = 0; // must be 0 | - rcr2.reserved_11_10 = 0; // must be 0 | - rcr2.reserved_31_16 = 0; // must be 0 | - - //wcr1.wcsn = x; // don't care in sync mode | - wcr1.wcsa = 0; // no delay for ~CS needed | - //wcr1.wen = x; // don't care in sync mode | - wcr1.wea = 0; // no delay for ~WR_N needed | - //wcr1.wben = x; // don't care in sync mode | - //wcr1.wbea = x; // don't care in sync mode | - wcr1.wadvn = 0; // no delay for ~LBA needed | - wcr1.wadva = 0; // no delay for ~LBA needed | - wcr1.wwsc = 1; // no wait state in needed | - wcr1.wbed = 1; // BE is disabled | - wcr1.wal = 0; // clear ~LBA when needed | - - wcr2.wbcdd = 0; // write clock division is not needed | - wcr2.reserved_31_1 = 0; // must be 0 | - - wcr.bcm = 0; // clock is only active during access | - //wcr.gbcd = x; // don't care when BCM=0 | - wcr.inten = 0; // interrupt is not used | - //wcr.intpol = x; // don't care when interrupt is not used | - wcr.wdog_en = 1; // watchdog is enabled | - wcr.wdog_limit = 00; // timeout is 128 BCLK cycles | - wcr.reserved_3 = 0; // must be 0 | - wcr.reserved_7_6 = 0; // must be 0 | - wcr.reserved_31_11 = 0; // must be 0 | - - wiar.ips_req = 0; // IPS not needed | - wiar.ips_ack = 0; // IPS not needed | - //wiar.irq = x; // don't touch | - //wiar.errst = x; // don't touch | - wiar.aclk_en = 1; // clock is enabled | - wiar.reserved_31_5 = 0; // must be 0 | - - //ear.error_addr = x; // read-only | - - // write modified registers - eim_write_32(EIM_CS0GCR1, (uint32_t *)&gcr1); - eim_write_32(EIM_CS0GCR2, (uint32_t *)&gcr2); - eim_write_32(EIM_CS0RCR1, (uint32_t *)&rcr1); - eim_write_32(EIM_CS0RCR2, (uint32_t *)&rcr2); - eim_write_32(EIM_CS0WCR1, (uint32_t *)&wcr1); - eim_write_32(EIM_CS0WCR2, (uint32_t *)&wcr2); - eim_write_32(EIM_WCR, (uint32_t *)&wcr); - eim_write_32(EIM_WIAR, (uint32_t *)&wiar);/* - eim_write_32(EIM_EAR, (uint32_t *)&ear);*/ -} - - -//------------------------------------------------------------------------------ -void eim_write_32(off_t offset, uint32_t *pvalue) -//------------------------------------------------------------------------------ -{ - // calculate memory offset - uint32_t *ptr = (uint32_t *)_eim_calc_offset(offset); - - // write data to memory - memcpy(ptr, pvalue, sizeof(uint32_t)); -} - -//------------------------------------------------------------------------------ -void eim_read_32(off_t offset, uint32_t *pvalue) -//------------------------------------------------------------------------------ -{ - // calculate memory offset - uint32_t *ptr = (uint32_t *)_eim_calc_offset(offset); - - // read data from memory - memcpy(pvalue, ptr, sizeof(uint32_t)); -} - - -//------------------------------------------------------------------------------ -off_t _eim_calc_offset(off_t offset) -//------------------------------------------------------------------------------ -{ - // make sure that memory is mapped - if (mem_map_ptr == MAP_FAILED) _eim_remap_mem(offset); - - // calculate starting and ending addresses of currently mapped page - off_t offset_low = mem_base_addr; - off_t offset_high = mem_base_addr + (mem_page_size - 1); - - // check that offset is in currently mapped page, remap new page otherwise - if ((offset < offset_low) || (offset > offset_high)) _eim_remap_mem(offset); - - // calculate pointer - return (off_t)mem_map_ptr + (offset - mem_base_addr); -} - - -//------------------------------------------------------------------------------ -void _eim_remap_mem(off_t offset) -//------------------------------------------------------------------------------ -{ - // unmap old memory page if needed - if (mem_map_ptr != MAP_FAILED) - { int ok = munmap(mem_map_ptr, mem_page_size); - if (ok != 0) - { printf("ERROR: munmap() failed.\n"); - exit(EXIT_FAILURE); - } - } - - // calculate starting address of new page - while (offset % mem_page_size) offset--; - - // try to map new memory page - mem_map_ptr = mmap(NULL, mem_page_size, PROT_READ | PROT_WRITE, MAP_SHARED, mem_dev_fd, offset); - if (mem_map_ptr == MAP_FAILED) - { printf("ERROR: mmap() failed.\n"); - exit(EXIT_FAILURE); - } - - // save last mapped page address - mem_base_addr = offset; -} - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/sw/test-sha256/novena-eim.h b/sw/test-sha256/novena-eim.h deleted file mode 100644 index 3d29f77..0000000 --- a/sw/test-sha256/novena-eim.h +++ /dev/null @@ -1,297 +0,0 @@ -//------------------------------------------------------------------------------ -// novena-eim.h -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// Defined Values -//------------------------------------------------------------------------------ -#define MEMORY_DEVICE "/dev/mem" - - -//------------------------------------------------------------------------------ -// IOMUXC Values -//------------------------------------------------------------------------------ -#define IOMUXC_MUX_MODE_ALT0 0 // 000 - -#define IOMUXC_PAD_CTL_SRE_FAST 1 // 1 -#define IOMUXC_PAD_CTL_DSE_33_OHM 7 // 111 -#define IOMUXC_PAD_CTL_SPEED_MEDIUM_10 2 // 10 -#define IOMUXC_PAD_CTL_ODE_DISABLED 0 // 0 -#define IOMUXC_PAD_CTL_PKE_DISABLED 0 // 0 -#define IOMUXC_PAD_CTL_PUE_PULL 1 // 1 -#define IOMUXC_PAD_CTL_PUS_100K_OHM_PU 2 // 10 -#define IOMUXC_PAD_CTL_HYS_DISABLED 0 // 0 - -//------------------------------------------------------------------------------ -// CCM Values -//------------------------------------------------------------------------------ -#define CCM_CGR_OFF 0 // 00 -#define CCM_CGR_ON_EXCEPT_STOP 3 // 11 - - -//------------------------------------------------------------------------------ -// CPU Registers -//------------------------------------------------------------------------------ -enum IMX6DQ_REGISTER_OFFSET -{ - IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B = 0x020E00F8, - IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B = 0x020E0100, - IOMUXC_SW_MUX_CTL_PAD_EIM_RW = 0x020E0104, - IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B = 0x020E0108, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD00 = 0x020E0114, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD01 = 0x020E0118, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD02 = 0x020E011C, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD03 = 0x020E0120, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD04 = 0x020E0124, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD05 = 0x020E0128, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD06 = 0x020E012C, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD07 = 0x020E0130, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD08 = 0x020E0134, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD09 = 0x020E0138, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD10 = 0x020E013C, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD11 = 0x020E0140, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD12 = 0x020E0144, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD13 = 0x020E0148, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD14 = 0x020E014C, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD15 = 0x020E0150, - IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B = 0x020E0154, - IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK = 0x020E0158, - - IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B = 0x020E040C, - IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B = 0x020E0414, - IOMUXC_SW_PAD_CTL_PAD_EIM_RW = 0x020E0418, - IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B = 0x020E041C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD00 = 0x020E0428, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD01 = 0x020E042C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD02 = 0x020E0430, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD03 = 0x020E0434, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD04 = 0x020E0438, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD05 = 0x020E043C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD06 = 0x020E0440, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD07 = 0x020E0444, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD08 = 0x020E0448, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD09 = 0x020E044C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD10 = 0x020E0450, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD11 = 0x020E0454, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD12 = 0x020E0458, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD13 = 0x020E045C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD14 = 0x020E0460, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD15 = 0x020E0464, - IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B = 0x020E0468, - IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK = 0x020E046C, - - CCM_CCGR6 = 0x020C4080, - - EIM_CS0GCR1 = 0x021B8000, - EIM_CS0GCR2 = 0x021B8004, - EIM_CS0RCR1 = 0x021B8008, - EIM_CS0RCR2 = 0x021B800C, - EIM_CS0WCR1 = 0x021B8010, - EIM_CS0WCR2 = 0x021B8014, - - EIM_WCR = 0x021B8090, - EIM_WIAR = 0x021B8094, - EIM_EAR = 0x021B8098, - - EIM_BASE_ADDR = 0x08000000 -}; - - -//------------------------------------------------------------------------------ -struct IOMUXC_SW_MUX_CTL_PAD_EIM -//------------------------------------------------------------------------------ -{ - uint32_t mux_mode : 3; - uint32_t reserved_3 : 1; - uint32_t sion : 1; - uint32_t reserved_31_5 : 27; -}; -//------------------------------------------------------------------------------ -struct IOMUXC_SW_PAD_CTL_PAD_EIM -//------------------------------------------------------------------------------ -{ - uint32_t sre : 1; - uint32_t reserved_2_1 : 2; - uint32_t dse : 3; - uint32_t speed : 2; - uint32_t reserved_10_8 : 3; - uint32_t ode : 1; - uint32_t pke : 1; - uint32_t pue : 1; - uint32_t pus : 2; - uint32_t hys : 1; - uint32_t reserved_31_17 : 15; -}; - - -//------------------------------------------------------------------------------ -struct CCM_CCGR6 -//------------------------------------------------------------------------------ -{ - uint32_t cg0_usboh3 : 2; - uint32_t cg1_usdhc1 : 2; - uint32_t cg2_usdhc2 : 2; - uint32_t cg3_usdhc3 : 2; - - uint32_t cg3_usdhc4 : 2; - uint32_t cg5_eim_slow : 2; - uint32_t cg6_vdoaxiclk : 2; - uint32_t cg7_vpu : 2; - - uint32_t cg8_reserved : 2; - uint32_t cg9_reserved : 2; - uint32_t cg10_reserved : 2; - uint32_t cg11_reserved : 2; - - uint32_t cg12_reserved : 2; - uint32_t cg13_reserved : 2; - uint32_t cg14_reserved : 2; - uint32_t cg15_reserved : 2; -}; - - -//------------------------------------------------------------------------------ -struct EIM_CS_GCR1 -//------------------------------------------------------------------------------ -{ - uint32_t csen : 1; - uint32_t swr : 1; - uint32_t srd : 1; - uint32_t mum : 1; - uint32_t wfl : 1; - uint32_t rfl : 1; - uint32_t cre : 1; - uint32_t crep : 1; - uint32_t bl : 3; - uint32_t wc : 1; - uint32_t bcd : 2; - uint32_t bcs : 2; - uint32_t dsz : 3; - uint32_t sp : 1; - uint32_t csrec : 3; - uint32_t aus : 1; - uint32_t gbc : 3; - uint32_t wp : 1; - uint32_t psz : 4; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_GCR2 -//------------------------------------------------------------------------------ -{ - uint32_t adh : 2; - uint32_t reserved_3_2 : 2; - uint32_t daps : 4; - uint32_t dae : 1; - uint32_t dap : 1; - uint32_t reserved_11_10 : 2; - uint32_t mux16_byp_grant : 1; - uint32_t reserved_31_13 : 19; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_RCR1 -//------------------------------------------------------------------------------ -{ - uint32_t rcsn : 3; - uint32_t reserved_3 : 1; - uint32_t rcsa : 3; - uint32_t reserved_7 : 1; - uint32_t oen : 3; - uint32_t reserved_11 : 1; - uint32_t oea : 3; - uint32_t reserved_15 : 1; - uint32_t radvn : 3; - uint32_t ral : 1; - uint32_t radva : 3; - uint32_t reserved_23 : 1; - uint32_t rwsc : 6; - uint32_t reserved_31_30 : 2; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_RCR2 -//------------------------------------------------------------------------------ -{ - uint32_t rben : 3; - uint32_t rbe : 1; - uint32_t rbea : 3; - uint32_t reserved_7 : 1; - uint32_t rl : 2; - uint32_t reserved_11_10 : 2; - uint32_t pat : 3; - uint32_t apr : 1; - uint32_t reserved_31_16 : 16; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_WCR1 -//------------------------------------------------------------------------------ -{ - uint32_t wcsn : 3; - uint32_t wcsa : 3; - uint32_t wen : 3; - uint32_t wea : 3; - uint32_t wben : 3; - uint32_t wbea : 3; - uint32_t wadvn : 3; - uint32_t wadva : 3; - uint32_t wwsc : 6; - uint32_t wbed : 1; - uint32_t wal : 1; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_WCR2 -//------------------------------------------------------------------------------ -{ - uint32_t wbcdd : 1; - uint32_t reserved_31_1 : 31; -}; -//------------------------------------------------------------------------------ -struct EIM_WCR -//------------------------------------------------------------------------------ -{ - uint32_t bcm : 1; - uint32_t gbcd : 2; - uint32_t reserved_3 : 1; - uint32_t inten : 1; - uint32_t intpol : 1; - uint32_t reserved_7_6 : 2; - uint32_t wdog_en : 1; - uint32_t wdog_limit : 2; - uint32_t reserved_31_11 : 21; -}; -//------------------------------------------------------------------------------ -struct EIM_WIAR -//------------------------------------------------------------------------------ -{ - uint32_t ips_req : 1; - uint32_t ips_ack : 1; - uint32_t irq : 1; - uint32_t errst : 1; - uint32_t aclk_en : 1; - uint32_t reserved_31_5 : 27; -}; -//------------------------------------------------------------------------------ -struct EIM_EAR -//------------------------------------------------------------------------------ -{ - uint32_t error_addr : 32; -}; - - -//------------------------------------------------------------------------------ -// Prototypes -//------------------------------------------------------------------------------ -int eim_setup (); -void eim_write_32 (off_t, uint32_t *); -void eim_read_32 (off_t, uint32_t *); - -void _eim_setup_iomuxc (); -void _eim_setup_ccm (); -void _eim_setup_eim (); -void _eim_cleanup (); -off_t _eim_calc_offset (off_t); -void _eim_remap_mem (off_t); - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/sw/test-sha256/test-sha256.c b/sw/test-sha256/test-sha256.c deleted file mode 100644 index 0ea0d8c..0000000 --- a/sw/test-sha256/test-sha256.c +++ /dev/null @@ -1,179 +0,0 @@ -//====================================================================== -// -// test-sha256.c -// ------------- -// test program for Cryptech Novena framwwork with EIM interface -// using the sha256 core. -// -//====================================================================== - -//------------------------------------------------------------------------------ -// Headers -//------------------------------------------------------------------------------ -#include -#include -#include -#include "novena-eim.h" - - -//------------------------------------------------------------------------------ -// Defines -// -// Symbolic names for the SHA256 core API. -//------------------------------------------------------------------------------ -#define SHA256_PREFIX (0x0000) -#define SHA256_BASE (EIM_BASE_ADDR + SHA256_PREFIX) - -#define ADDR_NAME0 (SHA256_BASE + (0x00 << 2)) -#define ADDR_NAME1 (SHA256_BASE + (0x01 << 2)) -#define ADDR_VERSION (SHA256_BASE + (0x02 << 2)) - -#define ADDR_CTRL (SHA256_BASE + (0x08 << 2)) -#define CTRL_INIT_BIT 0 -#define CTRL_NEXT_BIT 1 - -#define ADDR_STATUS (SHA256_BASE + (0x09 << 2)) -#define STATUS_READY_BIT 0 -#define STATUS_VALID_BIT 1 - -#define ADDR_BLOCK0 (SHA256_BASE + (0x10 << 2)) -#define ADDR_BLOCK1 (SHA256_BASE + (0x11 << 2)) -#define ADDR_BLOCK2 (SHA256_BASE + (0x12 << 2)) -#define ADDR_BLOCK3 (SHA256_BASE + (0x13 << 2)) -#define ADDR_BLOCK4 (SHA256_BASE + (0x14 << 2)) -#define ADDR_BLOCK5 (SHA256_BASE + (0x15 << 2)) -#define ADDR_BLOCK6 (SHA256_BASE + (0x16 << 2)) -#define ADDR_BLOCK7 (SHA256_BASE + (0x17 << 2)) -#define ADDR_BLOCK8 (SHA256_BASE + (0x18 << 2)) -#define ADDR_BLOCK9 (SHA256_BASE + (0x19 << 2)) -#define ADDR_BLOCK10 (SHA256_BASE + (0x1a << 2)) -#define ADDR_BLOCK11 (SHA256_BASE + (0x1b << 2)) -#define ADDR_BLOCK12 (SHA256_BASE + (0x1c << 2)) -#define ADDR_BLOCK13 (SHA256_BASE + (0x1d << 2)) -#define ADDR_BLOCK14 (SHA256_BASE + (0x1e << 2)) -#define ADDR_BLOCK15 (SHA256_BASE + (0x1f << 2)) - -#define ADDR_DIGEST0 (SHA256_BASE + (0x20 << 2)) -#define ADDR_DIGEST1 (SHA256_BASE + (0x21 << 2)) -#define ADDR_DIGEST2 (SHA256_BASE + (0x22 << 2)) -#define ADDR_DIGEST3 (SHA256_BASE + (0x23 << 2)) -#define ADDR_DIGEST4 (SHA256_BASE + (0x24 << 2)) -#define ADDR_DIGEST5 (SHA256_BASE + (0x25 << 2)) -#define ADDR_DIGEST6 (SHA256_BASE + (0x26 << 2)) -#define ADDR_DIGEST7 (SHA256_BASE + (0x27 << 2)) - - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -uint32_t get_w32(uint32_t addr) -{ - unsigned int read_data; - - eim_read_32(addr, &read_data); - - return read_data; -} - - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -void test_single_block() -{ - uint32_t write_data; - - write_data = 0x61626380; - eim_write_32(ADDR_BLOCK0, &write_data); - write_data = 0x00000000; - eim_write_32(ADDR_BLOCK1, &write_data); - eim_write_32(ADDR_BLOCK2, &write_data); - eim_write_32(ADDR_BLOCK3, &write_data); - eim_write_32(ADDR_BLOCK4, &write_data); - eim_write_32(ADDR_BLOCK5, &write_data); - eim_write_32(ADDR_BLOCK6, &write_data); - eim_write_32(ADDR_BLOCK7, &write_data); - eim_write_32(ADDR_BLOCK8, &write_data); - eim_write_32(ADDR_BLOCK9, &write_data); - eim_write_32(ADDR_BLOCK10, &write_data); - eim_write_32(ADDR_BLOCK11, &write_data); - eim_write_32(ADDR_BLOCK12, &write_data); - eim_write_32(ADDR_BLOCK13, &write_data); - eim_write_32(ADDR_BLOCK14, &write_data); - write_data = 0x00000018; - eim_write_32(ADDR_BLOCK15, &write_data); - - write_data = 0x00000001; - eim_write_32(ADDR_CTRL, &write_data); - - printf("digest0 = 0x%08x\n", get_w32(ADDR_DIGEST0)); - printf("digest1 = 0x%08x\n", get_w32(ADDR_DIGEST1)); - printf("digest2 = 0x%08x\n", get_w32(ADDR_DIGEST2)); - printf("digest3 = 0x%08x\n", get_w32(ADDR_DIGEST3)); - printf("digest4 = 0x%08x\n", get_w32(ADDR_DIGEST4)); - printf("digest5 = 0x%08x\n", get_w32(ADDR_DIGEST5)); - printf("digest6 = 0x%08x\n", get_w32(ADDR_DIGEST6)); - printf("digest7 = 0x%08x\n", get_w32(ADDR_DIGEST7)); - - // What we want to see: - // res0 = 256'hBA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD; - -} - - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -void test_dual_block() -{ - // Dual block test vectors as specified by NIST. - // tc1_0 = 512'h6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70718000000000000000; - // res1_0 = 256'h85E655D6417A17953363376A624CDE5C76E09589CAC5F811CC4B32C1F20E533A; - // tc1_1 = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0; - // res1_1 = 256'h248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1; - - -} - - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -void test_sha256() -{ - - test_single_block(); - -} - - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -int config_eim() -{ - int ok; - - // try to setup eim (return value should be 1) - printf("Configuring EIM .. "); - ok = eim_setup(); - if (ok < 1) { - printf("ERROR\n"); - return EXIT_FAILURE; - } - else { - printf("EIM Setup ok.\n"); - } - - return EXIT_SUCCESS; -} - -//------------------------------------------------------------------------------ -// main() -//------------------------------------------------------------------------------ -int main() -{ - config_eim(); - test_sha256(); - - return 0; -} - -//====================================================================== -// EOF test-sha256.c -//====================================================================== -- cgit v1.2.3 From ba254d4d83bed050f16026b750d6a7d175098c77 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Wed, 11 Feb 2015 12:13:23 -0500 Subject: Reformat C code for readability, remove non-API stuff from novena-eim.h, change eim_setup() success value to 0. --- sw/hash_tester.c | 286 +++++++------- sw/novena-eim.c | 1106 ++++++++++++++++++++++++++++++++++-------------------- sw/novena-eim.h | 349 +++-------------- 3 files changed, 894 insertions(+), 847 deletions(-) (limited to 'sw') diff --git a/sw/hash_tester.c b/sw/hash_tester.c index 4fbeaa3..a0ab0f1 100644 --- a/sw/hash_tester.c +++ b/sw/hash_tester.c @@ -63,13 +63,13 @@ int quiet = 0; int repeat = 0; /* instead of core number 0 we have a page of global registers */ -#define ADDR_GLOBAL_BOARD_TYPE EIM_BASE_ADDR + (0x00 << 2) -#define ADDR_GLOBAL_BITSTREAM_VER EIM_BASE_ADDR + (0x01 << 2) -#define ADDR_GLOBAL_DUMMY_REG EIM_BASE_ADDR + (0xFF << 2) +#define ADDR_GLOBAL_BOARD_TYPE EIM_BASE_ADDR + (0x00 << 2) +#define ADDR_GLOBAL_BITSTREAM_VER EIM_BASE_ADDR + (0x01 << 2) +#define ADDR_GLOBAL_DUMMY_REG EIM_BASE_ADDR + (0xFF << 2) -#define SEGMENT_OFFSET_HASHES EIM_BASE_ADDR + 0x000000 -#define SEGMENT_OFFSET_RNGS EIM_BASE_ADDR + 0x010000 -#define SEGMENT_OFFSET_CIPHERS EIM_BASE_ADDR + 0x020000 +#define SEGMENT_OFFSET_HASHES EIM_BASE_ADDR + 0x000000 +#define SEGMENT_OFFSET_RNGS EIM_BASE_ADDR + 0x010000 +#define SEGMENT_OFFSET_CIPHERS EIM_BASE_ADDR + 0x020000 /* addresses and codes common to all hash cores */ @@ -85,10 +85,10 @@ int repeat = 0; #define ADDR_BLOCK 0x40 #define ADDR_DIGEST 0x80 -#define HASH_CORE_SIZE 0x400 +#define HASH_CORE_SIZE 0x400 /* addresses and codes for the specific hash cores */ -#define SHA1_ADDR_BASE EIM_BASE_ADDR + (1*HASH_CORE_SIZE) +#define SHA1_ADDR_BASE SEGMENT_OFFSET_HASHES + (1*HASH_CORE_SIZE) #define SHA1_ADDR_NAME0 SHA1_ADDR_BASE + ADDR_NAME0 #define SHA1_ADDR_NAME1 SHA1_ADDR_BASE + ADDR_NAME1 #define SHA1_ADDR_VERSION SHA1_ADDR_BASE + ADDR_VERSION @@ -99,7 +99,7 @@ int repeat = 0; #define SHA1_BLOCK_LEN 512 / 8 #define SHA1_DIGEST_LEN 160 / 8 -#define SHA256_ADDR_BASE EIM_BASE_ADDR + (2*HASH_CORE_SIZE) +#define SHA256_ADDR_BASE SEGMENT_OFFSET_HASHES + (2*HASH_CORE_SIZE) #define SHA256_ADDR_NAME0 SHA256_ADDR_BASE + ADDR_NAME0 #define SHA256_ADDR_NAME1 SHA256_ADDR_BASE + ADDR_NAME1 #define SHA256_ADDR_VERSION SHA256_ADDR_BASE + ADDR_VERSION @@ -110,7 +110,7 @@ int repeat = 0; #define SHA256_BLOCK_LEN 512 / 8 #define SHA256_DIGEST_LEN 256 / 8 -#define SHA512_ADDR_BASE EIM_BASE_ADDR + (3*HASH_CORE_SIZE) +#define SHA512_ADDR_BASE SEGMENT_OFFSET_HASHES + (3*HASH_CORE_SIZE) #define SHA512_ADDR_NAME0 SHA512_ADDR_BASE + ADDR_NAME0 #define SHA512_ADDR_NAME1 SHA512_ADDR_BASE + ADDR_NAME1 #define SHA512_ADDR_VERSION SHA512_ADDR_BASE + ADDR_VERSION @@ -300,11 +300,11 @@ const uint8_t SHA512_DOUBLE_DIGEST[] = void dump(char *label, const uint8_t *buf, int len) { if (debug) { - int i; - printf("%s [", label); - for (i = 0; i < len; ++i) - printf(" %02x", buf[i]); - printf(" ]\n"); + int i; + printf("%s [", label); + for (i = 0; i < len; ++i) + printf(" %02x", buf[i]); + printf(" ]\n"); } } @@ -313,9 +313,9 @@ int tc_write(off_t offset, const uint8_t *buf, int len) dump("write ", buf, len); for (; len > 0; offset += 4, buf += 4, len -= 4) { - uint32_t val; - val = htonl(*(uint32_t *)buf); - eim_write_32(offset, &val); + uint32_t val; + val = htonl(*(uint32_t *)buf); + eim_write_32(offset, &val); } return 0; @@ -327,9 +327,9 @@ int tc_read(off_t offset, uint8_t *buf, int len) int rlen = len; for (; rlen > 0; offset += 4, rbuf += 4, rlen -= 4) { - uint32_t val; - eim_read_32(offset, &val); - *(uint32_t *)rbuf = ntohl(val); + uint32_t val; + eim_read_32(offset, &val); + *(uint32_t *)rbuf = ntohl(val); } dump("read ", buf, len); @@ -396,14 +396,14 @@ int tc_wait(off_t offset, uint8_t status) for (i = 0; i < 10; ++i) { if (tc_read(offset, buf, 4) != 0) return 1; - if (buf[3] & status) - return 0; + if (buf[3] & status) + return 0; } fprintf(stderr, "tc_wait timed out\n"); return 1; #endif } - + int tc_wait_ready(off_t offset) { return tc_wait(offset, STATUS_READY_BIT); @@ -414,6 +414,45 @@ int tc_wait_valid(off_t offset) return tc_wait(offset, STATUS_VALID_BIT); } +/* ---------------- sanity test case ---------------- */ + +int TC0() +{ + uint8_t board_type[4] = { 'P', 'V', 'T', '1'}; /* "PVT1" */ + uint8_t bitstream_ver[4] = { 0x00, 0x01, 0x00, 0x0B }; /* v0.1.0b */ + uint8_t t[4]; + + uint8_t seg_rngs_reg_first[4] = { 0xAA, 0xAA, 0xAA, 0xAA}; + uint8_t seg_rngs_reg_second[4] = { 0xBB, 0xBB, 0xBB, 0xBB}; + uint8_t seg_rngs_reg_third[4] = { 0xCC, 0xCC, 0xCC, 0xCC}; + + uint8_t seg_ciphers_reg_first[4] = { 0xDD, 0xDD, 0xDD, 0xDD}; + uint8_t seg_ciphers_reg_second[4] = { 0xEE, 0xEE, 0xEE, 0xEE}; + uint8_t seg_ciphers_reg_third[4] = { 0xFF, 0xFF, 0xFF, 0xFF}; + + if (!quiet) + printf("TC0: Reading board type, version, and dummy reg from global registers.\n"); + + /* write current time into dummy register, then try to read it back + * to make sure that we can actually write something into EIM + */ + (void)time((time_t *)t); + tc_write(ADDR_GLOBAL_DUMMY_REG, (void *)&t, 4); + + return + tc_expected(ADDR_GLOBAL_BOARD_TYPE, board_type, 4) || + tc_expected(ADDR_GLOBAL_BITSTREAM_VER, bitstream_ver, 4) || + tc_expected(ADDR_GLOBAL_DUMMY_REG, (void *)t, 4) || + + tc_expected(SEGMENT_OFFSET_RNGS + (0 << 2), seg_rngs_reg_first, 4) || + tc_expected(SEGMENT_OFFSET_RNGS + (1 << 2), seg_rngs_reg_second, 4) || + tc_expected(SEGMENT_OFFSET_RNGS + (2 << 2), seg_rngs_reg_third, 4) || + + tc_expected(SEGMENT_OFFSET_CIPHERS + (0 << 2), seg_ciphers_reg_first, 4) || + tc_expected(SEGMENT_OFFSET_CIPHERS + (1 << 2), seg_ciphers_reg_second, 4) || + tc_expected(SEGMENT_OFFSET_CIPHERS + (2 << 2), seg_ciphers_reg_third, 4); +} + /* ---------------- SHA-1 test cases ---------------- */ /* TC1: Read name and version from SHA-1 core. */ @@ -424,7 +463,7 @@ int TC1(void) uint8_t version[4] = { 0x30, 0x2e, 0x35, 0x30 }; /* "0.50" */ if (!quiet) - printf("TC1: Reading name, type and version words from SHA-1 core.\n"); + printf("TC1: Reading name, type and version words from SHA-1 core.\n"); return tc_expected(SHA1_ADDR_NAME0, name0, 4) || @@ -440,7 +479,7 @@ int TC2(void) int ret; if (!quiet) - printf("TC2: Single block message test for SHA-1.\n"); + printf("TC2: Single block message test for SHA-1.\n"); /* Write block to SHA-1. */ tc_write(SHA1_ADDR_BLOCK, block, SHA1_BLOCK_LEN); @@ -464,7 +503,7 @@ int TC3(void) int ret; if (!quiet) - printf("TC3: Double block message test for SHA-1.\n"); + printf("TC3: Double block message test for SHA-1.\n"); /* Write first block to SHA-1. */ tc_write(SHA1_ADDR_BLOCK, block[0], SHA1_BLOCK_LEN); @@ -493,7 +532,7 @@ int TC4(void) uint8_t version[4] = { 0x30, 0x2e, 0x38, 0x30 }; /* "0.80" */ if (!quiet) - printf("TC4: Reading name, type and version words from SHA-256 core.\n"); + printf("TC4: Reading name, type and version words from SHA-256 core.\n"); return tc_expected(SHA256_ADDR_NAME0, name0, 4) || @@ -508,7 +547,7 @@ int TC5() const uint8_t *expected = SHA256_SINGLE_DIGEST; if (!quiet) - printf("TC5: Single block message test for SHA-256.\n"); + printf("TC5: Single block message test for SHA-256.\n"); return /* Write block to SHA-256. */ @@ -532,7 +571,7 @@ int TC6() const uint8_t *expected = SHA256_DOUBLE_DIGEST; if (!quiet) - printf("TC6: Double block message test for SHA-256.\n"); + printf("TC6: Double block message test for SHA-256.\n"); return /* Write first block to SHA-256. */ @@ -574,11 +613,11 @@ int TC7() int i, n = 1000; if (!quiet) - printf("TC7: Message with %d blocks test for SHA-256.\n", n); + printf("TC7: Message with %d blocks test for SHA-256.\n", n); /* Write block data to SHA-256. */ if (tc_write(SHA256_ADDR_BLOCK, block, SHA256_BLOCK_LEN)) - return 1; + return 1; /* Start initial block hashing, wait and check status. */ if (tc_init(SHA256_ADDR_CTRL) || @@ -605,12 +644,12 @@ int TC7() /* TC8: Read name and version from SHA-512 core. */ int TC8() { - uint8_t name0[4] = { 0x73, 0x68, 0x61, 0x32 }; /* "sha2" */ - uint8_t name1[4] = { 0x2d, 0x35, 0x31, 0x32 }; /* "-512" */ - uint8_t version[4] = { 0x30, 0x2e, 0x38, 0x30 }; /* "0.80" */ + uint8_t name0[4] = { 0x73, 0x68, 0x61, 0x32 }; /* "sha2" */ + uint8_t name1[4] = { 0x2d, 0x35, 0x31, 0x32 }; /* "-512" */ + uint8_t version[4] = { 0x30, 0x2e, 0x38, 0x30 }; /* "0.80" */ if (!quiet) - printf("TC8: Reading name, type and version words from SHA-512 core.\n"); + printf("TC8: Reading name, type and version words from SHA-512 core.\n"); return tc_expected(SHA512_ADDR_NAME0, name0, 4) || @@ -638,22 +677,22 @@ int tc9(int mode, const uint8_t *expected, int digest_len) int TC9() { if (!quiet) - printf("TC9-1: Single block message test for SHA-512/224.\n"); + printf("TC9-1: Single block message test for SHA-512/224.\n"); if (tc9(MODE_SHA_512_224, SHA512_224_SINGLE_DIGEST, SHA512_224_DIGEST_LEN) != 0) return 1; if (!quiet) - printf("TC9-2: Single block message test for SHA-512/256.\n"); + printf("TC9-2: Single block message test for SHA-512/256.\n"); if (tc9(MODE_SHA_512_256, SHA512_256_SINGLE_DIGEST, SHA512_256_DIGEST_LEN) != 0) return 1; if (!quiet) - printf("TC9-3: Single block message test for SHA-384.\n"); + printf("TC9-3: Single block message test for SHA-384.\n"); if (tc9(MODE_SHA_384, SHA384_SINGLE_DIGEST, SHA384_DIGEST_LEN) != 0) return 1; if (!quiet) - printf("TC9-4: Single block message test for SHA-512.\n"); + printf("TC9-4: Single block message test for SHA-512.\n"); if (tc9(MODE_SHA_512, SHA512_SINGLE_DIGEST, SHA512_DIGEST_LEN) != 0) return 1; @@ -686,68 +725,31 @@ int tc10(int mode, const uint8_t *expected, int digest_len) int TC10() { if (!quiet) - printf("TC10-1: Double block message test for SHA-512/224.\n"); + printf("TC10-1: Double block message test for SHA-512/224.\n"); if (tc10(MODE_SHA_512_224, SHA512_224_DOUBLE_DIGEST, SHA512_224_DIGEST_LEN) != 0) return 1; if (!quiet) - printf("TC10-2: Double block message test for SHA-512/256.\n"); + printf("TC10-2: Double block message test for SHA-512/256.\n"); if (tc10(MODE_SHA_512_256, SHA512_256_DOUBLE_DIGEST, SHA512_256_DIGEST_LEN) != 0) return 1; if (!quiet) - printf("TC10-3: Double block message test for SHA-384.\n"); + printf("TC10-3: Double block message test for SHA-384.\n"); if (tc10(MODE_SHA_384, SHA384_DOUBLE_DIGEST, SHA384_DIGEST_LEN) != 0) return 1; if (!quiet) - printf("TC10-4: Double block message test for SHA-512.\n"); + printf("TC10-4: Double block message test for SHA-512.\n"); if (tc10(MODE_SHA_512, SHA512_DOUBLE_DIGEST, SHA512_DIGEST_LEN) != 0) return 1; return 0; } -int TC11() -{ - uint8_t board_type[4] = { 'P', 'V', 'T', '1'}; /* "PVT1" */ - uint8_t bitstream_ver[4] = { 0x00, 0x01, 0x00, 0x0B }; /* v0.1.0b */ - uint8_t t[4]; - - uint8_t seg_rngs_reg_first[4] = { 0xAA, 0xAA, 0xAA, 0xAA}; - uint8_t seg_rngs_reg_second[4] = { 0xBB, 0xBB, 0xBB, 0xBB}; - uint8_t seg_rngs_reg_third[4] = { 0xCC, 0xCC, 0xCC, 0xCC}; - - uint8_t seg_ciphers_reg_first[4] = { 0xDD, 0xDD, 0xDD, 0xDD}; - uint8_t seg_ciphers_reg_second[4] = { 0xEE, 0xEE, 0xEE, 0xEE}; - uint8_t seg_ciphers_reg_third[4] = { 0xFF, 0xFF, 0xFF, 0xFF}; - - // write current time into dummy register, then try to read it back - // to make sure that we can actually write something into eim - (void)time((time_t *)t); - tc_write(ADDR_GLOBAL_DUMMY_REG, (void *)&t, 4); - - if (!quiet) - printf("TC11: Reading board type, bitstream version and dummy register from global registers.\n"); - if (!quiet) - printf("TC11: Reading dummy registers from RNG and CIPHER memory segments.\n"); - - return - tc_expected(ADDR_GLOBAL_BOARD_TYPE, board_type, 4) || - tc_expected(ADDR_GLOBAL_BITSTREAM_VER, bitstream_ver, 4) || - tc_expected(ADDR_GLOBAL_DUMMY_REG, (void *)t, 4) || - - tc_expected(SEGMENT_OFFSET_RNGS + (0 << 2), seg_rngs_reg_first, 4) || - tc_expected(SEGMENT_OFFSET_RNGS + (1 << 2), seg_rngs_reg_second, 4) || - tc_expected(SEGMENT_OFFSET_RNGS + (2 << 2), seg_rngs_reg_third, 4) || - - tc_expected(SEGMENT_OFFSET_CIPHERS + (0 << 2), seg_ciphers_reg_first, 4) || - tc_expected(SEGMENT_OFFSET_CIPHERS + (1 << 2), seg_ciphers_reg_second, 4) || - tc_expected(SEGMENT_OFFSET_CIPHERS + (2 << 2), seg_ciphers_reg_third, 4); -} - /* ---------------- main ---------------- */ +/* signal handler for ctrl-c to end repeat testing */ unsigned long iter = 0; struct timeval tv_start, tv_end; void sighandler(int unused) @@ -756,19 +758,19 @@ void sighandler(int unused) gettimeofday(&tv_end, NULL); tv_diff = (double)(tv_end.tv_sec - tv_start.tv_sec) + - (double)(tv_end.tv_usec - tv_start.tv_usec)/1000000; + (double)(tv_end.tv_usec - tv_start.tv_usec)/1000000; printf("\n%lu iterations in %.3f seconds (%.3f iterations/sec)\n", - iter, tv_diff, (double)iter/tv_diff); - exit(0); + iter, tv_diff, (double)iter/tv_diff); + exit(EXIT_SUCCESS); } int main(int argc, char *argv[]) { typedef int (*tcfp)(void); + tcfp all_tests[] = { TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7, TC8, TC9, TC10 }; tcfp sha1_tests[] = { TC1, TC2, TC3 }; tcfp sha256_tests[] = { TC4, TC5, TC6, TC7 }; tcfp sha512_tests[] = { TC8, TC9, TC10 }; - tcfp all_tests[] = { TC1, TC2, TC3, TC4, TC5, TC6, TC7, TC8, TC9, TC10, TC11 }; char *usage = "Usage: %s [-h] [-d] [-q] [-r] tc...\n"; int i, j, opt; @@ -778,99 +780,97 @@ int main(int argc, char *argv[]) case 'h': case '?': printf(usage, argv[0]); - return 0; + return EXIT_SUCCESS; case 'd': debug = 1; break; - case 'q': - quiet = 1; - break; - case 'r': - repeat = 1; - break; + case 'q': + quiet = 1; + break; + case 'r': + repeat = 1; + break; default: fprintf(stderr, usage, argv[0]); - return 1; + return EXIT_FAILURE; } } - // try to setup eim (return value should be 1) - printf("Configuring EIM .. "); - if (eim_setup() < 1) { - printf("ERROR\n"); - return EXIT_FAILURE; - } - else { - printf("EIM Setup ok.\n"); + /* set up EIM */ + if (eim_setup() != 0) { + fprintf(stderr, "EIM setup failed\n"); + return EXIT_FAILURE; } + /* repeat one test until interrupted */ if (repeat) { - tcfp tc; - if (optind != argc - 1) { - fprintf(stderr, "only one test case can be repeated\n"); - return 1; - } - j = atoi(argv[optind]); - if (j <= 0 || j > sizeof(all_tests)/sizeof(all_tests[0])) { - fprintf(stderr, "invalid test number %s\n", argv[optind]); - return 1; - } - tc = (all_tests[j - 1]); - srand(time(NULL)); - signal(SIGINT, sighandler); - gettimeofday(&tv_start, NULL); - while (1) { - ++iter; - if ((iter & 0xffff) == 0) { - printf("."); - fflush(stdout); - } - if (tc() != 0) - sighandler(0); - } - return 0; /*NOTREACHED*/ + tcfp tc; + if (optind != argc - 1) { + fprintf(stderr, "only one test case can be repeated\n"); + return EXIT_FAILURE; + } + j = atoi(argv[optind]); + if (j < 0 || j >= sizeof(all_tests)/sizeof(all_tests[0])) { + fprintf(stderr, "invalid test number %s\n", argv[optind]); + return EXIT_FAILURE; + } + tc = (all_tests[j]); + srand(time(NULL)); + signal(SIGINT, sighandler); + gettimeofday(&tv_start, NULL); + while (1) { + ++iter; + if ((iter & 0xffff) == 0) { + printf("."); + fflush(stdout); + } + if (tc() != 0) + sighandler(0); + } + return EXIT_SUCCESS; /*NOTREACHED*/ } /* no args == run all tests */ if (optind >= argc) { for (j = 0; j < sizeof(all_tests)/sizeof(all_tests[0]); ++j) if (all_tests[j]() != 0) - return 1; - return 0; + return EXIT_FAILURE; + return EXIT_SUCCESS; } + /* run one or more tests (by number) or groups of tests (by name) */ for (i = optind; i < argc; ++i) { - if (strcmp(argv[i], "sha1") == 0) { + if (strcmp(argv[i], "all") == 0) { + for (j = 0; j < sizeof(all_tests)/sizeof(all_tests[0]); ++j) + if (all_tests[j]() != 0) + return EXIT_FAILURE; + } + else if (strcmp(argv[i], "sha1") == 0) { for (j = 0; j < sizeof(sha1_tests)/sizeof(sha1_tests[0]); ++j) if (sha1_tests[j]() != 0) - return 1; + return EXIT_FAILURE; } else if (strcmp(argv[i], "sha256") == 0) { for (j = 0; j < sizeof(sha256_tests)/sizeof(sha256_tests[0]); ++j) if (sha256_tests[j]() != 0) - return 1; + return EXIT_FAILURE; } else if (strcmp(argv[i], "sha512") == 0) { for (j = 0; j < sizeof(sha512_tests)/sizeof(sha512_tests[0]); ++j) if (sha512_tests[j]() != 0) - return 1; - } - else if (strcmp(argv[i], "all") == 0) { - for (j = 0; j < sizeof(all_tests)/sizeof(all_tests[0]); ++j) - if (all_tests[j]() != 0) - return 1; + return EXIT_FAILURE; } else if (isdigit(argv[i][0]) && - (((j = atoi(argv[i])) > 0) && - (j <= sizeof(all_tests)/sizeof(all_tests[0])))) { - if (all_tests[j - 1]() != 0) - return 1; + (((j = atoi(argv[i])) >= 0) && + (j < sizeof(all_tests)/sizeof(all_tests[0])))) { + if (all_tests[j]() != 0) + return EXIT_FAILURE; } else { fprintf(stderr, "unknown test case %s\n", argv[i]); - return 1; + return EXIT_FAILURE; } } - return 0; + return EXIT_SUCCESS; } diff --git a/sw/novena-eim.c b/sw/novena-eim.c index 1effff1..9b3d236 100644 --- a/sw/novena-eim.c +++ b/sw/novena-eim.c @@ -1,407 +1,699 @@ -//------------------------------------------------------------------------------ -// novena-eim.c -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// Headers -//------------------------------------------------------------------------------ -#include -#include -#include -#include -#include -#include -#include -#include "novena-eim.h" - - -//------------------------------------------------------------------------------ -// Variables -//------------------------------------------------------------------------------ -static long mem_page_size = 0; -static int mem_dev_fd = -1; -static void * mem_map_ptr = MAP_FAILED; -static off_t mem_base_addr = 0; - - -//------------------------------------------------------------------------------ -int eim_setup() -//------------------------------------------------------------------------------ -{ - // register cleanup function - int ok = atexit(_eim_cleanup); - if (ok != 0) - { printf("ERROR: atexit() failed.\n"); - return -1; - } - - // determine memory page size to use in mmap() - mem_page_size = sysconf(_SC_PAGESIZE); - if (mem_page_size < 1) - { printf("ERROR: sysconf(_SC_PAGESIZE) == %ld\n", mem_page_size); - return -1; - } - - // try to open memory device - mem_dev_fd = open(MEMORY_DEVICE, O_RDWR | O_SYNC); - if (mem_dev_fd == -1) - { printf("ERROR: open(%s) failed.\n", MEMORY_DEVICE); - return -1; - } - - /* Several blocks in the CPU have common pins, we can use I/O MUX Controller - * to configure what block will actually use I/O pins. We wait EIM module to be able - * to communicate with the on-board FPGA. Let's configure IOMUXC accordingly. - */ - _eim_setup_iomuxc(); - - /* We need to enable clocking of EIM block in order to be able to use it. - * Let's configure Clock Controller Module accordingly. - */ - _eim_setup_ccm(); - - /* We need to properly configure EIM mode and all the corresponding parameters. - * That's a lot of code, let's do it now. - */ - _eim_setup_eim(); - - - // done - return 1; -} - - -//------------------------------------------------------------------------------ -void _eim_cleanup() -//------------------------------------------------------------------------------ -{ - // unmap memory if needed - if (mem_map_ptr != MAP_FAILED) - { int ok = munmap(mem_map_ptr, mem_page_size); - if (ok != 0) printf("WARNING: munmap() failed.\n"); - } - - // close memory device if needed - if (mem_dev_fd != -1) - { int ok = close(mem_dev_fd); - if (ok != 0) printf("WARNING: close() failed.\n"); - } -} - - -//------------------------------------------------------------------------------ -void _eim_setup_iomuxc() -//------------------------------------------------------------------------------ -{ - // create structures - struct IOMUXC_SW_MUX_CTL_PAD_EIM reg_mux; // mux control register - struct IOMUXC_SW_PAD_CTL_PAD_EIM reg_pad; // pad control register - - // setup mux control register - reg_mux.mux_mode = IOMUXC_MUX_MODE_ALT0; // ALT0 mode must be used for EIM - reg_mux.sion = 0; // forced input not needed - reg_mux.reserved_3 = 0; // must be 0 - reg_mux.reserved_31_5 = 0; // must be 0 - - // setup pad control register - reg_pad.sre = IOMUXC_PAD_CTL_SRE_FAST; // fast slew rate - reg_pad.dse = IOMUXC_PAD_CTL_DSE_33_OHM; // highest drive strength - reg_pad.speed = IOMUXC_PAD_CTL_SPEED_MEDIUM_10; // medium speed - reg_pad.ode = IOMUXC_PAD_CTL_ODE_DISABLED; // open drain not needed - reg_pad.pke = IOMUXC_PAD_CTL_PKE_DISABLED; // neither pull nor keeper are needed - reg_pad.pue = IOMUXC_PAD_CTL_PUE_PULL; // doesn't matter actually, because PKE is disabled - reg_pad.pus = IOMUXC_PAD_CTL_PUS_100K_OHM_PU; // doesn't matter actually, because PKE is disabled - reg_pad.hys = IOMUXC_PAD_CTL_HYS_DISABLED; // use CMOS, not Schmitt trigger input - reg_pad.reserved_2_1 = 0; // must be 0 - reg_pad.reserved_10_8 = 0; // must be 0 - reg_pad.reserved_31_17 = 0; // must be 0 - - // all the pins must be configured to use the same ALT0 mode - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_RW, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD00, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD01, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD02, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD03, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD04, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD05, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD06, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD07, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD08, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD09, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD10, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD11, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD12, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD13, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD14, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD15, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B, (uint32_t *)®_mux); - eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK, (uint32_t *)®_mux); - - // we need to configure all the I/O pads too - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_RW, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD00, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD01, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD02, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD03, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD04, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD05, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD06, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD07, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD08, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD09, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD10, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD11, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD12, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD13, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD14, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD15, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B, (uint32_t *)®_pad); - eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK, (uint32_t *)®_pad); -} - - -//------------------------------------------------------------------------------ -void _eim_setup_ccm() -//------------------------------------------------------------------------------ -{ - // create structure - struct CCM_CCGR6 ccm_ccgr6; - - // read register - eim_read_32(CCM_CCGR6, (uint32_t *)&ccm_ccgr6); - - // modify register - ccm_ccgr6.cg0_usboh3 = CCM_CGR_ON_EXCEPT_STOP; - ccm_ccgr6.cg1_usdhc1 = CCM_CGR_OFF; - ccm_ccgr6.cg2_usdhc2 = CCM_CGR_ON_EXCEPT_STOP; - ccm_ccgr6.cg3_usdhc3 = CCM_CGR_ON_EXCEPT_STOP; - - ccm_ccgr6.cg3_usdhc4 = CCM_CGR_OFF; - ccm_ccgr6.cg5_eim_slow = CCM_CGR_ON_EXCEPT_STOP; - ccm_ccgr6.cg6_vdoaxiclk = CCM_CGR_OFF; - ccm_ccgr6.cg7_vpu = CCM_CGR_OFF; - - ccm_ccgr6.cg8_reserved = 0; - ccm_ccgr6.cg9_reserved = 0; - ccm_ccgr6.cg10_reserved = 0; - ccm_ccgr6.cg11_reserved = 0; - ccm_ccgr6.cg12_reserved = 0; - ccm_ccgr6.cg13_reserved = 0; - ccm_ccgr6.cg14_reserved = 0; - ccm_ccgr6.cg15_reserved = 0; - - // write register - eim_write_32(CCM_CCGR6, (uint32_t *)&ccm_ccgr6); -} - - -//------------------------------------------------------------------------------ -void _eim_setup_eim() -//------------------------------------------------------------------------------ -{ - // create structures - struct EIM_CS_GCR1 gcr1; - struct EIM_CS_GCR2 gcr2; - struct EIM_CS_RCR1 rcr1; - struct EIM_CS_RCR2 rcr2; - struct EIM_CS_WCR1 wcr1; - struct EIM_CS_WCR2 wcr2; - - struct EIM_WCR wcr; - struct EIM_WIAR wiar; - struct EIM_EAR ear; - - // read all the registers - eim_read_32(EIM_CS0GCR1, (uint32_t *)&gcr1); - eim_read_32(EIM_CS0GCR2, (uint32_t *)&gcr2); - eim_read_32(EIM_CS0RCR1, (uint32_t *)&rcr1); - eim_read_32(EIM_CS0RCR2, (uint32_t *)&rcr2); - eim_read_32(EIM_CS0WCR1, (uint32_t *)&wcr1); - eim_read_32(EIM_CS0WCR2, (uint32_t *)&wcr2); - - eim_read_32(EIM_WCR, (uint32_t *)&wcr); - eim_read_32(EIM_WIAR, (uint32_t *)&wiar); - eim_read_32(EIM_EAR, (uint32_t *)&ear); - - // manipulate registers as needed - gcr1.csen = 1; // chip select is enabled | - gcr1.swr = 1; // write is sync | - gcr1.srd = 1; // read is sync | - gcr1.mum = 1; // address and data are multiplexed | - gcr1.wfl = 0; // write latency is not fixed | - gcr1.rfl = 0; // read latency is not fixed | - gcr1.cre = 0; // CRE signal not needed | - //gcr1.crep = x; // don't care, CRE not used | - gcr1.bl = 4; // burst length | ? - gcr1.wc = 0; // write is not continuous | ? - gcr1.bcd = 3; // BCLK divisor is 3+1=4 | - gcr1.bcs = 1; // delay from ~CS to BCLK is 1 cycle | - gcr1.dsz = 1; // 16 bits per databeat at DATA[15:0] | - gcr1.sp = 0; // supervisor protection is disabled | - gcr1.csrec = 1; // ~CS recovery is 1 cycle | - gcr1.aus = 1; // address is not shifted | - gcr1.gbc = 1; // ~CS gap is 1 cycle | - gcr1.wp = 0; // write protection is not enabled | - //gcr1.psz = x; // don't care, page mode is not used | - - gcr2.adh = 0; // address hold duration is 1 cycle | - //gcr2.daps = x; // don't care, DTACK is not used | - gcr2.dae = 0; // DTACK is not used | - //gcr2.dap = x; // don't care, DTACK is not used | - gcr2.mux16_byp_grant = 1; // enable grant mechanism | ? - gcr2.reserved_3_2 = 0; // must be 0 | - gcr2.reserved_11_10 = 0; // must be 0 | - gcr2.reserved_31_13 = 0; // must be 0 | - - //rcr1.rcsn = x; // don't care in sync mode | - rcr1.rcsa = 0; // no delay for ~CS needed | - //rcr1.oen = x; // don't care in sync mode | - rcr1.oea = 0; // no delay for ~OE needed | - rcr1.radvn = 0; // no delay for ~LBA needed | - rcr1.ral = 0; // clear ~LBA when needed | - rcr1.radva = 0; // no delay for ~LBA needed | - rcr1.rwsc = 1; // one wait state | - rcr1.reserved_3 = 0; // must be 0 | - rcr1.reserved_7 = 0; // must be 0 | - rcr1.reserved_11 = 0; // must be 0 | - rcr1.reserved_15 = 0; // must be 0 | - rcr1.reserved_23 = 0; // must be 0 | - rcr1.reserved_31_30 = 0; // must be 0 | - - //rcr2.rben = x; // don't care in sync mode | - rcr2.rbe = 0; // BE is disabled | - //rcr2.rbea = x; // don't care when BE is not used | - rcr2.rl = 0; // read latency is 0 | ? - //rcr2.pat = x; // don't care when page read is not used | - rcr2.apr = 0; // page read mode is not used | - rcr2.reserved_7 = 0; // must be 0 | - rcr2.reserved_11_10 = 0; // must be 0 | - rcr2.reserved_31_16 = 0; // must be 0 | - - //wcr1.wcsn = x; // don't care in sync mode | - wcr1.wcsa = 0; // no delay for ~CS needed | - //wcr1.wen = x; // don't care in sync mode | - wcr1.wea = 0; // no delay for ~WR_N needed | - //wcr1.wben = x; // don't care in sync mode | - //wcr1.wbea = x; // don't care in sync mode | - wcr1.wadvn = 0; // no delay for ~LBA needed | - wcr1.wadva = 0; // no delay for ~LBA needed | - wcr1.wwsc = 1; // no wait state in needed | - wcr1.wbed = 1; // BE is disabled | - wcr1.wal = 0; // clear ~LBA when needed | - - wcr2.wbcdd = 0; // write clock division is not needed | - wcr2.reserved_31_1 = 0; // must be 0 | - - wcr.bcm = 0; // clock is only active during access | - //wcr.gbcd = x; // don't care when BCM=0 | - wcr.inten = 0; // interrupt is not used | - //wcr.intpol = x; // don't care when interrupt is not used | - wcr.wdog_en = 1; // watchdog is enabled | - wcr.wdog_limit = 00; // timeout is 128 BCLK cycles | - wcr.reserved_3 = 0; // must be 0 | - wcr.reserved_7_6 = 0; // must be 0 | - wcr.reserved_31_11 = 0; // must be 0 | - - wiar.ips_req = 0; // IPS not needed | - wiar.ips_ack = 0; // IPS not needed | - //wiar.irq = x; // don't touch | - //wiar.errst = x; // don't touch | - wiar.aclk_en = 1; // clock is enabled | - wiar.reserved_31_5 = 0; // must be 0 | - - //ear.error_addr = x; // read-only | - - // write modified registers - eim_write_32(EIM_CS0GCR1, (uint32_t *)&gcr1); - eim_write_32(EIM_CS0GCR2, (uint32_t *)&gcr2); - eim_write_32(EIM_CS0RCR1, (uint32_t *)&rcr1); - eim_write_32(EIM_CS0RCR2, (uint32_t *)&rcr2); - eim_write_32(EIM_CS0WCR1, (uint32_t *)&wcr1); - eim_write_32(EIM_CS0WCR2, (uint32_t *)&wcr2); - eim_write_32(EIM_WCR, (uint32_t *)&wcr); - eim_write_32(EIM_WIAR, (uint32_t *)&wiar);/* - eim_write_32(EIM_EAR, (uint32_t *)&ear);*/ -} - - -//------------------------------------------------------------------------------ -void eim_write_32(off_t offset, uint32_t *pvalue) -//------------------------------------------------------------------------------ -{ - // calculate memory offset - uint32_t *ptr = (uint32_t *)_eim_calc_offset(offset); - - // write data to memory - memcpy(ptr, pvalue, sizeof(uint32_t)); -} - -//------------------------------------------------------------------------------ -void eim_read_32(off_t offset, uint32_t *pvalue) -//------------------------------------------------------------------------------ -{ - // calculate memory offset - uint32_t *ptr = (uint32_t *)_eim_calc_offset(offset); - - // read data from memory - memcpy(pvalue, ptr, sizeof(uint32_t)); -} - - -//------------------------------------------------------------------------------ -off_t _eim_calc_offset(off_t offset) -//------------------------------------------------------------------------------ -{ - // make sure that memory is mapped - if (mem_map_ptr == MAP_FAILED) _eim_remap_mem(offset); - - // calculate starting and ending addresses of currently mapped page - off_t offset_low = mem_base_addr; - off_t offset_high = mem_base_addr + (mem_page_size - 1); - - // check that offset is in currently mapped page, remap new page otherwise - if ((offset < offset_low) || (offset > offset_high)) _eim_remap_mem(offset); - - // calculate pointer - return (off_t)mem_map_ptr + (offset - mem_base_addr); -} - - -//------------------------------------------------------------------------------ -void _eim_remap_mem(off_t offset) -//------------------------------------------------------------------------------ -{ - // unmap old memory page if needed - if (mem_map_ptr != MAP_FAILED) - { int ok = munmap(mem_map_ptr, mem_page_size); - if (ok != 0) - { printf("ERROR: munmap() failed.\n"); - exit(EXIT_FAILURE); - } - } - - // calculate starting address of new page - while (offset % mem_page_size) offset--; - - // try to map new memory page - mem_map_ptr = mmap(NULL, mem_page_size, PROT_READ | PROT_WRITE, MAP_SHARED, mem_dev_fd, offset); - if (mem_map_ptr == MAP_FAILED) - { printf("ERROR: mmap() failed.\n"); - exit(EXIT_FAILURE); - } - - // save last mapped page address - mem_base_addr = offset; -} - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ +/* + * novena-eim.c + * ------------ + * This module contains the userland magic to set up and use the EIM bus. + * + * + * Author: Pavel Shatov + * Copyright (c) 2014-2015, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ +#include +#include +#include +#include +#include +#include +#include + +#include "novena-eim.h" + + +//------------------------------------------------------------------------------ +// Defines +//------------------------------------------------------------------------------ +#define MEMORY_DEVICE "/dev/mem" + +#define IOMUXC_MUX_MODE_ALT0 0 // 000 + +#define IOMUXC_PAD_CTL_SRE_FAST 1 // 1 +#define IOMUXC_PAD_CTL_DSE_33_OHM 7 // 111 +#define IOMUXC_PAD_CTL_SPEED_MEDIUM_10 2 // 10 +#define IOMUXC_PAD_CTL_ODE_DISABLED 0 // 0 +#define IOMUXC_PAD_CTL_PKE_DISABLED 0 // 0 +#define IOMUXC_PAD_CTL_PUE_PULL 1 // 1 +#define IOMUXC_PAD_CTL_PUS_100K_OHM_PU 2 // 10 +#define IOMUXC_PAD_CTL_HYS_DISABLED 0 // 0 + +#define CCM_CGR_OFF 0 // 00 +#define CCM_CGR_ON_EXCEPT_STOP 3 // 11 + + +//------------------------------------------------------------------------------ +// CPU Registers +//------------------------------------------------------------------------------ +enum IMX6DQ_REGISTER_OFFSET +{ + IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B = 0x020E00F8, + IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B = 0x020E0100, + IOMUXC_SW_MUX_CTL_PAD_EIM_RW = 0x020E0104, + IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B = 0x020E0108, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD00 = 0x020E0114, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD01 = 0x020E0118, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD02 = 0x020E011C, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD03 = 0x020E0120, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD04 = 0x020E0124, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD05 = 0x020E0128, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD06 = 0x020E012C, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD07 = 0x020E0130, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD08 = 0x020E0134, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD09 = 0x020E0138, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD10 = 0x020E013C, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD11 = 0x020E0140, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD12 = 0x020E0144, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD13 = 0x020E0148, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD14 = 0x020E014C, + IOMUXC_SW_MUX_CTL_PAD_EIM_AD15 = 0x020E0150, + IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B = 0x020E0154, + IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK = 0x020E0158, + + IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B = 0x020E040C, + IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B = 0x020E0414, + IOMUXC_SW_PAD_CTL_PAD_EIM_RW = 0x020E0418, + IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B = 0x020E041C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD00 = 0x020E0428, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD01 = 0x020E042C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD02 = 0x020E0430, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD03 = 0x020E0434, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD04 = 0x020E0438, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD05 = 0x020E043C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD06 = 0x020E0440, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD07 = 0x020E0444, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD08 = 0x020E0448, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD09 = 0x020E044C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD10 = 0x020E0450, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD11 = 0x020E0454, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD12 = 0x020E0458, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD13 = 0x020E045C, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD14 = 0x020E0460, + IOMUXC_SW_PAD_CTL_PAD_EIM_AD15 = 0x020E0464, + IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B = 0x020E0468, + IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK = 0x020E046C, + + CCM_CCGR6 = 0x020C4080, + + EIM_CS0GCR1 = 0x021B8000, + EIM_CS0GCR2 = 0x021B8004, + EIM_CS0RCR1 = 0x021B8008, + EIM_CS0RCR2 = 0x021B800C, + EIM_CS0WCR1 = 0x021B8010, + EIM_CS0WCR2 = 0x021B8014, + + EIM_WCR = 0x021B8090, + EIM_WIAR = 0x021B8094, + EIM_EAR = 0x021B8098, + +}; + + +//------------------------------------------------------------------------------ +// Structures +//------------------------------------------------------------------------------ +struct IOMUXC_SW_MUX_CTL_PAD_EIM +{ + uint32_t mux_mode : 3; + uint32_t reserved_3 : 1; + uint32_t sion : 1; + uint32_t reserved_31_5 : 27; +}; + +struct IOMUXC_SW_PAD_CTL_PAD_EIM +{ + uint32_t sre : 1; + uint32_t reserved_2_1 : 2; + uint32_t dse : 3; + uint32_t speed : 2; + uint32_t reserved_10_8 : 3; + uint32_t ode : 1; + uint32_t pke : 1; + uint32_t pue : 1; + uint32_t pus : 2; + uint32_t hys : 1; + uint32_t reserved_31_17 : 15; +}; + +struct CCM_CCGR6 +{ + uint32_t cg0_usboh3 : 2; + uint32_t cg1_usdhc1 : 2; + uint32_t cg2_usdhc2 : 2; + uint32_t cg3_usdhc3 : 2; + + uint32_t cg3_usdhc4 : 2; + uint32_t cg5_eim_slow : 2; + uint32_t cg6_vdoaxiclk : 2; + uint32_t cg7_vpu : 2; + + uint32_t cg8_reserved : 2; + uint32_t cg9_reserved : 2; + uint32_t cg10_reserved : 2; + uint32_t cg11_reserved : 2; + + uint32_t cg12_reserved : 2; + uint32_t cg13_reserved : 2; + uint32_t cg14_reserved : 2; + uint32_t cg15_reserved : 2; +}; + +struct EIM_CS_GCR1 +{ + uint32_t csen : 1; + uint32_t swr : 1; + uint32_t srd : 1; + uint32_t mum : 1; + uint32_t wfl : 1; + uint32_t rfl : 1; + uint32_t cre : 1; + uint32_t crep : 1; + uint32_t bl : 3; + uint32_t wc : 1; + uint32_t bcd : 2; + uint32_t bcs : 2; + uint32_t dsz : 3; + uint32_t sp : 1; + uint32_t csrec : 3; + uint32_t aus : 1; + uint32_t gbc : 3; + uint32_t wp : 1; + uint32_t psz : 4; +}; + +struct EIM_CS_GCR2 +{ + uint32_t adh : 2; + uint32_t reserved_3_2 : 2; + uint32_t daps : 4; + uint32_t dae : 1; + uint32_t dap : 1; + uint32_t reserved_11_10 : 2; + uint32_t mux16_byp_grant : 1; + uint32_t reserved_31_13 : 19; +}; + +struct EIM_CS_RCR1 +{ + uint32_t rcsn : 3; + uint32_t reserved_3 : 1; + uint32_t rcsa : 3; + uint32_t reserved_7 : 1; + uint32_t oen : 3; + uint32_t reserved_11 : 1; + uint32_t oea : 3; + uint32_t reserved_15 : 1; + uint32_t radvn : 3; + uint32_t ral : 1; + uint32_t radva : 3; + uint32_t reserved_23 : 1; + uint32_t rwsc : 6; + uint32_t reserved_31_30 : 2; +}; + +struct EIM_CS_RCR2 +{ + uint32_t rben : 3; + uint32_t rbe : 1; + uint32_t rbea : 3; + uint32_t reserved_7 : 1; + uint32_t rl : 2; + uint32_t reserved_11_10 : 2; + uint32_t pat : 3; + uint32_t apr : 1; + uint32_t reserved_31_16 : 16; +}; + +struct EIM_CS_WCR1 +{ + uint32_t wcsn : 3; + uint32_t wcsa : 3; + uint32_t wen : 3; + uint32_t wea : 3; + uint32_t wben : 3; + uint32_t wbea : 3; + uint32_t wadvn : 3; + uint32_t wadva : 3; + uint32_t wwsc : 6; + uint32_t wbed : 1; + uint32_t wal : 1; +}; + +struct EIM_CS_WCR2 +{ + uint32_t wbcdd : 1; + uint32_t reserved_31_1 : 31; +}; + +struct EIM_WCR +{ + uint32_t bcm : 1; + uint32_t gbcd : 2; + uint32_t reserved_3 : 1; + uint32_t inten : 1; + uint32_t intpol : 1; + uint32_t reserved_7_6 : 2; + uint32_t wdog_en : 1; + uint32_t wdog_limit : 2; + uint32_t reserved_31_11 : 21; +}; + +struct EIM_WIAR +{ + uint32_t ips_req : 1; + uint32_t ips_ack : 1; + uint32_t irq : 1; + uint32_t errst : 1; + uint32_t aclk_en : 1; + uint32_t reserved_31_5 : 27; +}; + +struct EIM_EAR +{ + uint32_t error_addr : 32; +}; + + +//------------------------------------------------------------------------------ +// Variables +//------------------------------------------------------------------------------ +static long mem_page_size = 0; +static int mem_dev_fd = -1; +static void * mem_map_ptr = MAP_FAILED; +static off_t mem_base_addr = 0; + +//------------------------------------------------------------------------------ +// Prototypes +//------------------------------------------------------------------------------ +static void _eim_setup_iomuxc (void); +static void _eim_setup_ccm (void); +static void _eim_setup_eim (void); +static void _eim_cleanup (void); +static off_t _eim_calc_offset (off_t); +static void _eim_remap_mem (off_t); + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +int eim_setup(void) +{ + // register cleanup function + if (atexit(_eim_cleanup) != 0) { + fprintf(stderr, "ERROR: atexit() failed.\n"); + return -1; + } + + // determine memory page size to use in mmap() + mem_page_size = sysconf(_SC_PAGESIZE); + if (mem_page_size < 1) { + fprintf(stderr, "ERROR: sysconf(_SC_PAGESIZE) == %ld\n", mem_page_size); + return -1; + } + + // try to open memory device + mem_dev_fd = open(MEMORY_DEVICE, O_RDWR | O_SYNC); + if (mem_dev_fd == -1) { + fprintf(stderr, "ERROR: open(%s) failed.\n", MEMORY_DEVICE); + return -1; + } + + /* Several blocks in the CPU have common pins, we can use I/O MUX Controller + * to configure what block will actually use I/O pins. We wait EIM module to be able + * to communicate with the on-board FPGA. Let's configure IOMUXC accordingly. + */ + _eim_setup_iomuxc(); + + /* We need to enable clocking of EIM block in order to be able to use it. + * Let's configure Clock Controller Module accordingly. + */ + _eim_setup_ccm(); + + /* We need to properly configure EIM mode and all the corresponding parameters. + * That's a lot of code, let's do it now. + */ + _eim_setup_eim(); + + // done + return 0; +} + + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +static void _eim_cleanup(void) +{ + // unmap memory if needed + if (mem_map_ptr != MAP_FAILED) + if (munmap(mem_map_ptr, mem_page_size) != 0) + fprintf(stderr, "WARNING: munmap() failed.\n"); + + // close memory device if needed + if (mem_dev_fd != -1) + if (close(mem_dev_fd) != 0) + fprintf(stderr, "WARNING: close() failed.\n"); +} + + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +static void _eim_setup_iomuxc(void) +{ + // create structures + struct IOMUXC_SW_MUX_CTL_PAD_EIM reg_mux; // mux control register + struct IOMUXC_SW_PAD_CTL_PAD_EIM reg_pad; // pad control register + + // setup mux control register + reg_mux.mux_mode = IOMUXC_MUX_MODE_ALT0; // ALT0 mode must be used for EIM + reg_mux.sion = 0; // forced input not needed + reg_mux.reserved_3 = 0; // must be 0 + reg_mux.reserved_31_5 = 0; // must be 0 + + // setup pad control register + reg_pad.sre = IOMUXC_PAD_CTL_SRE_FAST; // fast slew rate + reg_pad.dse = IOMUXC_PAD_CTL_DSE_33_OHM; // highest drive strength + reg_pad.speed = IOMUXC_PAD_CTL_SPEED_MEDIUM_10; // medium speed + reg_pad.ode = IOMUXC_PAD_CTL_ODE_DISABLED; // open drain not needed + reg_pad.pke = IOMUXC_PAD_CTL_PKE_DISABLED; // neither pull nor keeper are needed + reg_pad.pue = IOMUXC_PAD_CTL_PUE_PULL; // doesn't matter actually, because PKE is disabled + reg_pad.pus = IOMUXC_PAD_CTL_PUS_100K_OHM_PU; // doesn't matter actually, because PKE is disabled + reg_pad.hys = IOMUXC_PAD_CTL_HYS_DISABLED; // use CMOS, not Schmitt trigger input + reg_pad.reserved_2_1 = 0; // must be 0 + reg_pad.reserved_10_8 = 0; // must be 0 + reg_pad.reserved_31_17 = 0; // must be 0 + + // all the pins must be configured to use the same ALT0 mode + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_RW, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD00, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD01, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD02, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD03, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD04, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD05, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD06, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD07, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD08, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD09, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD10, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD11, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD12, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD13, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD14, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_AD15, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B, (uint32_t *)®_mux); + eim_write_32(IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK, (uint32_t *)®_mux); + + // we need to configure all the I/O pads too + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_RW, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD00, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD01, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD02, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD03, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD04, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD05, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD06, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD07, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD08, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD09, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD10, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD11, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD12, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD13, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD14, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_AD15, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B, (uint32_t *)®_pad); + eim_write_32(IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK, (uint32_t *)®_pad); +} + + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +static void _eim_setup_ccm(void) +{ + // create structure + struct CCM_CCGR6 ccm_ccgr6; + + // read register + eim_read_32(CCM_CCGR6, (uint32_t *)&ccm_ccgr6); + + // modify register + ccm_ccgr6.cg0_usboh3 = CCM_CGR_ON_EXCEPT_STOP; + ccm_ccgr6.cg1_usdhc1 = CCM_CGR_OFF; + ccm_ccgr6.cg2_usdhc2 = CCM_CGR_ON_EXCEPT_STOP; + ccm_ccgr6.cg3_usdhc3 = CCM_CGR_ON_EXCEPT_STOP; + + ccm_ccgr6.cg3_usdhc4 = CCM_CGR_OFF; + ccm_ccgr6.cg5_eim_slow = CCM_CGR_ON_EXCEPT_STOP; + ccm_ccgr6.cg6_vdoaxiclk = CCM_CGR_OFF; + ccm_ccgr6.cg7_vpu = CCM_CGR_OFF; + + ccm_ccgr6.cg8_reserved = 0; + ccm_ccgr6.cg9_reserved = 0; + ccm_ccgr6.cg10_reserved = 0; + ccm_ccgr6.cg11_reserved = 0; + ccm_ccgr6.cg12_reserved = 0; + ccm_ccgr6.cg13_reserved = 0; + ccm_ccgr6.cg14_reserved = 0; + ccm_ccgr6.cg15_reserved = 0; + + // write register + eim_write_32(CCM_CCGR6, (uint32_t *)&ccm_ccgr6); +} + + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +static void _eim_setup_eim(void) +{ + // create structures + struct EIM_CS_GCR1 gcr1; + struct EIM_CS_GCR2 gcr2; + struct EIM_CS_RCR1 rcr1; + struct EIM_CS_RCR2 rcr2; + struct EIM_CS_WCR1 wcr1; + struct EIM_CS_WCR2 wcr2; + + struct EIM_WCR wcr; + struct EIM_WIAR wiar; + struct EIM_EAR ear; + + // read all the registers + eim_read_32(EIM_CS0GCR1, (uint32_t *)&gcr1); + eim_read_32(EIM_CS0GCR2, (uint32_t *)&gcr2); + eim_read_32(EIM_CS0RCR1, (uint32_t *)&rcr1); + eim_read_32(EIM_CS0RCR2, (uint32_t *)&rcr2); + eim_read_32(EIM_CS0WCR1, (uint32_t *)&wcr1); + eim_read_32(EIM_CS0WCR2, (uint32_t *)&wcr2); + + eim_read_32(EIM_WCR, (uint32_t *)&wcr); + eim_read_32(EIM_WIAR, (uint32_t *)&wiar); + eim_read_32(EIM_EAR, (uint32_t *)&ear); + + // manipulate registers as needed + gcr1.csen = 1; // chip select is enabled + gcr1.swr = 1; // write is sync + gcr1.srd = 1; // read is sync + gcr1.mum = 1; // address and data are multiplexed + gcr1.wfl = 0; // write latency is not fixed + gcr1.rfl = 0; // read latency is not fixed + gcr1.cre = 0; // CRE signal not needed + //gcr1.crep = x; // don't care, CRE not used + gcr1.bl = 4; // burst length + gcr1.wc = 0; // write is not continuous + gcr1.bcd = 3; // BCLK divisor is 3+1=4 + gcr1.bcs = 1; // delay from ~CS to BCLK is 1 cycle + gcr1.dsz = 1; // 16 bits per databeat at DATA[15:0] + gcr1.sp = 0; // supervisor protection is disabled + gcr1.csrec = 1; // ~CS recovery is 1 cycle + gcr1.aus = 1; // address is not shifted + gcr1.gbc = 1; // ~CS gap is 1 cycle + gcr1.wp = 0; // write protection is not enabled + //gcr1.psz = x; // don't care, page mode is not used + + gcr2.adh = 0; // address hold duration is 1 cycle + //gcr2.daps = x; // don't care, DTACK is not used + gcr2.dae = 0; // DTACK is not used + //gcr2.dap = x; // don't care, DTACK is not used + gcr2.mux16_byp_grant= 1; // enable grant mechanism + gcr2.reserved_3_2 = 0; // must be 0 + gcr2.reserved_11_10 = 0; // must be 0 + gcr2.reserved_31_13 = 0; // must be 0 + + //rcr1.rcsn = x; // don't care in sync mode + rcr1.rcsa = 0; // no delay for ~CS needed + //rcr1.oen = x; // don't care in sync mode + rcr1.oea = 0; // no delay for ~OE needed + rcr1.radvn = 0; // no delay for ~LBA needed + rcr1.ral = 0; // clear ~LBA when needed + rcr1.radva = 0; // no delay for ~LBA needed + rcr1.rwsc = 1; // one wait state + rcr1.reserved_3 = 0; // must be 0 + rcr1.reserved_7 = 0; // must be 0 + rcr1.reserved_11 = 0; // must be 0 + rcr1.reserved_15 = 0; // must be 0 + rcr1.reserved_23 = 0; // must be 0 + rcr1.reserved_31_30 = 0; // must be 0 + + //rcr2.rben = x; // don't care in sync mode + rcr2.rbe = 0; // BE is disabled + //rcr2.rbea = x; // don't care when BE is not used + rcr2.rl = 0; // read latency is 0 + //rcr2.pat = x; // don't care when page read is not used + rcr2.apr = 0; // page read mode is not used + rcr2.reserved_7 = 0; // must be 0 + rcr2.reserved_11_10 = 0; // must be 0 + rcr2.reserved_31_16 = 0; // must be 0 + + //wcr1.wcsn = x; // don't care in sync mode + wcr1.wcsa = 0; // no delay for ~CS needed + //wcr1.wen = x; // don't care in sync mode + wcr1.wea = 0; // no delay for ~WR_N needed + //wcr1.wben = x; // don't care in sync mode + //wcr1.wbea = x; // don't care in sync mode + wcr1.wadvn = 0; // no delay for ~LBA needed + wcr1.wadva = 0; // no delay for ~LBA needed + wcr1.wwsc = 1; // no wait state in needed + wcr1.wbed = 1; // BE is disabled + wcr1.wal = 0; // clear ~LBA when needed + + wcr2.wbcdd = 0; // write clock division is not needed + wcr2.reserved_31_1 = 0; // must be 0 + + wcr.bcm = 0; // clock is only active during access + //wcr.gbcd = x; // don't care when BCM=0 + wcr.inten = 0; // interrupt is not used + //wcr.intpol = x; // don't care when interrupt is not used + wcr.wdog_en = 1; // watchdog is enabled + wcr.wdog_limit = 00; // timeout is 128 BCLK cycles + wcr.reserved_3 = 0; // must be 0 + wcr.reserved_7_6 = 0; // must be 0 + wcr.reserved_31_11 = 0; // must be 0 + + wiar.ips_req = 0; // IPS not needed + wiar.ips_ack = 0; // IPS not needed + //wiar.irq = x; // don't touch + //wiar.errst = x; // don't touch + wiar.aclk_en = 1; // clock is enabled + wiar.reserved_31_5 = 0; // must be 0 + + //ear.error_addr = x; // read-only + + // write modified registers + eim_write_32(EIM_CS0GCR1, (uint32_t *)&gcr1); + eim_write_32(EIM_CS0GCR2, (uint32_t *)&gcr2); + eim_write_32(EIM_CS0RCR1, (uint32_t *)&rcr1); + eim_write_32(EIM_CS0RCR2, (uint32_t *)&rcr2); + eim_write_32(EIM_CS0WCR1, (uint32_t *)&wcr1); + eim_write_32(EIM_CS0WCR2, (uint32_t *)&wcr2); + eim_write_32(EIM_WCR, (uint32_t *)&wcr); + eim_write_32(EIM_WIAR, (uint32_t *)&wiar); +/* eim_write_32(EIM_EAR, (uint32_t *)&ear);*/ +} + + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +void eim_write_32(off_t offset, uint32_t *pvalue) +{ + // calculate memory offset + uint32_t *ptr = (uint32_t *)_eim_calc_offset(offset); + + // write data to memory + memcpy(ptr, pvalue, sizeof(uint32_t)); +} + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +void eim_read_32(off_t offset, uint32_t *pvalue) +{ + // calculate memory offset + uint32_t *ptr = (uint32_t *)_eim_calc_offset(offset); + + // read data from memory + memcpy(pvalue, ptr, sizeof(uint32_t)); +} + + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +static off_t _eim_calc_offset(off_t offset) +{ + // make sure that memory is mapped + if (mem_map_ptr == MAP_FAILED) + _eim_remap_mem(offset); + + // calculate starting and ending addresses of currently mapped page + off_t offset_low = mem_base_addr; + off_t offset_high = mem_base_addr + (mem_page_size - 1); + + // check that offset is in currently mapped page, remap new page otherwise + if ((offset < offset_low) || (offset > offset_high)) + _eim_remap_mem(offset); + + // calculate pointer + return (off_t)mem_map_ptr + (offset - mem_base_addr); +} + + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +static void _eim_remap_mem(off_t offset) +{ + // unmap old memory page if needed + if (mem_map_ptr != MAP_FAILED) { + if (munmap(mem_map_ptr, mem_page_size) != 0) { + fprintf(stderr, "ERROR: munmap() failed.\n"); + exit(EXIT_FAILURE); + } + } + + // calculate starting address of new page + while (offset % mem_page_size) + offset--; + + // try to map new memory page + mem_map_ptr = mmap(NULL, mem_page_size, PROT_READ | PROT_WRITE, MAP_SHARED, + mem_dev_fd, offset); + if (mem_map_ptr == MAP_FAILED) { + fprintf(stderr, "ERROR: mmap() failed.\n"); + exit(EXIT_FAILURE); + } + + // save last mapped page address + mem_base_addr = offset; +} + + +//------------------------------------------------------------------------------ +// End-of-File +//------------------------------------------------------------------------------ diff --git a/sw/novena-eim.h b/sw/novena-eim.h index 3d29f77..75613bf 100644 --- a/sw/novena-eim.h +++ b/sw/novena-eim.h @@ -1,297 +1,52 @@ -//------------------------------------------------------------------------------ -// novena-eim.h -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// Defined Values -//------------------------------------------------------------------------------ -#define MEMORY_DEVICE "/dev/mem" - - -//------------------------------------------------------------------------------ -// IOMUXC Values -//------------------------------------------------------------------------------ -#define IOMUXC_MUX_MODE_ALT0 0 // 000 - -#define IOMUXC_PAD_CTL_SRE_FAST 1 // 1 -#define IOMUXC_PAD_CTL_DSE_33_OHM 7 // 111 -#define IOMUXC_PAD_CTL_SPEED_MEDIUM_10 2 // 10 -#define IOMUXC_PAD_CTL_ODE_DISABLED 0 // 0 -#define IOMUXC_PAD_CTL_PKE_DISABLED 0 // 0 -#define IOMUXC_PAD_CTL_PUE_PULL 1 // 1 -#define IOMUXC_PAD_CTL_PUS_100K_OHM_PU 2 // 10 -#define IOMUXC_PAD_CTL_HYS_DISABLED 0 // 0 - -//------------------------------------------------------------------------------ -// CCM Values -//------------------------------------------------------------------------------ -#define CCM_CGR_OFF 0 // 00 -#define CCM_CGR_ON_EXCEPT_STOP 3 // 11 - - -//------------------------------------------------------------------------------ -// CPU Registers -//------------------------------------------------------------------------------ -enum IMX6DQ_REGISTER_OFFSET -{ - IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B = 0x020E00F8, - IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B = 0x020E0100, - IOMUXC_SW_MUX_CTL_PAD_EIM_RW = 0x020E0104, - IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B = 0x020E0108, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD00 = 0x020E0114, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD01 = 0x020E0118, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD02 = 0x020E011C, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD03 = 0x020E0120, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD04 = 0x020E0124, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD05 = 0x020E0128, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD06 = 0x020E012C, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD07 = 0x020E0130, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD08 = 0x020E0134, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD09 = 0x020E0138, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD10 = 0x020E013C, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD11 = 0x020E0140, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD12 = 0x020E0144, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD13 = 0x020E0148, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD14 = 0x020E014C, - IOMUXC_SW_MUX_CTL_PAD_EIM_AD15 = 0x020E0150, - IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B = 0x020E0154, - IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK = 0x020E0158, - - IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B = 0x020E040C, - IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B = 0x020E0414, - IOMUXC_SW_PAD_CTL_PAD_EIM_RW = 0x020E0418, - IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B = 0x020E041C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD00 = 0x020E0428, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD01 = 0x020E042C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD02 = 0x020E0430, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD03 = 0x020E0434, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD04 = 0x020E0438, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD05 = 0x020E043C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD06 = 0x020E0440, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD07 = 0x020E0444, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD08 = 0x020E0448, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD09 = 0x020E044C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD10 = 0x020E0450, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD11 = 0x020E0454, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD12 = 0x020E0458, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD13 = 0x020E045C, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD14 = 0x020E0460, - IOMUXC_SW_PAD_CTL_PAD_EIM_AD15 = 0x020E0464, - IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B = 0x020E0468, - IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK = 0x020E046C, - - CCM_CCGR6 = 0x020C4080, - - EIM_CS0GCR1 = 0x021B8000, - EIM_CS0GCR2 = 0x021B8004, - EIM_CS0RCR1 = 0x021B8008, - EIM_CS0RCR2 = 0x021B800C, - EIM_CS0WCR1 = 0x021B8010, - EIM_CS0WCR2 = 0x021B8014, - - EIM_WCR = 0x021B8090, - EIM_WIAR = 0x021B8094, - EIM_EAR = 0x021B8098, - - EIM_BASE_ADDR = 0x08000000 -}; - - -//------------------------------------------------------------------------------ -struct IOMUXC_SW_MUX_CTL_PAD_EIM -//------------------------------------------------------------------------------ -{ - uint32_t mux_mode : 3; - uint32_t reserved_3 : 1; - uint32_t sion : 1; - uint32_t reserved_31_5 : 27; -}; -//------------------------------------------------------------------------------ -struct IOMUXC_SW_PAD_CTL_PAD_EIM -//------------------------------------------------------------------------------ -{ - uint32_t sre : 1; - uint32_t reserved_2_1 : 2; - uint32_t dse : 3; - uint32_t speed : 2; - uint32_t reserved_10_8 : 3; - uint32_t ode : 1; - uint32_t pke : 1; - uint32_t pue : 1; - uint32_t pus : 2; - uint32_t hys : 1; - uint32_t reserved_31_17 : 15; -}; - - -//------------------------------------------------------------------------------ -struct CCM_CCGR6 -//------------------------------------------------------------------------------ -{ - uint32_t cg0_usboh3 : 2; - uint32_t cg1_usdhc1 : 2; - uint32_t cg2_usdhc2 : 2; - uint32_t cg3_usdhc3 : 2; - - uint32_t cg3_usdhc4 : 2; - uint32_t cg5_eim_slow : 2; - uint32_t cg6_vdoaxiclk : 2; - uint32_t cg7_vpu : 2; - - uint32_t cg8_reserved : 2; - uint32_t cg9_reserved : 2; - uint32_t cg10_reserved : 2; - uint32_t cg11_reserved : 2; - - uint32_t cg12_reserved : 2; - uint32_t cg13_reserved : 2; - uint32_t cg14_reserved : 2; - uint32_t cg15_reserved : 2; -}; - - -//------------------------------------------------------------------------------ -struct EIM_CS_GCR1 -//------------------------------------------------------------------------------ -{ - uint32_t csen : 1; - uint32_t swr : 1; - uint32_t srd : 1; - uint32_t mum : 1; - uint32_t wfl : 1; - uint32_t rfl : 1; - uint32_t cre : 1; - uint32_t crep : 1; - uint32_t bl : 3; - uint32_t wc : 1; - uint32_t bcd : 2; - uint32_t bcs : 2; - uint32_t dsz : 3; - uint32_t sp : 1; - uint32_t csrec : 3; - uint32_t aus : 1; - uint32_t gbc : 3; - uint32_t wp : 1; - uint32_t psz : 4; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_GCR2 -//------------------------------------------------------------------------------ -{ - uint32_t adh : 2; - uint32_t reserved_3_2 : 2; - uint32_t daps : 4; - uint32_t dae : 1; - uint32_t dap : 1; - uint32_t reserved_11_10 : 2; - uint32_t mux16_byp_grant : 1; - uint32_t reserved_31_13 : 19; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_RCR1 -//------------------------------------------------------------------------------ -{ - uint32_t rcsn : 3; - uint32_t reserved_3 : 1; - uint32_t rcsa : 3; - uint32_t reserved_7 : 1; - uint32_t oen : 3; - uint32_t reserved_11 : 1; - uint32_t oea : 3; - uint32_t reserved_15 : 1; - uint32_t radvn : 3; - uint32_t ral : 1; - uint32_t radva : 3; - uint32_t reserved_23 : 1; - uint32_t rwsc : 6; - uint32_t reserved_31_30 : 2; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_RCR2 -//------------------------------------------------------------------------------ -{ - uint32_t rben : 3; - uint32_t rbe : 1; - uint32_t rbea : 3; - uint32_t reserved_7 : 1; - uint32_t rl : 2; - uint32_t reserved_11_10 : 2; - uint32_t pat : 3; - uint32_t apr : 1; - uint32_t reserved_31_16 : 16; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_WCR1 -//------------------------------------------------------------------------------ -{ - uint32_t wcsn : 3; - uint32_t wcsa : 3; - uint32_t wen : 3; - uint32_t wea : 3; - uint32_t wben : 3; - uint32_t wbea : 3; - uint32_t wadvn : 3; - uint32_t wadva : 3; - uint32_t wwsc : 6; - uint32_t wbed : 1; - uint32_t wal : 1; -}; -//------------------------------------------------------------------------------ -struct EIM_CS_WCR2 -//------------------------------------------------------------------------------ -{ - uint32_t wbcdd : 1; - uint32_t reserved_31_1 : 31; -}; -//------------------------------------------------------------------------------ -struct EIM_WCR -//------------------------------------------------------------------------------ -{ - uint32_t bcm : 1; - uint32_t gbcd : 2; - uint32_t reserved_3 : 1; - uint32_t inten : 1; - uint32_t intpol : 1; - uint32_t reserved_7_6 : 2; - uint32_t wdog_en : 1; - uint32_t wdog_limit : 2; - uint32_t reserved_31_11 : 21; -}; -//------------------------------------------------------------------------------ -struct EIM_WIAR -//------------------------------------------------------------------------------ -{ - uint32_t ips_req : 1; - uint32_t ips_ack : 1; - uint32_t irq : 1; - uint32_t errst : 1; - uint32_t aclk_en : 1; - uint32_t reserved_31_5 : 27; -}; -//------------------------------------------------------------------------------ -struct EIM_EAR -//------------------------------------------------------------------------------ -{ - uint32_t error_addr : 32; -}; - - -//------------------------------------------------------------------------------ -// Prototypes -//------------------------------------------------------------------------------ -int eim_setup (); -void eim_write_32 (off_t, uint32_t *); -void eim_read_32 (off_t, uint32_t *); - -void _eim_setup_iomuxc (); -void _eim_setup_ccm (); -void _eim_setup_eim (); -void _eim_cleanup (); -off_t _eim_calc_offset (off_t); -void _eim_remap_mem (off_t); - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ +/* + * novena-eim.h + * ------------ + * This module contains the userland magic to set up and use the EIM bus. + * + * + * Author: Pavel Shatov + * Copyright (c) 2014-2015, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define EIM_BASE_ADDR 0x08000000 + +/* Set up EIM bus. + * Returns 0 on success, -1 on failure. + */ +int eim_setup(void); + +/* Write a 32-bit word to EIM. + * If EIM is not set up correctly, this will abort with a bus error. + */ +void eim_write_32(off_t, uint32_t *); + +/* Read a 32-bit word from EIM. + * If EIM is not set up correctly, this will abort with a bus error. + */ +void eim_read_32(off_t, uint32_t *); -- cgit v1.2.3 From f135907b11d6511cd260c4ab751a2bee2f30b662 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Wed, 11 Feb 2015 12:46:23 -0500 Subject: Change bitfield types back to unsigned int. --- sw/novena-eim.c | 245 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 127 insertions(+), 118 deletions(-) (limited to 'sw') diff --git a/sw/novena-eim.c b/sw/novena-eim.c index 9b3d236..85bfac0 100644 --- a/sw/novena-eim.c +++ b/sw/novena-eim.c @@ -131,7 +131,6 @@ enum IMX6DQ_REGISTER_OFFSET EIM_WCR = 0x021B8090, EIM_WIAR = 0x021B8094, EIM_EAR = 0x021B8098, - }; @@ -140,163 +139,163 @@ enum IMX6DQ_REGISTER_OFFSET //------------------------------------------------------------------------------ struct IOMUXC_SW_MUX_CTL_PAD_EIM { - uint32_t mux_mode : 3; - uint32_t reserved_3 : 1; - uint32_t sion : 1; - uint32_t reserved_31_5 : 27; + unsigned int mux_mode : 3; + unsigned int reserved_3 : 1; + unsigned int sion : 1; + unsigned int reserved_31_5 : 27; }; struct IOMUXC_SW_PAD_CTL_PAD_EIM { - uint32_t sre : 1; - uint32_t reserved_2_1 : 2; - uint32_t dse : 3; - uint32_t speed : 2; - uint32_t reserved_10_8 : 3; - uint32_t ode : 1; - uint32_t pke : 1; - uint32_t pue : 1; - uint32_t pus : 2; - uint32_t hys : 1; - uint32_t reserved_31_17 : 15; + unsigned int sre : 1; + unsigned int reserved_2_1 : 2; + unsigned int dse : 3; + unsigned int speed : 2; + unsigned int reserved_10_8 : 3; + unsigned int ode : 1; + unsigned int pke : 1; + unsigned int pue : 1; + unsigned int pus : 2; + unsigned int hys : 1; + unsigned int reserved_31_17 : 15; }; struct CCM_CCGR6 { - uint32_t cg0_usboh3 : 2; - uint32_t cg1_usdhc1 : 2; - uint32_t cg2_usdhc2 : 2; - uint32_t cg3_usdhc3 : 2; + unsigned int cg0_usboh3 : 2; + unsigned int cg1_usdhc1 : 2; + unsigned int cg2_usdhc2 : 2; + unsigned int cg3_usdhc3 : 2; - uint32_t cg3_usdhc4 : 2; - uint32_t cg5_eim_slow : 2; - uint32_t cg6_vdoaxiclk : 2; - uint32_t cg7_vpu : 2; + unsigned int cg3_usdhc4 : 2; + unsigned int cg5_eim_slow : 2; + unsigned int cg6_vdoaxiclk : 2; + unsigned int cg7_vpu : 2; - uint32_t cg8_reserved : 2; - uint32_t cg9_reserved : 2; - uint32_t cg10_reserved : 2; - uint32_t cg11_reserved : 2; + unsigned int cg8_reserved : 2; + unsigned int cg9_reserved : 2; + unsigned int cg10_reserved : 2; + unsigned int cg11_reserved : 2; - uint32_t cg12_reserved : 2; - uint32_t cg13_reserved : 2; - uint32_t cg14_reserved : 2; - uint32_t cg15_reserved : 2; + unsigned int cg12_reserved : 2; + unsigned int cg13_reserved : 2; + unsigned int cg14_reserved : 2; + unsigned int cg15_reserved : 2; }; struct EIM_CS_GCR1 { - uint32_t csen : 1; - uint32_t swr : 1; - uint32_t srd : 1; - uint32_t mum : 1; - uint32_t wfl : 1; - uint32_t rfl : 1; - uint32_t cre : 1; - uint32_t crep : 1; - uint32_t bl : 3; - uint32_t wc : 1; - uint32_t bcd : 2; - uint32_t bcs : 2; - uint32_t dsz : 3; - uint32_t sp : 1; - uint32_t csrec : 3; - uint32_t aus : 1; - uint32_t gbc : 3; - uint32_t wp : 1; - uint32_t psz : 4; + unsigned int csen : 1; + unsigned int swr : 1; + unsigned int srd : 1; + unsigned int mum : 1; + unsigned int wfl : 1; + unsigned int rfl : 1; + unsigned int cre : 1; + unsigned int crep : 1; + unsigned int bl : 3; + unsigned int wc : 1; + unsigned int bcd : 2; + unsigned int bcs : 2; + unsigned int dsz : 3; + unsigned int sp : 1; + unsigned int csrec : 3; + unsigned int aus : 1; + unsigned int gbc : 3; + unsigned int wp : 1; + unsigned int psz : 4; }; struct EIM_CS_GCR2 { - uint32_t adh : 2; - uint32_t reserved_3_2 : 2; - uint32_t daps : 4; - uint32_t dae : 1; - uint32_t dap : 1; - uint32_t reserved_11_10 : 2; - uint32_t mux16_byp_grant : 1; - uint32_t reserved_31_13 : 19; + unsigned int adh : 2; + unsigned int reserved_3_2 : 2; + unsigned int daps : 4; + unsigned int dae : 1; + unsigned int dap : 1; + unsigned int reserved_11_10 : 2; + unsigned int mux16_byp_grant : 1; + unsigned int reserved_31_13 : 19; }; struct EIM_CS_RCR1 { - uint32_t rcsn : 3; - uint32_t reserved_3 : 1; - uint32_t rcsa : 3; - uint32_t reserved_7 : 1; - uint32_t oen : 3; - uint32_t reserved_11 : 1; - uint32_t oea : 3; - uint32_t reserved_15 : 1; - uint32_t radvn : 3; - uint32_t ral : 1; - uint32_t radva : 3; - uint32_t reserved_23 : 1; - uint32_t rwsc : 6; - uint32_t reserved_31_30 : 2; + unsigned int rcsn : 3; + unsigned int reserved_3 : 1; + unsigned int rcsa : 3; + unsigned int reserved_7 : 1; + unsigned int oen : 3; + unsigned int reserved_11 : 1; + unsigned int oea : 3; + unsigned int reserved_15 : 1; + unsigned int radvn : 3; + unsigned int ral : 1; + unsigned int radva : 3; + unsigned int reserved_23 : 1; + unsigned int rwsc : 6; + unsigned int reserved_31_30 : 2; }; struct EIM_CS_RCR2 { - uint32_t rben : 3; - uint32_t rbe : 1; - uint32_t rbea : 3; - uint32_t reserved_7 : 1; - uint32_t rl : 2; - uint32_t reserved_11_10 : 2; - uint32_t pat : 3; - uint32_t apr : 1; - uint32_t reserved_31_16 : 16; + unsigned int rben : 3; + unsigned int rbe : 1; + unsigned int rbea : 3; + unsigned int reserved_7 : 1; + unsigned int rl : 2; + unsigned int reserved_11_10 : 2; + unsigned int pat : 3; + unsigned int apr : 1; + unsigned int reserved_31_16 : 16; }; struct EIM_CS_WCR1 { - uint32_t wcsn : 3; - uint32_t wcsa : 3; - uint32_t wen : 3; - uint32_t wea : 3; - uint32_t wben : 3; - uint32_t wbea : 3; - uint32_t wadvn : 3; - uint32_t wadva : 3; - uint32_t wwsc : 6; - uint32_t wbed : 1; - uint32_t wal : 1; + unsigned int wcsn : 3; + unsigned int wcsa : 3; + unsigned int wen : 3; + unsigned int wea : 3; + unsigned int wben : 3; + unsigned int wbea : 3; + unsigned int wadvn : 3; + unsigned int wadva : 3; + unsigned int wwsc : 6; + unsigned int wbed : 1; + unsigned int wal : 1; }; struct EIM_CS_WCR2 { - uint32_t wbcdd : 1; - uint32_t reserved_31_1 : 31; + unsigned int wbcdd : 1; + unsigned int reserved_31_1 : 31; }; struct EIM_WCR { - uint32_t bcm : 1; - uint32_t gbcd : 2; - uint32_t reserved_3 : 1; - uint32_t inten : 1; - uint32_t intpol : 1; - uint32_t reserved_7_6 : 2; - uint32_t wdog_en : 1; - uint32_t wdog_limit : 2; - uint32_t reserved_31_11 : 21; + unsigned int bcm : 1; + unsigned int gbcd : 2; + unsigned int reserved_3 : 1; + unsigned int inten : 1; + unsigned int intpol : 1; + unsigned int reserved_7_6 : 2; + unsigned int wdog_en : 1; + unsigned int wdog_limit : 2; + unsigned int reserved_31_11 : 21; }; struct EIM_WIAR { - uint32_t ips_req : 1; - uint32_t ips_ack : 1; - uint32_t irq : 1; - uint32_t errst : 1; - uint32_t aclk_en : 1; - uint32_t reserved_31_5 : 27; + unsigned int ips_req : 1; + unsigned int ips_ack : 1; + unsigned int irq : 1; + unsigned int errst : 1; + unsigned int aclk_en : 1; + unsigned int reserved_31_5 : 27; }; struct EIM_EAR { - uint32_t error_addr : 32; + unsigned int error_addr : 32; }; @@ -308,6 +307,7 @@ static int mem_dev_fd = -1; static void * mem_map_ptr = MAP_FAILED; static off_t mem_base_addr = 0; + //------------------------------------------------------------------------------ // Prototypes //------------------------------------------------------------------------------ @@ -318,7 +318,9 @@ static void _eim_cleanup (void); static off_t _eim_calc_offset (off_t); static void _eim_remap_mem (off_t); + //------------------------------------------------------------------------------ +// Set up EIM bus. Returns 0 on success, -1 on failure. //------------------------------------------------------------------------------ int eim_setup(void) { @@ -342,15 +344,10 @@ int eim_setup(void) return -1; } - /* Several blocks in the CPU have common pins, we can use I/O MUX Controller - * to configure what block will actually use I/O pins. We wait EIM module to be able - * to communicate with the on-board FPGA. Let's configure IOMUXC accordingly. - */ + // configure IOMUXC _eim_setup_iomuxc(); - /* We need to enable clocking of EIM block in order to be able to use it. - * Let's configure Clock Controller Module accordingly. - */ + // configure Clock Controller Module _eim_setup_ccm(); /* We need to properly configure EIM mode and all the corresponding parameters. @@ -364,6 +361,7 @@ int eim_setup(void) //------------------------------------------------------------------------------ +// Shut down EIM bus. This is called automatically on exit(). //------------------------------------------------------------------------------ static void _eim_cleanup(void) { @@ -380,6 +378,9 @@ static void _eim_cleanup(void) //------------------------------------------------------------------------------ +// Several blocks in the CPU have common pins. We use the I/O MUX Controller +// to configure what block will actually use I/O pins. We wait for the EIM +// module to be able to communicate with the on-board FPGA. //------------------------------------------------------------------------------ static void _eim_setup_iomuxc(void) { @@ -457,6 +458,7 @@ static void _eim_setup_iomuxc(void) //------------------------------------------------------------------------------ +// Configure Clock Controller Module to enable clocking of EIM block. //------------------------------------------------------------------------------ static void _eim_setup_ccm(void) { @@ -492,6 +494,7 @@ static void _eim_setup_ccm(void) //------------------------------------------------------------------------------ +// Configure EIM mode and all the corresponding parameters. That's a lot of code. //------------------------------------------------------------------------------ static void _eim_setup_eim(void) { @@ -622,6 +625,8 @@ static void _eim_setup_eim(void) //------------------------------------------------------------------------------ +// Write a 32-bit word to EIM. +// If EIM is not set up correctly, this will abort with a bus error. //------------------------------------------------------------------------------ void eim_write_32(off_t offset, uint32_t *pvalue) { @@ -633,6 +638,8 @@ void eim_write_32(off_t offset, uint32_t *pvalue) } //------------------------------------------------------------------------------ +// Read a 32-bit word from EIM. +// If EIM is not set up correctly, this will abort with a bus error. //------------------------------------------------------------------------------ void eim_read_32(off_t offset, uint32_t *pvalue) { @@ -645,6 +652,7 @@ void eim_read_32(off_t offset, uint32_t *pvalue) //------------------------------------------------------------------------------ +// Calculate an offset into the currently-mapped EIM page. //------------------------------------------------------------------------------ static off_t _eim_calc_offset(off_t offset) { @@ -666,6 +674,7 @@ static off_t _eim_calc_offset(off_t offset) //------------------------------------------------------------------------------ +// Map in a new EIM page. //------------------------------------------------------------------------------ static void _eim_remap_mem(off_t offset) { -- cgit v1.2.3