Update PAC (#3794)

This commit is contained in:
Dániel Buga 2025-07-15 12:38:29 +02:00 committed by GitHub
parent 6db771c80e
commit 906fa56435
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 88 additions and 105 deletions

View File

@ -73,13 +73,13 @@ ufmt-write = { version = "0.1.0", optional = true }
# IMPORTANT:
# Each supported device MUST have its PAC included below along with a
# corresponding feature.
esp32 = { version = "0.37.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "fba5fb9", optional = true }
esp32c2 = { version = "0.26.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "fba5fb9", optional = true }
esp32c3 = { version = "0.29.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "fba5fb9", optional = true }
esp32c6 = { version = "0.20.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "fba5fb9", optional = true }
esp32h2 = { version = "0.16.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "fba5fb9", optional = true }
esp32s2 = { version = "0.28.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "fba5fb9", optional = true }
esp32s3 = { version = "0.32.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "fba5fb9", optional = true }
esp32 = { version = "0.37.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "cd948ef", optional = true }
esp32c2 = { version = "0.26.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "cd948ef", optional = true }
esp32c3 = { version = "0.29.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "cd948ef", optional = true }
esp32c6 = { version = "0.20.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "cd948ef", optional = true }
esp32h2 = { version = "0.16.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "cd948ef", optional = true }
esp32s2 = { version = "0.28.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "cd948ef", optional = true }
esp32s3 = { version = "0.32.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "cd948ef", optional = true }
[target.'cfg(target_arch = "riscv32")'.dependencies]
riscv = { version = "0.12.1" }

View File

@ -234,17 +234,8 @@ pub fn enable_direct(
}
/// Disable the given peripheral interrupt.
pub fn disable(_core: Cpu, interrupt: Interrupt) {
unsafe {
let interrupt_number = interrupt as isize;
let intr_map_base = crate::soc::registers::INTERRUPT_MAP_BASE as *mut u32;
// set to 0 to disable the peripheral interrupt on chips with an interrupt
// controller other than PLIC use the disabled interrupt 31 otherwise
intr_map_base
.offset(interrupt_number)
.write_volatile(DISABLED_CPU_INTERRUPT);
}
pub fn disable(core: Cpu, interrupt: Interrupt) {
map_raw(core, interrupt, DISABLED_CPU_INTERRUPT)
}
/// Get status of peripheral interrupts
@ -253,21 +244,21 @@ pub fn status(_core: Cpu) -> InterruptStatus {
cfg_if::cfg_if! {
if #[cfg(interrupts_status_registers = "3")] {
InterruptStatus::from(
INTERRUPT_CORE0::regs().intr_status_reg_0().read().bits(),
INTERRUPT_CORE0::regs().intr_status_reg_1().read().bits(),
INTERRUPT_CORE0::regs().int_status_reg_2().read().bits(),
INTERRUPT_CORE0::regs().core_0_intr_status(0).read().bits(),
INTERRUPT_CORE0::regs().core_0_intr_status(1).read().bits(),
INTERRUPT_CORE0::regs().core_0_intr_status(2).read().bits(),
)
} else if #[cfg(interrupts_status_registers = "4")] {
InterruptStatus::from(
INTERRUPT_CORE0::regs().intr_status_reg_0().read().bits(),
INTERRUPT_CORE0::regs().intr_status_reg_1().read().bits(),
INTERRUPT_CORE0::regs().intr_status_reg_2().read().bits(),
INTERRUPT_CORE0::regs().intr_status_reg_3().read().bits(),
INTERRUPT_CORE0::regs().core_0_intr_status(0).read().bits(),
INTERRUPT_CORE0::regs().core_0_intr_status(1).read().bits(),
INTERRUPT_CORE0::regs().core_0_intr_status(2).read().bits(),
INTERRUPT_CORE0::regs().core_0_intr_status(3).read().bits(),
)
} else {
InterruptStatus::from(
INTERRUPT_CORE0::regs().intr_status_reg_0().read().bits(),
INTERRUPT_CORE0::regs().intr_status_reg_1().read().bits(),
INTERRUPT_CORE0::regs().core_0_intr_status(0).read().bits(),
INTERRUPT_CORE0::regs().core_0_intr_status(1).read().bits(),
)
}
}
@ -278,21 +269,25 @@ pub fn status(_core: Cpu) -> InterruptStatus {
/// # Safety
///
/// Do not use CPU interrupts in the [`RESERVED_INTERRUPTS`].
pub unsafe fn map(_core: Cpu, interrupt: Interrupt, which: CpuInterrupt) {
let interrupt_number = interrupt as isize;
let cpu_interrupt_number = which as isize;
#[cfg(not(multi_core))]
let intr_map_base = crate::soc::registers::INTERRUPT_MAP_BASE as *mut u32;
#[cfg(multi_core)]
let intr_map_base = match _core {
Cpu::ProCpu => crate::soc::registers::INTERRUPT_MAP_BASE as *mut u32,
Cpu::AppCpu => crate::soc::registers::INTERRUPT_MAP_BASE_APP_CPU as *mut u32,
};
pub unsafe fn map(core: Cpu, interrupt: Interrupt, which: CpuInterrupt) {
map_raw(core, interrupt, which as u32)
}
unsafe {
intr_map_base
.offset(interrupt_number)
.write_volatile(cpu_interrupt_number as u32 + EXTERNAL_INTERRUPT_OFFSET);
fn map_raw(core: Cpu, interrupt: Interrupt, cpu_interrupt_number: u32) {
let interrupt_number = interrupt as usize;
match core {
Cpu::ProCpu => {
INTERRUPT_CORE0::regs()
.core_0_intr_map(interrupt_number)
.write(|w| unsafe { w.bits(cpu_interrupt_number) });
}
#[cfg(multi_core)]
Cpu::AppCpu => {
INTERRUPT_CORE1::regs()
.core_1_intr_map(interrupt_number)
.write(|w| unsafe { w.bits(cpu_interrupt_number) });
}
}
}
@ -304,9 +299,7 @@ unsafe fn assigned_cpu_interrupt(interrupt: Interrupt) -> Option<CpuInterrupt> {
let cpu_intr = unsafe { intr_map_base.offset(interrupt_number).read_volatile() };
if cpu_intr > 0 && cpu_intr != DISABLED_CPU_INTERRUPT {
Some(unsafe {
core::mem::transmute::<u32, CpuInterrupt>(cpu_intr - EXTERNAL_INTERRUPT_OFFSET)
})
Some(unsafe { core::mem::transmute::<u32, CpuInterrupt>(cpu_intr) })
} else {
None
}
@ -425,9 +418,6 @@ mod classic {
#[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub(super) static DISABLED_CPU_INTERRUPT: u32 = 0;
#[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub(super) static EXTERNAL_INTERRUPT_OFFSET: u32 = 0;
#[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub(super) static PRIORITY_TO_INTERRUPT: &[usize] =
&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
@ -592,9 +582,6 @@ mod plic {
#[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub(super) static DISABLED_CPU_INTERRUPT: u32 = 31;
#[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub(super) static EXTERNAL_INTERRUPT_OFFSET: u32 = 0;
// don't use interrupts reserved for CLIC (0,3,4,7)
// for some reason also CPU interrupt 8 doesn't work by default since it's
// disabled after reset - so don't use that, too

View File

@ -174,31 +174,41 @@ pub fn enable_direct(interrupt: Interrupt, cpu_interrupt: CpuInterrupt) -> Resul
/// # Safety
///
/// Do not use CPU interrupts in the [`RESERVED_INTERRUPTS`].
pub unsafe fn map(core: Cpu, interrupt: Interrupt, which: CpuInterrupt) {
let interrupt_number = interrupt as isize;
let cpu_interrupt_number = which as isize;
unsafe {
let intr_map_base = match core {
Cpu::ProCpu => (*core0_interrupt_peripheral()).pro_mac_intr_map().as_ptr(),
#[cfg(multi_core)]
Cpu::AppCpu => (*core1_interrupt_peripheral()).app_mac_intr_map().as_ptr(),
};
intr_map_base
.offset(interrupt_number)
.write_volatile(cpu_interrupt_number as u32);
pub unsafe fn map(cpu: Cpu, interrupt: Interrupt, which: CpuInterrupt) {
let interrupt_number = interrupt as usize;
let cpu_interrupt_number = which as u32;
match cpu {
Cpu::ProCpu => unsafe {
(*core0_interrupt_peripheral())
.core_0_intr_map(interrupt_number)
.write(|w| w.bits(cpu_interrupt_number));
},
#[cfg(multi_core)]
Cpu::AppCpu => unsafe {
(*core1_interrupt_peripheral())
.core_1_intr_map(interrupt_number)
.write(|w| w.bits(cpu_interrupt_number));
},
}
}
/// Get cpu interrupt assigned to peripheral interrupt
pub(crate) fn bound_cpu_interrupt_for(cpu: Cpu, interrupt: Interrupt) -> Option<CpuInterrupt> {
let interrupt_number = interrupt as isize;
let intr_map_base = match cpu {
Cpu::ProCpu => unsafe { (*core0_interrupt_peripheral()).pro_mac_intr_map().as_ptr() },
let cpu_intr = match cpu {
Cpu::ProCpu => unsafe {
(*core0_interrupt_peripheral())
.core_0_intr_map(interrupt as usize)
.read()
.bits()
},
#[cfg(multi_core)]
Cpu::AppCpu => unsafe { (*core1_interrupt_peripheral()).app_mac_intr_map().as_ptr() },
Cpu::AppCpu => unsafe {
(*core1_interrupt_peripheral())
.core_1_intr_map(interrupt as usize)
.read()
.bits()
},
};
let cpu_intr = unsafe { intr_map_base.offset(interrupt_number).read_volatile() };
let cpu_intr = CpuInterrupt::from_u32(cpu_intr)?;
if cpu_intr.is_peripheral() {
@ -210,18 +220,7 @@ pub(crate) fn bound_cpu_interrupt_for(cpu: Cpu, interrupt: Interrupt) -> Option<
/// Disable the given peripheral interrupt
pub fn disable(core: Cpu, interrupt: Interrupt) {
unsafe {
let interrupt_number = interrupt as isize;
let intr_map_base = match core {
Cpu::ProCpu => (*core0_interrupt_peripheral()).pro_mac_intr_map().as_ptr(),
#[cfg(multi_core)]
Cpu::AppCpu => (*core1_interrupt_peripheral()).app_mac_intr_map().as_ptr(),
};
// To disable an interrupt, map it to a CPU peripheral interrupt
intr_map_base
.offset(interrupt_number)
.write_volatile(CpuInterrupt::Interrupt16Timer2Priority5 as _);
}
unsafe { map(core, interrupt, CpuInterrupt::Interrupt16Timer2Priority5) }
}
/// Clear the given CPU interrupt
@ -238,30 +237,30 @@ pub fn status(core: Cpu) -> InterruptStatus {
match core {
Cpu::ProCpu => InterruptStatus::from(
(*core0_interrupt_peripheral())
.pro_intr_status_0()
.core_0_intr_status(0)
.read()
.bits(),
(*core0_interrupt_peripheral())
.pro_intr_status_1()
.core_0_intr_status(1)
.read()
.bits(),
(*core0_interrupt_peripheral())
.pro_intr_status_2()
.core_0_intr_status(2)
.read()
.bits(),
),
#[cfg(multi_core)]
Cpu::AppCpu => InterruptStatus::from(
(*core1_interrupt_peripheral())
.app_intr_status_0()
.core_1_intr_status(0)
.read()
.bits(),
(*core1_interrupt_peripheral())
.app_intr_status_1()
.core_1_intr_status(1)
.read()
.bits(),
(*core1_interrupt_peripheral())
.app_intr_status_2()
.core_1_intr_status(2)
.read()
.bits(),
),
@ -276,38 +275,38 @@ pub fn status(core: Cpu) -> InterruptStatus {
match core {
Cpu::ProCpu => InterruptStatus::from(
(*core0_interrupt_peripheral())
.pro_intr_status_0()
.core_0_intr_status(0)
.read()
.bits(),
(*core0_interrupt_peripheral())
.pro_intr_status_1()
.core_0_intr_status(1)
.read()
.bits(),
(*core0_interrupt_peripheral())
.pro_intr_status_2()
.core_0_intr_status(2)
.read()
.bits(),
(*core0_interrupt_peripheral())
.pro_intr_status_3()
.core_0_intr_status(3)
.read()
.bits(),
),
#[cfg(multi_core)]
Cpu::AppCpu => InterruptStatus::from(
(*core1_interrupt_peripheral())
.app_intr_status_0()
.core_1_intr_status(0)
.read()
.bits(),
(*core1_interrupt_peripheral())
.app_intr_status_1()
.core_1_intr_status(1)
.read()
.bits(),
(*core1_interrupt_peripheral())
.app_intr_status_2()
.core_1_intr_status(2)
.read()
.bits(),
(*core1_interrupt_peripheral())
.app_intr_status_3()
.core_1_intr_status(3)
.read()
.bits(),
),
@ -475,9 +474,9 @@ mod vectored {
) -> InterruptStatus {
unsafe {
let intr_map_base = match core {
Cpu::ProCpu => (*core0_interrupt_peripheral()).pro_mac_intr_map().as_ptr(),
Cpu::ProCpu => (*core0_interrupt_peripheral()).core_0_intr_map(0).as_ptr(),
#[cfg(multi_core)]
Cpu::AppCpu => (*core1_interrupt_peripheral()).app_mac_intr_map().as_ptr(),
Cpu::AppCpu => (*core1_interrupt_peripheral()).core_1_intr_map(0).as_ptr(),
};
let mut res = InterruptStatus::empty();

View File

@ -1,21 +1,18 @@
use crate::hal::peripherals::{INTERRUPT_CORE0, Interrupt};
#[cfg(any(feature = "wifi", feature = "ble"))]
#[allow(unused_imports)]
use crate::{
binary,
hal::{interrupt, peripherals::Interrupt},
};
use crate::{binary, hal::interrupt};
pub(crate) fn setup_radio_isr() {
use crate::hal::peripherals::INTERRUPT_CORE0;
// make sure to disable WIFI_BB/MODEM_PERI_TIMEOUT by mapping it to CPU
// interrupt 31 which is masked by default for some reason for this
// interrupt, mapping it to 0 doesn't deactivate it
INTERRUPT_CORE0::regs()
.wifi_bb_intr_map()
.write(|w| unsafe { w.wifi_bb_intr_map().bits(31) });
.core_0_intr_map(Interrupt::WIFI_BB as usize)
.write(|w| unsafe { w.bits(31) });
INTERRUPT_CORE0::regs()
.modem_peri_timeout_intr_map()
.write(|w| unsafe { w.modem_peri_timeout_intr_map().bits(31) });
.core_0_intr_map(Interrupt::MODEM_PERI_TIMEOUT as usize)
.write(|w| unsafe { w.bits(31) });
}
pub(crate) fn shutdown_radio_isr() {