mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-05-24 03:10:28 +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
|
||||
use crate::pl011::Uart;
|
||||
use core::panic::PanicInfo;
|
||||
use log::{error, info, LevelFilter};
|
||||
use log::{error, info, trace, LevelFilter};
|
||||
use psci::system_off;
|
||||
|
||||
/// 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 {}",
|
||||
Utc.timestamp_opt(target.into(), 0).unwrap()
|
||||
);
|
||||
trace!(
|
||||
"matched={}, interrupt_pending={}",
|
||||
rtc.matched(),
|
||||
rtc.interrupt_pending()
|
||||
);
|
||||
while !rtc.matched() {
|
||||
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");
|
||||
|
||||
// ANCHOR: main_end
|
||||
|
@ -83,6 +83,35 @@ impl Rtc {
|
||||
let ris = unsafe { addr_of!((*self.registers).ris).read_volatile() };
|
||||
(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
|
||||
|
Loading…
x
Reference in New Issue
Block a user