mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-05-24 19:23:46 +02:00
Add methods to mask and clear interrupts.
This commit is contained in:
parent
d143528e07
commit
ce752db15a
@ -28,7 +28,7 @@ use core::hint::spin_loop;
|
|||||||
// ANCHOR: imports
|
// ANCHOR: imports
|
||||||
use crate::pl011::Uart;
|
use crate::pl011::Uart;
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
use log::{error, info, LevelFilter};
|
use log::{error, info, trace, LevelFilter};
|
||||||
use psci::system_off;
|
use psci::system_off;
|
||||||
|
|
||||||
/// Base address of the primary PL011 UART.
|
/// Base address of the primary PL011 UART.
|
||||||
@ -63,9 +63,43 @@ extern "C" fn main(x0: u64, x1: u64, x2: u64, x3: u64) {
|
|||||||
"Waiting for {}",
|
"Waiting for {}",
|
||||||
Utc.timestamp_opt(target.into(), 0).unwrap()
|
Utc.timestamp_opt(target.into(), 0).unwrap()
|
||||||
);
|
);
|
||||||
|
trace!(
|
||||||
|
"matched={}, interrupt_pending={}",
|
||||||
|
rtc.matched(),
|
||||||
|
rtc.interrupt_pending()
|
||||||
|
);
|
||||||
while !rtc.matched() {
|
while !rtc.matched() {
|
||||||
spin_loop();
|
spin_loop();
|
||||||
}
|
}
|
||||||
|
trace!(
|
||||||
|
"matched={}, interrupt_pending={}",
|
||||||
|
rtc.matched(),
|
||||||
|
rtc.interrupt_pending()
|
||||||
|
);
|
||||||
|
info!("Finished waiting");
|
||||||
|
|
||||||
|
// Wait another 3 seconds for an interrupt.
|
||||||
|
let target = timestamp + 6;
|
||||||
|
info!(
|
||||||
|
"Waiting for {}",
|
||||||
|
Utc.timestamp_opt(target.into(), 0).unwrap()
|
||||||
|
);
|
||||||
|
rtc.set_match(target);
|
||||||
|
rtc.clear_interrupt();
|
||||||
|
rtc.enable_interrupt(true);
|
||||||
|
trace!(
|
||||||
|
"matched={}, interrupt_pending={}",
|
||||||
|
rtc.matched(),
|
||||||
|
rtc.interrupt_pending()
|
||||||
|
);
|
||||||
|
while !rtc.interrupt_pending() {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
trace!(
|
||||||
|
"matched={}, interrupt_pending={}",
|
||||||
|
rtc.matched(),
|
||||||
|
rtc.interrupt_pending()
|
||||||
|
);
|
||||||
info!("Finished waiting");
|
info!("Finished waiting");
|
||||||
|
|
||||||
// ANCHOR: main_end
|
// ANCHOR: main_end
|
||||||
|
@ -83,6 +83,35 @@ impl Rtc {
|
|||||||
let ris = unsafe { addr_of!((*self.registers).ris).read_volatile() };
|
let ris = unsafe { addr_of!((*self.registers).ris).read_volatile() };
|
||||||
(ris & 0x01) != 0
|
(ris & 0x01) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether there is currently an interrupt pending.
|
||||||
|
///
|
||||||
|
/// This should be true iff `matched` returns true and the interrupt is
|
||||||
|
/// masked.
|
||||||
|
pub fn interrupt_pending(&self) -> bool {
|
||||||
|
// Safe because we know that self.registers points to the control
|
||||||
|
// registers of a PL031 device which is appropriately mapped.
|
||||||
|
let ris = unsafe { addr_of!((*self.registers).mis).read_volatile() };
|
||||||
|
(ris & 0x01) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets or clears the interrupt mask.
|
||||||
|
///
|
||||||
|
/// When the mask is true the interrupt is enabled; when it is false the
|
||||||
|
/// interrupt is disabled.
|
||||||
|
pub fn enable_interrupt(&mut self, mask: bool) {
|
||||||
|
let imsc = if mask { 0x01 } else { 0x00 };
|
||||||
|
// Safe because we know that self.registers points to the control
|
||||||
|
// registers of a PL031 device which is appropriately mapped.
|
||||||
|
unsafe { addr_of_mut!((*self.registers).imsc).write_volatile(imsc) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clears a pending interrupt, if any.
|
||||||
|
pub fn clear_interrupt(&mut self) {
|
||||||
|
// Safe because we know that self.registers points to the control
|
||||||
|
// registers of a PL031 device which is appropriately mapped.
|
||||||
|
unsafe { addr_of_mut!((*self.registers).icr).write_volatile(0x01) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safe because it just contains a pointer to device memory, which can be
|
// Safe because it just contains a pointer to device memory, which can be
|
||||||
|
Loading…
x
Reference in New Issue
Block a user