Skip to content

Commit 7a6cd63

Browse files
committed
fix(psram): fixed psram ptr check under xip_psram condition
Closes #15999 Closes #15997
1 parent 0e68077 commit 7a6cd63

File tree

5 files changed

+50
-42
lines changed

5 files changed

+50
-42
lines changed

components/esp_psram/system_layer/esp_psram.c

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ extern uint8_t _rodata_reserved_end;
6666
#endif /* CONFIG_SPIRAM_RODATA */
6767

6868
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
69-
extern uint8_t _instruction_reserved_start;
7069
extern uint8_t _instruction_reserved_end;
7170
#endif /* CONFIG_SPIRAM_FETCH_INSTRUCTIONS */
7271

@@ -472,23 +471,17 @@ bool IRAM_ATTR esp_psram_check_ptr_addr(const void *p)
472471
return true;
473472
}
474473

475-
#if CONFIG_SPIRAM_RODATA && !CONFIG_IDF_TARGET_ESP32S2
476-
if (mmu_psram_check_ptr_addr_in_rodata_alignment_gap(p)) {
477-
return true;
478-
}
479-
#endif /* CONFIG_SPIRAM_RODATA && !CONFIG_IDF_TARGET_ESP32S2 */
480-
481-
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && SOC_MMU_DI_VADDR_SHARED
482-
if (mmu_psram_check_ptr_addr_in_instruction_alignment_gap(p)) {
474+
#if CONFIG_SPIRAM_RODATA
475+
if (mmu_psram_check_ptr_addr_in_xip_psram_rodata_region(p)) {
483476
return true;
484477
}
485-
#endif /* CONFIG_SPIRAM_FETCH_INSTRUCTIONS && SOC_MMU_DI_VADDR_SHARED */
478+
#endif
486479

487480
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
488-
if ((intptr_t)p >= (uint32_t)&_instruction_reserved_start && (intptr_t)p < (uint32_t)&_instruction_reserved_end) {
481+
if (mmu_psram_check_ptr_addr_in_xip_psram_instruction_region(p)) {
489482
return true;
490483
}
491-
#endif /* CONFIG_SPIRAM_FETCH_INSTRUCTIONS */
484+
#endif
492485

493486
return false;
494487
}

components/esp_psram/test_apps/psram/main/test_psram.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -140,6 +140,18 @@ TEST_CASE("test spi1 flash operation after putting .text and .rodata into psram"
140140
TEST_ESP_OK(gptimer_disable(gptimer));
141141
TEST_ESP_OK(gptimer_del_timer(gptimer));
142142
}
143+
144+
TEST_CASE("test esp_psram_check_ptr_addr with xip rodata and instruction region", "[psram]")
145+
{
146+
bool on_psram = false;
147+
148+
on_psram = esp_psram_check_ptr_addr(s_get_partition);
149+
TEST_ASSERT(on_psram);
150+
151+
on_psram = esp_psram_check_ptr_addr(s_test_buf);
152+
TEST_ASSERT(on_psram);
153+
}
154+
143155
#endif //CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_RODATA
144156

145157
TEST_CASE("test psram unaligned access", "[psram]")

components/esp_psram/xip_impl/include/esp_private/mmu_psram_flash.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,13 @@ size_t mmu_psram_get_text_segment_length(void);
5656
void mmu_psram_get_instruction_alignment_gap_info(uint32_t *gap_start, uint32_t *gap_size);
5757

5858
/**
59-
* @brief Check if the pointer is in the instruction alignment gap
59+
* @brief Check if the pointer is in the xip psram instruction region
6060
*
6161
* @param[in] p Pointer to check
6262
*
63-
* @return true if the pointer is in the instruction alignment gap, false otherwise
63+
* @return true if the pointer is in the instruction region, false otherwise
6464
*/
65-
bool mmu_psram_check_ptr_addr_in_instruction_alignment_gap(const void *p);
65+
bool mmu_psram_check_ptr_addr_in_xip_psram_instruction_region(const void *p);
6666

6767
/**
6868
* @brief Copy Flash texts to PSRAM
@@ -101,13 +101,13 @@ size_t mmu_psram_get_rodata_segment_length(void);
101101
esp_err_t mmu_config_psram_rodata_segment(uint32_t start_page, uint32_t psram_size, uint32_t *out_page);
102102

103103
/**
104-
* @brief Check if the pointer is in the rodata alignment gap
104+
* @brief Check if the pointer is in the xip psram rodata region
105105
*
106106
* @param[in] p Pointer to check
107107
*
108-
* @return true if the pointer is in the rodata alignment gap, false otherwise
108+
* @return true if the pointer is in the rodata region, false otherwise
109109
*/
110-
bool mmu_psram_check_ptr_addr_in_rodata_alignment_gap(const void *p);
110+
bool mmu_psram_check_ptr_addr_in_xip_psram_rodata_region(const void *p);
111111
#endif //#if CONFIG_SPIRAM_RODATA
112112

113113
/*----------------------------------------------------------------------------

components/esp_psram/xip_impl/mmu_psram_flash.c

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#endif
3434

3535
#define ALIGN_UP_BY(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
36+
#define ALIGN_DOWN_BY(num, align) ((num) & (~((align) - 1)))
3637

3738
/*----------------------------------------------------------------------------
3839
Part 1 APIs (See @Backgrounds on top of this file)
@@ -44,10 +45,22 @@ const static char *TAG = "mmu_psram";
4445
//TODO IDF-4387
4546
static uint32_t page0_mapped = 0;
4647
static uint32_t page0_page = INVALID_PHY_PAGE;
48+
49+
/**
50+
* If using `int`, then for CLANG, with enabled optimization when inlined function is provided with the address of external symbol, the two least bits of the constant used inside that function get cleared.
51+
* Optimizer assumes that address of external symbol should be aligned to 4-bytes and therefore aligns constant value used for bitwise AND operation with that address.
52+
*
53+
* This means `extern int _instruction_reserved_start;` can be unaligned to 4 bytes, whereas using `char` can solve this issue.
54+
*
55+
* As we only use these symbol address, we declare them as `char` here
56+
*/
57+
extern char _instruction_reserved_start;
58+
extern char _instruction_reserved_end;
59+
extern char _rodata_reserved_start;
60+
extern char _rodata_reserved_end;
4761
#endif //#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA
4862

4963
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
50-
extern char _instruction_reserved_end;
5164
#define INSTRUCTION_ALIGNMENT_GAP_START ALIGN_UP_BY((uint32_t)&_instruction_reserved_end, 4)
5265
#define INSTRUCTION_ALIGNMENT_GAP_END ALIGN_UP_BY((uint32_t)&_instruction_reserved_end, CONFIG_MMU_PAGE_SIZE)
5366

@@ -71,11 +84,12 @@ void mmu_psram_get_instruction_alignment_gap_info(uint32_t *gap_start, uint32_t
7184
*gap_end = INSTRUCTION_ALIGNMENT_GAP_END;
7285
}
7386

74-
bool IRAM_ATTR mmu_psram_check_ptr_addr_in_instruction_alignment_gap(const void *p)
87+
bool mmu_psram_check_ptr_addr_in_xip_psram_instruction_region(const void *p)
7588
{
76-
if ((intptr_t)p >= INSTRUCTION_ALIGNMENT_GAP_START && (intptr_t)p < INSTRUCTION_ALIGNMENT_GAP_END) {
89+
if ((intptr_t)p >= ALIGN_DOWN_BY((uint32_t)&_instruction_reserved_start, CONFIG_MMU_PAGE_SIZE) && (intptr_t)p < ALIGN_UP_BY((uint32_t)&_instruction_reserved_end, CONFIG_MMU_PAGE_SIZE)) {
7790
return true;
7891
}
92+
7993
return false;
8094
}
8195

@@ -116,7 +130,6 @@ esp_err_t mmu_config_psram_text_segment(uint32_t start_page, uint32_t psram_size
116130
#endif //#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
117131

118132
#if CONFIG_SPIRAM_RODATA
119-
extern char _rodata_reserved_end;
120133
#define RODATA_ALIGNMENT_GAP_START ALIGN_UP_BY((uint32_t)&_rodata_reserved_end, 4)
121134
#define RODATA_ALIGNMENT_GAP_END ALIGN_UP_BY((uint32_t)&_rodata_reserved_end, CONFIG_MMU_PAGE_SIZE)
122135

@@ -142,11 +155,12 @@ void mmu_psram_get_rodata_alignment_gap_info(uint32_t *gap_start, uint32_t *gap_
142155
*gap_end = RODATA_ALIGNMENT_GAP_END;
143156
}
144157

145-
bool IRAM_ATTR mmu_psram_check_ptr_addr_in_rodata_alignment_gap(const void *p)
158+
bool mmu_psram_check_ptr_addr_in_xip_psram_rodata_region(const void *p)
146159
{
147-
if ((intptr_t)p >= RODATA_ALIGNMENT_GAP_START && (intptr_t)p < RODATA_ALIGNMENT_GAP_END) {
160+
if ((intptr_t)p >= ALIGN_DOWN_BY((uint32_t)&_rodata_reserved_start, CONFIG_MMU_PAGE_SIZE) && (intptr_t)p < ALIGN_UP_BY((uint32_t)&_rodata_reserved_end, CONFIG_MMU_PAGE_SIZE)) {
148161
return true;
149162
}
163+
150164
return false;
151165
}
152166

@@ -192,19 +206,6 @@ esp_err_t mmu_config_psram_rodata_segment(uint32_t start_page, uint32_t psram_si
192206
/*----------------------------------------------------------------------------
193207
Part 2 APIs (See @Backgrounds on top of this file)
194208
-------------------------------------------------------------------------------*/
195-
/**
196-
* If using `int`, then for CLANG, with enabled optimization when inlined function is provided with the address of external symbol, the two least bits of the constant used inside that function get cleared.
197-
* Optimizer assumes that address of external symbol should be aligned to 4-bytes and therefore aligns constant value used for bitwise AND operation with that address.
198-
*
199-
* This means `extern int _instruction_reserved_start;` can be unaligned to 4 bytes, whereas using `char` can solve this issue.
200-
*
201-
* As we only use these symbol address, we declare them as `char` here
202-
*/
203-
extern char _instruction_reserved_start;
204-
extern char _instruction_reserved_end;
205-
extern char _rodata_reserved_start;
206-
extern char _rodata_reserved_end;
207-
208209
//------------------------------------Copy Flash .text to PSRAM-------------------------------------//
209210
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
210211
static uint32_t instruction_in_spiram;

components/esp_psram/xip_impl/mmu_psram_flash_v2.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,12 @@ void mmu_psram_get_instruction_alignment_gap_info(uint32_t *gap_start, uint32_t
127127
*gap_end = INSTRUCTION_ALIGNMENT_GAP_END;
128128
}
129129

130-
bool IRAM_ATTR mmu_psram_check_ptr_addr_in_instruction_alignment_gap(const void *p)
130+
bool mmu_psram_check_ptr_addr_in_xip_psram_instruction_region(const void *p)
131131
{
132-
if ((intptr_t)p >= INSTRUCTION_ALIGNMENT_GAP_START && (intptr_t)p < INSTRUCTION_ALIGNMENT_GAP_END) {
132+
if ((intptr_t)p >= ALIGN_DOWN_BY((uint32_t)&_instruction_reserved_start, CONFIG_MMU_PAGE_SIZE) && (intptr_t)p < ALIGN_UP_BY((uint32_t)&_instruction_reserved_end, CONFIG_MMU_PAGE_SIZE)) {
133133
return true;
134134
}
135+
135136
return false;
136137
}
137138

@@ -188,11 +189,12 @@ void mmu_psram_get_rodata_alignment_gap_info(uint32_t *gap_start, uint32_t *gap_
188189
*gap_end = RODATA_ALIGNMENT_GAP_END;
189190
}
190191

191-
bool IRAM_ATTR mmu_psram_check_ptr_addr_in_rodata_alignment_gap(const void *p)
192+
bool mmu_psram_check_ptr_addr_in_xip_psram_rodata_region(const void *p)
192193
{
193-
if ((intptr_t)p >= RODATA_ALIGNMENT_GAP_START && (intptr_t)p < RODATA_ALIGNMENT_GAP_END) {
194+
if ((intptr_t)p >= ALIGN_DOWN_BY((uint32_t)&_rodata_reserved_start, CONFIG_MMU_PAGE_SIZE) && (intptr_t)p < ALIGN_UP_BY((uint32_t)&_rodata_reserved_end, CONFIG_MMU_PAGE_SIZE)) {
194195
return true;
195196
}
197+
196198
return false;
197199
}
198200

0 commit comments

Comments
 (0)