From 384e12708569ec92a1229c44fa09eb5ddd32a728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Thu, 20 May 2021 23:55:32 +0200 Subject: [PATCH] Add first draft of memory checking for CCM RAM --- stm-firmware/boot/startup-tests.c | 64 +++++++++++++++++++++++++ stm-firmware/boot/startup-tests.h | 18 +++++++ stm-firmware/boot/startup_stm32f407vx.c | 5 ++ 3 files changed, 87 insertions(+) create mode 100644 stm-firmware/boot/startup-tests.c create mode 100644 stm-firmware/boot/startup-tests.h diff --git a/stm-firmware/boot/startup-tests.c b/stm-firmware/boot/startup-tests.c new file mode 100644 index 0000000..6eacdd8 --- /dev/null +++ b/stm-firmware/boot/startup-tests.c @@ -0,0 +1,64 @@ +#include "startup-tests.h" + +uint32_t startup_test_perform_ccm_ram_check(void) +{ + const void *ccmram_base = (void *)0x10000000UL; + const uint32_t ccmram_size = 64U * 1024UL; + volatile uint32_t *word_ptr; + uint32_t target_val; + uint32_t idx; + uint32_t ret = 0UL; + + + /* Perform inversion test with 0x55 and 0xAA, Part 1 */ + for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) { + word_ptr[idx] = idx & 1 ? 0x55AA55AAUL : 0xAA55AA55UL; + } + for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) { + target_val = idx & 1 ? 0x55AA55AAUL : 0xAA55AA55UL; + if (target_val != word_ptr[idx]) { + ret = (uint32_t)&word_ptr[idx]; + goto exit_ret_address; + } + } + + /* Perform inversion test with 0x55 and 0xAA, Part 2 */ + for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) { + word_ptr[idx] = idx & 1 ? 0xAA55AA55UL : 0x55AA55AAUL; + } + for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) { + target_val = idx & 1 ? 0x55AA55AAUL : 0xAA55AA55UL; + if (target_val != word_ptr[idx]) { + ret = (uint32_t)&word_ptr[idx]; + goto exit_ret_address; + } + } + + /* Perform static test with 0xFF */ + for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) { + word_ptr[idx] = 0xFFFFFFFFUL; + } + for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) { + target_val = 0xFFFFFFFFUL; + if (target_val != word_ptr[idx]) { + ret = (uint32_t)&word_ptr[idx]; + goto exit_ret_address; + } + } + + /* Perform static test with 0x00 */ + for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) { + word_ptr[idx] = 0x0UL; + } + for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) { + target_val = 0x0UL; + if (target_val != word_ptr[idx]) { + ret = (uint32_t)&word_ptr[idx]; + goto exit_ret_address; + } + } + + +exit_ret_address: + return ret; +} diff --git a/stm-firmware/boot/startup-tests.h b/stm-firmware/boot/startup-tests.h new file mode 100644 index 0000000..90ebdb9 --- /dev/null +++ b/stm-firmware/boot/startup-tests.h @@ -0,0 +1,18 @@ +#ifndef _STARTUP_TESTS_H_ +#define _STARTUP_TESTS_H_ + +#include + +/** + * @brief Do a RAM check of the CCM RAM. + * + * Loop over the whole CCM memory area and check it. + * + * @return 0 if successful. Else the defect address is returned. + * @warning This will completely corrupt this memory! + * You have to ensure to set it to sane values afterwards! + */ +uint32_t startup_test_perform_ccm_ram_check(void); + + +#endif /* _STARTUP_TESTS_H_ */ diff --git a/stm-firmware/boot/startup_stm32f407vx.c b/stm-firmware/boot/startup_stm32f407vx.c index c6fb891..d159ff5 100644 --- a/stm-firmware/boot/startup_stm32f407vx.c +++ b/stm-firmware/boot/startup_stm32f407vx.c @@ -19,6 +19,7 @@ */ #include +#include "startup-tests.h" /* C++ library init */ # if defined(__cplusplus) @@ -297,6 +298,10 @@ void Reset_Handler(void) { */ CPACR |= (0xF << 20); + if (startup_test_perform_ccm_ram_check()) { + /* Hang forever in case of an error. We cannot handle this (yet?) */ + while (1); + } /* Copy .data section */ __init_section(&__ld_load_data, &__ld_sdata, &__ld_edata);