commit 8d68ec27fd9b641a44348f04ec8e241b944f8122
parent af462d90037b8c518b0fce273cfb3f463480d993
Author: filipton <filipton12@gmail.com>
Date: Thu, 2 Jan 2025 15:04:15 +0100
wip: better port of mmu_ll/mmu_hal function for vaddr to paddr conversion
Diffstat:
7 files changed, 187 insertions(+), 10 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
-version = 3
+version = 4
[[package]]
name = "embedded-storage"
@@ -13,11 +13,77 @@ name = "esp-hal-ota"
version = "0.1.4"
dependencies = [
"embedded-storage",
+ "esp32c2",
+ "esp32c3",
+ "esp32c6",
+ "esp32h2",
+ "esp32s2",
+ "esp32s3",
"log",
]
[[package]]
+name = "esp32c2"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e74f8ceff5249a39f6ffeaea7a9c048b36fd1ba67d365330e0970927c57759ab"
+dependencies = [
+ "vcell",
+]
+
+[[package]]
+name = "esp32c3"
+version = "0.26.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d1750382dc49fa333ee6b1ba96f8c540038b9666f5a233dc1221c98e3236118"
+dependencies = [
+ "vcell",
+]
+
+[[package]]
+name = "esp32c6"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b98fcf7ae90ee4d55f06170dfeaaebbf2a1619bb38b4e14b9009b4d636b87e7"
+dependencies = [
+ "vcell",
+]
+
+[[package]]
+name = "esp32h2"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1530274ade78283655a6810dd5d1840404945f4a5bf3d74729c35946beb8304"
+dependencies = [
+ "vcell",
+]
+
+[[package]]
+name = "esp32s2"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f77ec7a694eb60741f53236e625456abf672ba5b0b73c4a2d708a343c6f3495"
+dependencies = [
+ "vcell",
+]
+
+[[package]]
+name = "esp32s3"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe69dca8db0ed37d222555f12dfaf99232592e84f54e56dd81e450a4769718bf"
+dependencies = [
+ "vcell",
+]
+
+[[package]]
name = "log"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+
+[[package]]
+name = "vcell"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
diff --git a/Cargo.toml b/Cargo.toml
@@ -12,10 +12,24 @@ repository = "https://github.com/filipton/esp-hal-ota"
embedded-storage = "0.3.1"
log = { version = "0.4.22", optional = true }
+esp32s2 = { version = "0.25.0", optional = true }
+esp32s3 = { version = "0.29.0", optional = true }
+
+esp32c2 = { version = "0.23.0", optional = true }
+esp32c3 = { version = "0.26.0", optional = true }
+esp32c6 = { version = "0.17.0", optional = true }
+
+esp32h2 = { version = "0.13.0", optional = true }
+
[features]
default = ["log"]
log = ["dep:log"]
-esp32c3 = []
-esp32s2 = []
-esp32s3 = []
+esp32s2 = ["dep:esp32s2"]
+esp32s3 = ["dep:esp32s3"]
+
+esp32c2 = ["dep:esp32c2"]
+esp32c3 = ["dep:esp32c3"]
+esp32c6 = ["dep:esp32c6"]
+
+esp32h2 = ["dep:esp32h2"]
diff --git a/src/lib.rs b/src/lib.rs
@@ -5,7 +5,8 @@ pub use structs::*;
pub mod crc32;
pub mod helpers;
-pub mod paddr;
+pub mod mmu_hal;
+pub mod mmu_ll;
pub mod structs;
const PART_OFFSET: u32 = 0x8000;
@@ -225,7 +226,7 @@ where
/// Returns currently booted partition index
pub fn get_currently_booted_partition(&self) -> Option<usize> {
- paddr::esp_get_current_running_partition(self.get_partitions())
+ mmu_hal::esp_get_current_running_partition(self.get_partitions())
}
/// BUG: this wont work if user has ota partitions not starting from ota0
@@ -235,7 +236,7 @@ where
/// it will read from them to eliminate possibility of wrong PADDR result.
/// (ESP-IDF has if's for PADDR-chain so it can fail somehow)
pub fn get_next_ota_partition(&self) -> Option<usize> {
- let curr_part = paddr::esp_get_current_running_partition(self.get_partitions());
+ let curr_part = mmu_hal::esp_get_current_running_partition(self.get_partitions());
curr_part.map(|next_part| (next_part + 1) % self.pinfo.ota_partitions_count)
}
diff --git a/src/mmu_hal.rs b/src/mmu_hal.rs
@@ -0,0 +1,53 @@
+pub const MMU_PAGE_8KB: u32 = 0x2000;
+pub const MMU_PAGE_16KB: u32 = 0x4000;
+pub const MMU_PAGE_32KB: u32 = 0x8000;
+pub const MMU_PAGE_64KB: u32 = 0x10000;
+
+fn mmu_hal_pages_to_bytes(mmu_id: u32, page_num: u32) -> u32 {
+ let mmu_page_size = crate::mmu_ll::mmu_ll_get_page_size(mmu_id);
+ let shift_code = match mmu_page_size {
+ MMU_PAGE_64KB => 16,
+ MMU_PAGE_32KB => 15,
+ MMU_PAGE_16KB => 14,
+ _ => panic!("WRONG MMU_PAGE_SIZE! 0x{:X?}", 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 = crate::mmu_ll::mmu_ll_get_entry_id(mmu_id, ptr as u32);
+
+ if !crate::mmu_ll::mmu_ll_check_entry_valid(mmu_id, entry_id) {
+ #[cfg(feature = "log")]
+ log::error!("mmu_ll_check_entry_valid failed!");
+
+ return None;
+ }
+
+ // 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 = crate::mmu_ll::mmu_ll_entry_id_to_paddr_base(mmu_id, 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
+}
diff --git a/src/mmu_ll/esp32s3.rs b/src/mmu_ll/esp32s3.rs
@@ -0,0 +1,22 @@
+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;
+
+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 {
+ (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 }
+}
diff --git a/src/mmu_ll/mod.rs b/src/mmu_ll/mod.rs
@@ -0,0 +1,4 @@
+#[cfg(feature = "esp32s3")]
+mod esp32s3;
+#[cfg(feature = "esp32s3")]
+pub use esp32s3::*;
diff --git a/src/paddr.rs b/src/paddr.rs
@@ -51,9 +51,21 @@ impl ExtMemDefs {
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
}
@@ -81,14 +93,19 @@ fn mmu_hal_pages_to_bytes(_mmu_id: u32, page_num: u32) -> u32 {
}
pub fn esp_get_current_running_partition(partitions: &[(u32, u32)]) -> Option<usize> {
- // we are using 0 as mmu_id - all code paths for esp32c3,esp32s2,esp32s3 arent using mmu_id
+ // 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(0, ptr as 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(0, 1);
+ 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);