forked from rcore-os/zCore
cargo fmt
This commit is contained in:
parent
ad11af41d4
commit
fe64fc2021
|
@ -1,10 +1,10 @@
|
|||
#![allow(dead_code)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
|
||||
use trapframe::TrapFrame;
|
||||
use spin::Mutex;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
use spin::Mutex;
|
||||
use trapframe::TrapFrame;
|
||||
|
||||
pub type InterruptHandle = Arc<dyn Fn() + Send + Sync>;
|
||||
lazy_static! {
|
||||
|
@ -75,7 +75,7 @@ pub fn irq_remove_handle(irq: u8) -> bool {
|
|||
table[irq] = None;
|
||||
false
|
||||
}
|
||||
None => true
|
||||
None => true,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -278,7 +278,7 @@ pub fn irq_add_handle(_irq: u8, _handle: Arc<dyn Fn() + Send + Sync>) -> bool {
|
|||
#[export_name = "hal_irq_remove_handle"]
|
||||
pub fn irq_remove_handle(_irq: u8) -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
/// Enable IRQ.
|
||||
#[linkage = "weak"]
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
use {
|
||||
super::*,
|
||||
alloc::sync::Arc,
|
||||
spin::Mutex,
|
||||
};
|
||||
use {super::*, alloc::sync::Arc, spin::Mutex};
|
||||
|
||||
pub struct EventInterrupt{
|
||||
pub struct EventInterrupt {
|
||||
vector: u8,
|
||||
inner: Mutex<EventInterruptInner>,
|
||||
}
|
||||
|
@ -17,7 +13,7 @@ struct EventInterruptInner {
|
|||
impl EventInterrupt {
|
||||
pub fn new(vector: usize) -> Arc<Self> {
|
||||
// TODO check vector is a vaild IRQ number
|
||||
Arc::new( EventInterrupt {
|
||||
Arc::new(EventInterrupt {
|
||||
vector: vector as u8,
|
||||
inner: Default::default(),
|
||||
})
|
||||
|
@ -25,21 +21,27 @@ impl EventInterrupt {
|
|||
}
|
||||
|
||||
impl InterruptTrait for EventInterrupt {
|
||||
fn mask_interrupt_locked(&self) { kernel_hal::irq_disable(self.vector as u8); }
|
||||
|
||||
fn unmask_interrupt_locked(&self) { kernel_hal::irq_enable(self.vector as u8); }
|
||||
|
||||
fn mask_interrupt_locked(&self) {
|
||||
kernel_hal::irq_disable(self.vector as u8);
|
||||
}
|
||||
|
||||
fn unmask_interrupt_locked(&self) {
|
||||
kernel_hal::irq_enable(self.vector as u8);
|
||||
}
|
||||
|
||||
fn register_interrupt_handler(&self, handle: Arc<dyn Fn() + Send + Sync>) -> ZxResult {
|
||||
let mut inner = self.inner.lock();
|
||||
if inner.register {
|
||||
return Err(ZxError::ALREADY_BOUND);
|
||||
}
|
||||
if kernel_hal::irq_add_handle(self.vector, handle) {
|
||||
inner.register = true;
|
||||
inner.register = true;
|
||||
Ok(())
|
||||
} else { Err(ZxError::ALREADY_BOUND) }
|
||||
} else {
|
||||
Err(ZxError::ALREADY_BOUND)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn unregister_interrupt_handler(&self) -> ZxResult {
|
||||
let mut inner = self.inner.lock();
|
||||
if !inner.register {
|
||||
|
@ -48,6 +50,8 @@ impl InterruptTrait for EventInterrupt {
|
|||
if kernel_hal::irq_remove_handle(self.vector) {
|
||||
inner.register = false;
|
||||
Ok(())
|
||||
} else { Err(ZxError::ALREADY_BOUND) } // maybe a better error code?
|
||||
} else {
|
||||
Err(ZxError::ALREADY_BOUND)
|
||||
} // maybe a better error code?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,10 @@
|
|||
use {
|
||||
crate::object::*,
|
||||
alloc::sync::Arc,
|
||||
spin::Mutex,
|
||||
bitflags::bitflags,
|
||||
crate::signal::*,
|
||||
self::virtual_interrupt::*,
|
||||
self::event_interrupt::*,
|
||||
self::event_interrupt::*, self::virtual_interrupt::*, crate::object::*, crate::signal::*,
|
||||
alloc::sync::Arc, bitflags::bitflags, spin::Mutex,
|
||||
};
|
||||
|
||||
mod virtual_interrupt;
|
||||
mod event_interrupt;
|
||||
mod virtual_interrupt;
|
||||
|
||||
pub trait InterruptTrait: Sync + Send {
|
||||
fn mask_interrupt_locked(&self);
|
||||
|
@ -76,7 +71,11 @@ impl Interrupt {
|
|||
trait_: EventInterrupt::new(vector),
|
||||
});
|
||||
let event_interrupt_clone = event_interrupt.clone();
|
||||
event_interrupt.trait_.register_interrupt_handler(Arc::new(move || { event_interrupt_clone.interrupt_handle()} ))?;
|
||||
event_interrupt
|
||||
.trait_
|
||||
.register_interrupt_handler(Arc::new(move || {
|
||||
event_interrupt_clone.interrupt_handle()
|
||||
}))?;
|
||||
event_interrupt.trait_.unmask_interrupt_locked();
|
||||
Ok(event_interrupt)
|
||||
}
|
||||
|
@ -91,7 +90,10 @@ impl Interrupt {
|
|||
if inner.port.is_some() || self.hasvcpu {
|
||||
return Err(ZxError::ALREADY_BOUND);
|
||||
}
|
||||
if self.flags.contains(InterruptFlags::UNMASK_PREWAIT_UNLOCKED | InterruptFlags::MASK_POSTWAIT) {
|
||||
if self
|
||||
.flags
|
||||
.contains(InterruptFlags::UNMASK_PREWAIT_UNLOCKED | InterruptFlags::MASK_POSTWAIT)
|
||||
{
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
}
|
||||
inner.port = Some(port.clone());
|
||||
|
@ -162,13 +164,18 @@ impl Interrupt {
|
|||
}
|
||||
if inner.timestamp > 0 {
|
||||
// TODO: use a function to send the package
|
||||
inner.packet_id = inner.port.as_ref().unwrap().as_ref().push_interrupt(inner.timestamp, inner.key);
|
||||
inner.packet_id = inner
|
||||
.port
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.push_interrupt(inner.timestamp, inner.key);
|
||||
if self.flags.contains(InterruptFlags::MASK_POSTWAIT) {
|
||||
self.trait_.mask_interrupt_locked();
|
||||
}
|
||||
inner.timestamp = 0;
|
||||
} else {
|
||||
inner.state = InterruptState::IDLE;
|
||||
inner.state = InterruptState::IDLE;
|
||||
}
|
||||
}
|
||||
if inner.defer_unmask {
|
||||
|
@ -186,7 +193,11 @@ impl Interrupt {
|
|||
match inner.state {
|
||||
InterruptState::NEEDACK => {
|
||||
inner.state = InterruptState::DESTORY;
|
||||
if !in_queue { Err(ZxError::NOT_FOUND) } else { Ok(()) }
|
||||
if !in_queue {
|
||||
Err(ZxError::NOT_FOUND)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
InterruptState::IDLE => {
|
||||
|
@ -194,7 +205,7 @@ impl Interrupt {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
_ => Ok(())
|
||||
_ => Ok(()),
|
||||
}
|
||||
} else {
|
||||
inner.state = InterruptState::DESTORY;
|
||||
|
@ -206,7 +217,7 @@ impl Interrupt {
|
|||
pub async fn wait(self: &Arc<Self>) -> ZxResult<i64> {
|
||||
let mut defer_unmask = false;
|
||||
let object = self.clone() as Arc<dyn KernelObject>;
|
||||
loop {
|
||||
loop {
|
||||
{
|
||||
let mut inner = self.inner.lock();
|
||||
if inner.port.is_some() || self.hasvcpu {
|
||||
|
@ -220,7 +231,7 @@ impl Interrupt {
|
|||
inner.timestamp = 0;
|
||||
self.base.signal_clear(Signal::INTERRUPT_SIGNAL);
|
||||
return Ok(timestamp);
|
||||
},
|
||||
}
|
||||
InterruptState::NEEDACK => {
|
||||
if self.flags.contains(InterruptFlags::UNMASK_PREWAIT) {
|
||||
self.trait_.unmask_interrupt_locked();
|
||||
|
@ -258,7 +269,7 @@ impl Interrupt {
|
|||
self.trait_.mask_interrupt_locked();
|
||||
}
|
||||
inner.timestamp = 0;
|
||||
|
||||
|
||||
inner.state = InterruptState::NEEDACK;
|
||||
}
|
||||
}
|
||||
|
@ -280,7 +291,9 @@ enum InterruptState {
|
|||
}
|
||||
|
||||
impl Default for InterruptState {
|
||||
fn default() -> Self { InterruptState::IDLE }
|
||||
fn default() -> Self {
|
||||
InterruptState::IDLE
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
|
@ -308,7 +321,7 @@ bitflags! {
|
|||
}
|
||||
|
||||
impl InterruptOptions {
|
||||
pub fn to_mode(self)-> Self {
|
||||
pub fn to_mode(self) -> Self {
|
||||
InterruptOptions::from_bits_truncate(0xe) & self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
use {
|
||||
super::*,
|
||||
alloc::sync::Arc,
|
||||
};
|
||||
use {super::*, alloc::sync::Arc};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct VirtualInterrupt{
|
||||
}
|
||||
pub struct VirtualInterrupt {}
|
||||
|
||||
impl VirtualInterrupt {
|
||||
pub fn new() -> Arc<Self> {
|
||||
|
@ -16,6 +12,10 @@ impl VirtualInterrupt {
|
|||
impl InterruptTrait for VirtualInterrupt {
|
||||
fn mask_interrupt_locked(&self) {}
|
||||
fn unmask_interrupt_locked(&self) {}
|
||||
fn register_interrupt_handler(&self, _handle: Arc<dyn Fn() + Send + Sync>) -> ZxResult { Ok(()) }
|
||||
fn unregister_interrupt_handler(&self) -> ZxResult { Ok(()) }
|
||||
}
|
||||
fn register_interrupt_handler(&self, _handle: Arc<dyn Fn() + Send + Sync>) -> ZxResult {
|
||||
Ok(())
|
||||
}
|
||||
fn unregister_interrupt_handler(&self) -> ZxResult {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use super::*;
|
||||
|
||||
mod bti;
|
||||
mod interrupt;
|
||||
mod iommu;
|
||||
mod pmt;
|
||||
mod interrupt;
|
||||
mod resource;
|
||||
|
||||
pub use self::{bti::*, iommu::*, pmt::*, interrupt::*, resource::*};
|
||||
pub use self::{bti::*, interrupt::*, iommu::*, pmt::*, resource::*};
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
pub use self::port_packet::*;
|
||||
use super::*;
|
||||
use crate::object::*;
|
||||
use alloc::collections::vec_deque::VecDeque;
|
||||
use alloc::collections::btree_map::BTreeMap;
|
||||
use alloc::collections::vec_deque::VecDeque;
|
||||
use alloc::sync::Arc;
|
||||
use spin::Mutex;
|
||||
use bitflags::bitflags;
|
||||
use spin::Mutex;
|
||||
|
||||
#[path = "port_packet.rs"]
|
||||
mod port_packet;
|
||||
|
@ -75,7 +75,11 @@ impl Port {
|
|||
let mut inner = self.inner.lock();
|
||||
inner.interrupt_pid += 1;
|
||||
let pid = inner.interrupt_pid;
|
||||
inner.interrupt_queue.push_back(PortInterruptPacket{timestamp, key, pid});
|
||||
inner.interrupt_queue.push_back(PortInterruptPacket {
|
||||
timestamp,
|
||||
key,
|
||||
pid,
|
||||
});
|
||||
inner.interrupt_grave.insert(pid, true);
|
||||
drop(inner);
|
||||
self.base.signal_set(Signal::READABLE);
|
||||
|
@ -92,7 +96,7 @@ impl Port {
|
|||
inner.interrupt_grave.insert(pid, false);
|
||||
in_queue
|
||||
}
|
||||
None => false
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +109,9 @@ impl Port {
|
|||
if self.can_bind_to_interrupt() {
|
||||
while let Some(packet) = inner.interrupt_queue.pop_front() {
|
||||
let in_queue = inner.interrupt_grave.remove(&packet.pid).unwrap();
|
||||
if inner.queue.is_empty() && (inner.interrupt_queue.is_empty() || !self.can_bind_to_interrupt()) {
|
||||
if inner.queue.is_empty()
|
||||
&& (inner.interrupt_queue.is_empty() || !self.can_bind_to_interrupt())
|
||||
{
|
||||
self.base.signal_clear(Signal::READABLE);
|
||||
}
|
||||
if !in_queue {
|
||||
|
@ -114,12 +120,15 @@ impl Port {
|
|||
return PortPacketRepr {
|
||||
key: packet.key,
|
||||
status: ZxError::OK,
|
||||
data: PayloadRepr::Interrupt(packet.into())
|
||||
}.into();
|
||||
data: PayloadRepr::Interrupt(packet.into()),
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
if let Some(packet) = inner.queue.pop_front() {
|
||||
if inner.queue.is_empty() && (inner.interrupt_queue.is_empty() || !self.can_bind_to_interrupt()) {
|
||||
if inner.queue.is_empty()
|
||||
&& (inner.interrupt_queue.is_empty() || !self.can_bind_to_interrupt())
|
||||
{
|
||||
self.base.signal_clear(Signal::READABLE);
|
||||
}
|
||||
return packet;
|
||||
|
|
|
@ -64,7 +64,7 @@ pub struct PacketInterrupt {
|
|||
pub timestamp: i64,
|
||||
pub reserved0: u64,
|
||||
pub reserved1: u64,
|
||||
pub reserved2: u64,
|
||||
pub reserved2: u64,
|
||||
}
|
||||
|
||||
// Rust struct: for internal constructing and debugging
|
||||
|
|
|
@ -130,7 +130,6 @@ impl ThreadInner {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
impl Thread {
|
||||
/// Create a new thread.
|
||||
pub fn create(proc: &Arc<Process>, name: &str, _options: u32) -> ZxResult<Arc<Self>> {
|
||||
|
|
|
@ -2,7 +2,7 @@ use {
|
|||
super::*,
|
||||
bitflags::bitflags,
|
||||
kernel_hal::DevVAddr,
|
||||
zircon_object::{vm::*, dev::*, signal::*, task::*},
|
||||
zircon_object::{dev::*, signal::*, task::*, vm::*},
|
||||
};
|
||||
|
||||
impl Syscall<'_> {
|
||||
|
@ -144,9 +144,12 @@ impl Syscall<'_> {
|
|||
resource: HandleValue,
|
||||
src_num: usize,
|
||||
options: u32,
|
||||
mut out: UserOutPtr<HandleValue>
|
||||
mut out: UserOutPtr<HandleValue>,
|
||||
) -> ZxResult {
|
||||
info!("interrupt.create: handle={:?} src_num={:?} options={:?}", resource, src_num, options);
|
||||
info!(
|
||||
"interrupt.create: handle={:?} src_num={:?} options={:?}",
|
||||
resource, src_num, options
|
||||
);
|
||||
let proc = self.thread.proc();
|
||||
let options = InterruptOptions::from_bits_truncate(options);
|
||||
if options.contains(InterruptOptions::VIRTUAL) {
|
||||
|
@ -171,7 +174,10 @@ impl Syscall<'_> {
|
|||
key: u64,
|
||||
options: u32,
|
||||
) -> ZxResult {
|
||||
info!("interrupt.bind: interrupt={:?} port={:?} key={:?} options={:?}", interrupt, port, key, options);
|
||||
info!(
|
||||
"interrupt.bind: interrupt={:?} port={:?} key={:?} options={:?}",
|
||||
interrupt, port, key, options
|
||||
);
|
||||
let proc = self.thread.proc();
|
||||
let interrupt = proc.get_object_with_rights::<Interrupt>(interrupt, Rights::READ)?;
|
||||
let port = proc.get_object_with_rights::<Port>(port, Rights::WRITE)?;
|
||||
|
@ -187,15 +193,29 @@ impl Syscall<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn sys_interrupt_trigger(&self, interrupt: HandleValue, options: u32, timestamp: i64) -> ZxResult {
|
||||
info!("interrupt.trigger: interrupt={:?} options={:?} timestamp={:?}", interrupt, options, timestamp);
|
||||
let interrupt = self.thread.proc().get_object_with_rights::<Interrupt>(interrupt, Rights::SIGNAL)?;
|
||||
pub fn sys_interrupt_trigger(
|
||||
&self,
|
||||
interrupt: HandleValue,
|
||||
options: u32,
|
||||
timestamp: i64,
|
||||
) -> ZxResult {
|
||||
info!(
|
||||
"interrupt.trigger: interrupt={:?} options={:?} timestamp={:?}",
|
||||
interrupt, options, timestamp
|
||||
);
|
||||
let interrupt = self
|
||||
.thread
|
||||
.proc()
|
||||
.get_object_with_rights::<Interrupt>(interrupt, Rights::SIGNAL)?;
|
||||
interrupt.trigger(timestamp)
|
||||
}
|
||||
|
||||
pub fn sys_interrupt_ack(&self, interrupt: HandleValue) -> ZxResult {
|
||||
info!("interupt.ack: interrupt={:?}", interrupt);
|
||||
let interrupt = self.thread.proc().get_object_with_rights::<Interrupt>(interrupt, Rights::WRITE)?;
|
||||
let interrupt = self
|
||||
.thread
|
||||
.proc()
|
||||
.get_object_with_rights::<Interrupt>(interrupt, Rights::WRITE)?;
|
||||
interrupt.ack()
|
||||
}
|
||||
|
||||
|
@ -205,7 +225,11 @@ impl Syscall<'_> {
|
|||
interrupt.destroy()
|
||||
}
|
||||
|
||||
pub async fn sys_interrupt_wait(&self, interrupt: HandleValue, mut out: UserOutPtr<i64>) -> ZxResult {
|
||||
pub async fn sys_interrupt_wait(
|
||||
&self,
|
||||
interrupt: HandleValue,
|
||||
mut out: UserOutPtr<i64>,
|
||||
) -> ZxResult {
|
||||
info!("interrupt.wait: handle={:?}", interrupt);
|
||||
assert_eq!(core::mem::size_of::<PortPacket>(), 48);
|
||||
let proc = self.thread.proc();
|
||||
|
@ -214,7 +238,11 @@ impl Syscall<'_> {
|
|||
pin_mut!(future);
|
||||
let timestamp = self
|
||||
.thread
|
||||
.blocking_run(future, ThreadState::BlockedInterrupt, Deadline::forever().into())
|
||||
.blocking_run(
|
||||
future,
|
||||
ThreadState::BlockedInterrupt,
|
||||
Deadline::forever().into(),
|
||||
)
|
||||
.await?;
|
||||
out.write_if_not_null(timestamp)?;
|
||||
Ok(())
|
||||
|
|
|
@ -276,7 +276,9 @@ impl Syscall<'_> {
|
|||
self.sys_object_get_child(a0 as _, a1 as _, a2 as _, a3.into())
|
||||
}
|
||||
Sys::PC_FIRMWARE_TABLES => self.sys_pc_firmware_tables(a0 as _, a1.into(), a2.into()),
|
||||
Sys::INTERRUPT_CREATE => self.sys_interrupt_create(a0 as _, a1 as _, a2 as _, a3.into()),
|
||||
Sys::INTERRUPT_CREATE => {
|
||||
self.sys_interrupt_create(a0 as _, a1 as _, a2 as _, a3.into())
|
||||
}
|
||||
Sys::INTERRUPT_BIND => self.sys_interrupt_bind(a0 as _, a1 as _, a2 as _, a3 as _),
|
||||
Sys::INTERRUPT_TRIGGER => self.sys_interrupt_trigger(a0 as _, a1 as _, a2 as _),
|
||||
Sys::INTERRUPT_ACK => self.sys_interrupt_ack(a0 as _),
|
||||
|
|
Loading…
Reference in New Issue