commit b67b5ae5ebbda634fbd7cb802d3a8fcbd7ea78dc
parent 43d1c36bfec21b22256aa7cd5a3965e4b7da3633
Author: filipton <filipton12@gmail.com>
Date: Thu, 2 Jan 2025 17:14:34 +0100
wip: port esp32
Diffstat:
6 files changed, 141 insertions(+), 27 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -13,6 +13,7 @@ name = "esp-hal-ota"
version = "0.1.4"
dependencies = [
"embedded-storage",
+ "esp32",
"esp32c2",
"esp32c3",
"esp32c6",
@@ -23,6 +24,15 @@ dependencies = [
]
[[package]]
+name = "esp32"
+version = "0.34.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af7d3208ef4ffd96c3105b3fb6fd19e8512bc128b24cb866dc26a734b09f454c"
+dependencies = [
+ "vcell",
+]
+
+[[package]]
name = "esp32c2"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
@@ -12,6 +12,8 @@ repository = "https://github.com/filipton/esp-hal-ota"
embedded-storage = "0.3.1"
log = { version = "0.4.22", optional = true }
+esp32 = { version = "0.34.0", optional = true }
+
esp32s2 = { version = "0.25.0", optional = true }
esp32s3 = { version = "0.29.0", optional = true }
@@ -25,6 +27,8 @@ esp32h2 = { version = "0.13.0", optional = true }
default = ["log"]
log = ["dep:log"]
+esp32 = ["dep:esp32"]
+
esp32s2 = ["dep:esp32s2"]
esp32s3 = ["dep:esp32s3"]
diff --git a/src/lib.rs b/src/lib.rs
@@ -1,5 +1,6 @@
#![no_std]
#![feature(concat_idents)]
+#![cfg_attr(feature = "esp32", feature(asm_experimental_arch))]
#![doc = include_str!("../README.md")]
use embedded_storage::{ReadStorage, Storage};
diff --git a/src/mmu_ll/esp32.rs b/src/mmu_ll/esp32.rs
@@ -0,0 +1,96 @@
+const SOC_MMU_VADDR_MASK: u32 = 0x3FFFFF;
+const SOC_MMU_INVALID: u32 = 1 << 8;
+const MMU_LL_PSRAM_ENTRY_START_ID: u32 = 1152;
+const SOC_IRAM0_CACHE_ADDRESS_LOW: u32 = 0x400D0000;
+const SOC_IRAM0_CACHE_ADDRESS_HIGH: u32 = 0x40400000;
+const SOC_IRAM1_CACHE_ADDRESS_LOW: u32 = 0x40400000;
+const SOC_IRAM1_CACHE_ADDRESS_HIGH: u32 = 0x40800000;
+const SOC_IROM0_CACHE_ADDRESS_LOW: u32 = 0x40800000;
+const SOC_IROM0_CACHE_ADDRESS_HIGH: u32 = 0x40C00000;
+const SOC_DRAM1_CACHE_ADDRESS_LOW: u32 = 0x3F800000;
+const SOC_DRAM1_CACHE_ADDRESS_HIGH: u32 = 0x3FC00000;
+const SOC_DROM0_CACHE_ADDRESS_LOW: u32 = 0x3F400000;
+const SOC_DROM0_CACHE_ADDRESS_HIGH: u32 = 0x3F800000;
+const DPORT_PRO_FLASH_MMU_TABLE: u32 = 0x3FF10000;
+
+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 mut offset = 0;
+ let mut shift_code = 0;
+ let mut vaddr_mask = 0;
+
+ if soc_address_in_bus!(SOC_DROM0_CACHE, vaddr) {
+ offset = 0;
+ shift_code = 16;
+ vaddr_mask = SOC_MMU_VADDR_MASK;
+ } else if soc_address_in_bus!(SOC_IRAM0_CACHE, vaddr) {
+ offset = 64;
+ shift_code = 16;
+ vaddr_mask = SOC_MMU_VADDR_MASK;
+ } else if soc_address_in_bus!(SOC_IRAM1_CACHE, vaddr) {
+ offset = 128;
+ shift_code = 16;
+ vaddr_mask = SOC_MMU_VADDR_MASK;
+ } else if soc_address_in_bus!(SOC_IROM0_CACHE, vaddr) {
+ offset = 192;
+ shift_code = 16;
+ vaddr_mask = SOC_MMU_VADDR_MASK;
+ } else if soc_address_in_bus!(SOC_DRAM1_CACHE, vaddr) {
+ offset = MMU_LL_PSRAM_ENTRY_START_ID;
+ shift_code = 15;
+ vaddr_mask = SOC_MMU_VADDR_MASK >> 1;
+ } else {
+ #[cfg(feature = "log")]
+ log::error!("mmu_ll_get_entry_id failed!");
+ }
+
+ offset + ((vaddr & vaddr_mask) >> shift_code)
+}
+
+pub fn mmu_ll_entry_id_to_paddr_base(_mmu_id: u32, entry_id: u32) -> u32 {
+ let level = unsafe { dport_interrupt_disable() };
+ let mmu_val = unsafe { *(DPORT_PRO_FLASH_MMU_TABLE as *const u32).offset(entry_id as isize) };
+ unsafe { dport_interrupt_restore(level) };
+
+ if entry_id >= MMU_LL_PSRAM_ENTRY_START_ID {
+ mmu_val << 15
+ } else {
+ mmu_val << 16
+ }
+}
+
+pub fn mmu_ll_check_entry_valid(_mmu_id: u32, entry_id: u32) -> bool {
+ let level = unsafe { dport_interrupt_disable() };
+ let mmu_val = unsafe { *(DPORT_PRO_FLASH_MMU_TABLE as *const u32).offset(entry_id as isize) };
+ unsafe { dport_interrupt_restore(level) };
+
+ (mmu_val & SOC_MMU_INVALID) == 0
+}
+
+// NOTE:Idk if required!
+// Only used when using second core etc.
+
+const SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL: u32 = 5;
+#[inline(always)]
+unsafe fn dport_interrupt_disable() -> u32 {
+ let level: u32;
+ core::arch::asm!(
+ "rsil {0}, {1}",
+ out(reg) level,
+ const SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL,
+ options(nomem, nostack)
+ );
+ level
+}
+
+#[inline(always)]
+unsafe fn dport_interrupt_restore(level: u32) {
+ core::arch::asm!(
+ "wsr.ps {0}; rsync",
+ in(reg) level,
+ options(nomem, nostack)
+ );
+}
diff --git a/src/mmu_ll/esp32s2.rs b/src/mmu_ll/esp32s2.rs
@@ -2,13 +2,24 @@ 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)
- }};
-}
+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;
pub fn mmu_ll_get_page_size(_mmu_id: u32) -> u32 {
crate::mmu_hal::MMU_PAGE_64KB
@@ -46,23 +57,3 @@ 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/mod.rs b/src/mmu_ll/mod.rs
@@ -1,3 +1,15 @@
+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)
+ }};
+}
+
+#[cfg(feature = "esp32")]
+mod esp32;
+#[cfg(feature = "esp32")]
+pub use esp32::*;
+
#[cfg(feature = "esp32s2")]
mod esp32s2;
#[cfg(feature = "esp32s2")]