Skip to content
This repository has been archived by the owner on Jan 22, 2022. It is now read-only.

Commit

Permalink
Cache invalidates and flushes on SAME70 now abort
Browse files Browse the repository at this point in the history
  • Loading branch information
dc42 committed Dec 24, 2020
1 parent 3647d1b commit 148bc8a
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 57 deletions.
18 changes: 8 additions & 10 deletions cores/arduino/Cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,15 +242,16 @@ bool Cache::Disable() noexcept

#if SAME70

extern "C" [[noreturn]] void vAssertCalled(uint32_t line, const char *file) noexcept;

void Cache::Flush(const volatile void *start, size_t length) noexcept
{
if ((SCB->CCR & SCB_CCR_DC_Msk) != 0) // if data cache is enabled
{
// We assume that the DMA buffer is entirely inside or entirely outside the non-cached RAM area
if (start < (void*)&_nocache_ram_start || start >= (void*)&_nocache_ram_end)
// The DMA buffer should be entirely inside the non-cached RAM area
if ((const char *)start < (const char *)&_nocache_ram_start || (const char *)start + length >= (const char *)&_nocache_ram_end)
{
const uint32_t startAddr = reinterpret_cast<uint32_t>(start);
SCB_CleanDCache_by_Addr(reinterpret_cast<uint32_t*>(startAddr & ~3), length + (startAddr & 3));
vAssertCalled(__LINE__, __FILE__);
}
}
}
Expand All @@ -262,13 +263,10 @@ void Cache::Invalidate(const volatile void *start, size_t length) noexcept
#if SAME70
if ((SCB->CCR & SCB_CCR_DC_Msk) != 0) // if data cache is enabled
{
// We assume that the DMA buffer is entirely inside or entirely outside the non-cached RAM area
if (start < (void*)&_nocache_ram_start || start >= (void*)&_nocache_ram_end)
// The DMA buffer should be entirely inside the non-cached RAM area
if ((const char *)start < (const char *)&_nocache_ram_start || (const char *)start + length >= (const char *)&_nocache_ram_end)
{
// Caution! if any part of the cache line is dirty, the written data will be lost!
//TODO make this an abort instead of trying to invalidate the cache
const uint32_t startAddr = reinterpret_cast<uint32_t>(start);
SCB_InvalidateDCache_by_Addr(reinterpret_cast<uint32_t*>(startAddr & ~3), length + (startAddr & 3));
vAssertCalled(__LINE__, __FILE__);
}
}
#else
Expand Down
39 changes: 19 additions & 20 deletions cores/arduino/Flash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,7 @@ extern "C" {
* \param pus_page The first page accessed.
* \param pus_offset Byte offset in the first page.
*/
static void translate_address(Efc **pp_efc, uint32_t ul_addr,
uint16_t *pus_page, uint16_t *pus_offset)
static void translate_address(Efc **pp_efc, uint32_t ul_addr, uint16_t *pus_page, uint16_t *pus_offset) noexcept
{
Efc *p_efc;
uint16_t us_page;
Expand Down Expand Up @@ -228,7 +227,7 @@ static void translate_address(Efc **pp_efc, uint32_t ul_addr,
* \param us_offset Byte offset inside page.
* \param pul_addr Computed address (optional).
*/
static void compute_address(Efc *p_efc, uint16_t us_page, uint16_t us_offset, uint32_t *pul_addr)
static void compute_address(Efc *p_efc, uint16_t us_page, uint16_t us_offset, uint32_t *pul_addr) noexcept
{
uint32_t ul_addr;

Expand Down Expand Up @@ -278,7 +277,7 @@ static void compute_address(Efc *p_efc, uint16_t us_page, uint16_t us_offset, ui
* \param pul_actual_start Actual start address of lock range.
* \param pul_actual_end Actual end address of lock range.
*/
static void compute_lock_range(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end)
static void compute_lock_range(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end) noexcept
{
uint32_t ul_actual_start, ul_actual_end;

Expand All @@ -303,7 +302,7 @@ static void compute_lock_range(uint32_t ul_start, uint32_t ul_end, uint32_t *pul
*
* \return 0 if successful; otherwise returns an error code.
*/
uint32_t flash_init(uint32_t ul_mode, uint32_t ul_fws)
uint32_t flash_init(uint32_t ul_mode, uint32_t ul_fws) noexcept
{
efc_init(EFC, ul_mode, ul_fws);

Expand All @@ -322,7 +321,7 @@ uint32_t flash_init(uint32_t ul_mode, uint32_t ul_fws)
*
* \return 0 if successful; otherwise returns an error code.
*/
uint32_t flash_set_wait_state(uint32_t ul_address, uint32_t ul_fws)
uint32_t flash_set_wait_state(uint32_t ul_address, uint32_t ul_fws) noexcept
{
Efc *p_efc;

Expand All @@ -341,7 +340,7 @@ uint32_t flash_set_wait_state(uint32_t ul_address, uint32_t ul_fws)
*
* \return The actual descriptor length.
*/
uint32_t flash_get_descriptor(uint32_t ul_address, uint32_t *pul_flash_descriptor, uint32_t ul_size)
uint32_t flash_get_descriptor(uint32_t ul_address, uint32_t *pul_flash_descriptor, uint32_t ul_size) noexcept
{
Efc *p_efc;
uint32_t ul_tmp;
Expand Down Expand Up @@ -377,7 +376,7 @@ uint32_t flash_get_descriptor(uint32_t ul_address, uint32_t *pul_flash_descripto
*
* \return The flash total page count.
*/
uint32_t flash_get_page_count(const uint32_t *pul_flash_descriptor)
uint32_t flash_get_page_count(const uint32_t *pul_flash_descriptor) noexcept
{
return (pul_flash_descriptor[1] / pul_flash_descriptor[2]);
}
Expand All @@ -392,7 +391,7 @@ uint32_t flash_get_page_count(const uint32_t *pul_flash_descriptor)
*
* \return The flash page count per region (plane).
*/
uint32_t flash_get_page_count_per_region(const uint32_t *pul_flash_descriptor)
uint32_t flash_get_page_count_per_region(const uint32_t *pul_flash_descriptor) noexcept
{
return (pul_flash_descriptor[4] / pul_flash_descriptor[2]);
}
Expand All @@ -407,7 +406,7 @@ uint32_t flash_get_page_count_per_region(const uint32_t *pul_flash_descriptor)
*
* \return The flash region (plane) count.
*/
uint32_t flash_get_region_count(const uint32_t *pul_flash_descriptor)
uint32_t flash_get_region_count(const uint32_t *pul_flash_descriptor) noexcept
{
return (pul_flash_descriptor[3]);
}
Expand All @@ -423,7 +422,7 @@ uint32_t flash_get_region_count(const uint32_t *pul_flash_descriptor)
*
* \return 0 if successful; otherwise returns an error code.
*/
uint32_t flash_erase_all(uint32_t ul_address)
uint32_t flash_erase_all(uint32_t ul_address) noexcept
{
Efc *p_efc;

Expand All @@ -444,7 +443,7 @@ uint32_t flash_erase_all(uint32_t ul_address)
*
* \return 0 if successful; otherwise returns an error code.
*/
uint32_t flash_erase_page(uint32_t ul_address, uint8_t uc_page_num)
uint32_t flash_erase_page(uint32_t ul_address, uint8_t uc_page_num) noexcept
{
Efc *p_efc;
uint16_t us_page;
Expand Down Expand Up @@ -477,7 +476,7 @@ uint32_t flash_erase_page(uint32_t ul_address, uint8_t uc_page_num)
*
* \return 0 if successful; otherwise returns an error code.
*/
uint32_t flash_erase_sector(uint32_t ul_address)
uint32_t flash_erase_sector(uint32_t ul_address) noexcept
{
Efc *p_efc;
uint16_t us_page;
Expand Down Expand Up @@ -508,7 +507,7 @@ uint32_t flash_erase_sector(uint32_t ul_address)
*
* \return 0 if successful, otherwise returns an error code.
*/
uint32_t flash_write(uint32_t ul_address, const void *p_buffer, uint32_t ul_size, uint32_t ul_erase_flag)
uint32_t flash_write(uint32_t ul_address, const void *p_buffer, uint32_t ul_size, uint32_t ul_erase_flag) noexcept
{
Efc *p_efc;
uint32_t ul_fws_temp;
Expand Down Expand Up @@ -603,7 +602,7 @@ uint32_t flash_write(uint32_t ul_address, const void *p_buffer, uint32_t ul_size
*
* \return 0 if successful, otherwise returns an error code.
*/
uint32_t flash_lock(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end)
uint32_t flash_lock(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end) noexcept
{
Efc *p_efc;
uint32_t ul_actual_start, ul_actual_end;
Expand Down Expand Up @@ -651,7 +650,7 @@ uint32_t flash_lock(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_sta
*
* \return 0 if successful, otherwise returns an error code.
*/
uint32_t flash_unlock(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end)
uint32_t flash_unlock(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end) noexcept
{
Efc *p_efc;
uint32_t ul_actual_start, ul_actual_end;
Expand Down Expand Up @@ -694,7 +693,7 @@ uint32_t flash_unlock(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_s
*
* \return The number of locked regions inside the given address range.
*/
uint32_t flash_is_locked(uint32_t ul_start, uint32_t ul_end)
uint32_t flash_is_locked(uint32_t ul_start, uint32_t ul_end) noexcept
{
Efc *p_efc;
uint16_t us_start_page, us_end_page;
Expand Down Expand Up @@ -771,7 +770,7 @@ uint32_t flash_is_locked(uint32_t ul_start, uint32_t ul_end)
*
* \return 0 if successful; otherwise returns an error code.
*/
uint32_t flash_set_gpnvm(uint32_t ul_gpnvm)
uint32_t flash_set_gpnvm(uint32_t ul_gpnvm) noexcept
{
if (ul_gpnvm >= GPNVM_NUM_MAX) {
return FLASH_RC_INVALID;
Expand All @@ -795,7 +794,7 @@ uint32_t flash_set_gpnvm(uint32_t ul_gpnvm)
*
* \return 0 if successful; otherwise returns an error code.
*/
uint32_t flash_clear_gpnvm(uint32_t ul_gpnvm)
uint32_t flash_clear_gpnvm(uint32_t ul_gpnvm) noexcept
{
if (ul_gpnvm >= GPNVM_NUM_MAX) {
return FLASH_RC_INVALID;
Expand Down Expand Up @@ -832,7 +831,7 @@ uint32_t flash_read_gpnvm_bits() noexcept
* \retval 0 If the given GPNVM bit is currently cleared.
* otherwise returns an error code.
*/
uint32_t flash_is_gpnvm_set(uint32_t ul_gpnvm)
uint32_t flash_is_gpnvm_set(uint32_t ul_gpnvm) noexcept
{
uint32_t ul_gpnvm_bits;

Expand Down
32 changes: 16 additions & 16 deletions cores/arduino/Flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,26 +94,26 @@ typedef enum flash_farg_page_num {
#define FLASH_ACCESS_MODE_64 EFC_ACCESS_MODE_64
//! @}

uint32_t flash_init(uint32_t ul_mode, uint32_t ul_fws);
uint32_t flash_set_wait_state(uint32_t ul_address, uint32_t ul_fws);
uint32_t flash_get_descriptor(uint32_t ul_address, uint32_t *pul_flash_descriptor, uint32_t ul_size);
uint32_t flash_get_page_count(const uint32_t *pul_flash_descriptor);
uint32_t flash_get_page_count_per_region(const uint32_t *pul_flash_descriptor);
uint32_t flash_get_region_count(const uint32_t *pul_flash_descriptor);
uint32_t flash_erase_all(uint32_t ul_address);
uint32_t flash_init(uint32_t ul_mode, uint32_t ul_fws) noexcept;
uint32_t flash_set_wait_state(uint32_t ul_address, uint32_t ul_fws) noexcept;
uint32_t flash_get_descriptor(uint32_t ul_address, uint32_t *pul_flash_descriptor, uint32_t ul_size) noexcept;
uint32_t flash_get_page_count(const uint32_t *pul_flash_descriptor) noexcept;
uint32_t flash_get_page_count_per_region(const uint32_t *pul_flash_descriptor) noexcept;
uint32_t flash_get_region_count(const uint32_t *pul_flash_descriptor) noexcept;
uint32_t flash_erase_all(uint32_t ul_address) noexcept;

#if (SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAMS70 || SAME70)
uint32_t flash_erase_page(uint32_t ul_address, uint8_t uc_page_num);
uint32_t flash_erase_sector(uint32_t ul_address);
uint32_t flash_erase_page(uint32_t ul_address, uint8_t uc_page_num) noexcept;
uint32_t flash_erase_sector(uint32_t ul_address) noexcept;
#endif

uint32_t flash_write(uint32_t ul_address, const void *p_buffer, uint32_t ul_size, uint32_t ul_erase_flag);
uint32_t flash_lock(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end);
uint32_t flash_unlock(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end);
uint32_t flash_is_locked(uint32_t ul_start, uint32_t ul_end);
uint32_t flash_set_gpnvm(uint32_t ul_gpnvm);
uint32_t flash_clear_gpnvm(uint32_t ul_gpnvm);
uint32_t flash_is_gpnvm_set(uint32_t ul_gpnvm);
uint32_t flash_write(uint32_t ul_address, const void *p_buffer, uint32_t ul_size, uint32_t ul_erase_flag) noexcept;
uint32_t flash_lock(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end) noexcept;
uint32_t flash_unlock(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end) noexcept;
uint32_t flash_is_locked(uint32_t ul_start, uint32_t ul_end) noexcept;
uint32_t flash_set_gpnvm(uint32_t ul_gpnvm) noexcept;
uint32_t flash_clear_gpnvm(uint32_t ul_gpnvm) noexcept;
uint32_t flash_is_gpnvm_set(uint32_t ul_gpnvm) noexcept;
uint32_t flash_read_gpnvm_bits() noexcept;
uint32_t flash_read_unique_id(uint32_t *pul_data) noexcept; // read 4 dwords of unique ID

Expand Down
23 changes: 12 additions & 11 deletions variants/same70/startup_same70.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ const DeviceVectors exception_table = {
.pfnRSWDT_Handler = (void*) RSWDT_Handler /* 63 Reinforced Secure Watchdog Timer */
};

// This must be marked noinline so that R0 is loaded with the required value for SP
// This must be marked noinline so that R0 is loaded with the required value for SP. Return is via LR so it's OK to return with a different SP.
__attribute((noinline)) void SetStackPointer(uint32_t *topOfStack)
{
__asm volatile("msr msp, r0");
Expand All @@ -329,7 +329,7 @@ __attribute((noinline)) void SetStackPointer(uint32_t *topOfStack)
* \brief This is the code that gets called on processor reset.
* To initialize the device, and call the main() routine.
*/
__attribute__((noreturn)) void Reset_Handler(void)
__attribute__((noreturn, naked)) void Reset_Handler(void)
{
// If TCM is allocated then SP may point beyond the end of RAM, so move it
SetStackPointer(&_ezero_nocache);
Expand All @@ -348,6 +348,12 @@ __attribute__((noreturn)) void Reset_Handler(void)
}
}

/* Clear the zero segment */
for (uint32_t *pDest = &_szero; pDest < &_ezero;)
{
*pDest++ = 0;
}

// Check that no TCM is allocated before we relocate the stack to the top of memory. This uses a RAMFUNC, so we must initialise the relocate segment before here.
// The temporary stack we are on is in the non-cached memory segment, so don't clear that segment until after we have relocated the stack.
if (flash_read_gpnvm_bits() & ((1ul << 7) | (1ul << 8)))
Expand All @@ -372,13 +378,7 @@ __attribute__((noreturn)) void Reset_Handler(void)
*pDest++ = 0;
}

/* Clear the zero segment */
for (uint32_t *pDest = &_szero; pDest < &_ezero;)
{
*pDest++ = 0;
}

/* Set the vector table base address */
// Set the vector table base address
const uint32_t * const pSrc = (uint32_t *) & _sfixed;
SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk);

Expand All @@ -401,6 +401,7 @@ __attribute__((noreturn)) void Reset_Handler(void)
*/
void Dummy_Handler(void)
{
while (1) {
}
while (1) { }
}

// End

0 comments on commit 148bc8a

Please sign in to comment.