feat(cache): support esp_cache_msync for instructions

This commit is contained in:
Armando
2023-09-14 19:55:24 +08:00
parent 900aebd158
commit 0a1503897c
2 changed files with 22 additions and 4 deletions

View File

@@ -37,7 +37,8 @@ esp_err_t esp_cache_msync(void *addr, size_t size, int flags)
ESP_RETURN_ON_FALSE_ISR(!ovf, ESP_ERR_INVALID_ARG, TAG, "wrong size, total size overflow");
bool both_dir = (flags & ESP_CACHE_MSYNC_FLAG_DIR_C2M) && (flags & ESP_CACHE_MSYNC_FLAG_DIR_M2C);
ESP_RETURN_ON_FALSE_ISR(!both_dir, ESP_ERR_INVALID_ARG, TAG, "both C2M and M2C directions are selected, you should only select one");
bool both_type = (flags & ESP_CACHE_MSYNC_FLAG_TYPE_DATA) && (flags & ESP_CACHE_MSYNC_FLAG_TYPE_INST);
ESP_RETURN_ON_FALSE_ISR(!both_dir && !both_type, ESP_ERR_INVALID_ARG, TAG, "both C2M and M2C directions, or both data and instruction type are selected, you should only select one direction or one type");
uint32_t vaddr = (uint32_t)addr;
bool valid = false;
@@ -46,10 +47,14 @@ esp_err_t esp_cache_msync(void *addr, size_t size, int flags)
valid = cache_hal_vaddr_to_cache_level_id(vaddr, size, &cache_level, &cache_id);
ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_ARG, TAG, "invalid addr or null pointer");
uint32_t data_cache_line_size = cache_hal_get_cache_line_size(CACHE_TYPE_DATA, cache_level);
cache_type_t cache_type = CACHE_TYPE_DATA;
if (flags & ESP_CACHE_MSYNC_FLAG_TYPE_INST) {
cache_type = CACHE_TYPE_INSTRUCTION;
}
uint32_t cache_line_size = cache_hal_get_cache_line_size(cache_type, cache_level);
if ((flags & ESP_CACHE_MSYNC_FLAG_UNALIGNED) == 0) {
bool aligned_addr = (((uint32_t)addr % data_cache_line_size) == 0) && ((size % data_cache_line_size) == 0);
ESP_RETURN_ON_FALSE_ISR(aligned_addr, ESP_ERR_INVALID_ARG, TAG, "start address: 0x%x, or the size: 0x%x is(are) not aligned with the data cache line size (0x%x)B", (uint32_t)addr, size, data_cache_line_size);
bool aligned_addr = (((uint32_t)addr % cache_line_size) == 0) && ((size % cache_line_size) == 0);
ESP_RETURN_ON_FALSE_ISR(aligned_addr, ESP_ERR_INVALID_ARG, TAG, "start address: 0x%x, or the size: 0x%x is(are) not aligned with cache line size (0x%x)B", (uint32_t)addr, size, cache_line_size);
}
if (flags & ESP_CACHE_MSYNC_FLAG_DIR_M2C) {
@@ -62,6 +67,9 @@ esp_err_t esp_cache_msync(void *addr, size_t size, int flags)
assert(valid);
} else {
ESP_EARLY_LOGV(TAG, "C2M DIR");
if (flags & ESP_CACHE_MSYNC_FLAG_TYPE_INST) {
ESP_RETURN_ON_FALSE_ISR(false, ESP_ERR_INVALID_ARG, TAG, "C2M direction doesn't support instruction type");
}
#if SOC_CACHE_WRITEBACK_SUPPORTED

View File

@@ -36,6 +36,15 @@ extern "C" {
* @brief Cache msync direction: from memory to Cache
*/
#define ESP_CACHE_MSYNC_FLAG_DIR_M2C BIT(3)
/**
* @brief Cache msync type: data
* @note If you don't set type (ESP_CACHE_MSYNC_FLAG_TYPE_x flags), it is by default data type
*/
#define ESP_CACHE_MSYNC_FLAG_TYPE_DATA BIT(4)
/**
* @brief Cache msync type: instruction
*/
#define ESP_CACHE_MSYNC_FLAG_TYPE_INST BIT(5)
/**
* @brief Memory sync between Cache and storage memory
@@ -54,6 +63,7 @@ extern "C" {
* This API is cache-safe and thread-safe
*
* @note If you don't set direction (ESP_CACHE_MSYNC_FLAG_DIR_x flags), this API is by default C2M direction
* @note If you don't set type (ESP_CACHE_MSYNC_FLAG_TYPE_x flags), this API is by default doing msync for data
* @note You should not call this during any Flash operations (e.g. esp_flash APIs, nvs and some other APIs that are based on esp_flash APIs)
* @note If XIP_From_PSRAM is enabled (by enabling both CONFIG_SPIRAM_FETCH_INSTRUCTIONS and CONFIG_SPIRAM_RODATA), you can call this API during Flash operations
*