Use memory fence when disabling cache to avoid -O2 problems
This commit is contained in:
parent
a930756c26
commit
cc92ce4820
@ -1 +1 @@
|
||||
Subproject commit 57133eefeb077f73b5ac17ee044d9feaf566da8e
|
||||
Subproject commit baca4c084334aa8625f525a4032d66a397199ea6
|
@ -29,8 +29,18 @@
|
||||
|
||||
// Turn off cache and invalidate all data in it.
|
||||
void nrf_peripherals_disable_and_clear_cache(void) {
|
||||
// Memory fence for hardware and compiler reasons. If this routine is inlined, the compiler
|
||||
// needs to know that everything written out be stored before this is called.
|
||||
// -O2 optimization needed this on SAMD51. Assuming nRF may have the same issue.
|
||||
// __sync_synchronize() includes volatile asm(), which tells the compiler not to assume
|
||||
// state across this call.
|
||||
__sync_synchronize();
|
||||
|
||||
// Disabling cache also invalidates all cache entries.
|
||||
NRF_NVMC->ICACHECNF &= ~(1 << NVMC_ICACHECNF_CACHEEN_Pos);
|
||||
|
||||
// Memory fence for hardware and compiler reasons.
|
||||
__sync_synchronize();
|
||||
}
|
||||
|
||||
// Enable cache
|
||||
|
@ -58,6 +58,9 @@ static supervisor_allocation *supervisor_cache = NULL;
|
||||
|
||||
// Wait until both the write enable and write in progress bits have cleared.
|
||||
static bool wait_for_flash_ready(void) {
|
||||
if (flash_device == NULL) {
|
||||
return false;
|
||||
}
|
||||
bool ok = true;
|
||||
// Both the write enable and write in progress bits should be low.
|
||||
if (flash_device->no_ready_bit) {
|
||||
@ -192,6 +195,9 @@ static bool copy_block(uint32_t src_address, uint32_t dest_address) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#define READ_JEDEC_ID_RETRY_COUNT (100)
|
||||
|
||||
// If this fails, flash_device will remain NULL.
|
||||
void supervisor_flash_init(void) {
|
||||
if (flash_device != NULL) {
|
||||
return;
|
||||
@ -220,7 +226,11 @@ void supervisor_flash_init(void) {
|
||||
#else
|
||||
// The response will be 0xff if the flash needs more time to start up.
|
||||
uint8_t jedec_id_response[3] = {0xff, 0xff, 0xff};
|
||||
while (jedec_id_response[0] == 0xff) {
|
||||
// Response can also be 0x00 if reading before ready. When compiled with `-O2`, typically
|
||||
// takes three tries to read on Grand Central M4.
|
||||
|
||||
size_t count = READ_JEDEC_ID_RETRY_COUNT;
|
||||
while ((count-- > 0) && (jedec_id_response[0] == 0xff || jedec_id_response[2] == 0x00)) {
|
||||
spi_flash_read_command(CMD_READ_JEDEC_ID, jedec_id_response, 3);
|
||||
}
|
||||
for (uint8_t i = 0; i < EXTERNAL_FLASH_DEVICE_COUNT; i++) {
|
||||
@ -234,6 +244,7 @@ void supervisor_flash_init(void) {
|
||||
}
|
||||
#endif
|
||||
if (flash_device == NULL) {
|
||||
// Flash did not respond. Give up.
|
||||
return;
|
||||
}
|
||||
|
||||
@ -293,6 +304,9 @@ uint32_t supervisor_flash_get_block_size(void) {
|
||||
|
||||
// The total number of available blocks.
|
||||
uint32_t supervisor_flash_get_block_count(void) {
|
||||
if (flash_device == NULL) {
|
||||
return 0;
|
||||
}
|
||||
// We subtract one erase sector size because we may use it as a staging area
|
||||
// for writes.
|
||||
return (flash_device->total_size - SPI_FLASH_ERASE_SIZE) / FILESYSTEM_BLOCK_SIZE;
|
||||
|
Loading…
Reference in New Issue
Block a user