Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xtensa/esp32: When PSRAM is enabled allow drivers and tasks to allocate memory from a separate internal memory #1958

Merged
merged 15 commits into from Oct 25, 2020

Conversation

Ouss4
Copy link
Member

@Ouss4 Ouss4 commented Oct 9, 2020

Summary

When external RAM and external FLASH are used together we have to make sure that:

  • For drivers, in case of a DMA transfer, the buffer is DMA capable, i.e. doesn't originate from external RAM. If it does allocate memory from an internal heap then copy it back.
  • When accessing flash, the cache needs to be disabled, as a consequence any memory access or code execution need to be from internal memory. A "special" critical section around flash operations is created to make sure that:
    • Buffers don't originate from external RAM
    • Tasks' stack aren't allocated from external RAM
    • const variables aren't in .ro.data.
    • Code during this sections is in IRAM.

Impact

Impacts ESP32 when both PSRAM and SPIFLASH are enabled.

Testing

esp32-core:spiflash with PSRAM enabled and disabled.

allocated in an internal heap.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
… from DRAM

when the given buffer is from PSRAM.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
memory region is available.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
warning that's not relevant anymore.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
@@ -73,6 +73,18 @@
#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)

#ifdef CONFIG_XTENSA_USE_SEPERATE_IMEM
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see these macros are used in some places, and they are defined in multi *.c files, so maybe we can move these into a new file like xtensa_mm.h ,and let these *.c include xtensa_mm.h.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These macros come from config.h (which is generated based on the .config file created by Kconfig tools)
*.c files include the config.h and use the macros.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see what macros you are talking about, Github confused me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@donghengqaz done. PTAL.

if (esp32_ptr_extram(txbuffer))
{
tp = up_imm_malloc(bytes);
if (tp == NULL)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the esp32_spi_dma_exchange can't return error code tell callers that the function failed, so maybe we add an assert function here ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something like the following?

   if (esp32_ptr_extram(txbuffer))
     {
       tp = up_imm_malloc(bytes);
-      if (tp == NULL)
-        {
-          return;
-        }
+      DEBUGASSERT(tp != NULL);
     }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

rp = up_imm_malloc(bytes);
if (rp == NULL)
{
goto error_with_tp;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
code, assert the return of the imm_malloc function.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
to be 4 bytes.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
range 0x2000 0x28000
default 0x28000

config XTENSA_IMEM_PROCFS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i feel it's more convenient for users to have this info in /proc/meminfo than the dedicated file. how do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was concerned that this change would be too "invasive" in procfsmeminfo. This feature is "too" Xtensa/ESP32 specific.

@@ -81,6 +81,21 @@ config XTENSA_CP_INITSET
is provided by CONFIG_XTENSA_CP_INITSET. Each bit corresponds to one
coprocessor with the same bit layout as for the CPENABLE register.

config XTENSA_USE_SEPERATE_IMEM
bool "Use a seperate heap for internal memory"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess the description should at least explain:

  • what's internal memory
  • what uses the memory if this config is enabled

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a help section.

if (esp32_ptr_extram(txbuffer))
{
tp = up_imm_malloc(bytes);
DEBUGASSERT(tp != NULL);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't you need memcpy here?
(i don't understand what this function is doing. just a wild guess.)

if (esp32_ptr_extram(rxbuffer))
{
memcpy(rxbuffer, rp, bytes);
up_imm_free(rp);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tp and rp are modified above. (tp += n)
i guess you should free the original pointer.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. Thanks, done.

#ifdef CONFIG_XTENSA_USE_SEPERATE_IMEM
if (esp32_ptr_extram(txbuffer))
{
up_imm_free(tp);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
bool up_imm_heapmember(FAR void *mem);
int up_imm_mallinfo(FAR struct mallinfo *info);
#endif

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming up_imm_* does not follow the NuttX naming conventions. These should all be xtensa_imm_* . See https://cwiki.apache.org/confluence/display/NUTTX/Naming+of+Architecture%2C+MCU%2C+and+Board+Interfaces

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prefix up_ is reserved only for MCU interfaces called directly by the OS and prototyped in included/nuttx/*.h (usually arch.h)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally I had in mind that maybe other architectures would need the same functionality and that prototypes would go to one of the locations you mentioned.
But I didn't follow with that and forgot to rename the functions. Thanks for the reminder. Fixed!

@@ -77,8 +77,13 @@
void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
{
board_autoled_on(LED_HEAPALLOCATE);
#ifdef CONFIG_XTENSA_USE_SEPERATE_IMEM
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A small typo: SEPERATE -> SEPARATE

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -73,6 +73,18 @@
#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)

#ifdef CONFIG_XTENSA_USE_SEPERATE_IMEM
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SEPERATE -> SEPARATE

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -81,6 +81,16 @@ config XTENSA_CP_INITSET
is provided by CONFIG_XTENSA_CP_INITSET. Each bit corresponds to one
coprocessor with the same bit layout as for the CPENABLE register.

config XTENSA_USE_SEPERATE_IMEM
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A small typo: SEPERATE -> SEPARATE

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

config XTENSA_IMEM_PROCFS
bool "Internal memory PROCFS support"
default n
depends on XTENSA_USE_SEPERATE_IMEM && !DISABLE_MOUNTPOINT && FS_PROCFS && FS_PROCFS_REGISTER
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please align "depends on" below "default n"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ouss4 Ouss4 force-pushed the coex branch 2 times, most recently from 7b1234b to 8eb6b04 Compare October 25, 2020 21:41
be prefixed by xtensa_ instead of up_.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
@acassis acassis merged commit 9b98f20 into apache:master Oct 25, 2020
acassis pushed a commit that referenced this pull request Oct 25, 2020
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
@Ouss4 Ouss4 deleted the coex branch October 26, 2020 09:47
@btashton btashton added this to To-Add in Release Notes - 10.1.0 Apr 12, 2021
@jerpelea jerpelea moved this from To-Add to arch in Release Notes - 10.1.0 Apr 13, 2021
@jerpelea jerpelea moved this from arch to Added in Release Notes - 10.1.0 Apr 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet

5 participants