1 /*
2  * SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 #include <stdlib.h>
9 #include <stdint.h>
10 #include <stdbool.h>
11 
12 #include "soc/soc.h"
13 #include "soc/soc_caps.h"
14 #include "sdkconfig.h"
15 #include "esp_attr.h"
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
21 /** The content of this file is to be kept in sync with the common section of esp_memory_utils.h **/
22 
23 /**
24  * @brief Check if the IRAM and DRAM are separate or using the same memory space
25  *
26  * @return true if the DRAM and IRAM are sharing the same memory space, false otherwise
27  */
28 __attribute__((always_inline))
esp_dram_match_iram(void)29 inline static bool esp_dram_match_iram(void) {
30     return (SOC_DRAM_LOW == SOC_IRAM_LOW && SOC_DRAM_HIGH == SOC_IRAM_HIGH);
31 }
32 
33 /**
34  * @brief Check if the pointer is in iram
35  *
36  * @param p pointer
37  *
38  * @return true: is in iram; false: not in iram
39  */
40 __attribute__((always_inline))
esp_ptr_in_iram(const void * p)41 inline static bool esp_ptr_in_iram(const void *p) {
42 #if CONFIG_IDF_TARGET_ESP32 && CONFIG_FREERTOS_UNICORE
43     return ((intptr_t)p >= SOC_CACHE_APP_LOW && (intptr_t)p < SOC_IRAM_HIGH);
44 #else
45     return ((intptr_t)p >= SOC_IRAM_LOW && (intptr_t)p < SOC_IRAM_HIGH);
46 #endif
47 }
48 
49 /**
50  * @brief Check if the pointer is in dram
51  *
52  * @param p pointer
53  *
54  * @return true: is in dram; false: not in dram
55  */
56 __attribute__((always_inline))
esp_ptr_in_dram(const void * p)57 inline static bool esp_ptr_in_dram(const void *p) {
58     return ((intptr_t)p >= SOC_DRAM_LOW && (intptr_t)p < SOC_DRAM_HIGH);
59 }
60 
61 /**
62  * @brief Check if the pointer is in diram_dram
63  *
64  * @param p pointer
65  *
66  * @return true: is in diram_dram; false: not in diram_dram
67  */
68 __attribute__((always_inline))
esp_ptr_in_diram_dram(const void * p)69 inline static bool esp_ptr_in_diram_dram(const void *p) {
70     return ((intptr_t)p >= SOC_DIRAM_DRAM_LOW && (intptr_t)p < SOC_DIRAM_DRAM_HIGH);
71 }
72 
73 /**
74  * @brief Check if the pointer is in diram_iram
75  *
76  * @param p pointer
77  *
78  * @return true: is in diram_iram; false: not in diram_iram
79  */
80 __attribute__((always_inline))
esp_ptr_in_diram_iram(const void * p)81 inline static bool esp_ptr_in_diram_iram(const void *p) {
82 // TODO: IDF-5980 esp32c6 D/I RAM share the same address
83 #if SOC_DIRAM_IRAM_LOW == SOC_DIRAM_DRAM_LOW
84     return false;
85 #else
86     return ((intptr_t)p >= SOC_DIRAM_IRAM_LOW && (intptr_t)p < SOC_DIRAM_IRAM_HIGH);
87 #endif
88 }
89 
90 /**
91  * @brief Check if the pointer is in rtc_iram_fast
92  *
93  * @param p pointer
94  *
95  * @return true: is in rtc_iram_fast; false: not in rtc_iram_fast
96  */
97 __attribute__((always_inline))
esp_ptr_in_rtc_iram_fast(const void * p)98 inline static bool esp_ptr_in_rtc_iram_fast(const void *p) {
99 #if SOC_RTC_FAST_MEM_SUPPORTED
100     return ((intptr_t)p >= SOC_RTC_IRAM_LOW && (intptr_t)p < SOC_RTC_IRAM_HIGH);
101 #else
102     return false;
103 #endif
104 }
105 
106 /**
107  * @brief Check if the pointer is in rtc_dram_fast
108  *
109  * @param p pointer
110  *
111  * @return true: is in rtc_dram_fast; false: not in rtc_dram_fast
112  */
113 __attribute__((always_inline))
esp_ptr_in_rtc_dram_fast(const void * p)114 inline static bool esp_ptr_in_rtc_dram_fast(const void *p) {
115 #if SOC_RTC_FAST_MEM_SUPPORTED
116     return ((intptr_t)p >= SOC_RTC_DRAM_LOW && (intptr_t)p < SOC_RTC_DRAM_HIGH);
117 #else
118     return false;
119 #endif
120 }
121 
122 /**
123  * @brief Check if the pointer is in rtc_slow
124  *
125  * @param p pointer
126  *
127  * @return true: is in rtc_slow; false: not in rtc_slow
128  */
129 __attribute__((always_inline))
esp_ptr_in_rtc_slow(const void * p)130 inline static bool esp_ptr_in_rtc_slow(const void *p) {
131 #if SOC_RTC_SLOW_MEM_SUPPORTED
132     return ((intptr_t)p >= SOC_RTC_DATA_LOW && (intptr_t)p < SOC_RTC_DATA_HIGH);
133 #else
134     return false;
135 #endif
136 }
137 
138 
139 /* Convert a D/IRAM DRAM pointer to equivalent word address in IRAM
140 
141    - Address must be word aligned
142    - Address must pass esp_ptr_in_diram_dram() test, or result will be invalid pointer
143 */
144 __attribute__((always_inline))
esp_ptr_diram_dram_to_iram(const void * p)145 inline static void * esp_ptr_diram_dram_to_iram(const void *p) {
146 #if SOC_DIRAM_INVERTED
147     return (void *) ( SOC_DIRAM_IRAM_LOW + (SOC_DIRAM_DRAM_HIGH - (intptr_t)p) - 4);
148 #else
149     return (void *) ( SOC_DIRAM_IRAM_LOW + ((intptr_t)p - SOC_DIRAM_DRAM_LOW) );
150 #endif
151 }
152 
153 /* Convert a D/IRAM IRAM pointer to equivalent word address in DRAM
154 
155    - Address must be word aligned
156    - Address must pass esp_ptr_in_diram_iram() test, or result will be invalid pointer
157 */
158 __attribute__((always_inline))
esp_ptr_diram_iram_to_dram(const void * p)159 inline static void * esp_ptr_diram_iram_to_dram(const void *p) {
160 #if SOC_DIRAM_INVERTED
161     return (void *) ( SOC_DIRAM_DRAM_LOW + (SOC_DIRAM_IRAM_HIGH - (intptr_t)p) - 4);
162 #else
163     return (void *) ( SOC_DIRAM_DRAM_LOW + ((intptr_t)p - SOC_DIRAM_IRAM_LOW) );
164 #endif
165 }
166 
167 /** End of the common section that has to be in sync with esp_memory_utils.h **/
168 /** Don't add new functions below **/
169 
170 #ifdef __cplusplus
171 }
172 #endif
173