Skip to content

Commit bec390c

Browse files
committed
Refactor MMU related code into its own module
1 parent 24f8458 commit bec390c

File tree

3 files changed

+51
-39
lines changed

3 files changed

+51
-39
lines changed

esp-hal/src/soc/esp32s3/mmu.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//! Thin MMU bindings
2+
//!
3+
//! More general information about the MMU can be found here:
4+
//! https://docs.espressif.com/projects/esp-idf/en/stable/esp32s3/api-reference/system/mm.html#introduction
5+
6+
const DBUS_VADDR_BASE: u32 = 0x3C000000;
7+
const DR_REG_MMU_TABLE: u32 = 0x600C5000;
8+
const ENTRY_INVALID: u32 = 1 << 14;
9+
const ICACHE_MMU_SIZE: usize = 0x800;
10+
const TABLE_SIZE: usize = ICACHE_MMU_SIZE / core::mem::size_of::<u32>();
11+
12+
pub(super) const ENTRY_ACCESS_SPIRAM: u32 = 1 << 15;
13+
pub(super) const PAGE_SIZE: usize = 0x10000;
14+
15+
extern "C" {
16+
/// Set DCache mmu mapping.
17+
///
18+
/// [`ext_ram`]: u32 ENTRY_ACCESS_FLASH for flash, ENTRY_ACCESS_SPIRAM for spiram, ENTRY_INVALID for invalid.
19+
/// [`vaddr`]: u32 Virtual address in CPU address space.
20+
/// [`paddr`]: u32 Physical address in external memory. Should be aligned by psize.
21+
/// [`psize`]: u32 Page size of DCache, in kilobytes. Should be 64 here.
22+
/// [`num`]: u32 Pages to be set.
23+
/// [`fixes`]: u32 0 for physical pages grow with virtual pages, other for virtual pages map to same physical page.
24+
pub(super) fn cache_dbus_mmu_set(
25+
ext_ram: u32,
26+
vaddr: u32,
27+
paddr: u32,
28+
psize: u32,
29+
num: u32,
30+
fixed: u32,
31+
) -> i32;
32+
}
33+
34+
#[procmacros::ram]
35+
pub(super) fn last_mapped_index() -> Option<usize> {
36+
let mmu_table_ptr = DR_REG_MMU_TABLE as *const u32;
37+
(0..TABLE_SIZE)
38+
.rev()
39+
.find(|&i| unsafe { mmu_table_ptr.add(i).read_volatile() } != ENTRY_INVALID)
40+
}
41+
42+
#[procmacros::ram]
43+
pub(super) fn index_to_data_address(index: usize) -> u32 {
44+
DBUS_VADDR_BASE + (PAGE_SIZE * index) as u32
45+
}

esp-hal/src/soc/esp32s3/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ crate::unstable_module! {
2323
}
2424
pub mod cpu_control;
2525
pub mod gpio;
26+
mod mmu;
2627
pub mod peripherals;
2728

2829
/// The name of the chip ("esp32s3") as `&str`

esp-hal/src/soc/esp32s3/psram.rs

Lines changed: 5 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,10 @@
5757
//! # }
5858
//! ```
5959
60+
use super::mmu;
6061
use crate::peripherals::{EXTMEM, IO_MUX, SPI0, SPI1};
6162
pub use crate::soc::psram_common::*;
6263

63-
const EXTMEM_ORIGIN: u32 = 0x3C000000;
64-
6564
/// Frequency of flash memory
6665
#[derive(Copy, Clone, Debug, Default)]
6766
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -125,7 +124,6 @@ pub(crate) fn init_psram(config: PsramConfig) {
125124
const CONFIG_ESP32S3_DATA_CACHE_SIZE: u32 = 0x8000;
126125
const CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS: u8 = 8;
127126
const CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE: u8 = 32;
128-
const MMU_ACCESS_SPIRAM: u32 = 1 << 15;
129127
const START_PAGE: u32 = 0;
130128

131129
extern "C" {
@@ -144,48 +142,16 @@ pub(crate) fn init_psram(config: PsramConfig) {
144142
);
145143

146144
fn Cache_Resume_DCache(param: u32);
147-
148-
/// Set DCache mmu mapping.
149-
///
150-
/// [`ext_ram`]: u32 DPORT_MMU_ACCESS_FLASH for flash, DPORT_MMU_ACCESS_SPIRAM for spiram, DPORT_MMU_INVALID for invalid.
151-
/// [`vaddr`]: u32 Virtual address in CPU address space.
152-
/// [`paddr`]: u32 Physical address in external memory. Should be aligned by psize.
153-
/// [`psize`]: u32 Page size of DCache, in kilobytes. Should be 64 here.
154-
/// [`num`]: u32 Pages to be set.
155-
/// [`fixes`]: u32 0 for physical pages grow with virtual pages, other for virtual pages map to same physical page.
156-
fn cache_dbus_mmu_set(
157-
ext_ram: u32,
158-
vaddr: u32,
159-
paddr: u32,
160-
psize: u32,
161-
num: u32,
162-
fixed: u32,
163-
) -> i32;
164145
}
165146

166147
let start = unsafe {
167-
const MMU_PAGE_SIZE: u32 = 0x10000;
168-
const ICACHE_MMU_SIZE: usize = 0x800;
169-
const FLASH_MMU_TABLE_SIZE: usize = ICACHE_MMU_SIZE / core::mem::size_of::<u32>();
170-
const MMU_INVALID: u32 = 1 << 14;
171-
const DR_REG_MMU_TABLE: u32 = 0x600C5000;
172148

173149
// calculate the PSRAM start address to map
174150
// the linker scripts can produce a gap between mapped IROM and DROM segments
175151
// bigger than a flash page - i.e. we will see an unmapped memory slot
176152
// start from the end and find the last mapped flash page
177-
//
178-
// More general information about the MMU can be found here:
179-
// https://docs.espressif.com/projects/esp-idf/en/stable/esp32s3/api-reference/system/mm.html#introduction
180-
let mmu_table_ptr = DR_REG_MMU_TABLE as *const u32;
181-
let mut mapped_pages = 0;
182-
for i in (0..FLASH_MMU_TABLE_SIZE).rev() {
183-
if mmu_table_ptr.add(i).read_volatile() != MMU_INVALID {
184-
mapped_pages = (i + 1) as u32;
185-
break;
186-
}
187-
}
188-
let start = EXTMEM_ORIGIN + (MMU_PAGE_SIZE * mapped_pages);
153+
let psram_start_index = mmu::last_mapped_index().map(|e| e + 1).unwrap_or(0);
154+
let start = mmu::index_to_data_address(psram_start_index);
189155
debug!("PSRAM start address = {:x}", start);
190156

191157
// Configure the mode of instruction cache : cache size, cache line size.
@@ -205,8 +171,8 @@ pub(crate) fn init_psram(config: PsramConfig) {
205171
CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE,
206172
);
207173

208-
if cache_dbus_mmu_set(
209-
MMU_ACCESS_SPIRAM,
174+
if mmu::cache_dbus_mmu_set(
175+
mmu::ENTRY_ACCESS_SPIRAM,
210176
start,
211177
START_PAGE << 16,
212178
64,

0 commit comments

Comments
 (0)