Updates for Xtensa enabled 1.83 compiler (#2615)
* test ci * fix ci with new compiler * god bless clippy fix * refmuts * clippy * tests work * use new compiler * use new compiler * bump MSRV of esp-hal and crates that depend on esp-hal * fix eyesore * clippy again * remove hardcoded compiler version * bump rust-version as well * note MSRV bump in changelog
This commit is contained in:
parent
a12e7fece1
commit
85d30e9816
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -23,7 +23,7 @@ on:
|
|||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
MSRV: "1.79.0"
|
MSRV: "1.83.0"
|
||||||
RUSTDOCFLAGS: -Dwarnings
|
RUSTDOCFLAGS: -Dwarnings
|
||||||
DEFMT_LOG: trace
|
DEFMT_LOG: trace
|
||||||
|
|
||||||
|
|||||||
@ -7,10 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- Bump MSRV to 1.83 (#2615)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
name = "esp-hal-embassy"
|
name = "esp-hal-embassy"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79.0"
|
rust-version = "1.83.0"
|
||||||
description = "Embassy support for esp-hal"
|
description = "Embassy support for esp-hal"
|
||||||
repository = "https://github.com/esp-rs/esp-hal"
|
repository = "https://github.com/esp-rs/esp-hal"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[](https://crates.io/crates/esp-hal-embassy)
|
[](https://crates.io/crates/esp-hal-embassy)
|
||||||
[](https://docs.rs/esp-hal-embassy)
|
[](https://docs.rs/esp-hal-embassy)
|
||||||

|

|
||||||

|

|
||||||
[](https://matrix.to/#/#esp-rs:matrix.org)
|
[](https://matrix.to/#/#esp-rs:matrix.org)
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ Note that this crate currently requires you to enable the `unstable` feature on
|
|||||||
|
|
||||||
## Minimum Supported Rust Version (MSRV)
|
## Minimum Supported Rust Version (MSRV)
|
||||||
|
|
||||||
This crate is guaranteed to compile on stable Rust 1.79 and up. It _might_
|
This crate is guaranteed to compile on stable Rust 1.83 and up. It _might_
|
||||||
compile with older versions but that may change in any new patch release.
|
compile with older versions but that may change in any new patch release.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
name = "esp-hal-procmacros"
|
name = "esp-hal-procmacros"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.76.0"
|
rust-version = "1.83.0"
|
||||||
description = "Procedural macros for esp-hal"
|
description = "Procedural macros for esp-hal"
|
||||||
repository = "https://github.com/esp-rs/esp-hal"
|
repository = "https://github.com/esp-rs/esp-hal"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|||||||
@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- ESP32-S3: Added SDMMC signals (#2556)
|
- ESP32-S3: Added SDMMC signals (#2556)
|
||||||
@ -35,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- Bump MSRV to 1.83 (#2615)
|
||||||
- In addition to taking by value, peripheral drivers can now mutably borrow DMA channel objects. (#2526)
|
- In addition to taking by value, peripheral drivers can now mutably borrow DMA channel objects. (#2526)
|
||||||
- DMA channel objects are no longer wrapped in `Channel`. The `Channel` drivers are now managed by DMA enabled peripheral drivers. (#2526)
|
- DMA channel objects are no longer wrapped in `Channel`. The `Channel` drivers are now managed by DMA enabled peripheral drivers. (#2526)
|
||||||
- The `Dpi` driver and `DpiTransfer` now have a `Mode` type parameter. The driver's asyncness is determined by the asyncness of the `Lcd` used to create it. (#2526)
|
- The `Dpi` driver and `DpiTransfer` now have a `Mode` type parameter. The driver's asyncness is determined by the asyncness of the `Lcd` used to create it. (#2526)
|
||||||
@ -200,8 +202,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [0.21.0]
|
## [0.21.0]
|
||||||
|
|
||||||
- Bump MSRV to 1.79.0 (#1971)
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Introduce traits for the DMA buffer objects (#1976, #2213)
|
- Introduce traits for the DMA buffer objects (#1976, #2213)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
name = "esp-hal"
|
name = "esp-hal"
|
||||||
version = "0.22.0"
|
version = "0.22.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79.0"
|
rust-version = "1.83.0"
|
||||||
description = "Bare-metal HAL for Espressif devices"
|
description = "Bare-metal HAL for Espressif devices"
|
||||||
documentation = "https://docs.esp-rs.org/esp-hal/"
|
documentation = "https://docs.esp-rs.org/esp-hal/"
|
||||||
repository = "https://github.com/esp-rs/esp-hal"
|
repository = "https://github.com/esp-rs/esp-hal"
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[](https://crates.io/crates/esp-hal)
|
[](https://crates.io/crates/esp-hal)
|
||||||
[](https://docs.esp-rs.org/esp-hal)
|
[](https://docs.esp-rs.org/esp-hal)
|
||||||

|

|
||||||

|

|
||||||
[](https://matrix.to/#/#esp-rs:matrix.org)
|
[](https://matrix.to/#/#esp-rs:matrix.org)
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a
|
|||||||
|
|
||||||
## Minimum Supported Rust Version (MSRV)
|
## Minimum Supported Rust Version (MSRV)
|
||||||
|
|
||||||
This crate is guaranteed to compile on stable Rust 1.79 and up. It _might_
|
This crate is guaranteed to compile on stable Rust 1.83 and up. It _might_
|
||||||
compile with older versions but that may change in any new patch release.
|
compile with older versions but that may change in any new patch release.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|||||||
@ -327,7 +327,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, ADC1> Adc<'d, ADC1> {
|
impl<ADC1> Adc<'_, ADC1> {
|
||||||
/// Enable the Hall sensor
|
/// Enable the Hall sensor
|
||||||
pub fn enable_hall_sensor() {
|
pub fn enable_hall_sensor() {
|
||||||
unsafe { &*RTC_IO::ptr() }
|
unsafe { &*RTC_IO::ptr() }
|
||||||
|
|||||||
@ -391,7 +391,7 @@ impl DebugAssist<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(assist_debug_region_monitor, multi_core))]
|
#[cfg(all(assist_debug_region_monitor, multi_core))]
|
||||||
impl<'d> DebugAssist<'d> {
|
impl DebugAssist<'_> {
|
||||||
/// Enable region monitoring of read/write performed by the secondary CPU in
|
/// Enable region monitoring of read/write performed by the secondary CPU in
|
||||||
/// a certain memory region0. Whenever the bus reads or writes in the
|
/// a certain memory region0. Whenever the bus reads or writes in the
|
||||||
/// specified memory region, an interrupt will be triggered.
|
/// specified memory region, an interrupt will be triggered.
|
||||||
|
|||||||
@ -1892,7 +1892,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, M, CH> ChannelRx<'a, M, CH>
|
impl<M, CH> ChannelRx<'_, M, CH>
|
||||||
where
|
where
|
||||||
M: Mode,
|
M: Mode,
|
||||||
CH: DmaRxChannel,
|
CH: DmaRxChannel,
|
||||||
@ -2186,7 +2186,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, M, CH> ChannelTx<'a, M, CH>
|
impl<M, CH> ChannelTx<'_, M, CH>
|
||||||
where
|
where
|
||||||
M: Mode,
|
M: Mode,
|
||||||
CH: DmaTxChannel,
|
CH: DmaTxChannel,
|
||||||
|
|||||||
@ -194,7 +194,7 @@ pub(super) fn init_dma(_cs: CriticalSection<'_>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, CH, M> Channel<'d, M, CH>
|
impl<CH, M> Channel<'_, M, CH>
|
||||||
where
|
where
|
||||||
CH: DmaChannel,
|
CH: DmaChannel,
|
||||||
M: Mode,
|
M: Mode,
|
||||||
|
|||||||
@ -2459,7 +2459,7 @@ mod asynch {
|
|||||||
pin: Flex<'d, P>,
|
pin: Flex<'d, P>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, P: InputPin> PinFuture<'d, P> {
|
impl<P: InputPin> PinFuture<'_, P> {
|
||||||
fn pin_mask(&self) -> u32 {
|
fn pin_mask(&self) -> u32 {
|
||||||
let bank = self.pin.gpio_bank(private::Internal);
|
let bank = self.pin.gpio_bank(private::Internal);
|
||||||
1 << (self.pin.number() - bank.offset())
|
1 << (self.pin.number() - bank.offset())
|
||||||
|
|||||||
@ -401,7 +401,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, I, BUF, DM> Deref for I2sParallelTransfer<'d, BUF, DM, I>
|
impl<I, BUF, DM> Deref for I2sParallelTransfer<'_, BUF, DM, I>
|
||||||
where
|
where
|
||||||
I: Instance,
|
I: Instance,
|
||||||
BUF: DmaTxBuffer,
|
BUF: DmaTxBuffer,
|
||||||
@ -414,7 +414,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, I, BUF, DM> DerefMut for I2sParallelTransfer<'d, BUF, DM, I>
|
impl<I, BUF, DM> DerefMut for I2sParallelTransfer<'_, BUF, DM, I>
|
||||||
where
|
where
|
||||||
I: Instance,
|
I: Instance,
|
||||||
BUF: DmaTxBuffer,
|
BUF: DmaTxBuffer,
|
||||||
@ -425,7 +425,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, I, BUF, DM> Drop for I2sParallelTransfer<'d, BUF, DM, I>
|
impl<I, BUF, DM> Drop for I2sParallelTransfer<'_, BUF, DM, I>
|
||||||
where
|
where
|
||||||
I: Instance,
|
I: Instance,
|
||||||
BUF: DmaTxBuffer,
|
BUF: DmaTxBuffer,
|
||||||
|
|||||||
@ -432,7 +432,7 @@ impl<'d, BUF: DmaRxBuffer> CameraTransfer<'d, BUF> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, BUF: DmaRxBuffer> Deref for CameraTransfer<'d, BUF> {
|
impl<BUF: DmaRxBuffer> Deref for CameraTransfer<'_, BUF> {
|
||||||
type Target = BUF::View;
|
type Target = BUF::View;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
@ -440,13 +440,13 @@ impl<'d, BUF: DmaRxBuffer> Deref for CameraTransfer<'d, BUF> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, BUF: DmaRxBuffer> DerefMut for CameraTransfer<'d, BUF> {
|
impl<BUF: DmaRxBuffer> DerefMut for CameraTransfer<'_, BUF> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.buffer_view
|
&mut self.buffer_view
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, BUF: DmaRxBuffer> Drop for CameraTransfer<'d, BUF> {
|
impl<BUF: DmaRxBuffer> Drop for CameraTransfer<'_, BUF> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.stop_peripherals();
|
self.stop_peripherals();
|
||||||
|
|
||||||
|
|||||||
@ -661,7 +661,7 @@ impl<'d, BUF: DmaTxBuffer, DM: Mode> DpiTransfer<'d, BUF, DM> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, BUF: DmaTxBuffer, DM: Mode> Deref for DpiTransfer<'d, BUF, DM> {
|
impl<BUF: DmaTxBuffer, DM: Mode> Deref for DpiTransfer<'_, BUF, DM> {
|
||||||
type Target = BUF::View;
|
type Target = BUF::View;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
@ -669,13 +669,13 @@ impl<'d, BUF: DmaTxBuffer, DM: Mode> Deref for DpiTransfer<'d, BUF, DM> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, BUF: DmaTxBuffer, DM: Mode> DerefMut for DpiTransfer<'d, BUF, DM> {
|
impl<BUF: DmaTxBuffer, DM: Mode> DerefMut for DpiTransfer<'_, BUF, DM> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.buffer_view
|
&mut self.buffer_view
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, BUF: DmaTxBuffer, DM: Mode> Drop for DpiTransfer<'d, BUF, DM> {
|
impl<BUF: DmaTxBuffer, DM: Mode> Drop for DpiTransfer<'_, BUF, DM> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.stop_peripherals();
|
self.stop_peripherals();
|
||||||
|
|
||||||
|
|||||||
@ -396,7 +396,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, DM: Mode> core::fmt::Debug for I8080<'d, DM> {
|
impl<DM: Mode> core::fmt::Debug for I8080<'_, DM> {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
||||||
f.debug_struct("I8080").finish()
|
f.debug_struct("I8080").finish()
|
||||||
}
|
}
|
||||||
@ -470,7 +470,7 @@ impl<'d, BUF: DmaTxBuffer, DM: Mode> I8080Transfer<'d, BUF, DM> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, BUF: DmaTxBuffer, DM: Mode> Deref for I8080Transfer<'d, BUF, DM> {
|
impl<BUF: DmaTxBuffer, DM: Mode> Deref for I8080Transfer<'_, BUF, DM> {
|
||||||
type Target = BUF::View;
|
type Target = BUF::View;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
@ -478,7 +478,7 @@ impl<'d, BUF: DmaTxBuffer, DM: Mode> Deref for I8080Transfer<'d, BUF, DM> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, BUF: DmaTxBuffer, DM: Mode> DerefMut for I8080Transfer<'d, BUF, DM> {
|
impl<BUF: DmaTxBuffer, DM: Mode> DerefMut for I8080Transfer<'_, BUF, DM> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.buf_view
|
&mut self.buf_view
|
||||||
}
|
}
|
||||||
@ -523,7 +523,7 @@ impl<'d, BUF: DmaTxBuffer> I8080Transfer<'d, BUF, crate::Async> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, BUF: DmaTxBuffer, DM: Mode> Drop for I8080Transfer<'d, BUF, DM> {
|
impl<BUF: DmaTxBuffer, DM: Mode> Drop for I8080Transfer<'_, BUF, DM> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.stop_peripherals();
|
self.stop_peripherals();
|
||||||
|
|
||||||
@ -645,7 +645,7 @@ impl<'d> TxEightBits<'d> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> TxPins for TxEightBits<'d> {
|
impl TxPins for TxEightBits<'_> {
|
||||||
fn configure(&mut self) {
|
fn configure(&mut self) {
|
||||||
const SIGNALS: [OutputSignal; 8] = [
|
const SIGNALS: [OutputSignal; 8] = [
|
||||||
OutputSignal::LCD_DATA_0,
|
OutputSignal::LCD_DATA_0,
|
||||||
@ -706,7 +706,7 @@ impl<'d> TxSixteenBits<'d> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> TxPins for TxSixteenBits<'d> {
|
impl TxPins for TxSixteenBits<'_> {
|
||||||
fn configure(&mut self) {
|
fn configure(&mut self) {
|
||||||
const SIGNALS: [OutputSignal; 16] = [
|
const SIGNALS: [OutputSignal; 16] = [
|
||||||
OutputSignal::LCD_DATA_0,
|
OutputSignal::LCD_DATA_0,
|
||||||
|
|||||||
@ -369,7 +369,7 @@ impl TimerHW<LowSpeed> for Timer<'_, LowSpeed> {
|
|||||||
|
|
||||||
#[cfg(esp32)]
|
#[cfg(esp32)]
|
||||||
/// Timer HW implementation for HighSpeed timers
|
/// Timer HW implementation for HighSpeed timers
|
||||||
impl<'a> TimerHW<HighSpeed> for Timer<'a, HighSpeed> {
|
impl TimerHW<HighSpeed> for Timer<'_, HighSpeed> {
|
||||||
/// Get the current source timer frequency from the HW
|
/// Get the current source timer frequency from the HW
|
||||||
fn freq_hw(&self) -> Option<HertzU32> {
|
fn freq_hw(&self) -> Option<HertzU32> {
|
||||||
self.clock_source.map(|source| match source {
|
self.clock_source.map(|source| match source {
|
||||||
|
|||||||
@ -109,9 +109,9 @@ impl<'d> Usb<'d> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<'d> Sync for Usb<'d> {}
|
unsafe impl Sync for Usb<'_> {}
|
||||||
|
|
||||||
unsafe impl<'d> UsbPeripheral for Usb<'d> {
|
unsafe impl UsbPeripheral for Usb<'_> {
|
||||||
const REGISTERS: *const () = peripherals::USB0::ptr() as *const ();
|
const REGISTERS: *const () = peripherals::USB0::ptr() as *const ();
|
||||||
|
|
||||||
const HIGH_SPEED: bool = false;
|
const HIGH_SPEED: bool = false;
|
||||||
@ -250,7 +250,7 @@ pub mod asynch {
|
|||||||
_usb: Usb<'d>,
|
_usb: Usb<'d>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> Bus<'d> {
|
impl Bus<'_> {
|
||||||
fn init(&mut self) {
|
fn init(&mut self) {
|
||||||
Usb::_enable();
|
Usb::_enable();
|
||||||
|
|
||||||
@ -328,7 +328,7 @@ pub mod asynch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> Drop for Bus<'d> {
|
impl Drop for Bus<'_> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
Bus::disable(self);
|
Bus::disable(self);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use crate::rsa::{
|
|||||||
RsaMultiplication,
|
RsaMultiplication,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'d, DM: crate::Mode> Rsa<'d, DM> {
|
impl<DM: crate::Mode> Rsa<'_, DM> {
|
||||||
/// After the RSA Accelerator is released from reset, the memory blocks
|
/// After the RSA Accelerator is released from reset, the memory blocks
|
||||||
/// needs to be initialized, only after that peripheral should be used.
|
/// needs to be initialized, only after that peripheral should be used.
|
||||||
/// This function would return without an error if the memory is initialized
|
/// This function would return without an error if the memory is initialized
|
||||||
@ -79,7 +79,7 @@ pub mod operand_sizes {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'd, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularMultiplication<'a, 'd, T, DM>
|
impl<'d, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularMultiplication<'_, 'd, T, DM>
|
||||||
where
|
where
|
||||||
T: RsaMode<InputType = [u32; N]>,
|
T: RsaMode<InputType = [u32; N]>,
|
||||||
{
|
{
|
||||||
@ -98,7 +98,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'd, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularExponentiation<'a, 'd, T, DM>
|
impl<'d, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularExponentiation<'_, 'd, T, DM>
|
||||||
where
|
where
|
||||||
T: RsaMode<InputType = [u32; N]>,
|
T: RsaMode<InputType = [u32; N]>,
|
||||||
{
|
{
|
||||||
@ -108,7 +108,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'd, T: RsaMode + Multi, DM: crate::Mode, const N: usize> RsaMultiplication<'a, 'd, T, DM>
|
impl<'d, T: RsaMode + Multi, DM: crate::Mode, const N: usize> RsaMultiplication<'_, 'd, T, DM>
|
||||||
where
|
where
|
||||||
T: RsaMode<InputType = [u32; N]>,
|
T: RsaMode<InputType = [u32; N]>,
|
||||||
{
|
{
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use crate::rsa::{
|
|||||||
RsaMultiplication,
|
RsaMultiplication,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'d, DM: crate::Mode> Rsa<'d, DM> {
|
impl<DM: crate::Mode> Rsa<'_, DM> {
|
||||||
/// After the RSA accelerator is released from reset, the memory blocks
|
/// After the RSA accelerator is released from reset, the memory blocks
|
||||||
/// needs to be initialized, only after that peripheral should be used.
|
/// needs to be initialized, only after that peripheral should be used.
|
||||||
/// This function would return without an error if the memory is
|
/// This function would return without an error if the memory is
|
||||||
@ -248,7 +248,7 @@ pub mod operand_sizes {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'd, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularExponentiation<'a, 'd, T, DM>
|
impl<'d, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularExponentiation<'_, 'd, T, DM>
|
||||||
where
|
where
|
||||||
T: RsaMode<InputType = [u32; N]>,
|
T: RsaMode<InputType = [u32; N]>,
|
||||||
{
|
{
|
||||||
@ -268,7 +268,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'd, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularMultiplication<'a, 'd, T, DM>
|
impl<'d, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularMultiplication<'_, 'd, T, DM>
|
||||||
where
|
where
|
||||||
T: RsaMode<InputType = [u32; N]>,
|
T: RsaMode<InputType = [u32; N]>,
|
||||||
{
|
{
|
||||||
@ -281,7 +281,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'd, T: RsaMode + Multi, DM: crate::Mode, const N: usize> RsaMultiplication<'a, 'd, T, DM>
|
impl<'d, T: RsaMode + Multi, DM: crate::Mode, const N: usize> RsaMultiplication<'_, 'd, T, DM>
|
||||||
where
|
where
|
||||||
T: RsaMode<InputType = [u32; N]>,
|
T: RsaMode<InputType = [u32; N]>,
|
||||||
{
|
{
|
||||||
|
|||||||
@ -234,7 +234,7 @@ impl Drop for Ext1WakeupSource<'_, '_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> RtcioWakeupSource<'a, 'b> {
|
impl RtcioWakeupSource<'_, '_> {
|
||||||
fn apply_pin(&self, pin: &mut dyn RtcPin, level: WakeupLevel) {
|
fn apply_pin(&self, pin: &mut dyn RtcPin, level: WakeupLevel) {
|
||||||
let rtcio = unsafe { &*crate::peripherals::RTC_IO::PTR };
|
let rtcio = unsafe { &*crate::peripherals::RTC_IO::PTR };
|
||||||
|
|
||||||
|
|||||||
@ -127,7 +127,7 @@ pub struct AppCoreGuard<'a> {
|
|||||||
phantom: PhantomData<&'a ()>,
|
phantom: PhantomData<&'a ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Drop for AppCoreGuard<'a> {
|
impl Drop for AppCoreGuard<'_> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
internal_park_core(Cpu::AppCpu);
|
internal_park_core(Cpu::AppCpu);
|
||||||
@ -323,6 +323,7 @@ impl<'d> CpuControl<'d> {
|
|||||||
where
|
where
|
||||||
F: FnOnce(),
|
F: FnOnce(),
|
||||||
{
|
{
|
||||||
|
#[allow(static_mut_refs)] // FIXME
|
||||||
match START_CORE1_FUNCTION.take() {
|
match START_CORE1_FUNCTION.take() {
|
||||||
Some(entry) => {
|
Some(entry) => {
|
||||||
let entry = unsafe { ManuallyDrop::take(&mut *entry.cast::<ManuallyDrop<F>>()) };
|
let entry = unsafe { ManuallyDrop::take(&mut *entry.cast::<ManuallyDrop<F>>()) };
|
||||||
|
|||||||
@ -127,7 +127,7 @@ pub struct AppCoreGuard<'a> {
|
|||||||
phantom: PhantomData<&'a ()>,
|
phantom: PhantomData<&'a ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Drop for AppCoreGuard<'a> {
|
impl Drop for AppCoreGuard<'_> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
internal_park_core(Cpu::AppCpu);
|
internal_park_core(Cpu::AppCpu);
|
||||||
@ -259,6 +259,7 @@ impl<'d> CpuControl<'d> {
|
|||||||
where
|
where
|
||||||
F: FnOnce(),
|
F: FnOnce(),
|
||||||
{
|
{
|
||||||
|
#[allow(static_mut_refs)] // FIXME
|
||||||
match START_CORE1_FUNCTION.take() {
|
match START_CORE1_FUNCTION.take() {
|
||||||
Some(entry) => {
|
Some(entry) => {
|
||||||
let entry = unsafe { ManuallyDrop::take(&mut *entry.cast::<ManuallyDrop<F>>()) };
|
let entry = unsafe { ManuallyDrop::take(&mut *entry.cast::<ManuallyDrop<F>>()) };
|
||||||
|
|||||||
@ -30,6 +30,7 @@ static mut MAPPED_PSRAM: MappedPsram = MappedPsram { memory_range: 0..0 };
|
|||||||
pub(crate) fn psram_range() -> Range<usize> {
|
pub(crate) fn psram_range() -> Range<usize> {
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(any(feature = "quad-psram", feature = "octal-psram"))] {
|
if #[cfg(any(feature = "quad-psram", feature = "octal-psram"))] {
|
||||||
|
#[allow(static_mut_refs)]
|
||||||
unsafe { MAPPED_PSRAM.memory_range.clone() }
|
unsafe { MAPPED_PSRAM.memory_range.clone() }
|
||||||
} else {
|
} else {
|
||||||
0..0
|
0..0
|
||||||
|
|||||||
@ -315,7 +315,7 @@ pub mod dma {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, M, T> SpiDma<'d, M, T>
|
impl<M, T> SpiDma<'_, M, T>
|
||||||
where
|
where
|
||||||
M: Mode,
|
M: Mode,
|
||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
|
|||||||
@ -155,7 +155,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T> OneShotTimer<'d, Async, T>
|
impl<T> OneShotTimer<'_, Async, T>
|
||||||
where
|
where
|
||||||
T: Timer,
|
T: Timer,
|
||||||
{
|
{
|
||||||
@ -197,7 +197,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, M, T> OneShotTimer<'d, M, T>
|
impl<M, T> OneShotTimer<'_, M, T>
|
||||||
where
|
where
|
||||||
M: Mode,
|
M: Mode,
|
||||||
T: Timer,
|
T: Timer,
|
||||||
@ -329,7 +329,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, M, T> PeriodicTimer<'d, M, T>
|
impl<M, T> PeriodicTimer<'_, M, T>
|
||||||
where
|
where
|
||||||
M: Mode,
|
M: Mode,
|
||||||
T: Timer,
|
T: Timer,
|
||||||
|
|||||||
@ -90,7 +90,7 @@ pub struct Touch<'d, TOUCHMODE: TouchMode, MODE: Mode> {
|
|||||||
_touch_mode: PhantomData<TOUCHMODE>,
|
_touch_mode: PhantomData<TOUCHMODE>,
|
||||||
_mode: PhantomData<MODE>,
|
_mode: PhantomData<MODE>,
|
||||||
}
|
}
|
||||||
impl<'d, TOUCHMODE: TouchMode, MODE: Mode> Touch<'d, TOUCHMODE, MODE> {
|
impl<TOUCHMODE: TouchMode, MODE: Mode> Touch<'_, TOUCHMODE, MODE> {
|
||||||
/// Common initialization of the touch peripheral.
|
/// Common initialization of the touch peripheral.
|
||||||
fn initialize_common(config: Option<TouchConfig>) {
|
fn initialize_common(config: Option<TouchConfig>) {
|
||||||
let rtccntl = unsafe { &*RTC_CNTL::ptr() };
|
let rtccntl = unsafe { &*RTC_CNTL::ptr() };
|
||||||
|
|||||||
@ -7,10 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- Bump MSRV to 1.83 (#2615)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
name = "esp-ieee802154"
|
name = "esp-ieee802154"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.76.0"
|
rust-version = "1.83.0"
|
||||||
description = "Low-level IEEE 802.15.4 driver for the ESP32-C6 and ESP32-H2"
|
description = "Low-level IEEE 802.15.4 driver for the ESP32-C6 and ESP32-H2"
|
||||||
repository = "https://github.com/esp-rs/esp-hal"
|
repository = "https://github.com/esp-rs/esp-hal"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[](https://crates.io/crates/esp-ieee802154)
|
[](https://crates.io/crates/esp-ieee802154)
|
||||||
[](https://docs.rs/esp-ieee802154)
|
[](https://docs.rs/esp-ieee802154)
|
||||||

|

|
||||||

|

|
||||||
[](https://matrix.to/#/#esp-rs:matrix.org)
|
[](https://matrix.to/#/#esp-rs:matrix.org)
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ Implements the PHY/MAC layers of the IEEE802.15.4 protocol stack, and supports s
|
|||||||
|
|
||||||
## Minimum Supported Rust Version (MSRV)
|
## Minimum Supported Rust Version (MSRV)
|
||||||
|
|
||||||
This crate is guaranteed to compile on stable Rust 1.76 and up. It _might_
|
This crate is guaranteed to compile on stable Rust 1.83 and up. It _might_
|
||||||
compile with older versions but that may change in any new patch release.
|
compile with older versions but that may change in any new patch release.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|||||||
@ -478,7 +478,7 @@ type LockInner<'a> = critical_section::CriticalSection<'a>;
|
|||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
struct LockToken<'a>(LockInner<'a>);
|
struct LockToken<'a>(LockInner<'a>);
|
||||||
|
|
||||||
impl<'a> LockToken<'a> {
|
impl LockToken<'_> {
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
unsafe fn conjure() -> Self {
|
unsafe fn conjure() -> Self {
|
||||||
#[cfg(feature = "critical-section")]
|
#[cfg(feature = "critical-section")]
|
||||||
|
|||||||
@ -7,11 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- Bump MSRV to 1.83 (#2615)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed triggering a debug-assertion during scan (#2612)
|
- Fixed triggering a debug-assertion during scan (#2612)
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
name = "esp-wifi"
|
name = "esp-wifi"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79.0"
|
rust-version = "1.83.0"
|
||||||
authors = ["The ESP-RS team"]
|
authors = ["The ESP-RS team"]
|
||||||
description = "A WiFi, Bluetooth and ESP-NOW driver for use with Espressif chips and bare-metal Rust"
|
description = "A WiFi, Bluetooth and ESP-NOW driver for use with Espressif chips and bare-metal Rust"
|
||||||
documentation = "https://docs.esp-rs.org/esp-hal/"
|
documentation = "https://docs.esp-rs.org/esp-hal/"
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[](https://crates.io/crates/esp-wifi)
|
[](https://crates.io/crates/esp-wifi)
|
||||||
[](https://docs.esp-rs.org/esp-hal)
|
[](https://docs.esp-rs.org/esp-hal)
|
||||||

|

|
||||||

|

|
||||||
[](https://matrix.to/#/#esp-rs:matrix.org)
|
[](https://matrix.to/#/#esp-rs:matrix.org)
|
||||||
|
|
||||||
@ -24,7 +24,10 @@ If a cell contains an em dash (—) this means that the particular feature i
|
|||||||
| ESP32-S2 | ✓ | — | — | ✓ |
|
| ESP32-S2 | ✓ | — | — | ✓ |
|
||||||
| ESP32-S3 | ✓ | ✓ | ✓ | ✓ |
|
| ESP32-S3 | ✓ | ✓ | ✓ | ✓ |
|
||||||
|
|
||||||
Minimum supported Rust compiler version: 1.79.0
|
## Minimum Supported Rust Version (MSRV)
|
||||||
|
|
||||||
|
This crate is guaranteed to compile on stable Rust 1.83 and up. It _might_
|
||||||
|
compile with older versions but that may change in any new patch release.
|
||||||
|
|
||||||
## Missing / To be done
|
## Missing / To be done
|
||||||
|
|
||||||
|
|||||||
@ -790,7 +790,7 @@ fn lint_package(chip: &Chip, path: &Path, args: &[&str], fix: bool) -> Result<()
|
|||||||
// build in release to reuse example artifacts
|
// build in release to reuse example artifacts
|
||||||
let cargo_args = builder.arg("--release");
|
let cargo_args = builder.arg("--release");
|
||||||
let cargo_args = if fix {
|
let cargo_args = if fix {
|
||||||
cargo_args.arg("--fix").arg("--lib")
|
cargo_args.arg("--fix").arg("--lib").arg("--allow-dirty")
|
||||||
} else {
|
} else {
|
||||||
cargo_args.arg("--").arg("-D").arg("warnings")
|
cargo_args.arg("--").arg("-D").arg("warnings")
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use core::arch::{asm, global_asm};
|
use core::arch::global_asm;
|
||||||
|
|
||||||
use crate::cfg_asm;
|
use crate::cfg_global_asm;
|
||||||
|
|
||||||
// We could cfg symbols away and reduce frame size depending on features enabled
|
// We could cfg symbols away and reduce frame size depending on features enabled
|
||||||
// i.e the frame size is a fixed size based on all the features right now
|
// i.e the frame size is a fixed size based on all the features right now
|
||||||
@ -89,33 +89,148 @@ global_asm!(
|
|||||||
.set PS_EXCM, 0x00000010
|
.set PS_EXCM, 0x00000010
|
||||||
.set PS_UM, 0x00000020
|
.set PS_UM, 0x00000020
|
||||||
.set PS_WOE, 0x00040000
|
.set PS_WOE, 0x00040000
|
||||||
|
|
||||||
|
// Spills all active windowed registers (i.e. registers not visible as
|
||||||
|
// A0-A15) to their ABI-defined spill regions on the stack.
|
||||||
|
// It will spill registers to their reserved locations in previous frames.
|
||||||
|
//
|
||||||
|
// Unlike the Xtensa HAL implementation, this code requires that the
|
||||||
|
// EXCM and WOE bit be enabled in PS, and relies on repeated hardware
|
||||||
|
// exception handling to do the register spills. The trick is to do a
|
||||||
|
// noop write to the high registers, which the hardware will trap
|
||||||
|
// (into an overflow exception) in the case where those registers are
|
||||||
|
// already used by an existing call frame. Then it rotates the window
|
||||||
|
// and repeats until all but the A0-A3 registers of the original frame
|
||||||
|
// are guaranteed to be spilled, eventually rotating back around into
|
||||||
|
// the original frame. Advantages:
|
||||||
|
//
|
||||||
|
// - Vastly smaller code size
|
||||||
|
//
|
||||||
|
// - More easily maintained if changes are needed to window over/underflow
|
||||||
|
// exception handling.
|
||||||
|
//
|
||||||
|
// - Requires no scratch registers to do its work, so can be used safely in any
|
||||||
|
// context.
|
||||||
|
//
|
||||||
|
// - If the WOE bit is not enabled (for example, in code written for
|
||||||
|
// the CALL0 ABI), this becomes a silent noop and operates compatbily.
|
||||||
|
//
|
||||||
|
// - Hilariously it's ACTUALLY FASTER than the HAL routine. And not
|
||||||
|
// just a little bit, it's MUCH faster. With a mostly full register
|
||||||
|
// file on an LX6 core (ESP-32) I'm measuring 145 cycles to spill
|
||||||
|
// registers with this vs. 279 (!) to do it with
|
||||||
|
// xthal_spill_windows().
|
||||||
|
|
||||||
|
.macro SPILL_REGISTERS
|
||||||
|
and a12, a12, a12
|
||||||
|
rotw 3
|
||||||
|
and a12, a12, a12
|
||||||
|
rotw 3
|
||||||
|
and a12, a12, a12
|
||||||
|
rotw 3
|
||||||
|
and a12, a12, a12
|
||||||
|
rotw 3
|
||||||
|
and a12, a12, a12
|
||||||
|
rotw 4
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro SAVE_CONTEXT level:req
|
||||||
|
mov a0, a1 // save a1/sp
|
||||||
|
addmi sp, sp, -XT_STK_FRMSZ // only allow multiple of 256
|
||||||
|
|
||||||
|
s32i a0, sp, +XT_STK_A1 // save interruptee's A1/SP
|
||||||
|
s32e a0, sp, -12 // for debug backtrace
|
||||||
|
|
||||||
|
.ifc \\level,1
|
||||||
|
rsr a0, PS
|
||||||
|
s32i a0, sp, +XT_STK_PS // save interruptee's PS
|
||||||
|
|
||||||
|
rsr a0, EXCCAUSE
|
||||||
|
s32i a0, sp, +XT_STK_EXCCAUSE
|
||||||
|
rsr a0, EXCVADDR
|
||||||
|
s32i a0, sp, +XT_STK_EXCVADDR
|
||||||
|
.else
|
||||||
|
rsr a0, EPS\\level
|
||||||
|
s32i a0, sp, +XT_STK_PS // save interruptee's PS
|
||||||
|
.endif
|
||||||
|
|
||||||
|
rsr a0, EPC\\level
|
||||||
|
s32i a0, sp, +XT_STK_PC // save interruptee's PC
|
||||||
|
s32e a0, sp, -16 // for debug backtrace
|
||||||
|
|
||||||
|
rsr a0, EXCSAVE\\level
|
||||||
|
s32i a0, sp, +XT_STK_A0 // save interruptee's A0
|
||||||
|
|
||||||
|
call0 save_context
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro RESTORE_CONTEXT level:req
|
||||||
|
|
||||||
|
// Restore context and return
|
||||||
|
call0 restore_context
|
||||||
|
|
||||||
|
.ifc \\level,1
|
||||||
|
l32i a0, sp, +XT_STK_PS // retrieve interruptee's PS
|
||||||
|
wsr a0, PS
|
||||||
|
l32i a0, sp, +XT_STK_PC // retrieve interruptee's PC
|
||||||
|
wsr a0, EPC\\level
|
||||||
|
.else
|
||||||
|
l32i a0, sp, +XT_STK_PS // retrieve interruptee's PS
|
||||||
|
wsr a0, EPS\\level
|
||||||
|
l32i a0, sp, +XT_STK_PC // retrieve interruptee's PC
|
||||||
|
wsr a0, EPC\\level
|
||||||
|
.endif
|
||||||
|
|
||||||
|
l32i a0, sp, +XT_STK_A0 // retrieve interruptee's A0
|
||||||
|
l32i sp, sp, +XT_STK_A1 // remove exception frame
|
||||||
|
rsync // ensure PS and EPC written
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro HANDLE_INTERRUPT_LEVEL level
|
||||||
|
SAVE_CONTEXT \\level
|
||||||
|
|
||||||
|
movi a0, (\\level | PS_WOE)
|
||||||
|
wsr a0, PS
|
||||||
|
rsync
|
||||||
|
|
||||||
|
movi a6, \\level // put interrupt level in a6 = a2 in callee
|
||||||
|
mov a7, sp // put address of save frame in a7=a3 in callee
|
||||||
|
call4 __level_\\level\\()_interrupt // call handler <= actual call!
|
||||||
|
|
||||||
|
RESTORE_CONTEXT \\level
|
||||||
|
rfi \\level
|
||||||
|
|
||||||
|
.endm
|
||||||
"
|
"
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Save processor state to stack.
|
cfg_global_asm!(
|
||||||
///
|
|
||||||
/// *Must only be called with call0.*
|
|
||||||
/// *For spill all window registers to work WOE must be enabled on entry
|
|
||||||
///
|
|
||||||
/// Saves all registers except PC, PS, A0, A1
|
|
||||||
///
|
|
||||||
/// Inputs:
|
|
||||||
/// A0 is the return address
|
|
||||||
/// A1 is the stack pointers
|
|
||||||
/// Exceptions are disabled (PS.EXCM = 1)
|
|
||||||
///
|
|
||||||
/// Output:
|
|
||||||
/// A0 is the return address
|
|
||||||
/// A1 is the stack pointer
|
|
||||||
/// A3, A9 are used as scratch registers
|
|
||||||
/// EPC1 is changed
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".rwtext"]
|
|
||||||
unsafe extern "C" fn save_context() {
|
|
||||||
cfg_asm!(
|
|
||||||
{
|
|
||||||
"
|
"
|
||||||
|
// Save processor state to stack.
|
||||||
|
//
|
||||||
|
// *Must only be called with call0.*
|
||||||
|
// *For spill all window registers to work WOE must be enabled on entry
|
||||||
|
//
|
||||||
|
// Saves all registers except PC, PS, A0, A1
|
||||||
|
//
|
||||||
|
// Inputs:
|
||||||
|
// A0 is the return address
|
||||||
|
// A1 is the stack pointers
|
||||||
|
// Exceptions are disabled (PS.EXCM = 1)
|
||||||
|
//
|
||||||
|
// Output:
|
||||||
|
// A0 is the return address
|
||||||
|
// A1 is the stack pointer
|
||||||
|
// A3, A9 are used as scratch registers
|
||||||
|
// EPC1 is changed
|
||||||
|
.section .rwtext,\"ax\",@progbits
|
||||||
|
.global save_context
|
||||||
|
.p2align 2
|
||||||
|
.type save_context,@function
|
||||||
|
save_context:
|
||||||
|
.Lsave_context_start:
|
||||||
s32i a2, sp, +XT_STK_A2
|
s32i a2, sp, +XT_STK_A2
|
||||||
s32i a3, sp, +XT_STK_A3
|
s32i a3, sp, +XT_STK_A3
|
||||||
s32i a4, sp, +XT_STK_A4
|
s32i a4, sp, +XT_STK_A4
|
||||||
@ -263,102 +378,15 @@ unsafe extern "C" fn save_context() {
|
|||||||
",
|
",
|
||||||
"
|
"
|
||||||
ret
|
ret
|
||||||
",
|
.Lsave_context_end:
|
||||||
},
|
.size .Lsave_context_start, .Lsave_context_end
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
global_asm!(
|
.section .rwtext,\"ax\",@progbits
|
||||||
r#"
|
.global restore_context
|
||||||
// Spills all active windowed registers (i.e. registers not visible as
|
.p2align 2
|
||||||
// A0-A15) to their ABI-defined spill regions on the stack.
|
.type restore_context,@function
|
||||||
// It will spill registers to their reserved locations in previous frames.
|
restore_context:
|
||||||
//
|
.Lrestore_context_start:
|
||||||
// Unlike the Xtensa HAL implementation, this code requires that the
|
|
||||||
// EXCM and WOE bit be enabled in PS, and relies on repeated hardware
|
|
||||||
// exception handling to do the register spills. The trick is to do a
|
|
||||||
// noop write to the high registers, which the hardware will trap
|
|
||||||
// (into an overflow exception) in the case where those registers are
|
|
||||||
// already used by an existing call frame. Then it rotates the window
|
|
||||||
// and repeats until all but the A0-A3 registers of the original frame
|
|
||||||
// are guaranteed to be spilled, eventually rotating back around into
|
|
||||||
// the original frame. Advantages:
|
|
||||||
//
|
|
||||||
// - Vastly smaller code size
|
|
||||||
//
|
|
||||||
// - More easily maintained if changes are needed to window over/underflow
|
|
||||||
// exception handling.
|
|
||||||
//
|
|
||||||
// - Requires no scratch registers to do its work, so can be used safely in any
|
|
||||||
// context.
|
|
||||||
//
|
|
||||||
// - If the WOE bit is not enabled (for example, in code written for
|
|
||||||
// the CALL0 ABI), this becomes a silent noop and operates compatbily.
|
|
||||||
//
|
|
||||||
// - Hilariously it's ACTUALLY FASTER than the HAL routine. And not
|
|
||||||
// just a little bit, it's MUCH faster. With a mostly full register
|
|
||||||
// file on an LX6 core (ESP-32) I'm measuring 145 cycles to spill
|
|
||||||
// registers with this vs. 279 (!) to do it with
|
|
||||||
// xthal_spill_windows().
|
|
||||||
|
|
||||||
.macro SPILL_REGISTERS
|
|
||||||
and a12, a12, a12
|
|
||||||
rotw 3
|
|
||||||
and a12, a12, a12
|
|
||||||
rotw 3
|
|
||||||
and a12, a12, a12
|
|
||||||
rotw 3
|
|
||||||
and a12, a12, a12
|
|
||||||
rotw 3
|
|
||||||
and a12, a12, a12
|
|
||||||
rotw 4
|
|
||||||
.endm
|
|
||||||
"#
|
|
||||||
);
|
|
||||||
|
|
||||||
global_asm!(
|
|
||||||
r#"
|
|
||||||
.macro SAVE_CONTEXT level:req
|
|
||||||
mov a0, a1 // save a1/sp
|
|
||||||
addmi sp, sp, -XT_STK_FRMSZ // only allow multiple of 256
|
|
||||||
|
|
||||||
s32i a0, sp, +XT_STK_A1 // save interruptee's A1/SP
|
|
||||||
s32e a0, sp, -12 // for debug backtrace
|
|
||||||
|
|
||||||
.ifc \level,1
|
|
||||||
rsr a0, PS
|
|
||||||
s32i a0, sp, +XT_STK_PS // save interruptee's PS
|
|
||||||
|
|
||||||
rsr a0, EXCCAUSE
|
|
||||||
s32i a0, sp, +XT_STK_EXCCAUSE
|
|
||||||
rsr a0, EXCVADDR
|
|
||||||
s32i a0, sp, +XT_STK_EXCVADDR
|
|
||||||
.else
|
|
||||||
rsr a0, EPS\level
|
|
||||||
s32i a0, sp, +XT_STK_PS // save interruptee's PS
|
|
||||||
.endif
|
|
||||||
|
|
||||||
rsr a0, EPC\level
|
|
||||||
s32i a0, sp, +XT_STK_PC // save interruptee's PC
|
|
||||||
s32e a0, sp, -16 // for debug backtrace
|
|
||||||
|
|
||||||
rsr a0, EXCSAVE\level
|
|
||||||
s32i a0, sp, +XT_STK_A0 // save interruptee's A0
|
|
||||||
|
|
||||||
call0 save_context
|
|
||||||
|
|
||||||
.endm
|
|
||||||
"#
|
|
||||||
);
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".rwtext"]
|
|
||||||
unsafe extern "C" fn restore_context() {
|
|
||||||
cfg_asm!(
|
|
||||||
{
|
|
||||||
"
|
|
||||||
l32i a3, sp, +XT_STK_SAR
|
l32i a3, sp, +XT_STK_SAR
|
||||||
wsr a3, SAR
|
wsr a3, SAR
|
||||||
",
|
",
|
||||||
@ -464,48 +492,25 @@ unsafe extern "C" fn restore_context() {
|
|||||||
l32i a14, sp, +XT_STK_A14
|
l32i a14, sp, +XT_STK_A14
|
||||||
l32i a15, sp, +XT_STK_A15
|
l32i a15, sp, +XT_STK_A15
|
||||||
ret
|
ret
|
||||||
|
.Lrestore_context_end:
|
||||||
|
.size .Lrestore_context_start, .Lrestore_context_end
|
||||||
",
|
",
|
||||||
}, options(noreturn));
|
|
||||||
}
|
|
||||||
|
|
||||||
global_asm!(
|
|
||||||
r#"
|
|
||||||
.macro RESTORE_CONTEXT level:req
|
|
||||||
|
|
||||||
// Restore context and return
|
|
||||||
call0 restore_context
|
|
||||||
|
|
||||||
.ifc \level,1
|
|
||||||
l32i a0, sp, +XT_STK_PS // retrieve interruptee's PS
|
|
||||||
wsr a0, PS
|
|
||||||
l32i a0, sp, +XT_STK_PC // retrieve interruptee's PC
|
|
||||||
wsr a0, EPC\level
|
|
||||||
.else
|
|
||||||
l32i a0, sp, +XT_STK_PS // retrieve interruptee's PS
|
|
||||||
wsr a0, EPS\level
|
|
||||||
l32i a0, sp, +XT_STK_PC // retrieve interruptee's PC
|
|
||||||
wsr a0, EPC\level
|
|
||||||
.endif
|
|
||||||
|
|
||||||
l32i a0, sp, +XT_STK_A0 // retrieve interruptee's A0
|
|
||||||
l32i sp, sp, +XT_STK_A1 // remove exception frame
|
|
||||||
rsync // ensure PS and EPC written
|
|
||||||
|
|
||||||
.endm
|
|
||||||
"#
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Handle Other Exceptions or Level 1 interrupt by storing full context and
|
global_asm!(
|
||||||
/// then calling regular function
|
|
||||||
///
|
|
||||||
/// # Input:
|
|
||||||
/// * A0 stored in EXCSAVE1
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".rwtext"]
|
|
||||||
unsafe extern "C" fn __default_naked_exception() {
|
|
||||||
asm!(
|
|
||||||
"
|
"
|
||||||
|
// Handle Other Exceptions or Level 1 interrupt by storing full context and
|
||||||
|
// then calling regular function
|
||||||
|
//
|
||||||
|
// # Input:
|
||||||
|
// * A0 stored in EXCSAVE1
|
||||||
|
|
||||||
|
.section .rwtext,\"ax\",@progbits
|
||||||
|
.global __default_naked_exception
|
||||||
|
.p2align 2
|
||||||
|
.type __default_naked_exception,@function
|
||||||
|
__default_naked_exception:
|
||||||
|
.Ldefault_naked_exception_start:
|
||||||
SAVE_CONTEXT 1
|
SAVE_CONTEXT 1
|
||||||
|
|
||||||
movi a0, (PS_INTLEVEL_EXCM | PS_WOE)
|
movi a0, (PS_INTLEVEL_EXCM | PS_WOE)
|
||||||
@ -520,7 +525,7 @@ unsafe extern "C" fn __default_naked_exception() {
|
|||||||
|
|
||||||
j .RestoreContext
|
j .RestoreContext
|
||||||
|
|
||||||
.Level1Interrupt:
|
.Level1Interrupt:
|
||||||
movi a0, (1 | PS_WOE) // set PS.INTLEVEL accordingly
|
movi a0, (1 | PS_WOE) // set PS.INTLEVEL accordingly
|
||||||
wsr a0, PS
|
wsr a0, PS
|
||||||
rsync
|
rsync
|
||||||
@ -529,27 +534,25 @@ unsafe extern "C" fn __default_naked_exception() {
|
|||||||
mov a7, sp // put address of save frame in a7=a3 in callee
|
mov a7, sp // put address of save frame in a7=a3 in callee
|
||||||
call4 __level_1_interrupt // call handler <= actual call!
|
call4 __level_1_interrupt // call handler <= actual call!
|
||||||
|
|
||||||
.RestoreContext:
|
.RestoreContext:
|
||||||
RESTORE_CONTEXT 1
|
RESTORE_CONTEXT 1
|
||||||
|
|
||||||
rfe // PS.EXCM is cleared
|
rfe // PS.EXCM is cleared
|
||||||
",
|
.Ldefault_naked_exception_end:
|
||||||
options(noreturn)
|
.size .Ldefault_naked_exception_start, .Ldefault_naked_exception_end
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handle Double Exceptions by storing full context and then calling regular
|
// Handle Double Exceptions by storing full context and then calling regular
|
||||||
/// function Double exceptions are not a normal occurrence. They indicate a bug
|
// function Double exceptions are not a normal occurrence. They indicate a bug
|
||||||
/// of some kind.
|
// of some kind.
|
||||||
///
|
//
|
||||||
/// # Input:
|
// # Input:
|
||||||
/// * A0 stored in EXCSAVE1
|
// * A0 stored in EXCSAVE1
|
||||||
#[naked]
|
.section .rwtext,\"ax\",@progbits
|
||||||
#[no_mangle]
|
.global __default_naked_double_exception
|
||||||
#[link_section = ".rwtext"]
|
.p2align 2
|
||||||
unsafe extern "C" fn __default_naked_double_exception() {
|
.type __default_naked_double_exception,@function
|
||||||
asm!(
|
__default_naked_double_exception:
|
||||||
"
|
.Ldefault_double_naked_exception_start:
|
||||||
mov a0, a1 // save a1/sp
|
mov a0, a1 // save a1/sp
|
||||||
addmi sp, sp, -XT_STK_FRMSZ // only allow multiple of 256
|
addmi sp, sp, -XT_STK_FRMSZ // only allow multiple of 256
|
||||||
|
|
||||||
@ -592,99 +595,315 @@ unsafe extern "C" fn __default_naked_double_exception() {
|
|||||||
rsync // ensure PS and EPC written
|
rsync // ensure PS and EPC written
|
||||||
|
|
||||||
rfde
|
rfde
|
||||||
",
|
.Ldefault_double_naked_exception_end:
|
||||||
options(noreturn)
|
.size .Ldefault_double_naked_exception_start, .Ldefault_double_naked_exception_end
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
global_asm!(
|
// Handle Level 2 Interrupt by storing full context and then calling regular
|
||||||
r#"
|
// function
|
||||||
.macro HANDLE_INTERRUPT_LEVEL level
|
//
|
||||||
SAVE_CONTEXT \level
|
// # Input:
|
||||||
|
// * A0 stored in EXCSAVE2
|
||||||
|
.section .rwtext,\"ax\",@progbits
|
||||||
|
.global __default_naked_level_2_interrupt
|
||||||
|
.p2align 2
|
||||||
|
.type __default_naked_level_2_interrupt,@function
|
||||||
|
__default_naked_level_2_interrupt:
|
||||||
|
.Ldefault_naked_level_2_interrupt_start:
|
||||||
|
HANDLE_INTERRUPT_LEVEL 2
|
||||||
|
.Ldefault_naked_level_2_interrupt_end:
|
||||||
|
.size .Ldefault_naked_level_2_interrupt_start, .Ldefault_naked_level_2_interrupt_end
|
||||||
|
|
||||||
movi a0, (\level | PS_WOE)
|
// Handle Level 3 Interrupt by storing full context and then calling regular
|
||||||
wsr a0, PS
|
// function
|
||||||
rsync
|
//
|
||||||
|
// # Input:
|
||||||
|
// * A0 stored in EXCSAVE3
|
||||||
|
.section .rwtext,\"ax\",@progbits
|
||||||
|
.global __default_naked_level_3_interrupt
|
||||||
|
.p2align 2
|
||||||
|
.type __default_naked_level_3_interrupt,@function
|
||||||
|
__default_naked_level_3_interrupt:
|
||||||
|
.Ldefault_naked_level_3_interrupt_start:
|
||||||
|
HANDLE_INTERRUPT_LEVEL 3
|
||||||
|
.Ldefault_naked_level_3_interrupt_end:
|
||||||
|
.size .Ldefault_naked_level_3_interrupt_start, .Ldefault_naked_level_3_interrupt_end
|
||||||
|
|
||||||
movi a6, \level // put interrupt level in a6 = a2 in callee
|
// Handle Level 4 Interrupt by storing full context and then calling regular
|
||||||
mov a7, sp // put address of save frame in a7=a3 in callee
|
// function
|
||||||
call4 __level_\level\()_interrupt // call handler <= actual call!
|
//
|
||||||
|
// # Input:
|
||||||
|
// * A0 stored in EXCSAVE4
|
||||||
|
.section .rwtext,\"ax\",@progbits
|
||||||
|
.global __default_naked_level_4_interrupt
|
||||||
|
.p2align 2
|
||||||
|
.type __default_naked_level_4_interrupt,@function
|
||||||
|
__default_naked_level_4_interrupt:
|
||||||
|
.Ldefault_naked_level_4_interrupt_start:
|
||||||
|
HANDLE_INTERRUPT_LEVEL 4
|
||||||
|
.Ldefault_naked_level_4_interrupt_end:
|
||||||
|
.size .Ldefault_naked_level_4_interrupt_start, .Ldefault_naked_level_4_interrupt_end
|
||||||
|
|
||||||
RESTORE_CONTEXT \level
|
// Handle Level 5 Interrupt by storing full context and then calling regular
|
||||||
rfi \level
|
// function
|
||||||
|
//
|
||||||
|
// # Input:
|
||||||
|
// * A0 stored in EXCSAVE5
|
||||||
|
.section .rwtext,\"ax\",@progbits
|
||||||
|
.global __default_naked_level_5_interrupt
|
||||||
|
.p2align 2
|
||||||
|
.type __default_naked_level_5_interrupt,@function
|
||||||
|
__default_naked_level_5_interrupt:
|
||||||
|
.Ldefault_naked_level_5_interrupt_start:
|
||||||
|
HANDLE_INTERRUPT_LEVEL 5
|
||||||
|
.Ldefault_naked_level_5_interrupt_end:
|
||||||
|
.size .Ldefault_naked_level_5_interrupt_start, .Ldefault_naked_level_5_interrupt_end
|
||||||
|
|
||||||
.endm
|
// Handle Level 6 (=Debug) Interrupt by storing full context and then calling
|
||||||
"#
|
// regular function
|
||||||
|
//
|
||||||
|
// # Input:
|
||||||
|
// * A0 stored in EXCSAVE6
|
||||||
|
.section .rwtext,\"ax\",@progbits
|
||||||
|
.global __default_naked_level_6_interrupt
|
||||||
|
.p2align 2
|
||||||
|
.type __default_naked_level_6_interrupt,@function
|
||||||
|
__default_naked_level_6_interrupt:
|
||||||
|
.Ldefault_naked_level_6_interrupt_start:
|
||||||
|
HANDLE_INTERRUPT_LEVEL 6
|
||||||
|
.Ldefault_naked_level_6_interrupt_end:
|
||||||
|
.size .Ldefault_naked_level_6_interrupt_start, .Ldefault_naked_level_6_interrupt_end
|
||||||
|
|
||||||
|
// Handle Level 7 (=NMI) Interrupt by storing full context and then calling
|
||||||
|
// regular function
|
||||||
|
//
|
||||||
|
// # Input:
|
||||||
|
// * A0 stored in EXCSAVE7
|
||||||
|
.section .rwtext,\"ax\",@progbits
|
||||||
|
.global __default_naked_level_7_interrupt
|
||||||
|
.p2align 2
|
||||||
|
.type __default_naked_level_7_interrupt,@function
|
||||||
|
__default_naked_level_7_interrupt:
|
||||||
|
.Ldefault_naked_level_7_interrupt_start:
|
||||||
|
HANDLE_INTERRUPT_LEVEL 7
|
||||||
|
.Ldefault_naked_level_7_interrupt_end:
|
||||||
|
.size .Ldefault_naked_level_7_interrupt_start, .Ldefault_naked_level_7_interrupt_end
|
||||||
|
"
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Handle Level 2 Interrupt by storing full context and then calling regular
|
// Raw vector handlers
|
||||||
/// function
|
//
|
||||||
///
|
// The interrupt handlers all use special return instructions.
|
||||||
/// # Input:
|
// rust still generates a ret.w instruction, which will never be reached.
|
||||||
/// * A0 stored in EXCSAVE2
|
// generation of the ret.w can be prevented by using
|
||||||
#[naked]
|
// core::intrinsics::unreachable, but then a break 15,1 will be generated (which
|
||||||
#[no_mangle]
|
// takes 3 bytes instead of 2) or a 'loop {}', but then a jump to own address
|
||||||
#[link_section = ".rwtext"]
|
// will be generated which is also 3 bytes. No way found yet to prevent this
|
||||||
unsafe extern "C" fn __default_naked_level_2_interrupt() {
|
// generation altogether.
|
||||||
asm!("HANDLE_INTERRUPT_LEVEL 2", options(noreturn));
|
global_asm!(
|
||||||
}
|
"
|
||||||
|
.section .WindowOverflow8.text,\"ax\",@progbits
|
||||||
|
.global _WindowOverflow8
|
||||||
|
.p2align 2
|
||||||
|
.type _WindowOverflow8,@function
|
||||||
|
_WindowOverflow8:
|
||||||
|
s32e a0, a9, -16
|
||||||
|
l32e a0, a1, -12
|
||||||
|
|
||||||
/// Handle Level 3 Interrupt by storing full context and then calling regular
|
s32e a1, a9, -12
|
||||||
/// function
|
s32e a2, a9, -8
|
||||||
///
|
s32e a3, a9, -4
|
||||||
/// # Input:
|
s32e a4, a0, -32
|
||||||
/// * A0 stored in EXCSAVE3
|
s32e a5, a0, -28
|
||||||
#[naked]
|
s32e a6, a0, -24
|
||||||
#[no_mangle]
|
s32e a7, a0, -20
|
||||||
#[link_section = ".rwtext"]
|
rfwo
|
||||||
unsafe extern "C" fn __default_naked_level_3_interrupt() {
|
|
||||||
asm!("HANDLE_INTERRUPT_LEVEL 3", options(noreturn));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handle Level 4 Interrupt by storing full context and then calling regular
|
.section .WindowUnderflow8.text,\"ax\",@progbits
|
||||||
/// function
|
.global _WindowUnderflow8
|
||||||
///
|
.p2align 2
|
||||||
/// # Input:
|
.type _WindowUnderflow8,@function
|
||||||
/// * A0 stored in EXCSAVE4
|
_WindowUnderflow8:
|
||||||
#[naked]
|
l32e a0, a9, -16
|
||||||
#[no_mangle]
|
l32e a1, a9, -12
|
||||||
#[link_section = ".rwtext"]
|
l32e a2, a9, -8
|
||||||
unsafe extern "C" fn __default_naked_level_4_interrupt() {
|
l32e a7, a1, -12
|
||||||
asm!("HANDLE_INTERRUPT_LEVEL 4", options(noreturn));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handle Level 5 Interrupt by storing full context and then calling regular
|
l32e a3, a9, -4
|
||||||
/// function
|
l32e a4, a7, -32
|
||||||
///
|
l32e a5, a7, -28
|
||||||
/// # Input:
|
l32e a6, a7, -24
|
||||||
/// * A0 stored in EXCSAVE5
|
l32e a7, a7, -20
|
||||||
#[naked]
|
rfwu
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".rwtext"]
|
|
||||||
unsafe extern "C" fn __default_naked_level_5_interrupt() {
|
|
||||||
asm!("HANDLE_INTERRUPT_LEVEL 5", options(noreturn));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handle Level 6 (=Debug) Interrupt by storing full context and then calling
|
.section .WindowOverflow12.text,\"ax\",@progbits
|
||||||
/// regular function
|
.global _WindowOverflow12
|
||||||
///
|
.p2align 2
|
||||||
/// # Input:
|
.type _WindowOverflow12,@function
|
||||||
/// * A0 stored in EXCSAVE6
|
_WindowOverflow12:
|
||||||
#[naked]
|
s32e a0, a13, -16
|
||||||
#[no_mangle]
|
l32e a0, a1, -12
|
||||||
#[link_section = ".rwtext"]
|
|
||||||
unsafe extern "C" fn __default_naked_level_6_interrupt() {
|
|
||||||
asm!("HANDLE_INTERRUPT_LEVEL 6", options(noreturn));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handle Level 7 (=NMI) Interrupt by storing full context and then calling
|
s32e a1, a13, -12
|
||||||
/// regular function
|
s32e a2, a13, -8
|
||||||
///
|
s32e a3, a13, -4
|
||||||
/// # Input:
|
s32e a4, a0, -48
|
||||||
/// * A0 stored in EXCSAVE7
|
s32e a5, a0, -44
|
||||||
#[naked]
|
s32e a6, a0, -40
|
||||||
#[no_mangle]
|
s32e a7, a0, -36
|
||||||
#[link_section = ".rwtext"]
|
s32e a8, a0, -32
|
||||||
unsafe extern "C" fn __default_naked_level_7_interrupt() {
|
s32e a9, a0, -28
|
||||||
asm!("HANDLE_INTERRUPT_LEVEL 7", options(noreturn));
|
s32e a10, a0, -24
|
||||||
}
|
s32e a11, a0, -20
|
||||||
|
rfwo
|
||||||
|
|
||||||
|
.section .WindowUnderflow12.text,\"ax\",@progbits
|
||||||
|
.global _WindowUnderflow12
|
||||||
|
.p2align 2
|
||||||
|
.type _WindowUnderflow12,@function
|
||||||
|
_WindowUnderflow12:
|
||||||
|
l32e a0, a13, -16
|
||||||
|
l32e a1, a13, -12
|
||||||
|
l32e a2, a13, -8
|
||||||
|
l32e a11, a1, -12
|
||||||
|
|
||||||
|
l32e a3, a13, -4
|
||||||
|
l32e a4, a11, -48
|
||||||
|
l32e a5, a11, -44
|
||||||
|
l32e a6, a11, -40
|
||||||
|
l32e a7, a11, -36
|
||||||
|
l32e a8, a11, -32
|
||||||
|
l32e a9, a11, -28
|
||||||
|
l32e a10, a11, -24
|
||||||
|
l32e a11, a11, -20
|
||||||
|
rfwu
|
||||||
|
|
||||||
|
.section .WindowOverflow4.text,\"ax\",@progbits
|
||||||
|
.global _WindowOverflow4
|
||||||
|
.p2align 2
|
||||||
|
.type _WindowOverflow4,@function
|
||||||
|
_WindowOverflow4:
|
||||||
|
s32e a0, a5, -16
|
||||||
|
s32e a1, a5, -12
|
||||||
|
s32e a2, a5, -8
|
||||||
|
s32e a3, a5, -4
|
||||||
|
rfwo
|
||||||
|
|
||||||
|
.section .WindowUnderflow4.text,\"ax\",@progbits
|
||||||
|
.global _WindowUnderflow4
|
||||||
|
.p2align 2
|
||||||
|
.type _WindowUnderflow4,@function
|
||||||
|
_WindowUnderflow4:
|
||||||
|
l32e a0, a5, -16
|
||||||
|
l32e a1, a5, -12
|
||||||
|
l32e a2, a5, -8
|
||||||
|
l32e a3, a5, -4
|
||||||
|
rfwu
|
||||||
|
|
||||||
|
// inline the _AllocAException saves on the ret.w for WindowUnderflow4
|
||||||
|
// this makes that it just fits, which is needed for the bbci instructions
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
_AllocAException:
|
||||||
|
rsr a0, WINDOWBASE // grab WINDOWBASE before rotw changes it
|
||||||
|
rotw -1 // WINDOWBASE goes to a4, new a0-a3 are scratch
|
||||||
|
rsr a2, PS
|
||||||
|
extui a3, a2, 8, 4 // XCHAL_PS_OWB_SHIFT, XCHAL_PS_OWB_BITS
|
||||||
|
xor a3, a3, a4 // bits changed from old to current windowbase
|
||||||
|
rsr a4, EXCSAVE1 // restore original a0 (now in a4)
|
||||||
|
slli a3, a3, 8 // XCHAL_PS_OWB_SHIFT
|
||||||
|
xor a2, a2, a3 // flip changed bits in old window base
|
||||||
|
wsr a2, PS // update PS.OWB to new window base
|
||||||
|
rsync
|
||||||
|
|
||||||
|
bbci a4, 31, _WindowUnderflow4
|
||||||
|
rotw -1 // original a0 goes to a8
|
||||||
|
bbci a8, 30, _WindowUnderflow8
|
||||||
|
rotw -1
|
||||||
|
j _WindowUnderflow12
|
||||||
|
|
||||||
|
.section .KernelExceptionVector.text,\"ax\",@progbits
|
||||||
|
.global _KernelExceptionVector
|
||||||
|
.p2align 2
|
||||||
|
.type _KernelExceptionVector,@function
|
||||||
|
_KernelExceptionVector:
|
||||||
|
wsr a0, EXCSAVE1 // preserve a0
|
||||||
|
rsr a0, EXCCAUSE // get exception cause
|
||||||
|
|
||||||
|
beqi a0, 5, .AllocAException
|
||||||
|
|
||||||
|
call0 __naked_kernel_exception
|
||||||
|
|
||||||
|
.section .UserExceptionVector.text,\"ax\",@progbits
|
||||||
|
.global _UserExceptionVector
|
||||||
|
.p2align 2
|
||||||
|
.type _UserExceptionVector,@function
|
||||||
|
_UserExceptionVector:
|
||||||
|
wsr a0, EXCSAVE1 // preserve a0
|
||||||
|
rsr a0, EXCCAUSE // get exception cause
|
||||||
|
|
||||||
|
beqi a0, 5, .AllocAException
|
||||||
|
|
||||||
|
call0 __naked_user_exception
|
||||||
|
|
||||||
|
.AllocAException:
|
||||||
|
call0 _AllocAException
|
||||||
|
|
||||||
|
.section .DoubleExceptionVector.text,\"ax\",@progbits
|
||||||
|
.global _DoubleExceptionVector
|
||||||
|
.p2align 2
|
||||||
|
.type _DoubleExceptionVector,@function
|
||||||
|
_DoubleExceptionVector:
|
||||||
|
wsr a0, EXCSAVE1 // preserve a0 (EXCSAVE1 can be reused as long as there
|
||||||
|
// is no double exception in the first exception until
|
||||||
|
// EXCSAVE1 is stored to the stack.)
|
||||||
|
call0 __naked_double_exception // used as long jump
|
||||||
|
|
||||||
|
.section .Level2InterruptVector.text,\"ax\",@progbits
|
||||||
|
.global _Level2InterruptVector
|
||||||
|
.p2align 2
|
||||||
|
.type _Level2InterruptVector,@function
|
||||||
|
_Level2InterruptVector:
|
||||||
|
wsr a0, EXCSAVE2 // preserve a0
|
||||||
|
call0 __naked_level_2_interrupt // used as long jump
|
||||||
|
|
||||||
|
.section .Level3InterruptVector.text,\"ax\",@progbits
|
||||||
|
.global _Level3InterruptVector
|
||||||
|
.p2align 2
|
||||||
|
.type _Level3InterruptVector,@function
|
||||||
|
_Level3InterruptVector:
|
||||||
|
wsr a0, EXCSAVE3 // preserve a0
|
||||||
|
call0 __naked_level_3_interrupt // used as long jump
|
||||||
|
|
||||||
|
.section .Level4InterruptVector.text,\"ax\",@progbits
|
||||||
|
.global _Level4InterruptVector
|
||||||
|
.p2align 2
|
||||||
|
.type _Level4InterruptVector,@function
|
||||||
|
_Level4InterruptVector:
|
||||||
|
wsr a0, EXCSAVE4 // preserve a0
|
||||||
|
call0 __naked_level_4_interrupt // used as long jump
|
||||||
|
|
||||||
|
.section .Level5InterruptVector.text,\"ax\",@progbits
|
||||||
|
.global _Level5InterruptVector
|
||||||
|
.p2align 2
|
||||||
|
.type _Level5InterruptVector,@function
|
||||||
|
_Level5InterruptVector:
|
||||||
|
wsr a0, EXCSAVE5 // preserve a0
|
||||||
|
call0 __naked_level_5_interrupt // used as long jump
|
||||||
|
|
||||||
|
.section .DebugExceptionVector.text,\"ax\",@progbits
|
||||||
|
.global _Level6InterruptVector
|
||||||
|
.p2align 2
|
||||||
|
.type _Level6InterruptVector,@function
|
||||||
|
_Level6InterruptVector:
|
||||||
|
wsr a0, EXCSAVE6 // preserve a0
|
||||||
|
call0 __naked_level_6_interrupt // used as long jump
|
||||||
|
|
||||||
|
.section .NMIExceptionVector.text,\"ax\",@progbits
|
||||||
|
.global _Level7InterruptVector
|
||||||
|
.p2align 2
|
||||||
|
.type _Level7InterruptVector,@function
|
||||||
|
_Level7InterruptVector:
|
||||||
|
wsr a0, EXCSAVE7 // preserve a0
|
||||||
|
call0 __naked_level_7_interrupt // used as long jump
|
||||||
|
"
|
||||||
|
);
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
use core::arch::asm;
|
|
||||||
|
|
||||||
use super::ExceptionCause;
|
use super::ExceptionCause;
|
||||||
|
|
||||||
/// State of the CPU saved when entering exception or interrupt
|
/// State of the CPU saved when entering exception or interrupt
|
||||||
@ -161,293 +159,3 @@ extern "C" fn __default_interrupt(level: u32, save_frame: &Context) {
|
|||||||
extern "C" fn __default_double_exception(cause: ExceptionCause, save_frame: &Context) {
|
extern "C" fn __default_double_exception(cause: ExceptionCause, save_frame: &Context) {
|
||||||
panic!("Double Exception: {:?}, {:08x?}", cause, save_frame)
|
panic!("Double Exception: {:?}, {:08x?}", cause, save_frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Raw vector handlers
|
|
||||||
//
|
|
||||||
// The interrupt handlers all use special return instructions.
|
|
||||||
// rust still generates a ret.w instruction, which will never be reached.
|
|
||||||
// generation of the ret.w can be prevented by using
|
|
||||||
// core::intrinsics::unreachable, but then a break 15,1 will be generated (which
|
|
||||||
// takes 3 bytes instead of 2) or a 'loop {}', but then a jump to own address
|
|
||||||
// will be generated which is also 3 bytes. No way found yet to prevent this
|
|
||||||
// generation altogether.
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".KernelExceptionVector.text"]
|
|
||||||
unsafe extern "C" fn _KernelExceptionVector() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
wsr a0, EXCSAVE1 // preserve a0
|
|
||||||
rsr a0, EXCCAUSE // get exception cause
|
|
||||||
|
|
||||||
beqi a0, 5, .AllocAException
|
|
||||||
|
|
||||||
call0 __naked_kernel_exception
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".UserExceptionVector.text"]
|
|
||||||
unsafe extern "C" fn _UserExceptionVector() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
wsr a0, EXCSAVE1 // preserve a0
|
|
||||||
rsr a0, EXCCAUSE // get exception cause
|
|
||||||
|
|
||||||
beqi a0, 5, .AllocAException
|
|
||||||
|
|
||||||
call0 __naked_user_exception
|
|
||||||
|
|
||||||
.AllocAException:
|
|
||||||
call0 _AllocAException
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".DoubleExceptionVector.text"]
|
|
||||||
unsafe extern "C" fn _DoubleExceptionVector() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
wsr a0, EXCSAVE1 // preserve a0 (EXCSAVE1 can be reused as long as there
|
|
||||||
// is no double exception in the first exception until
|
|
||||||
// EXCSAVE1 is stored to the stack.)
|
|
||||||
call0 __naked_double_exception // used as long jump
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".Level2InterruptVector.text"]
|
|
||||||
unsafe extern "C" fn _Level2InterruptVector() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
wsr a0, EXCSAVE2 // preserve a0
|
|
||||||
call0 __naked_level_2_interrupt // used as long jump
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".Level3InterruptVector.text"]
|
|
||||||
unsafe extern "C" fn _Level3InterruptVector() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
wsr a0, EXCSAVE3 // preserve a0
|
|
||||||
call0 __naked_level_3_interrupt // used as long jump
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".Level4InterruptVector.text"]
|
|
||||||
unsafe extern "C" fn _Level4InterruptVector() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
wsr a0, EXCSAVE4 // preserve a0
|
|
||||||
call0 __naked_level_4_interrupt // used as long jump
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".Level5InterruptVector.text"]
|
|
||||||
unsafe extern "C" fn _Level5InterruptVector() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
wsr a0, EXCSAVE5 // preserve a0
|
|
||||||
call0 __naked_level_5_interrupt // used as long jump
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".DebugExceptionVector.text"]
|
|
||||||
unsafe extern "C" fn _Level6InterruptVector() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
wsr a0, EXCSAVE6 // preserve a0
|
|
||||||
call0 __naked_level_6_interrupt // used as long jump
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".NMIExceptionVector.text"]
|
|
||||||
unsafe extern "C" fn _Level7InterruptVector() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
wsr a0, EXCSAVE7 // preserve a0
|
|
||||||
call0 __naked_level_7_interrupt // used as long jump
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".WindowOverflow4.text"]
|
|
||||||
unsafe extern "C" fn _WindowOverflow4() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
s32e a0, a5, -16
|
|
||||||
s32e a1, a5, -12
|
|
||||||
s32e a2, a5, -8
|
|
||||||
s32e a3, a5, -4
|
|
||||||
rfwo
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".WindowUnderflow4.text"]
|
|
||||||
unsafe extern "C" fn _WindowUnderflow4() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
l32e a0, a5, -16
|
|
||||||
l32e a1, a5, -12
|
|
||||||
l32e a2, a5, -8
|
|
||||||
l32e a3, a5, -4
|
|
||||||
rfwu
|
|
||||||
|
|
||||||
// inline the _AllocAException saves on the ret.w for WindowUnderflow4
|
|
||||||
// this makes that it just fits, which is needed for the bbci instructions
|
|
||||||
|
|
||||||
.align 4
|
|
||||||
_AllocAException:
|
|
||||||
rsr a0, WINDOWBASE // grab WINDOWBASE before rotw changes it
|
|
||||||
rotw -1 // WINDOWBASE goes to a4, new a0-a3 are scratch
|
|
||||||
rsr a2, PS
|
|
||||||
extui a3, a2, 8, 4 // XCHAL_PS_OWB_SHIFT, XCHAL_PS_OWB_BITS
|
|
||||||
xor a3, a3, a4 // bits changed from old to current windowbase
|
|
||||||
rsr a4, EXCSAVE1 // restore original a0 (now in a4)
|
|
||||||
slli a3, a3, 8 // XCHAL_PS_OWB_SHIFT
|
|
||||||
xor a2, a2, a3 // flip changed bits in old window base
|
|
||||||
wsr a2, PS // update PS.OWB to new window base
|
|
||||||
rsync
|
|
||||||
|
|
||||||
bbci a4, 31, _WindowUnderflow4
|
|
||||||
rotw -1 // original a0 goes to a8
|
|
||||||
bbci a8, 30, _WindowUnderflow8
|
|
||||||
rotw -1
|
|
||||||
j _WindowUnderflow12
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".WindowOverflow8.text"]
|
|
||||||
unsafe extern "C" fn _WindowOverflow8() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
s32e a0, a9, -16
|
|
||||||
l32e a0, a1, -12
|
|
||||||
|
|
||||||
s32e a1, a9, -12
|
|
||||||
s32e a2, a9, -8
|
|
||||||
s32e a3, a9, -4
|
|
||||||
s32e a4, a0, -32
|
|
||||||
s32e a5, a0, -28
|
|
||||||
s32e a6, a0, -24
|
|
||||||
s32e a7, a0, -20
|
|
||||||
rfwo
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".WindowUnderflow8.text"]
|
|
||||||
unsafe extern "C" fn _WindowUnderflow8() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
l32e a0, a9, -16
|
|
||||||
l32e a1, a9, -12
|
|
||||||
l32e a2, a9, -8
|
|
||||||
l32e a7, a1, -12
|
|
||||||
|
|
||||||
l32e a3, a9, -4
|
|
||||||
l32e a4, a7, -32
|
|
||||||
l32e a5, a7, -28
|
|
||||||
l32e a6, a7, -24
|
|
||||||
l32e a7, a7, -20
|
|
||||||
rfwu
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".WindowOverflow12.text"]
|
|
||||||
unsafe extern "C" fn _WindowOverflow12() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
s32e a0, a13, -16
|
|
||||||
l32e a0, a1, -12
|
|
||||||
|
|
||||||
s32e a1, a13, -12
|
|
||||||
s32e a2, a13, -8
|
|
||||||
s32e a3, a13, -4
|
|
||||||
s32e a4, a0, -48
|
|
||||||
s32e a5, a0, -44
|
|
||||||
s32e a6, a0, -40
|
|
||||||
s32e a7, a0, -36
|
|
||||||
s32e a8, a0, -32
|
|
||||||
s32e a9, a0, -28
|
|
||||||
s32e a10, a0, -24
|
|
||||||
s32e a11, a0, -20
|
|
||||||
rfwo
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[naked]
|
|
||||||
#[no_mangle]
|
|
||||||
#[link_section = ".WindowUnderflow12.text"]
|
|
||||||
unsafe extern "C" fn _WindowUnderflow12() {
|
|
||||||
asm!(
|
|
||||||
"
|
|
||||||
l32e a0, a13, -16
|
|
||||||
l32e a1, a13, -12
|
|
||||||
l32e a2, a13, -8
|
|
||||||
l32e a11, a1, -12
|
|
||||||
|
|
||||||
l32e a3, a13, -4
|
|
||||||
l32e a4, a11, -48
|
|
||||||
l32e a5, a11, -44
|
|
||||||
l32e a6, a11, -40
|
|
||||||
l32e a7, a11, -36
|
|
||||||
l32e a8, a11, -32
|
|
||||||
l32e a9, a11, -28
|
|
||||||
l32e a10, a11, -24
|
|
||||||
l32e a11, a11, -20
|
|
||||||
rfwu
|
|
||||||
",
|
|
||||||
options(noreturn)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -170,3 +170,23 @@ macro_rules! cfg_asm {
|
|||||||
cfg_asm!(@inner, [], [$($opts)*], $($asms)*)
|
cfg_asm!(@inner, [], [$($opts)*], $($asms)*)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! cfg_global_asm {
|
||||||
|
{@inner, [$($x:tt)*], } => {
|
||||||
|
global_asm!{$($x)*}
|
||||||
|
};
|
||||||
|
(@inner, [$($x:tt)*], #[cfg($meta:meta)] $asm:literal, $($rest:tt)*) => {
|
||||||
|
#[cfg($meta)]
|
||||||
|
cfg_global_asm!{@inner, [$($x)* $asm,], $($rest)*}
|
||||||
|
#[cfg(not($meta))]
|
||||||
|
cfg_global_asm!{@inner, [$($x)*], $($rest)*}
|
||||||
|
};
|
||||||
|
{@inner, [$($x:tt)*], $asm:literal, $($rest:tt)*} => {
|
||||||
|
cfg_global_asm!{@inner, [$($x)* $asm,], $($rest)*}
|
||||||
|
};
|
||||||
|
{$($asms:tt)*} => {
|
||||||
|
cfg_global_asm!{@inner, [], $($asms)*}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user