eculocate

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

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:
MCargo.lock | 68+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
MCargo.toml | 20+++++++++++++++++---
Msrc/lib.rs | 7++++---
Asrc/mmu_hal.rs | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/mmu_ll/esp32s3.rs | 22++++++++++++++++++++++
Asrc/mmu_ll/mod.rs | 4++++
Msrc/paddr.rs | 23++++++++++++++++++++---
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);