eculocate

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

commit b67b5ae5ebbda634fbd7cb802d3a8fcbd7ea78dc
parent 43d1c36bfec21b22256aa7cd5a3965e4b7da3633
Author: filipton <filipton12@gmail.com>
Date:   Thu,  2 Jan 2025 17:14:34 +0100

wip: port esp32

Diffstat:
MCargo.lock | 10++++++++++
MCargo.toml | 4++++
Msrc/lib.rs | 1+
Asrc/mmu_ll/esp32.rs | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/mmu_ll/esp32s2.rs | 45++++++++++++++++++---------------------------
Msrc/mmu_ll/mod.rs | 12++++++++++++
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")]