diff --git a/system/testcodes/aes128_tests_dma230/aes128_tests_dma230.c b/system/testcodes/aes128_tests_dma230/aes128_tests_dma230.c index 36bc54900904cd499bb5b92a8bfd15ec7568479f..3db83d702d9ba0bc6450ff42a51dd838d7669d7f 100644 --- a/system/testcodes/aes128_tests_dma230/aes128_tests_dma230.c +++ b/system/testcodes/aes128_tests_dma230/aes128_tests_dma230.c @@ -13,6 +13,9 @@ static volatile dma_pl230_channel_data aes_ip_chain[2]; static volatile dma_pl230_channel_data aes_op_chain[2]; +int pl230_dma_detect(void); +int ID_Check(const unsigned int id_array[], unsigned int offset); + // associate DMA channel numbers #define DMA_CHAN_AES128_IP (0) #define DMA_CHAN_AES128_OP (1) @@ -202,6 +205,67 @@ volatile int aes_err_irq_expected; uint8_t shift_buf1[sizeof(shift_patt)]; uint8_t shift_buf2[sizeof(shift_patt)]; +#if defined ( __CC_ARM ) +__asm unsigned int address_test_read(unsigned int addr); +#else + unsigned int address_test_read(unsigned int addr); +#endif + +void HardFault_Handler_c(unsigned int * hardfault_args, unsigned lr_value); + +/* Global variables */ +volatile int hardfault_occurred; +volatile int hardfault_expected; +volatile int temp_data; + +/* Detect if DMA230 is in System */ +int pl230_dma_detect(void) +{ + int result; + int volatile rdata; /* dummy variable for read data in bus fault testing */ + unsigned const int pl230_id[12] = { + 0x30, 0xB2, 0x0B, 0x00, + 0x0D, 0xF0, 0x05, 0xB1}; + puts("Detect if DMA controller is present..."); + hardfault_occurred = 0; + hardfault_expected = 1; + rdata = address_test_read(CMSDK_PL230_BASE+ 0xFE0); + hardfault_expected = 0; + result = hardfault_occurred ? 1 : ID_Check(&pl230_id[0], CMSDK_PL230_BASE); + hardfault_occurred = 0; + if (result!=0) { + puts("** TEST SKIPPED ** DMA controller is not present.\n"); + UartEndSimulation(); + } + return(result); +} + +int ID_Check(const unsigned int id_array[], unsigned int offset) +{ + int i; + unsigned long expected_val, actual_val; + unsigned long compare_mask; + int mismatch = 0; + unsigned long test_addr; + + /* Check the peripheral ID and component ID */ + for (i=0;i<8;i++) { + test_addr = offset + 4*i + 0xFE0; + expected_val = id_array[i]; + actual_val = HW32_REG(test_addr); + + /* create mask to ignore version numbers */ + if (i==2) { compare_mask = 0xF0;} // mask out version field + else { compare_mask = 0x00;} // compare whole value + + if ((expected_val & (~compare_mask)) != (actual_val & (~compare_mask))) { + printf ("Difference found: %x, expected %x, actual %x\n", test_addr, expected_val, actual_val); + mismatch++; + } + + } // end_for + return (mismatch); +} /* Note: Hardware supports byte, half-word or word accesses So memcpy() can be used to load/save data @@ -440,174 +504,183 @@ void aes128_decrypt_dma(uint8_t *key, uint32_t nbytes, uint8_t *input, uint8_t * int main(void) { + + char rx_char [256] = "SoCLabs AES128v1"; // init to 0 unsigned char id_string [16] = {0}; int i, fail=0; - unsigned char * p; - - UartStdOutInit(); - printf("%s\n",rx_char); - printf("AES128 test program\n"); - printf(" AES128 ID: "); - // iterate over 3 32-bit fields - p = (unsigned char *)AES128->CORE_NAME; - for (i = 0; i < 12; i++) { - id_string[i^3]=*p; // fix byte ordering per word - p+=1; - } - id_string[12] = 0; - printf("%s\n",id_string); - - aes_key_irq_occurred = 0; - aes_key_irq_expected = 1; - NVIC_ClearPendingIRQ(EXP0_IRQn); - NVIC_EnableIRQ(EXP0_IRQn); - aes_ip_irq_occurred = 0; - aes_ip_irq_expected = 1; - NVIC_ClearPendingIRQ(EXP1_IRQn); - NVIC_EnableIRQ(EXP1_IRQn); - aes_op_irq_occurred = 0; - aes_op_irq_expected = 1; - NVIC_ClearPendingIRQ(EXP2_IRQn); - NVIC_EnableIRQ(EXP2_IRQn); - aes_err_irq_occurred = 0; - aes_err_irq_expected = 1; - NVIC_ClearPendingIRQ(EXP3_IRQn); - NVIC_EnableIRQ(EXP3_IRQn); - - printf("AES128 SW (memcpy) tests...\n"); - printf(" AES128 reference pattern test\n"); - - printf(" AES128 input/output bypass test\n"); - aes128_bypass_memcpy(test_key128, sizeof(test_text128), test_text128, buf128); - fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); - - if (aes_key_irq_occurred != 1){ fail++; - printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); } - if (aes_ip_irq_occurred != 2){ fail++; - printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); } - if (aes_op_irq_occurred != 1){ fail++; - printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); } - if (aes_err_irq_occurred != 0){ fail++; - printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); } - - printf(" AES128 encrypt test\n"); - aes128_encrypt_memcpy(test_key128, sizeof(test_text128), test_text128, buf128); - fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_exp128); - - printf(" AES128 decrypt test\n"); - aes128_decrypt_memcpy(test_key128, sizeof(buf128), buf128, buf128); - fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); - - aes_key_irq_occurred = 0; - aes_ip_irq_occurred = 0; - aes_op_irq_occurred = 0; - aes_err_irq_occurred = 0; - - printf(" AES128 logic toggle test\n"); - printf(" AES128 input/output pattern test\n"); - aes128_bypass_memcpy(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); - fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf1, shift_patt); - - if (aes_key_irq_occurred != 1){ fail++; - printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); } - if (aes_ip_irq_occurred != (129+1)){ fail++; - printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); } - if (aes_op_irq_occurred != 129){ fail++; - printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); } - if (aes_err_irq_occurred != 0){ fail++; - printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); } - - printf(" AES128 pattern encrypt test\n"); - aes128_encrypt_memcpy(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); - printf(" AES128 pattern decrypt test\n"); - aes128_decrypt_memcpy(test_key128, sizeof(shift_patt), shift_buf1, shift_buf2); - fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf2, shift_patt); - - printf("AES128 DMA tests...\n"); - - aes_key_irq_occurred = 0; - aes_ip_irq_occurred = 0; - aes_op_irq_occurred = 0; - aes_err_irq_occurred = 0; - dma_error_irq_expected = 0; - dma_error_irq_occurred = 0; - dma_done_irq_expected = 1; - dma_done_irq_occurred = 0; - NVIC_ClearPendingIRQ(DMA_IRQn); - NVIC_EnableIRQ(DMA_IRQn); - - printf(" AES128 dma input/output bypass test\n"); - aes128_bypass_dma(test_key128, sizeof(test_text128), test_text128, buf128); - fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); - - if (dma_done_irq_occurred < 2){ - puts ("ERROR: DMA err IRQ missing"); - fail++; - } else - printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred); - - printf(" AES128 dma encrypt test\n"); - aes128_encrypt_dma(test_key128, sizeof(test_text128), test_text128, buf128); - fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_exp128); - - printf(" AES128 dma decrypt test\n"); - aes128_decrypt_dma(test_key128, sizeof(buf128), buf128, buf128); - fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); - - if (dma_done_irq_occurred < 6){ - puts ("ERROR: DMA err IRQ missing"); - fail++; - } else - printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred); - - printf(" AES128 dma unaligned pattern test\n"); - aes128_bypass_dma(test_key128,(16*63), shift_patt, shift_buf1+3); - fail += aes128_buffer_verify((16*63), shift_buf1+3, shift_patt); - - printf(" AES128 dma input/output pattern test\n"); - aes128_bypass_dma(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); - fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf1, shift_patt); - printf(" AES128 dma pattern encrypt test\n"); - aes128_encrypt_dma(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); - printf(" AES128 dma pattern decrypt test\n"); - aes128_decrypt_dma(test_key128, sizeof(shift_patt), shift_buf1, shift_buf2); - fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf2, shift_patt); - - if (dma_done_irq_occurred < (2*7)){ - puts ("ERROR: DMA err IRQ missing"); - fail++; - } else - printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred); - - // check IRQ masked by DRQs - except when Iinput buffer empty after DMA done - if (aes_key_irq_occurred != 0){ fail++; - printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); } - if (aes_ip_irq_occurred != 7){ fail++; - printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); } - if (aes_op_irq_occurred != 0){ fail++; - printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); } - if (aes_err_irq_occurred != 0){ fail++; - printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); } - - NVIC_DisableIRQ(DMA_IRQn); - NVIC_DisableIRQ(EXP0_IRQn); - NVIC_DisableIRQ(EXP1_IRQn); - NVIC_DisableIRQ(EXP2_IRQn); - NVIC_DisableIRQ(EXP3_IRQn); - - printf ("Data retrieved from the AES is: %s\n", id_string); - printf ("Data expected from the AES is: %s\n", rx_char); - if (fail >0) - printf("** AES TESTS FAILED (%d) **\n", fail); - else - printf("** AES TEST PASSED **\n"); - // End simulation - - - UartEndSimulation(); - - return 0; + unsigned char * p; + // Exception Handler Variables + temp_data=0; + hardfault_occurred = 0; + hardfault_expected = 0; + if (pl230_dma_detect()!=0) { + return 0; /* Quit test if DMA is not present */ + } + + UartStdOutInit(); + printf("%s\n",rx_char); + printf("AES128 test program\n"); + printf(" AES128 ID: "); + // iterate over 3 32-bit fields + p = (unsigned char *)AES128->CORE_NAME; + for (i = 0; i < 12; i++) { + id_string[i^3]=*p; // fix byte ordering per word + p+=1; + } + id_string[12] = 0; + printf("%s\n",id_string); + + aes_key_irq_occurred = 0; + aes_key_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP0_IRQn); + NVIC_EnableIRQ(EXP0_IRQn); + aes_ip_irq_occurred = 0; + aes_ip_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP1_IRQn); + NVIC_EnableIRQ(EXP1_IRQn); + aes_op_irq_occurred = 0; + aes_op_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP2_IRQn); + NVIC_EnableIRQ(EXP2_IRQn); + aes_err_irq_occurred = 0; + aes_err_irq_expected = 1; + NVIC_ClearPendingIRQ(EXP3_IRQn); + NVIC_EnableIRQ(EXP3_IRQn); + + printf("AES128 SW (memcpy) tests...\n"); + printf(" AES128 reference pattern test\n"); + + printf(" AES128 input/output bypass test\n"); + aes128_bypass_memcpy(test_key128, sizeof(test_text128), test_text128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); + + if (aes_key_irq_occurred != 1){ fail++; + printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); } + if (aes_ip_irq_occurred != 2){ fail++; + printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); } + if (aes_op_irq_occurred != 1){ fail++; + printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); } + if (aes_err_irq_occurred != 0){ fail++; + printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); } + + printf(" AES128 encrypt test\n"); + aes128_encrypt_memcpy(test_key128, sizeof(test_text128), test_text128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_exp128); + + printf(" AES128 decrypt test\n"); + aes128_decrypt_memcpy(test_key128, sizeof(buf128), buf128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); + + aes_key_irq_occurred = 0; + aes_ip_irq_occurred = 0; + aes_op_irq_occurred = 0; + aes_err_irq_occurred = 0; + + printf(" AES128 logic toggle test\n"); + printf(" AES128 input/output pattern test\n"); + aes128_bypass_memcpy(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); + fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf1, shift_patt); + + if (aes_key_irq_occurred != 1){ fail++; + printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); } + if (aes_ip_irq_occurred != (129+1)){ fail++; + printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); } + if (aes_op_irq_occurred != 129){ fail++; + printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); } + if (aes_err_irq_occurred != 0){ fail++; + printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); } + + printf(" AES128 pattern encrypt test\n"); + aes128_encrypt_memcpy(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); + printf(" AES128 pattern decrypt test\n"); + aes128_decrypt_memcpy(test_key128, sizeof(shift_patt), shift_buf1, shift_buf2); + fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf2, shift_patt); + + printf("AES128 DMA tests...\n"); + + aes_key_irq_occurred = 0; + aes_ip_irq_occurred = 0; + aes_op_irq_occurred = 0; + aes_err_irq_occurred = 0; + dma_error_irq_expected = 0; + dma_error_irq_occurred = 0; + dma_done_irq_expected = 1; + dma_done_irq_occurred = 0; + NVIC_ClearPendingIRQ(DMA_IRQn); + NVIC_EnableIRQ(DMA_IRQn); + + printf(" AES128 dma input/output bypass test\n"); + aes128_bypass_dma(test_key128, sizeof(test_text128), test_text128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); + + if (dma_done_irq_occurred < 2){ + puts ("ERROR: DMA err IRQ missing"); + fail++; + } else + printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred); + + printf(" AES128 dma encrypt test\n"); + aes128_encrypt_dma(test_key128, sizeof(test_text128), test_text128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_exp128); + + printf(" AES128 dma decrypt test\n"); + aes128_decrypt_dma(test_key128, sizeof(buf128), buf128, buf128); + fail += aes128_buffer_verify(AES_BLOCK_SIZE, buf128, test_text128); + + if (dma_done_irq_occurred < 6){ + puts ("ERROR: DMA err IRQ missing"); + fail++; + } else + printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred); + + printf(" AES128 dma unaligned pattern test\n"); + aes128_bypass_dma(test_key128,(16*63), shift_patt, shift_buf1+3); + fail += aes128_buffer_verify((16*63), shift_buf1+3, shift_patt); + + printf(" AES128 dma input/output pattern test\n"); + aes128_bypass_dma(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); + fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf1, shift_patt); + printf(" AES128 dma pattern encrypt test\n"); + aes128_encrypt_dma(test_key128, sizeof(shift_patt), shift_patt, shift_buf1); + printf(" AES128 dma pattern decrypt test\n"); + aes128_decrypt_dma(test_key128, sizeof(shift_patt), shift_buf1, shift_buf2); + fail += aes128_buffer_verify(sizeof(shift_patt), shift_buf2, shift_patt); + + if (dma_done_irq_occurred < (2*7)){ + puts ("ERROR: DMA err IRQ missing"); + fail++; + } else + printf(" ++ DMA_DONE IRQ count = %d\n", dma_done_irq_occurred); + + // check IRQ masked by DRQs - except when Iinput buffer empty after DMA done + if (aes_key_irq_occurred != 0){ fail++; + printf(" ++ AES key request IRQ count = %d\n", aes_key_irq_occurred); } + if (aes_ip_irq_occurred != 7){ fail++; + printf(" ++ AES inp request missing: IRQ count = %d\n", aes_ip_irq_occurred); } + if (aes_op_irq_occurred != 0){ fail++; + printf(" ++ AES out request missing: IRQ count = %d\n", aes_op_irq_occurred); } + if (aes_err_irq_occurred != 0){ fail++; + printf(" ++ AES err request missing: IRQ count = %d\n", aes_err_irq_occurred); } + + NVIC_DisableIRQ(DMA_IRQn); + NVIC_DisableIRQ(EXP0_IRQn); + NVIC_DisableIRQ(EXP1_IRQn); + NVIC_DisableIRQ(EXP2_IRQn); + NVIC_DisableIRQ(EXP3_IRQn); + + printf ("Data retrieved from the AES is: %s\n", id_string); + printf ("Data expected from the AES is: %s\n", rx_char); + if (fail >0) + printf("** AES TESTS FAILED (%d) **\n", fail); + else + printf("** AES TEST PASSED **\n"); + // End simulation + + + UartEndSimulation(); + + return 0; } @@ -686,3 +759,85 @@ void EXP3_Handler(void) } } +/* Test function for read */ +#if defined ( __CC_ARM ) +/* Test function for read - for ARM / Keil */ +__asm unsigned int address_test_read(unsigned int addr) +{ + LDR R1,[R0] + DSB ; Ensure bus fault occurred before leaving this subroutine + MOVS R0, R1 + BX LR +} +#else +/* Test function for read - for gcc */ +unsigned int address_test_read(unsigned int addr) __attribute__((naked)); +unsigned int address_test_read(unsigned int addr) +{ + __asm(" ldr r1,[r0]\n" + " dsb \n" + " movs r0, r1 \n" + " bx lr \n" + ); +} +#endif + +#if defined ( __CC_ARM ) +/* ARM or Keil toolchain */ +__asm void HardFault_Handler(void) +{ + MOVS r0, #4 + MOV r1, LR + TST r0, r1 + BEQ stacking_used_MSP + MRS R0, PSP ; // first parameter - stacking was using PSP + B get_LR_and_branch +stacking_used_MSP + MRS R0, MSP ; // first parameter - stacking was using MSP +get_LR_and_branch + MOV R1, LR ; // second parameter is LR current value + LDR R2,=__cpp(HardFault_Handler_c) + BX R2 + ALIGN +} +#else +/* gcc toolchain */ +void HardFault_Handler(void) __attribute__((naked)); +void HardFault_Handler(void) +{ + __asm(" movs r0,#4\n" + " mov r1,lr\n" + " tst r0,r1\n" + " beq stacking_used_MSP\n" + " mrs r0,psp\n" /* first parameter - stacking was using PSP */ + " ldr r1,=HardFault_Handler_c \n" + " bx r1\n" + "stacking_used_MSP:\n" + " mrs r0,msp\n" /* first parameter - stacking was using PSP */ + " ldr r1,=HardFault_Handler_c \n" + " bx r1\n" + ".pool\n" ); +} + +#endif +/* C part of the fault handler - common between ARM / Keil /gcc */ +void HardFault_Handler_c(unsigned int * hardfault_args, unsigned lr_value) +{ + unsigned int stacked_pc; + unsigned int stacked_r0; + hardfault_occurred++; + puts ("[Hard Fault Handler]"); + if (hardfault_expected==0) { + puts ("ERROR : Unexpected HardFault interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } + stacked_r0 = ((unsigned long) hardfault_args[0]); + stacked_pc = ((unsigned long) hardfault_args[6]); + printf(" - Stacked R0 : 0x%x\n", stacked_r0); + printf(" - Stacked PC : 0x%x\n", stacked_pc); + /* Modify R0 to a valid address */ + hardfault_args[0] = (unsigned long) &temp_data; + + return; +} \ No newline at end of file