You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2022/03/23 16:35:51 UTC

[GitHub] [incubator-nuttx] Ouss4 commented on a change in pull request #5827: Add SPIRAM to ESP32-S2

Ouss4 commented on a change in pull request #5827:
URL: https://github.com/apache/incubator-nuttx/pull/5827#discussion_r833438890



##########
File path: arch/xtensa/src/esp32s2/esp32s2_spiram.c
##########
@@ -0,0 +1,450 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s2/esp32s2_spiram.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <debug.h>
+#include <string.h>
+#include <sys/param.h>
+#include <nuttx/config.h>
+#include <nuttx/spinlock.h>
+
+#include "xtensa.h"
+#include "xtensa_attr.h"
+#include "esp32s2_psram.h"
+#include "esp32s2_spiram.h"
+#include "hardware/esp32s2_soc.h"
+#include "hardware/esp32s2_cache_memory.h"
+#include "hardware/esp32s2_extmem.h"
+#include "hardware/esp32s2_iomux.h"
+
+/****************************************************************************
+ * Pre-processor Prototypes
+ ****************************************************************************/
+
+#define PSRAM_MODE PSRAM_VADDR_MODE_NORMAL
+
+#if defined(CONFIG_ESP32S2_SPIRAM)
+
+#define MMU_PAGE_TO_BYTES(page_id)      ((page_id) << 16)
+#define BYTES_TO_MMU_PAGE(bytes)        ((bytes) / MMU_PAGE_SIZE)
+
+#if defined(CONFIG_ESP32S2_SPIRAM_SPEED_40M)
+#  define PSRAM_SPEED PSRAM_CACHE_S40M
+#else  /* #if CONFIG_ESP32S2_SPIRAM_SPEED_80M */
+#  define PSRAM_SPEED PSRAM_CACHE_S80M
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+static bool g_spiram_inited;
+
+/* These variables are in bytes */
+
+static uint32_t g_allocable_vaddr_start;
+static uint32_t g_allocable_vaddr_end;
+static DRAM_ATTR uint32_t g_mapped_vaddr_start;
+
+static uint32_t g_instruction_in_spiram;
+static uint32_t g_rodata_in_spiram;
+
+#if defined(CONFIG_ESP32S2_SPIRAM_FETCH_INSTRUCTIONS)
+static int      g_instr_flash2spiram_offs;
+static uint32_t g_instr_start_page;
+static uint32_t g_instr_end_page;
+#endif
+
+#if defined(CONFIG_ESP32S2_SPIRAM_RODATA)
+static int      g_rodata_flash2spiram_offs;
+static uint32_t g_rodata_start_page;
+static uint32_t g_rodata_end_page;
+#endif
+
+#if defined(CONFIG_ESP32S2_SPIRAM_FETCH_INSTRUCTIONS) || \
+    defined(CONFIG_ES32S3_SPIRAM_RODATA)
+static uint32_t page0_mapped;
+static uint32_t page0_page = INVALID_PHY_PAGE;
+#endif
+
+/* Let's export g_mapped_size to export heap */
+
+DRAM_ATTR uint32_t g_mapped_size;
+
+/****************************************************************************
+ * ROM Function Prototypes
+ ****************************************************************************/
+
+extern void cache_writeback_all(void);
+extern uint32_t cache_suspend_dcache(void);
+extern void cache_resume_dcache(uint32_t val);
+extern int cache_dbus_mmu_set(uint32_t ext_ram, uint32_t vaddr,
+                              uint32_t paddr, uint32_t psize,
+                              uint32_t num, uint32_t fixed);
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mmu_map_psram
+ *
+ * Description:
+ *   Map the PSRAM to MMU
+ *
+ * Input Parameters:
+ *   start_paddr - start of physical PSRAM address
+ *   end_paddr   - end of physical PSRAM address
+ *   out_start_vaddr - start of virtual address
+ *
+ * Returned Value:
+ *   Zero value (OK) on success or a negative error.
+ *
+ ****************************************************************************/
+
+int mmu_map_psram(uint32_t start_paddr, uint32_t end_paddr,
+                  uint32_t *out_start_vaddr)
+{
+  /* For now, this function should only run when virtual address is enough
+   * Decide these logics when there's a real PSRAM with larger size
+   */
+
+  uint32_t map_length = end_paddr - start_paddr;
+
+  if (map_length > SOC_EXTRAM_DATA_SIZE)
+    {
+      /* Decide these logics when there's a real PSRAM with larger size */
+
+      merr("PSRAM physical size is too large, not support mapping it yet!");
+      return -ENOMEM;
+    }
+
+  /* should be MMU page aligned */
+
+  assert((start_paddr % MMU_PAGE_SIZE) == 0);
+
+  uint32_t start_vaddr = DPORT_CACHE_ADDRESS_LOW;
+  uint32_t end_vaddr = start_vaddr + map_length;
+  uint32_t cache_bus_mask = 0;
+
+  cache_bus_mask |= (end_vaddr > 0) ? EXTMEM_PRO_DCACHE_MASK_DPORT : 0;
+  cache_bus_mask |= (end_vaddr >= DPORT_ADDRESS_HIGH) ?
+                    EXTMEM_PRO_DCACHE_MASK_DRAM1 : 0;
+  cache_bus_mask |= (end_vaddr >= DRAM1_ADDRESS_HIGH) ?
+                    EXTMEM_PRO_DCACHE_MASK_DRAM0 : 0;
+
+  assert(end_vaddr <= DRAM0_CACHE_ADDRESS_HIGH);
+
+  minfo("start_paddr is %x, map_length is %xB, %d pages",
+        start_paddr, map_length, BYTES_TO_MMU_PAGE(map_length));
+
+  /* No need to disable cache, this file is put in Internal RAM */
+
+  cache_dbus_mmu_set(MMU_ACCESS_SPIRAM, start_vaddr, start_paddr, 64,
+                     BYTES_TO_MMU_PAGE(map_length), 0);
+
+  REG_CLR_BIT(EXTMEM_PRO_DCACHE_CTRL1_REG, cache_bus_mask);
+
+  *out_start_vaddr = start_vaddr;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: mmu_map_psram
+ *
+ * Description:
+ *   Initialize the CACHE to use with PSRAM
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void IRAM_ATTR esp_spiram_init_cache(void)
+{
+  int ret;
+  static DRAM_ATTR uint32_t vaddr_start = 0;
+  uint32_t start_page = 0;
+  uint32_t psram_available_size = esp_spiram_get_size();
+
+  /* Map the PSRAM physical range to MMU */
+
+  ret = mmu_map_psram(MMU_PAGE_TO_BYTES(start_page),
+                      MMU_PAGE_TO_BYTES(start_page) +
+                      psram_available_size, &vaddr_start);
+  if (ret < 0)
+    {
+      merr("MMU PSRAM mapping wrong!");
+      abort();
+    }
+
+  /* After mapping, we DON'T care about the PSRAM PHYSICAL
+   * ADDRESSS ANYMORE!
+   */
+
+  g_allocable_vaddr_start = vaddr_start;
+  g_allocable_vaddr_end   = vaddr_start + psram_available_size;
+}
+
+/****************************************************************************
+ * Name: esp_spiram_test
+ *
+ * Description:
+ *   Simple RAM test. Writes a word every 32 bytes. Takes about a second
+ *   to complete for 4MiB. Returns true when RAM seems OK, false when test
+ *   fails. WARNING: Do not run this before the 2nd cpu has been initialized
+ *   (in a two-core system) or after the heap allocator has taken ownership
+ *   of the memory.

Review comment:
       Why do we need this function at all?  We have the app `ramtest` that does the same thing.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org