commit d05dfc53b4c880eba990971e118ce916a786ccd3
parent 8d68ec27fd9b641a44348f04ec8e241b944f8122
Author: filipton <filipton12@gmail.com>
Date: Thu, 2 Jan 2025 15:35:42 +0100
wip: esp32s2/esp32s3/esp32c3 new mmu ports
Diffstat:
5 files changed, 74 insertions(+), 127 deletions(-)
diff --git a/src/lib.rs b/src/lib.rs
@@ -1,4 +1,6 @@
#![no_std]
+#![feature(concat_idents)]
+#![doc = include_str!("../README.md")]
use embedded_storage::{ReadStorage, Storage};
pub use structs::*;
diff --git a/src/mmu_ll/esp32s3.rs b/src/mmu_ll/esp32c3.rs
diff --git a/src/mmu_ll/esp32s2.rs b/src/mmu_ll/esp32s2.rs
@@ -0,0 +1,68 @@
+const SOC_MMU_VADDR_MASK: u32 = 0x3FFFFF;
+const DR_REG_MMU_TABLE: u32 = 0x61801000;
+const SOC_MMU_VALID_VAL_MASK: u32 = 0x3fff;
+const SOC_MMU_INVALID: u32 = 1 << 14;
+
+macro_rules! soc_address_in_bus {
+ ($bus_name:ident, $vaddr:ident) => {{
+ $vaddr >= concat_idents!($bus_name, _ADDRESS_LOW)
+ && $vaddr < concat_idents!($bus_name, _ADDRESS_HIGH)
+ }};
+}
+
+pub fn mmu_ll_get_page_size(_mmu_id: u32) -> u32 {
+ crate::mmu_hal::MMU_PAGE_64KB
+}
+
+pub fn mmu_ll_get_entry_id(_mmu_id: u32, vaddr: u32) -> u32 {
+ let offset = if soc_address_in_bus!(SOC_DROM0, vaddr) {
+ PRO_CACHE_IBUS2_MMU_START / 4
+ } else if soc_address_in_bus!(SOC_IRAM0_CACHE, vaddr) {
+ PRO_CACHE_IBUS0_MMU_START / 4
+ } else if soc_address_in_bus!(SOC_IRAM1, vaddr) {
+ PRO_CACHE_IBUS1_MMU_START / 4
+ } else if soc_address_in_bus!(SOC_DPORT_CACHE, vaddr) {
+ PRO_CACHE_DBUS2_MMU_START / 4
+ } else if soc_address_in_bus!(SOC_DRAM1, vaddr) {
+ PRO_CACHE_DBUS1_MMU_START / 4
+ } else if soc_address_in_bus!(SOC_DRAM0_CACHE, vaddr) {
+ PRO_CACHE_DBUS0_MMU_START / 4
+ } else {
+ #[cfg(feature = "log")]
+ log::error!("mmu_ll_get_entry_id failed!");
+
+ 0
+ };
+
+ offset + ((vaddr & SOC_MMU_VADDR_MASK) >> 16)
+}
+
+pub fn mmu_ll_entry_id_to_paddr_base(_mmu_id: u32, entry_id: u32) -> u32 {
+ let ptr = (DR_REG_MMU_TABLE + entry_id * 4) as *const u32;
+ unsafe { ((*ptr) & SOC_MMU_VALID_VAL_MASK) << 16 }
+}
+
+pub fn mmu_ll_check_entry_valid(_mmu_id: u32, entry_id: u32) -> bool {
+ let ptr = (DR_REG_MMU_TABLE + entry_id * 4) as *const u32;
+ unsafe { ((*ptr) & SOC_MMU_INVALID) == 0 }
+}
+
+// https://github.com/espressif/esp-idf/blob/b5ac4fbdf9e9fb320bb0a98ee4fbaa18f8566f37/components/soc/esp32s2/include/soc/ext_mem_defs.h#L16
+const SOC_IRAM0_CACHE_ADDRESS_LOW: u32 = 0x40080000;
+const SOC_IRAM0_CACHE_ADDRESS_HIGH: u32 = 0x40400000;
+const SOC_IRAM1_ADDRESS_LOW: u32 = 0x40400000;
+const SOC_IRAM1_ADDRESS_HIGH: u32 = 0x40800000;
+const SOC_DROM0_ADDRESS_LOW: u32 = 0x3f000000;
+const SOC_DROM0_ADDRESS_HIGH: u32 = 0x3f400000;
+const SOC_DRAM0_CACHE_ADDRESS_LOW: u32 = 0x3fc00000;
+const SOC_DRAM0_CACHE_ADDRESS_HIGH: u32 = 0x3ff80000;
+const SOC_DRAM1_ADDRESS_LOW: u32 = 0x3f800000;
+const SOC_DRAM1_ADDRESS_HIGH: u32 = 0x3fc00000;
+const SOC_DPORT_CACHE_ADDRESS_LOW: u32 = 0x3f500000;
+const SOC_DPORT_CACHE_ADDRESS_HIGH: u32 = 0x3f800000;
+const PRO_CACHE_IBUS0_MMU_START: u32 = 0;
+const PRO_CACHE_IBUS1_MMU_START: u32 = 0x100;
+const PRO_CACHE_IBUS2_MMU_START: u32 = 0x200;
+const PRO_CACHE_DBUS0_MMU_START: u32 = 0x300;
+const PRO_CACHE_DBUS1_MMU_START: u32 = 0x400;
+const PRO_CACHE_DBUS2_MMU_START: u32 = 0x500;
diff --git a/src/mmu_ll/esp32s3.rs b/src/mmu_ll/esp32s3.rs
@@ -1,7 +1,7 @@
-const SOC_MMU_VADDR_MASK: u32 = 0x7FFFFF;
-const DR_REG_MMU_TABLE: u32 = 0x600c5000;
-const SOC_MMU_VALID_VAL_MASK: u32 = 0xff;
-const SOC_MMU_INVALID: u32 = 1 << 8;
+const SOC_MMU_VADDR_MASK: u32 = 0x1FFFFFF;
+const DR_REG_MMU_TABLE: u32 = 0x600C5000;
+const SOC_MMU_VALID_VAL_MASK: u32 = 0x3fff;
+const SOC_MMU_INVALID: u32 = 1 << 14;
pub fn mmu_ll_get_page_size(_mmu_id: u32) -> u32 {
crate::mmu_hal::MMU_PAGE_64KB
diff --git a/src/paddr.rs b/src/paddr.rs
@@ -1,123 +0,0 @@
-struct ExtMemDefs {}
-
-#[cfg(all(
- not(feature = "esp32c3"),
- not(feature = "esp32s2"),
- not(feature = "esp32s3")
-))]
-impl ExtMemDefs {
- const SOC_MMU_VADDR_MASK: u32 = 0;
- const DR_REG_MMU_TABLE: u32 = 0;
- const SOC_MMU_VALID_VAL_MASK: u32 = 0;
- const SOC_MMU_INVALID: u32 = 0;
- const MMU_PAGE_SIZE: u32 = 0;
-}
-
-/*
-#[cfg(feature = "esp32c2")]
-impl ExtMemDefs {
- const SOC_MMU_VADDR_MASK: u32 = ExtMemDefs::MMU_PAGE_SIZE * 64 - 1;
- const DR_REG_MMU_TABLE: u32 = 0x600c5000;
- const SOC_MMU_VALID_VAL_MASK: u32 = 0x3f;
- const SOC_MMU_INVALID: u32 = 1 << 6;
- const MMU_PAGE_SIZE: u32 = 0x10000;
-}
-*/
-
-#[cfg(feature = "esp32c3")]
-impl ExtMemDefs {
- const SOC_MMU_VADDR_MASK: u32 = 0x7FFFFF;
- const DR_REG_MMU_TABLE: u32 = 0x600c5000;
- const SOC_MMU_VALID_VAL_MASK: u32 = 0xff;
- const SOC_MMU_INVALID: u32 = 1 << 8;
- const MMU_PAGE_SIZE: u32 = 0x10000;
-}
-
-#[cfg(feature = "esp32s2")]
-impl ExtMemDefs {
- const SOC_MMU_VADDR_MASK: u32 = 0x3FFFFF;
- const DR_REG_MMU_TABLE: u32 = 0x61801000;
- const SOC_MMU_VALID_VAL_MASK: u32 = 0x3fff;
- const SOC_MMU_INVALID: u32 = 1 << 14;
- const MMU_PAGE_SIZE: u32 = 0x10000;
-}
-
-#[cfg(feature = "esp32s3")]
-impl ExtMemDefs {
- const SOC_MMU_VADDR_MASK: u32 = 0x1FFFFFF;
- const DR_REG_MMU_TABLE: u32 = 0x600c5000;
- const SOC_MMU_VALID_VAL_MASK: u32 = 0x3fff;
- const SOC_MMU_INVALID: u32 = 1 << 14;
- const MMU_PAGE_SIZE: u32 = 0x10000;
-}
-
-fn mmu_ll_get_page_size(mmu_id: u32) -> u32 {
- let extmem = unsafe { &*esp32c2::EXTMEM::ptr() };
- let bits = extmem.cache_conf_misc().read().cache_mmu_page_size().bits();
- match bits {
- 0 => crate::mmu_ll::MMU_PAGE_16KB,
- 1 => crate::mmu_ll::MMU_PAGE_32KB,
- _ => crate::mmu_ll::MMU_PAGE_64KB,
- }
-}
-
-// BUG: This might fail on esp32s2 (because getting entry_id is different there)
-// https://github.com/espressif/esp-idf/blob/master/components/hal/esp32s2/include/hal/mmu_ll.h#L145
-// https://github.com/espressif/esp-idf/blob/master/components/hal/esp32c3/include/hal/mmu_ll.h#L143
-//
-// esp32c3/esp32s3
-fn mmu_ll_get_entry_id(_mmu_id: u32, vaddr: u32) -> u32 {
- (vaddr & ExtMemDefs::SOC_MMU_VADDR_MASK) >> 16
-}
-
-#[allow(dead_code)]
-fn mmu_ll_check_entry_valid(_mmu_id: u32, entry_id: u32) -> bool {
- let ptr = (ExtMemDefs::DR_REG_MMU_TABLE + entry_id * 4) as *const u32;
- unsafe { ((*ptr) & ExtMemDefs::SOC_MMU_INVALID) == 0 }
-}
-
-fn mmu_ll_entry_id_to_paddr_base(_mmu_id: u32, entry_id: u32) -> u32 {
- let ptr = (ExtMemDefs::DR_REG_MMU_TABLE + entry_id * 4) as *const u32;
- unsafe { ((*ptr) & ExtMemDefs::SOC_MMU_VALID_VAL_MASK) << 16 }
-}
-
-fn mmu_hal_pages_to_bytes(_mmu_id: u32, page_num: u32) -> u32 {
- let shift_code = match ExtMemDefs::MMU_PAGE_SIZE {
- 0x10000 => 16,
- 0x8000 => 15,
- 0x4000 => 14,
- _ => panic!("WRONG MMU_PAGE SIZE! 0x{:X?}", ExtMemDefs::MMU_PAGE_SIZE),
- };
-
- page_num << shift_code
-}
-
-pub fn esp_get_current_running_partition(partitions: &[(u32, u32)]) -> Option<usize> {
- // NOTE:
- // mmu_id is always 0 because s_vaddr_to_paddr is using 0 for all targets
- // except esp32p4 (per SOC_MMU_PER_EXT_MEM_TARGET define)
- //
- // https://github.com/espressif/esp-idf/blob/b5ac4fbdf9e9fb320bb0a98ee4fbaa18f8566f37/components/esp_mm/esp_mmu_map.c#L754
- let mmu_id = 0;
-
- let ptr = esp_get_current_running_partition as *const () as *const u32;
- let entry_id = mmu_ll_get_entry_id(mmu_id, ptr as u32);
-
- // page_num is always 1
- // https://github.com/espressif/esp-idf/blob/master/components/hal/mmu_hal.c#L129
- let page_size_in_bytes = mmu_hal_pages_to_bytes(mmu_id, 1);
- let offset = (ptr as u32) % page_size_in_bytes;
-
- let paddr_base = mmu_ll_entry_id_to_paddr_base(0, entry_id);
- let paddr = paddr_base | offset;
-
- for i in 0..partitions.len() {
- let part = partitions[i];
-
- if paddr >= part.0 && paddr < part.0 + part.1 {
- return Some(i);
- }
- }
-
- None
-}