// Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include #include #include #include "soc/soc.h" #include "soc/soc_caps.h" #include "sdkconfig.h" #include "esp_attr.h" #ifdef __cplusplus extern "C" { #endif inline static bool IRAM_ATTR esp_ptr_dma_capable(const void *p) { return (intptr_t)p >= SOC_DMA_LOW && (intptr_t)p < SOC_DMA_HIGH; } inline static bool IRAM_ATTR esp_ptr_dma_ext_capable(const void *p) { #ifdef SOC_PSRAM_DMA_CAPABLE return (intptr_t)p >= SOC_DMA_EXT_LOW && (intptr_t)p < SOC_DMA_EXT_HIGH; #else return false; #endif } inline static bool IRAM_ATTR esp_ptr_word_aligned(const void *p) { return ((intptr_t)p) % 4 == 0; } inline static bool IRAM_ATTR esp_ptr_executable(const void *p) { intptr_t ip = (intptr_t) p; return (ip >= SOC_IROM_LOW && ip < SOC_IROM_HIGH) || (ip >= SOC_IRAM_LOW && ip < SOC_IRAM_HIGH) || (ip >= SOC_IROM_MASK_LOW && ip < SOC_IROM_MASK_HIGH) #if defined(SOC_CACHE_APP_LOW) && defined(CONFIG_FREERTOS_UNICORE) || (ip >= SOC_CACHE_APP_LOW && ip < SOC_CACHE_APP_HIGH) #endif || (ip >= SOC_RTC_IRAM_LOW && ip < SOC_RTC_IRAM_HIGH); } inline static bool IRAM_ATTR esp_ptr_byte_accessible(const void *p) { intptr_t ip = (intptr_t) p; bool r; r = (ip >= SOC_BYTE_ACCESSIBLE_LOW && ip < SOC_BYTE_ACCESSIBLE_HIGH); #if CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP /* For ESP32 case, RTC fast memory is accessible to PRO cpu only and hence * for single core configuration (where it gets added to system heap) following * additional check is required */ r |= (ip >= SOC_RTC_DRAM_LOW && ip < SOC_RTC_DRAM_HIGH); #endif #if CONFIG_SPIRAM #if CONFIG_SPIRAM_SIZE != -1 // Fixed size, can be more accurate r |= (ip >= SOC_EXTRAM_DATA_LOW && ip < (SOC_EXTRAM_DATA_LOW + CONFIG_SPIRAM_SIZE)); #else r |= (ip >= SOC_EXTRAM_DATA_LOW && ip < (SOC_EXTRAM_DATA_HIGH)); #endif #endif return r; } inline static bool IRAM_ATTR esp_ptr_internal(const void *p) { bool r; r = ((intptr_t)p >= SOC_MEM_INTERNAL_LOW && (intptr_t)p < SOC_MEM_INTERNAL_HIGH); r |= ((intptr_t)p >= SOC_RTC_DATA_LOW && (intptr_t)p < SOC_RTC_DATA_HIGH); #if CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP /* For ESP32 case, RTC fast memory is accessible to PRO cpu only and hence * for single core configuration (where it gets added to system heap) following * additional check is required */ r |= ((intptr_t)p >= SOC_RTC_DRAM_LOW && (intptr_t)p < SOC_RTC_DRAM_HIGH); #endif return r; } inline static bool IRAM_ATTR esp_ptr_external_ram(const void *p) { #if SOC_SPIRAM_SUPPORTED return ((intptr_t)p >= SOC_EXTRAM_DATA_LOW && (intptr_t)p < SOC_EXTRAM_DATA_HIGH); #else return false; // SoC has no external RAM #endif } inline static bool IRAM_ATTR esp_ptr_in_iram(const void *p) { #if CONFIG_IDF_TARGET_ESP32 && CONFIG_FREERTOS_UNICORE return ((intptr_t)p >= SOC_CACHE_APP_LOW && (intptr_t)p < SOC_IRAM_HIGH); #else return ((intptr_t)p >= SOC_IRAM_LOW && (intptr_t)p < SOC_IRAM_HIGH); #endif } inline static bool IRAM_ATTR esp_ptr_in_drom(const void *p) { return ((intptr_t)p >= SOC_DROM_LOW && (intptr_t)p < SOC_DROM_HIGH); } inline static bool IRAM_ATTR esp_ptr_in_dram(const void *p) { return ((intptr_t)p >= SOC_DRAM_LOW && (intptr_t)p < SOC_DRAM_HIGH); } inline static bool IRAM_ATTR esp_ptr_in_diram_dram(const void *p) { return ((intptr_t)p >= SOC_DIRAM_DRAM_LOW && (intptr_t)p < SOC_DIRAM_DRAM_HIGH); } inline static bool IRAM_ATTR esp_ptr_in_diram_iram(const void *p) { return ((intptr_t)p >= SOC_DIRAM_IRAM_LOW && (intptr_t)p < SOC_DIRAM_IRAM_HIGH); } inline static bool IRAM_ATTR esp_ptr_in_rtc_iram_fast(const void *p) { return ((intptr_t)p >= SOC_RTC_IRAM_LOW && (intptr_t)p < SOC_RTC_IRAM_HIGH); } inline static bool IRAM_ATTR esp_ptr_in_rtc_dram_fast(const void *p) { return ((intptr_t)p >= SOC_RTC_DRAM_LOW && (intptr_t)p < SOC_RTC_DRAM_HIGH); } inline static bool IRAM_ATTR esp_ptr_in_rtc_slow(const void *p) { return ((intptr_t)p >= SOC_RTC_DATA_LOW && (intptr_t)p < SOC_RTC_DATA_HIGH); } /* Convert a D/IRAM DRAM pointer to equivalent word address in IRAM - Address must be word aligned - Address must pass esp_ptr_in_diram_dram() test, or result will be invalid pointer */ inline static void * IRAM_ATTR esp_ptr_diram_dram_to_iram(const void *p) { #if SOC_DIRAM_INVERTED return (void *) ( SOC_DIRAM_IRAM_LOW + (SOC_DIRAM_DRAM_HIGH - (intptr_t)p) - 4); #else return (void *) ( SOC_DIRAM_IRAM_LOW + ((intptr_t)p - SOC_DIRAM_DRAM_LOW) ); #endif } /* Convert a D/IRAM IRAM pointer to equivalent word address in DRAM - Address must be word aligned - Address must pass esp_ptr_in_diram_iram() test, or result will be invalid pointer */ inline static void * IRAM_ATTR esp_ptr_diram_iram_to_dram(const void *p) { #if SOC_DIRAM_INVERTED return (void *) ( SOC_DIRAM_DRAM_LOW + (SOC_DIRAM_IRAM_HIGH - (intptr_t)p) - 4); #else return (void *) ( SOC_DIRAM_DRAM_LOW + ((intptr_t)p - SOC_DIRAM_IRAM_LOW) ); #endif } inline static bool IRAM_ATTR esp_stack_ptr_in_dram(uint32_t sp) { //Check if stack ptr is in between SOC_DRAM_LOW and SOC_DRAM_HIGH, and 16 byte aligned. return !(sp < SOC_DRAM_LOW + 0x10 || sp > SOC_DRAM_HIGH - 0x10 || ((sp & 0xF) != 0)); } #if CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY inline static bool IRAM_ATTR esp_stack_ptr_in_extram(uint32_t sp) { //Check if stack ptr is in between SOC_EXTRAM_DATA_LOW and SOC_EXTRAM_DATA_HIGH, and 16 byte aligned. return !(sp < SOC_EXTRAM_DATA_LOW + 0x10 || sp > SOC_EXTRAM_DATA_HIGH - 0x10 || ((sp & 0xF) != 0)); } #endif inline static bool IRAM_ATTR esp_stack_ptr_is_sane(uint32_t sp) { return esp_stack_ptr_in_dram(sp) #if CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY || esp_stack_ptr_in_extram(sp) #endif #if CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP || esp_ptr_in_rtc_dram_fast((void*) sp) #endif ; } #ifdef __cplusplus } #endif