1e2841179SLoGin use core::{
2e2841179SLoGin any::Any,
3e2841179SLoGin fmt::Debug,
4e2841179SLoGin sync::atomic::{AtomicI64, Ordering},
5e2841179SLoGin };
63bc96fa4SLoGin
73bc96fa4SLoGin use alloc::{
8196b75dcSLoGin collections::{btree_map, BTreeMap},
9196b75dcSLoGin string::{String, ToString},
103bc96fa4SLoGin sync::{Arc, Weak},
113bc96fa4SLoGin vec::Vec,
123bc96fa4SLoGin };
133bc96fa4SLoGin use system_error::SystemError;
143bc96fa4SLoGin
153bc96fa4SLoGin use crate::{
16e2841179SLoGin arch::{interrupt::TrapFrame, CurrentIrqArch},
173bc96fa4SLoGin driver::base::{
183bc96fa4SLoGin device::DeviceId,
193bc96fa4SLoGin kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
203bc96fa4SLoGin kset::KSet,
213bc96fa4SLoGin },
223bc96fa4SLoGin filesystem::kernfs::KernFSInode,
233bc96fa4SLoGin libs::{
24338f6903SLoGin cpumask::CpuMask,
25e2841179SLoGin mutex::{Mutex, MutexGuard},
26e2841179SLoGin rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
273bc96fa4SLoGin spinlock::{SpinLock, SpinLockGuard},
283bc96fa4SLoGin },
29338f6903SLoGin mm::percpu::PerCpuVar,
303bc96fa4SLoGin process::ProcessControlBlock,
31e2841179SLoGin sched::completion::Completion,
32338f6903SLoGin smp::cpu::smp_cpu_manager,
333bc96fa4SLoGin };
343bc96fa4SLoGin
353bc96fa4SLoGin use super::{
363bc96fa4SLoGin dummychip::no_irq_chip,
373bc96fa4SLoGin handle::bad_irq_handler,
38338f6903SLoGin irqchip::IrqChip,
39e2841179SLoGin irqdata::{IrqCommonData, IrqData, IrqHandlerData, IrqLineStatus, IrqStatus},
40f049d1afSLoGin irqdomain::{irq_domain_manager, IrqDomain},
41196b75dcSLoGin sysfs::{irq_sysfs_del, IrqKObjType},
423bc96fa4SLoGin HardwareIrqNumber, InterruptArch, IrqNumber,
433bc96fa4SLoGin };
443bc96fa4SLoGin
453bc96fa4SLoGin /// 中断流处理程序
46e2841179SLoGin pub trait IrqFlowHandler: Debug + Send + Sync + Any {
handle(&self, irq_desc: &Arc<IrqDesc>, trap_frame: &mut TrapFrame)47e2841179SLoGin fn handle(&self, irq_desc: &Arc<IrqDesc>, trap_frame: &mut TrapFrame);
48e2841179SLoGin }
49e2841179SLoGin
50e2841179SLoGin /// 中断处理程序
51e2841179SLoGin pub trait IrqHandler: Debug + Send + Sync + Any {
handle( &self, irq: IrqNumber, static_data: Option<&dyn IrqHandlerData>, dynamic_data: Option<Arc<dyn IrqHandlerData>>, ) -> Result<IrqReturn, SystemError>52e2841179SLoGin fn handle(
53e2841179SLoGin &self,
54e2841179SLoGin irq: IrqNumber,
55e2841179SLoGin static_data: Option<&dyn IrqHandlerData>,
56e2841179SLoGin dynamic_data: Option<Arc<dyn IrqHandlerData>>,
57e2841179SLoGin ) -> Result<IrqReturn, SystemError>;
58e2841179SLoGin }
59e2841179SLoGin
60e2841179SLoGin /// 中断处理函数返回值
61e2841179SLoGin ///
62e2841179SLoGin /// 用于指示中断处理函数是否处理了中断
63e2841179SLoGin #[derive(Debug, Clone, Copy, PartialEq, Eq)]
64e2841179SLoGin pub enum IrqReturn {
65e2841179SLoGin /// 中断未被处理
66e2841179SLoGin NotHandled,
67e2841179SLoGin /// 中断已被处理
68e2841179SLoGin Handled,
69e2841179SLoGin /// 中断已被处理,并且需要唤醒中断线程
70e2841179SLoGin WakeThread,
713bc96fa4SLoGin }
723bc96fa4SLoGin
733bc96fa4SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irqdesc.h#55
743bc96fa4SLoGin #[derive(Debug)]
753bc96fa4SLoGin pub struct IrqDesc {
763bc96fa4SLoGin inner: SpinLock<InnerIrqDesc>,
773bc96fa4SLoGin
78e2841179SLoGin handler: RwLock<Option<&'static dyn IrqFlowHandler>>,
79e2841179SLoGin /// 一个用于串行化 request_irq()和free_irq() 的互斥锁
80e2841179SLoGin request_mutex: Mutex<()>,
813bc96fa4SLoGin kobj_state: LockedKObjectState,
82e2841179SLoGin /// 当前描述符内正在运行的中断线程数
83e2841179SLoGin threads_active: AtomicI64,
843bc96fa4SLoGin }
853bc96fa4SLoGin
863bc96fa4SLoGin impl IrqDesc {
873bc96fa4SLoGin #[inline(never)]
new(irq: IrqNumber, name: Option<String>, irqd_flags: IrqStatus) -> Arc<Self>883bc96fa4SLoGin pub fn new(irq: IrqNumber, name: Option<String>, irqd_flags: IrqStatus) -> Arc<Self> {
893bc96fa4SLoGin // 初始化的过程参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdesc.c#392
903bc96fa4SLoGin let common_data = Arc::new(IrqCommonData::new());
913bc96fa4SLoGin let irq_data = Arc::new(IrqData::new(
923bc96fa4SLoGin irq,
933bc96fa4SLoGin HardwareIrqNumber::new(irq.data()),
943bc96fa4SLoGin common_data.clone(),
953bc96fa4SLoGin no_irq_chip(),
963bc96fa4SLoGin ));
973bc96fa4SLoGin
983bc96fa4SLoGin irq_data.irqd_set(IrqStatus::IRQD_IRQ_DISABLED);
99e2841179SLoGin common_data.insert_status(IrqStatus::IRQD_IRQ_MASKED);
1003bc96fa4SLoGin
1013bc96fa4SLoGin let irq_desc = IrqDesc {
1023bc96fa4SLoGin inner: SpinLock::new(InnerIrqDesc {
103338f6903SLoGin percpu_affinity: None,
104338f6903SLoGin percpu_enabled: None,
1053bc96fa4SLoGin common_data,
1063bc96fa4SLoGin irq_data,
107196b75dcSLoGin desc_internal_state: IrqDescState::empty(),
108e2841179SLoGin line_status: IrqLineStatus::empty(),
1093bc96fa4SLoGin actions: Vec::new(),
1103bc96fa4SLoGin name,
1113bc96fa4SLoGin parent_irq: None,
1123bc96fa4SLoGin depth: 1,
1133bc96fa4SLoGin wake_depth: 0,
1143bc96fa4SLoGin kern_inode: None,
1153bc96fa4SLoGin kset: None,
1163bc96fa4SLoGin parent_kobj: None,
117*0102d69fSLoGin threads_oneshot: 0,
1183bc96fa4SLoGin }),
119e2841179SLoGin request_mutex: Mutex::new(()),
120e2841179SLoGin handler: RwLock::new(None),
1213bc96fa4SLoGin kobj_state: LockedKObjectState::new(Some(KObjectState::INITIALIZED)),
122e2841179SLoGin threads_active: AtomicI64::new(0),
1233bc96fa4SLoGin };
124f049d1afSLoGin let irq_desc = Arc::new(irq_desc);
125f049d1afSLoGin irq_desc.irq_data().set_irq_desc(Arc::downgrade(&irq_desc));
1263bc96fa4SLoGin irq_desc.set_handler(bad_irq_handler());
1273bc96fa4SLoGin irq_desc.inner().irq_data.irqd_set(irqd_flags);
1283bc96fa4SLoGin
129f049d1afSLoGin return irq_desc;
1303bc96fa4SLoGin }
1313bc96fa4SLoGin
132e2841179SLoGin /// 返回当前活跃的中断线程数量
133e2841179SLoGin #[allow(dead_code)]
threads_active(&self) -> i64134e2841179SLoGin pub fn threads_active(&self) -> i64 {
135e2841179SLoGin self.threads_active.load(Ordering::SeqCst)
1363bc96fa4SLoGin }
1373bc96fa4SLoGin
138e2841179SLoGin /// 增加当前活跃的中断线程数量, 返回增加前的值
inc_threads_active(&self) -> i64139e2841179SLoGin pub fn inc_threads_active(&self) -> i64 {
140e2841179SLoGin self.threads_active.fetch_add(1, Ordering::SeqCst)
141e2841179SLoGin }
142e2841179SLoGin
143e2841179SLoGin /// 减少当前活跃的中断线程数量, 返回减少前的值
144e2841179SLoGin #[allow(dead_code)]
dec_threads_active(&self) -> i64145e2841179SLoGin pub fn dec_threads_active(&self) -> i64 {
146e2841179SLoGin self.threads_active.fetch_sub(1, Ordering::SeqCst)
147e2841179SLoGin }
148e2841179SLoGin
set_handler(&self, handler: &'static dyn IrqFlowHandler)149e2841179SLoGin pub fn set_handler(&self, handler: &'static dyn IrqFlowHandler) {
150e2841179SLoGin self.chip_bus_lock();
151e2841179SLoGin let mut guard = self.handler.write_irqsave();
152e2841179SLoGin *guard = Some(handler);
153e2841179SLoGin self.chip_bus_sync_unlock();
154e2841179SLoGin }
155e2841179SLoGin
156338f6903SLoGin /// 设置中断处理程序(不对desc->inner)
157338f6903SLoGin ///
158338f6903SLoGin ///
159338f6903SLoGin /// ## Safety
160338f6903SLoGin ///
161338f6903SLoGin /// 需要保证irq_data和chip是当前irqdesc的
set_handler_no_lock_inner( &self, handler: &'static dyn IrqFlowHandler, irq_data: &Arc<IrqData>, chip: &Arc<dyn IrqChip>, )162338f6903SLoGin pub fn set_handler_no_lock_inner(
163338f6903SLoGin &self,
164338f6903SLoGin handler: &'static dyn IrqFlowHandler,
165338f6903SLoGin irq_data: &Arc<IrqData>,
166338f6903SLoGin chip: &Arc<dyn IrqChip>,
167338f6903SLoGin ) {
168338f6903SLoGin chip.irq_bus_lock(irq_data).ok();
169338f6903SLoGin let mut guard = self.handler.write_irqsave();
170338f6903SLoGin *guard = Some(handler);
171338f6903SLoGin chip.irq_bus_sync_unlock(irq_data).ok();
172338f6903SLoGin }
173338f6903SLoGin
handler(&self) -> Option<&'static dyn IrqFlowHandler>174e2841179SLoGin pub fn handler(&self) -> Option<&'static dyn IrqFlowHandler> {
175e2841179SLoGin let guard = self.handler.read_irqsave();
176e2841179SLoGin *guard
177e2841179SLoGin }
178e2841179SLoGin
inner(&self) -> SpinLockGuard<InnerIrqDesc>179e2841179SLoGin pub fn inner(&self) -> SpinLockGuard<InnerIrqDesc> {
1803bc96fa4SLoGin self.inner.lock_irqsave()
1813bc96fa4SLoGin }
1823bc96fa4SLoGin
actions(&self) -> Vec<Arc<IrqAction>>183196b75dcSLoGin pub fn actions(&self) -> Vec<Arc<IrqAction>> {
184196b75dcSLoGin self.inner().actions.clone()
185196b75dcSLoGin }
186196b75dcSLoGin
187e2841179SLoGin /// 对中断请求过程加锁
request_mutex_lock(&self) -> MutexGuard<()>188e2841179SLoGin pub fn request_mutex_lock(&self) -> MutexGuard<()> {
189e2841179SLoGin self.request_mutex.lock()
190e2841179SLoGin }
191e2841179SLoGin
irq(&self) -> IrqNumber1923bc96fa4SLoGin pub fn irq(&self) -> IrqNumber {
1933bc96fa4SLoGin self.inner().irq_data.irq()
1943bc96fa4SLoGin }
195196b75dcSLoGin
hardware_irq(&self) -> HardwareIrqNumber196196b75dcSLoGin pub fn hardware_irq(&self) -> HardwareIrqNumber {
197196b75dcSLoGin self.inner().irq_data.hardware_irq()
198196b75dcSLoGin }
199196b75dcSLoGin
irq_data(&self) -> Arc<IrqData>200196b75dcSLoGin pub fn irq_data(&self) -> Arc<IrqData> {
201196b75dcSLoGin self.inner().irq_data.clone()
202196b75dcSLoGin }
203196b75dcSLoGin
204196b75dcSLoGin /// 标记当前irq描述符已经被添加到sysfs
mark_in_sysfs(&self)205196b75dcSLoGin pub fn mark_in_sysfs(&self) {
206196b75dcSLoGin self.inner()
207196b75dcSLoGin .desc_internal_state
208196b75dcSLoGin .insert(IrqDescState::IRQS_SYSFS);
209196b75dcSLoGin }
210196b75dcSLoGin
mark_not_in_sysfs(&self)211196b75dcSLoGin pub fn mark_not_in_sysfs(&self) {
212196b75dcSLoGin self.inner()
213196b75dcSLoGin .desc_internal_state
214196b75dcSLoGin .remove(IrqDescState::IRQS_SYSFS);
215196b75dcSLoGin }
216196b75dcSLoGin
217196b75dcSLoGin /// 判断当前描述符是否已经添加到了sysfs
in_sysfs(&self) -> bool218196b75dcSLoGin pub fn in_sysfs(&self) -> bool {
219196b75dcSLoGin self.inner()
220196b75dcSLoGin .desc_internal_state
221196b75dcSLoGin .contains(IrqDescState::IRQS_SYSFS)
222196b75dcSLoGin }
223196b75dcSLoGin
name(&self) -> Option<String>224196b75dcSLoGin pub fn name(&self) -> Option<String> {
225196b75dcSLoGin self.inner().name.clone()
226196b75dcSLoGin }
227e2841179SLoGin
can_request(&self) -> bool228e2841179SLoGin pub fn can_request(&self) -> bool {
229e2841179SLoGin self.inner().can_request()
230e2841179SLoGin }
231e2841179SLoGin
232e2841179SLoGin #[allow(dead_code)]
set_norequest(&self)233e2841179SLoGin pub fn set_norequest(&self) {
234e2841179SLoGin self.inner().set_norequest();
235e2841179SLoGin }
236e2841179SLoGin
237e2841179SLoGin #[allow(dead_code)]
clear_norequest(&self)238e2841179SLoGin pub fn clear_norequest(&self) {
239e2841179SLoGin self.inner().clear_norequest();
240e2841179SLoGin }
241e2841179SLoGin
nested_thread(&self) -> bool242e2841179SLoGin pub fn nested_thread(&self) -> bool {
243e2841179SLoGin self.inner().nested_thread()
244e2841179SLoGin }
245e2841179SLoGin
246e2841179SLoGin /// 中断是否可以线程化
can_thread(&self) -> bool247e2841179SLoGin pub fn can_thread(&self) -> bool {
248e2841179SLoGin !self
249e2841179SLoGin .inner()
250e2841179SLoGin .line_status
251e2841179SLoGin .contains(IrqLineStatus::IRQ_NOTHREAD)
252e2841179SLoGin }
253e2841179SLoGin
chip_bus_lock(&self)254e2841179SLoGin pub fn chip_bus_lock(&self) {
255e2841179SLoGin let irq_data = self.inner().irq_data.clone();
256e2841179SLoGin irq_data
257e2841179SLoGin .chip_info_read_irqsave()
258e2841179SLoGin .chip()
259e2841179SLoGin .irq_bus_lock(&irq_data)
260e2841179SLoGin .ok();
261e2841179SLoGin }
262e2841179SLoGin
263e2841179SLoGin /// 同步释放低速总线锁
264e2841179SLoGin ///
265e2841179SLoGin /// ## 锁
266e2841179SLoGin ///
267e2841179SLoGin /// 进入此函数时,必须持有低速总线锁,并且desc的inner锁和irqdata的inner锁
268e2841179SLoGin /// 必须已经释放。否则将死锁。
chip_bus_sync_unlock(&self)269e2841179SLoGin pub fn chip_bus_sync_unlock(&self) {
270e2841179SLoGin let irq_data = self.inner().irq_data.clone();
271e2841179SLoGin irq_data
272e2841179SLoGin .chip_info_write_irqsave()
273e2841179SLoGin .chip()
274e2841179SLoGin .irq_bus_sync_unlock(&irq_data)
275e2841179SLoGin .ok();
276e2841179SLoGin }
277e2841179SLoGin
set_percpu_devid_flags(&self)278338f6903SLoGin pub fn set_percpu_devid_flags(&self) {
279338f6903SLoGin self.modify_status(
280338f6903SLoGin IrqLineStatus::empty(),
281338f6903SLoGin IrqLineStatus::IRQ_NOAUTOEN
282338f6903SLoGin | IrqLineStatus::IRQ_PER_CPU
283338f6903SLoGin | IrqLineStatus::IRQ_NOTHREAD
284338f6903SLoGin | IrqLineStatus::IRQ_NOPROBE
285338f6903SLoGin | IrqLineStatus::IRQ_PER_CPU_DEVID,
286338f6903SLoGin );
287338f6903SLoGin }
288338f6903SLoGin
set_probe(&self)289*0102d69fSLoGin pub fn set_probe(&self) {
290*0102d69fSLoGin self.modify_status(IrqLineStatus::IRQ_NOPROBE, IrqLineStatus::empty());
291*0102d69fSLoGin }
292*0102d69fSLoGin
set_noprobe(&self)293*0102d69fSLoGin pub fn set_noprobe(&self) {
294*0102d69fSLoGin self.modify_status(IrqLineStatus::empty(), IrqLineStatus::IRQ_NOPROBE);
295*0102d69fSLoGin }
296*0102d69fSLoGin
modify_status(&self, clear: IrqLineStatus, set: IrqLineStatus)297e2841179SLoGin pub fn modify_status(&self, clear: IrqLineStatus, set: IrqLineStatus) {
298e2841179SLoGin let mut desc_guard = self.inner();
299e2841179SLoGin desc_guard.line_status.remove(clear);
300e2841179SLoGin desc_guard.line_status.insert(set);
301e2841179SLoGin
302e2841179SLoGin let mut trigger = desc_guard.common_data().trigger_type();
303e2841179SLoGin
304e2841179SLoGin desc_guard.common_data().clear_status(
305e2841179SLoGin IrqStatus::IRQD_NO_BALANCING
306e2841179SLoGin | IrqStatus::IRQD_PER_CPU
307e2841179SLoGin | IrqStatus::IRQD_TRIGGER_MASK
308e2841179SLoGin | IrqStatus::IRQD_LEVEL
309e2841179SLoGin | IrqStatus::IRQD_MOVE_PCNTXT,
310e2841179SLoGin );
311e2841179SLoGin
312e2841179SLoGin if desc_guard
313e2841179SLoGin .line_status
314e2841179SLoGin .contains(IrqLineStatus::IRQ_NO_BALANCING)
315e2841179SLoGin {
316e2841179SLoGin desc_guard
317e2841179SLoGin .common_data()
318e2841179SLoGin .insert_status(IrqStatus::IRQD_NO_BALANCING);
319e2841179SLoGin }
320e2841179SLoGin
321e2841179SLoGin if desc_guard.line_status.contains(IrqLineStatus::IRQ_PER_CPU) {
322e2841179SLoGin desc_guard
323e2841179SLoGin .common_data()
324e2841179SLoGin .insert_status(IrqStatus::IRQD_PER_CPU);
325e2841179SLoGin }
326e2841179SLoGin
327e2841179SLoGin if desc_guard
328e2841179SLoGin .line_status
329e2841179SLoGin .contains(IrqLineStatus::IRQ_MOVE_PCNTXT)
330e2841179SLoGin {
331e2841179SLoGin desc_guard
332e2841179SLoGin .common_data()
333e2841179SLoGin .insert_status(IrqStatus::IRQD_MOVE_PCNTXT);
334e2841179SLoGin }
335e2841179SLoGin
336e2841179SLoGin if desc_guard.line_status.is_level_type() {
337e2841179SLoGin desc_guard
338e2841179SLoGin .common_data()
339e2841179SLoGin .insert_status(IrqStatus::IRQD_LEVEL);
340e2841179SLoGin }
341e2841179SLoGin
342e2841179SLoGin let tmp = desc_guard.line_status.trigger_type();
343e2841179SLoGin
344e2841179SLoGin if tmp != IrqLineStatus::IRQ_TYPE_NONE {
345e2841179SLoGin trigger = tmp;
346e2841179SLoGin }
347e2841179SLoGin
348e2841179SLoGin desc_guard.common_data().set_trigger_type(trigger);
349e2841179SLoGin }
3503bc96fa4SLoGin }
3513bc96fa4SLoGin
3523bc96fa4SLoGin #[allow(dead_code)]
3533bc96fa4SLoGin #[derive(Debug)]
354e2841179SLoGin pub struct InnerIrqDesc {
3553bc96fa4SLoGin /// per irq and chip data passed down to chip functions
3563bc96fa4SLoGin common_data: Arc<IrqCommonData>,
3573bc96fa4SLoGin irq_data: Arc<IrqData>,
3583bc96fa4SLoGin actions: Vec<Arc<IrqAction>>,
3593bc96fa4SLoGin name: Option<String>,
3603bc96fa4SLoGin parent_irq: Option<IrqNumber>,
3613bc96fa4SLoGin /// nested irq disables
3623bc96fa4SLoGin depth: u32,
3633bc96fa4SLoGin /// nested wake enables
3643bc96fa4SLoGin wake_depth: u32,
365196b75dcSLoGin desc_internal_state: IrqDescState,
366e2841179SLoGin /// 中断线的状态
367e2841179SLoGin line_status: IrqLineStatus,
3683bc96fa4SLoGin
3693bc96fa4SLoGin kern_inode: Option<Arc<KernFSInode>>,
3703bc96fa4SLoGin kset: Option<Arc<KSet>>,
3713bc96fa4SLoGin parent_kobj: Option<Weak<dyn KObject>>,
372338f6903SLoGin /// per-cpu enabled mask
373338f6903SLoGin percpu_enabled: Option<CpuMask>,
374338f6903SLoGin /// per-cpu affinity
375338f6903SLoGin percpu_affinity: Option<CpuMask>,
376e2841179SLoGin // wait_for_threads: EventWaitQueue
377*0102d69fSLoGin /// bitfield to handle shared oneshot threads
378*0102d69fSLoGin threads_oneshot: u64,
379e2841179SLoGin }
380e2841179SLoGin
381e2841179SLoGin impl InnerIrqDesc {
name(&self) -> Option<&String>382e2841179SLoGin pub fn name(&self) -> Option<&String> {
383e2841179SLoGin self.name.as_ref()
384e2841179SLoGin }
385e2841179SLoGin
386338f6903SLoGin #[allow(dead_code)]
set_name(&mut self, name: Option<String>)387338f6903SLoGin pub fn set_name(&mut self, name: Option<String>) {
388338f6903SLoGin self.name = name;
389338f6903SLoGin }
390338f6903SLoGin
can_request(&self) -> bool391e2841179SLoGin pub fn can_request(&self) -> bool {
392e2841179SLoGin !self.line_status.contains(IrqLineStatus::IRQ_NOREQUEST)
393e2841179SLoGin }
394e2841179SLoGin
395e2841179SLoGin #[allow(dead_code)]
set_norequest(&mut self)396e2841179SLoGin pub fn set_norequest(&mut self) {
397e2841179SLoGin self.line_status.insert(IrqLineStatus::IRQ_NOREQUEST);
398e2841179SLoGin }
399e2841179SLoGin
400e2841179SLoGin #[allow(dead_code)]
clear_norequest(&mut self)401e2841179SLoGin pub fn clear_norequest(&mut self) {
402e2841179SLoGin self.line_status.remove(IrqLineStatus::IRQ_NOREQUEST);
403e2841179SLoGin }
404e2841179SLoGin
405338f6903SLoGin #[allow(dead_code)]
set_noprobe(&mut self)406338f6903SLoGin pub fn set_noprobe(&mut self) {
407338f6903SLoGin self.line_status.insert(IrqLineStatus::IRQ_NOPROBE);
408338f6903SLoGin }
409338f6903SLoGin
410338f6903SLoGin #[allow(dead_code)]
clear_noprobe(&mut self)411338f6903SLoGin pub fn clear_noprobe(&mut self) {
412338f6903SLoGin self.line_status.remove(IrqLineStatus::IRQ_NOPROBE);
413338f6903SLoGin }
414338f6903SLoGin
set_nothread(&mut self)415338f6903SLoGin pub fn set_nothread(&mut self) {
416338f6903SLoGin self.line_status.insert(IrqLineStatus::IRQ_NOTHREAD);
417338f6903SLoGin }
418338f6903SLoGin
clear_nothread(&mut self)419338f6903SLoGin pub fn clear_nothread(&mut self) {
420338f6903SLoGin self.line_status.remove(IrqLineStatus::IRQ_NOTHREAD);
421338f6903SLoGin }
422338f6903SLoGin
nested_thread(&self) -> bool423e2841179SLoGin pub fn nested_thread(&self) -> bool {
424e2841179SLoGin self.line_status.contains(IrqLineStatus::IRQ_NESTED_THREAD)
425e2841179SLoGin }
426e2841179SLoGin
line_status_set_per_cpu(&mut self)427e2841179SLoGin pub fn line_status_set_per_cpu(&mut self) {
428e2841179SLoGin self.line_status.insert(IrqLineStatus::IRQ_PER_CPU);
429e2841179SLoGin }
430e2841179SLoGin
431e2841179SLoGin #[allow(dead_code)]
line_status_clear_per_cpu(&mut self)432e2841179SLoGin pub fn line_status_clear_per_cpu(&mut self) {
433e2841179SLoGin self.line_status.remove(IrqLineStatus::IRQ_PER_CPU);
434e2841179SLoGin }
435e2841179SLoGin
436e2841179SLoGin #[allow(dead_code)]
line_status(&self) -> &IrqLineStatus437e2841179SLoGin pub fn line_status(&self) -> &IrqLineStatus {
438e2841179SLoGin &self.line_status
439e2841179SLoGin }
440e2841179SLoGin
line_status_set_no_debug(&mut self)441e2841179SLoGin pub fn line_status_set_no_debug(&mut self) {
442e2841179SLoGin self.line_status.insert(IrqLineStatus::IRQ_NO_BALANCING);
443e2841179SLoGin }
444e2841179SLoGin
445e2841179SLoGin #[allow(dead_code)]
line_status_clear_no_debug(&mut self)446e2841179SLoGin pub fn line_status_clear_no_debug(&mut self) {
447e2841179SLoGin self.line_status.remove(IrqLineStatus::IRQ_NO_BALANCING);
448e2841179SLoGin }
449e2841179SLoGin
can_autoenable(&self) -> bool450e2841179SLoGin pub fn can_autoenable(&self) -> bool {
451e2841179SLoGin !self.line_status.contains(IrqLineStatus::IRQ_NOAUTOEN)
452e2841179SLoGin }
453e2841179SLoGin
can_thread(&self) -> bool454e2841179SLoGin pub fn can_thread(&self) -> bool {
455e2841179SLoGin !self.line_status.contains(IrqLineStatus::IRQ_NOTHREAD)
456e2841179SLoGin }
457e2841179SLoGin
threads_oneshot(&self) -> u64458*0102d69fSLoGin pub fn threads_oneshot(&self) -> u64 {
459*0102d69fSLoGin self.threads_oneshot
460*0102d69fSLoGin }
461*0102d69fSLoGin
462e2841179SLoGin /// 中断是否可以设置CPU亲和性
can_set_affinity(&self) -> bool463e2841179SLoGin pub fn can_set_affinity(&self) -> bool {
464b5b571e0SLoGin if !self.common_data.status().can_balance()
465b5b571e0SLoGin || !self
466e2841179SLoGin .irq_data()
467e2841179SLoGin .chip_info_read_irqsave()
468e2841179SLoGin .chip()
469e2841179SLoGin .can_set_affinity()
470e2841179SLoGin {
471e2841179SLoGin return false;
472e2841179SLoGin }
473e2841179SLoGin
474e2841179SLoGin return true;
475e2841179SLoGin }
476e2841179SLoGin
actions(&self) -> &Vec<Arc<IrqAction>>477e2841179SLoGin pub fn actions(&self) -> &Vec<Arc<IrqAction>> {
478e2841179SLoGin &self.actions
479e2841179SLoGin }
480e2841179SLoGin
add_action(&mut self, action: Arc<IrqAction>)481e2841179SLoGin pub fn add_action(&mut self, action: Arc<IrqAction>) {
482e2841179SLoGin self.actions.push(action);
483e2841179SLoGin }
484e2841179SLoGin
clear_actions(&mut self)485338f6903SLoGin pub fn clear_actions(&mut self) {
486338f6903SLoGin self.actions.clear();
487338f6903SLoGin }
488338f6903SLoGin
remove_action(&mut self, action: &Arc<IrqAction>)489338f6903SLoGin pub fn remove_action(&mut self, action: &Arc<IrqAction>) {
490338f6903SLoGin self.actions.retain(|a| !Arc::ptr_eq(a, action));
491338f6903SLoGin }
492338f6903SLoGin
internal_state(&self) -> &IrqDescState493e2841179SLoGin pub fn internal_state(&self) -> &IrqDescState {
494e2841179SLoGin &self.desc_internal_state
495e2841179SLoGin }
496e2841179SLoGin
internal_state_mut(&mut self) -> &mut IrqDescState497e2841179SLoGin pub(super) fn internal_state_mut(&mut self) -> &mut IrqDescState {
498e2841179SLoGin &mut self.desc_internal_state
499e2841179SLoGin }
500e2841179SLoGin
irq_data(&self) -> &Arc<IrqData>501e2841179SLoGin pub fn irq_data(&self) -> &Arc<IrqData> {
502e2841179SLoGin &self.irq_data
503e2841179SLoGin }
504e2841179SLoGin
common_data(&self) -> &Arc<IrqCommonData>505e2841179SLoGin pub fn common_data(&self) -> &Arc<IrqCommonData> {
506e2841179SLoGin &self.common_data
507e2841179SLoGin }
508e2841179SLoGin
depth(&self) -> u32509e2841179SLoGin pub fn depth(&self) -> u32 {
510e2841179SLoGin self.depth
511e2841179SLoGin }
512e2841179SLoGin
wake_depth(&self) -> u32513e2841179SLoGin pub fn wake_depth(&self) -> u32 {
514e2841179SLoGin self.wake_depth
515e2841179SLoGin }
516e2841179SLoGin
set_depth(&mut self, depth: u32)517e2841179SLoGin pub fn set_depth(&mut self, depth: u32) {
518e2841179SLoGin self.depth = depth;
519e2841179SLoGin }
520e2841179SLoGin
set_trigger_type(&mut self, trigger: IrqLineStatus)521e2841179SLoGin pub fn set_trigger_type(&mut self, trigger: IrqLineStatus) {
522e2841179SLoGin self.line_status.remove(IrqLineStatus::IRQ_TYPE_SENSE_MASK);
523e2841179SLoGin self.line_status
524e2841179SLoGin .insert(trigger & IrqLineStatus::IRQ_TYPE_SENSE_MASK);
525e2841179SLoGin }
526e2841179SLoGin
clear_level(&mut self)527e2841179SLoGin pub fn clear_level(&mut self) {
528e2841179SLoGin self.line_status.remove(IrqLineStatus::IRQ_LEVEL);
529e2841179SLoGin }
530e2841179SLoGin
set_level(&mut self)531e2841179SLoGin pub fn set_level(&mut self) {
532e2841179SLoGin self.line_status.insert(IrqLineStatus::IRQ_LEVEL);
533e2841179SLoGin }
534338f6903SLoGin
percpu_enabled(&self) -> &Option<CpuMask>535338f6903SLoGin pub fn percpu_enabled(&self) -> &Option<CpuMask> {
536338f6903SLoGin &self.percpu_enabled
537338f6903SLoGin }
538338f6903SLoGin
percpu_enabled_mut(&mut self) -> &mut Option<CpuMask>539338f6903SLoGin pub fn percpu_enabled_mut(&mut self) -> &mut Option<CpuMask> {
540338f6903SLoGin &mut self.percpu_enabled
541338f6903SLoGin }
542338f6903SLoGin
percpu_affinity(&self) -> &Option<CpuMask>543338f6903SLoGin pub fn percpu_affinity(&self) -> &Option<CpuMask> {
544338f6903SLoGin &self.percpu_affinity
545338f6903SLoGin }
546338f6903SLoGin
percpu_affinity_mut(&mut self) -> &mut Option<CpuMask>547338f6903SLoGin pub fn percpu_affinity_mut(&mut self) -> &mut Option<CpuMask> {
548338f6903SLoGin &mut self.percpu_affinity
549338f6903SLoGin }
5503bc96fa4SLoGin }
5513bc96fa4SLoGin
5523bc96fa4SLoGin impl KObject for IrqDesc {
as_any_ref(&self) -> &dyn Any5533bc96fa4SLoGin fn as_any_ref(&self) -> &dyn Any {
5543bc96fa4SLoGin self
5553bc96fa4SLoGin }
5563bc96fa4SLoGin
set_inode(&self, inode: Option<Arc<KernFSInode>>)5573bc96fa4SLoGin fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
5583bc96fa4SLoGin self.inner().kern_inode = inode;
5593bc96fa4SLoGin }
5603bc96fa4SLoGin
inode(&self) -> Option<Arc<KernFSInode>>5613bc96fa4SLoGin fn inode(&self) -> Option<Arc<KernFSInode>> {
5623bc96fa4SLoGin self.inner().kern_inode.clone()
5633bc96fa4SLoGin }
5643bc96fa4SLoGin
parent(&self) -> Option<Weak<dyn KObject>>5653bc96fa4SLoGin fn parent(&self) -> Option<Weak<dyn KObject>> {
5663bc96fa4SLoGin self.inner().parent_kobj.clone()
5673bc96fa4SLoGin }
5683bc96fa4SLoGin
set_parent(&self, parent: Option<Weak<dyn KObject>>)5693bc96fa4SLoGin fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
5703bc96fa4SLoGin self.inner().parent_kobj = parent;
5713bc96fa4SLoGin }
5723bc96fa4SLoGin
kset(&self) -> Option<Arc<KSet>>5733bc96fa4SLoGin fn kset(&self) -> Option<Arc<KSet>> {
5743bc96fa4SLoGin self.inner().kset.clone()
5753bc96fa4SLoGin }
5763bc96fa4SLoGin
set_kset(&self, kset: Option<Arc<KSet>>)5773bc96fa4SLoGin fn set_kset(&self, kset: Option<Arc<KSet>>) {
5783bc96fa4SLoGin self.inner().kset = kset;
5793bc96fa4SLoGin }
5803bc96fa4SLoGin
kobj_type(&self) -> Option<&'static dyn KObjType>5813bc96fa4SLoGin fn kobj_type(&self) -> Option<&'static dyn KObjType> {
5823bc96fa4SLoGin Some(&IrqKObjType)
5833bc96fa4SLoGin }
5843bc96fa4SLoGin
set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>)5853bc96fa4SLoGin fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {}
5863bc96fa4SLoGin
name(&self) -> String5873bc96fa4SLoGin fn name(&self) -> String {
588196b75dcSLoGin self.inner().irq_data.irq().data().to_string()
5893bc96fa4SLoGin }
5903bc96fa4SLoGin
set_name(&self, _name: String)5913bc96fa4SLoGin fn set_name(&self, _name: String) {}
5923bc96fa4SLoGin
kobj_state(&self) -> RwLockReadGuard<KObjectState>5933bc96fa4SLoGin fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
5943bc96fa4SLoGin self.kobj_state.read()
5953bc96fa4SLoGin }
5963bc96fa4SLoGin
kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>5973bc96fa4SLoGin fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
5983bc96fa4SLoGin self.kobj_state.write()
5993bc96fa4SLoGin }
6003bc96fa4SLoGin
set_kobj_state(&self, state: KObjectState)6013bc96fa4SLoGin fn set_kobj_state(&self, state: KObjectState) {
6023bc96fa4SLoGin *self.kobj_state_mut() = state;
6033bc96fa4SLoGin }
6043bc96fa4SLoGin }
6053bc96fa4SLoGin
606196b75dcSLoGin bitflags! {
607196b75dcSLoGin /// Bit masks for desc->desc_internal_state
608e2841179SLoGin pub struct IrqDescState: u32 {
609196b75dcSLoGin /// autodetection in progress
610196b75dcSLoGin const IRQS_AUTODETECT = 0x00000001;
611196b75dcSLoGin /// was disabled due to spurious interrupt detection
612196b75dcSLoGin const IRQS_SPURIOUS_DISABLED = 0x00000002;
613196b75dcSLoGin /// polling in progress
614196b75dcSLoGin const IRQS_POLL_INPROGRESS = 0x00000008;
615196b75dcSLoGin /// irq is not unmasked in primary handler
616196b75dcSLoGin const IRQS_ONESHOT = 0x00000020;
617196b75dcSLoGin /// irq is replayed
618196b75dcSLoGin const IRQS_REPLAY = 0x00000040;
619196b75dcSLoGin /// irq is waiting
620196b75dcSLoGin const IRQS_WAITING = 0x00000080;
621196b75dcSLoGin /// irq is pending and replayed later
622196b75dcSLoGin const IRQS_PENDING = 0x00000200;
623196b75dcSLoGin /// irq is suspended
624196b75dcSLoGin const IRQS_SUSPENDED = 0x00000800;
625196b75dcSLoGin /// irq line is used to deliver NMIs
626196b75dcSLoGin const IRQS_NMI = 0x00002000;
627196b75dcSLoGin /// descriptor has been added to sysfs
628196b75dcSLoGin const IRQS_SYSFS = 0x00004000;
629196b75dcSLoGin }
630196b75dcSLoGin }
631196b75dcSLoGin
6323bc96fa4SLoGin /// 每个中断的响应动作的描述符
6333bc96fa4SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/interrupt.h#118
6343bc96fa4SLoGin #[allow(dead_code)]
6353bc96fa4SLoGin #[derive(Debug)]
6363bc96fa4SLoGin pub struct IrqAction {
6373bc96fa4SLoGin inner: SpinLock<InnerIrqAction>,
638e2841179SLoGin /// 用于等待线程被创建的完成量
639e2841179SLoGin thread_completion: Completion,
6403bc96fa4SLoGin }
6413bc96fa4SLoGin
6423bc96fa4SLoGin impl IrqAction {
6433bc96fa4SLoGin #[allow(dead_code)]
new( irq: IrqNumber, name: String, handler: Option<&'static dyn IrqHandler>, thread_fn: Option<&'static dyn IrqHandler>, ) -> Arc<Self>6443bc96fa4SLoGin pub fn new(
6453bc96fa4SLoGin irq: IrqNumber,
6463bc96fa4SLoGin name: String,
647e2841179SLoGin handler: Option<&'static dyn IrqHandler>,
648e2841179SLoGin thread_fn: Option<&'static dyn IrqHandler>,
6493bc96fa4SLoGin ) -> Arc<Self> {
650e2841179SLoGin let action: IrqAction = IrqAction {
6513bc96fa4SLoGin inner: SpinLock::new(InnerIrqAction {
6523bc96fa4SLoGin dev_id: None,
653338f6903SLoGin per_cpu_dev_id: None,
6543bc96fa4SLoGin handler,
655e2841179SLoGin thread_fn,
6563bc96fa4SLoGin thread: None,
6573bc96fa4SLoGin secondary: None,
6583bc96fa4SLoGin irq,
6593bc96fa4SLoGin flags: IrqHandleFlags::empty(),
6603bc96fa4SLoGin name,
661e2841179SLoGin thread_flags: ThreadedHandlerFlags::empty(),
6623bc96fa4SLoGin }),
663e2841179SLoGin thread_completion: Completion::new(),
6643bc96fa4SLoGin };
6653bc96fa4SLoGin
6663bc96fa4SLoGin return Arc::new(action);
6673bc96fa4SLoGin }
668196b75dcSLoGin
inner(&self) -> SpinLockGuard<InnerIrqAction>669e2841179SLoGin pub fn inner(&self) -> SpinLockGuard<InnerIrqAction> {
670e2841179SLoGin self.inner.lock_irqsave()
671196b75dcSLoGin }
672196b75dcSLoGin
thread_completion(&self) -> &Completion673e2841179SLoGin pub fn thread_completion(&self) -> &Completion {
674e2841179SLoGin &self.thread_completion
675196b75dcSLoGin }
6763bc96fa4SLoGin }
6773bc96fa4SLoGin
6783bc96fa4SLoGin #[allow(dead_code)]
6793bc96fa4SLoGin #[derive(Debug)]
680e2841179SLoGin pub struct InnerIrqAction {
6813bc96fa4SLoGin /// cookie to identify the device
682e2841179SLoGin dev_id: Option<Arc<DeviceId>>,
683338f6903SLoGin /// cookie to identify the device (per cpu)
684338f6903SLoGin per_cpu_dev_id: Option<PerCpuVar<Arc<DeviceId>>>,
6853bc96fa4SLoGin /// 中断处理程序
686e2841179SLoGin handler: Option<&'static dyn IrqHandler>,
6873bc96fa4SLoGin /// interrupt handler function for threaded interrupts
688e2841179SLoGin thread_fn: Option<&'static dyn IrqHandler>,
6893bc96fa4SLoGin /// thread pointer for threaded interrupts
6903bc96fa4SLoGin thread: Option<Arc<ProcessControlBlock>>,
6913bc96fa4SLoGin /// pointer to secondary irqaction (force threading)
6923bc96fa4SLoGin secondary: Option<Arc<IrqAction>>,
6933bc96fa4SLoGin /// 中断号
6943bc96fa4SLoGin irq: IrqNumber,
6953bc96fa4SLoGin flags: IrqHandleFlags,
696e2841179SLoGin /// 中断线程的标志
697e2841179SLoGin thread_flags: ThreadedHandlerFlags,
6983bc96fa4SLoGin /// name of the device
6993bc96fa4SLoGin name: String,
7003bc96fa4SLoGin }
7013bc96fa4SLoGin
702e2841179SLoGin impl InnerIrqAction {
dev_id(&self) -> &Option<Arc<DeviceId>>703e2841179SLoGin pub fn dev_id(&self) -> &Option<Arc<DeviceId>> {
704e2841179SLoGin &self.dev_id
705e2841179SLoGin }
706e2841179SLoGin
dev_id_mut(&mut self) -> &mut Option<Arc<DeviceId>>707e2841179SLoGin pub fn dev_id_mut(&mut self) -> &mut Option<Arc<DeviceId>> {
708e2841179SLoGin &mut self.dev_id
709e2841179SLoGin }
710e2841179SLoGin
per_cpu_dev_id(&self) -> Option<&Arc<DeviceId>>711338f6903SLoGin pub fn per_cpu_dev_id(&self) -> Option<&Arc<DeviceId>> {
712338f6903SLoGin self.per_cpu_dev_id.as_ref().map(|v| v.get())
713338f6903SLoGin }
714338f6903SLoGin
715338f6903SLoGin #[allow(dead_code)]
per_cpu_dev_id_mut(&mut self) -> Option<&mut Arc<DeviceId>>716338f6903SLoGin pub fn per_cpu_dev_id_mut(&mut self) -> Option<&mut Arc<DeviceId>> {
717338f6903SLoGin self.per_cpu_dev_id.as_mut().map(|v| v.get_mut())
718338f6903SLoGin }
719338f6903SLoGin
handler(&self) -> Option<&'static dyn IrqHandler>720e2841179SLoGin pub fn handler(&self) -> Option<&'static dyn IrqHandler> {
721e2841179SLoGin self.handler
722e2841179SLoGin }
723e2841179SLoGin
set_handler(&mut self, handler: Option<&'static dyn IrqHandler>)724e2841179SLoGin pub fn set_handler(&mut self, handler: Option<&'static dyn IrqHandler>) {
725e2841179SLoGin self.handler = handler;
726e2841179SLoGin }
727e2841179SLoGin
thread_fn(&self) -> Option<&'static dyn IrqHandler>728e2841179SLoGin pub fn thread_fn(&self) -> Option<&'static dyn IrqHandler> {
729e2841179SLoGin self.thread_fn
730e2841179SLoGin }
731e2841179SLoGin
thread(&self) -> Option<Arc<ProcessControlBlock>>732e2841179SLoGin pub fn thread(&self) -> Option<Arc<ProcessControlBlock>> {
733e2841179SLoGin self.thread.clone()
734e2841179SLoGin }
735e2841179SLoGin
set_thread(&mut self, thread: Option<Arc<ProcessControlBlock>>)736e2841179SLoGin pub fn set_thread(&mut self, thread: Option<Arc<ProcessControlBlock>>) {
737e2841179SLoGin self.thread = thread;
738e2841179SLoGin }
739e2841179SLoGin
740e2841179SLoGin #[allow(dead_code)]
thread_flags(&self) -> &ThreadedHandlerFlags741e2841179SLoGin pub fn thread_flags(&self) -> &ThreadedHandlerFlags {
742e2841179SLoGin &self.thread_flags
743e2841179SLoGin }
744e2841179SLoGin
thread_flags_mut(&mut self) -> &mut ThreadedHandlerFlags745e2841179SLoGin pub fn thread_flags_mut(&mut self) -> &mut ThreadedHandlerFlags {
746e2841179SLoGin &mut self.thread_flags
747e2841179SLoGin }
748e2841179SLoGin
secondary(&self) -> Option<Arc<IrqAction>>749e2841179SLoGin pub fn secondary(&self) -> Option<Arc<IrqAction>> {
750e2841179SLoGin self.secondary.clone()
751e2841179SLoGin }
752e2841179SLoGin
753e2841179SLoGin #[allow(dead_code)]
irq(&self) -> IrqNumber754e2841179SLoGin pub fn irq(&self) -> IrqNumber {
755e2841179SLoGin self.irq
756e2841179SLoGin }
757e2841179SLoGin
758e2841179SLoGin #[allow(dead_code)]
set_irq(&mut self, irq: IrqNumber)759e2841179SLoGin pub fn set_irq(&mut self, irq: IrqNumber) {
760e2841179SLoGin self.irq = irq;
761e2841179SLoGin }
762e2841179SLoGin
flags(&self) -> &IrqHandleFlags763e2841179SLoGin pub fn flags(&self) -> &IrqHandleFlags {
764e2841179SLoGin &self.flags
765e2841179SLoGin }
766e2841179SLoGin
flags_mut(&mut self) -> &mut IrqHandleFlags767e2841179SLoGin pub fn flags_mut(&mut self) -> &mut IrqHandleFlags {
768e2841179SLoGin &mut self.flags
769e2841179SLoGin }
770e2841179SLoGin
name(&self) -> &String771e2841179SLoGin pub fn name(&self) -> &String {
772e2841179SLoGin &self.name
773e2841179SLoGin }
774e2841179SLoGin }
775e2841179SLoGin
776e2841179SLoGin bitflags! {
777e2841179SLoGin /// 这些标志由线程处理程序使用
778e2841179SLoGin pub struct ThreadedHandlerFlags: u32 {
779e2841179SLoGin /// IRQTF_RUNTHREAD - 表示应运行中断处理程序线程
780e2841179SLoGin const IRQTF_RUNTHREAD = 1 << 0;
781e2841179SLoGin /// IRQTF_WARNED - 已打印警告 "IRQ_WAKE_THREAD w/o thread_fn"
782e2841179SLoGin const IRQTF_WARNED = 1 << 1;
783e2841179SLoGin /// IRQTF_AFFINITY - 请求irq线程调整亲和性
784e2841179SLoGin const IRQTF_AFFINITY = 1 << 2;
785e2841179SLoGin /// IRQTF_FORCED_THREAD - irq操作被强制线程化
786e2841179SLoGin const IRQTF_FORCED_THREAD = 1 << 3;
787e2841179SLoGin /// IRQTF_READY - 表示irq线程已准备就绪
788e2841179SLoGin const IRQTF_READY = 1 << 4;
789e2841179SLoGin }
790e2841179SLoGin }
791e2841179SLoGin
792e2841179SLoGin /// Implements the `ThreadedHandlerFlags` structure.
793e2841179SLoGin impl ThreadedHandlerFlags {
794e2841179SLoGin /// 在 `ThreadedHandlerFlags` 结构中测试并设置特定的位。
795e2841179SLoGin ///
796e2841179SLoGin /// # 参数
797e2841179SLoGin ///
798e2841179SLoGin /// * `bit` - 要测试并设置的位。
799e2841179SLoGin ///
800e2841179SLoGin /// # 返回
801e2841179SLoGin ///
802e2841179SLoGin /// 如果操作前该位已被设置,则返回 `true`,否则返回 `false`。
test_and_set_bit(&mut self, bit: ThreadedHandlerFlags) -> bool803e2841179SLoGin pub fn test_and_set_bit(&mut self, bit: ThreadedHandlerFlags) -> bool {
804e2841179SLoGin let res = (self.bits & bit.bits) != 0;
805e2841179SLoGin self.bits |= bit.bits;
806e2841179SLoGin return res;
807e2841179SLoGin }
808e2841179SLoGin }
809e2841179SLoGin
8103bc96fa4SLoGin // 定义IrqFlags位标志
811b5b571e0SLoGin
8123bc96fa4SLoGin bitflags! {
8133bc96fa4SLoGin /// 这些标志仅由内核在中断处理例程中使用。
814b5b571e0SLoGin #[allow(clippy::bad_bit_mask)]
8153bc96fa4SLoGin pub struct IrqHandleFlags: u32 {
816e2841179SLoGin
817e2841179SLoGin const IRQF_TRIGGER_NONE = IrqLineStatus::IRQ_TYPE_NONE.bits();
818e2841179SLoGin const IRQF_TRIGGER_RISING = IrqLineStatus::IRQ_TYPE_EDGE_RISING.bits();
819e2841179SLoGin const IRQF_TRIGGER_FALLING = IrqLineStatus::IRQ_TYPE_EDGE_FALLING.bits();
820e2841179SLoGin const IRQF_TRIGGER_HIGH = IrqLineStatus::IRQ_TYPE_LEVEL_HIGH.bits();
821e2841179SLoGin const IRQF_TRIGGER_LOW = IrqLineStatus::IRQ_TYPE_LEVEL_LOW.bits();
822e2841179SLoGin const IRQF_TRIGGER_MASK = Self::IRQF_TRIGGER_HIGH.bits | Self::IRQF_TRIGGER_LOW.bits | Self::IRQF_TRIGGER_RISING.bits | Self::IRQF_TRIGGER_FALLING.bits;
8233bc96fa4SLoGin /// IRQF_SHARED - 允许多个设备共享中断
8243bc96fa4SLoGin const IRQF_SHARED = 0x00000080;
8253bc96fa4SLoGin /// IRQF_PROBE_SHARED - 当预期出现共享不匹配时,由调用者设置
8263bc96fa4SLoGin const IRQF_PROBE_SHARED = 0x00000100;
8273bc96fa4SLoGin /// IRQF_TIMER - 标记此中断为定时器中断
8283bc96fa4SLoGin const __IRQF_TIMER = 0x00000200;
8293bc96fa4SLoGin /// IRQF_PERCPU - 中断是每个CPU的
8303bc96fa4SLoGin const IRQF_PERCPU = 0x00000400;
8313bc96fa4SLoGin /// IRQF_NOBALANCING - 将此中断从中断平衡中排除
8323bc96fa4SLoGin const IRQF_NOBALANCING = 0x00000800;
8333bc96fa4SLoGin /// IRQF_IRQPOLL - 中断用于轮询(出于性能原因,只有在共享中断中首次注册的中断会被考虑)
8343bc96fa4SLoGin const IRQF_IRQPOLL = 0x00001000;
8353bc96fa4SLoGin /// IRQF_ONESHOT - 在硬中断处理程序完成后,不会重新启用中断。由需要在运行线程处理程序之前保持中断线路禁用的线程中断使用。
8363bc96fa4SLoGin const IRQF_ONESHOT = 0x00002000;
8373bc96fa4SLoGin /// IRQF_NO_SUSPEND - 在挂起期间不禁用此IRQ。不能保证此中断会从挂起状态唤醒系统。
8383bc96fa4SLoGin const IRQF_NO_SUSPEND = 0x00004000;
8393bc96fa4SLoGin /// IRQF_FORCE_RESUME - 即使设置了IRQF_NO_SUSPEND,也强制在恢复时启用它
8403bc96fa4SLoGin const IRQF_FORCE_RESUME = 0x00008000;
8413bc96fa4SLoGin /// IRQF_NO_THREAD - 中断不能被线程化
8423bc96fa4SLoGin const IRQF_NO_THREAD = 0x00010000;
8433bc96fa4SLoGin /// IRQF_EARLY_RESUME - 在syscore而不是在设备恢复时间早期恢复IRQ。
8443bc96fa4SLoGin const IRQF_EARLY_RESUME = 0x00020000;
8453bc96fa4SLoGin /// IRQF_COND_SUSPEND - 如果IRQ与NO_SUSPEND用户共享,则在挂起中断后执行此中断处理程序。对于系统唤醒设备用户,需要在他们的中断处理程序中实现唤醒检测。
8463bc96fa4SLoGin const IRQF_COND_SUSPEND = 0x00040000;
8473bc96fa4SLoGin /// IRQF_NO_AUTOEN - 当用户请求时,不会自动启用IRQ或NMI。用户稍后会通过enable_irq()或enable_nmi()显式启用它。
8483bc96fa4SLoGin const IRQF_NO_AUTOEN = 0x00080000;
8493bc96fa4SLoGin /// IRQF_NO_DEBUG - 从IPI和类似处理程序的逃逸检测中排除,取决于IRQF_PERCPU。
8503bc96fa4SLoGin const IRQF_NO_DEBUG = 0x00100000;
8513bc96fa4SLoGin const IRQF_TIMER = Self::__IRQF_TIMER.bits | Self::IRQF_NO_SUSPEND.bits | Self::IRQF_NO_THREAD.bits;
8523bc96fa4SLoGin }
8533bc96fa4SLoGin }
8543bc96fa4SLoGin
855e2841179SLoGin impl IrqHandleFlags {
856e2841179SLoGin /// 检查是否指定了触发类型
857e2841179SLoGin #[inline(always)]
trigger_type_specified(&self) -> bool858e2841179SLoGin pub fn trigger_type_specified(&self) -> bool {
859e2841179SLoGin (self.bits & Self::IRQF_TRIGGER_MASK.bits) != 0
860e2841179SLoGin }
861e2841179SLoGin
862e2841179SLoGin /// 插入触发类型
insert_trigger_type(&mut self, trigger: IrqLineStatus)863e2841179SLoGin pub fn insert_trigger_type(&mut self, trigger: IrqLineStatus) {
864e2841179SLoGin self.bits |= trigger.trigger_bits() & IrqHandleFlags::IRQF_TRIGGER_MASK.bits;
865e2841179SLoGin }
866e2841179SLoGin
867e2841179SLoGin #[allow(dead_code)]
remove_trigger_type(&mut self, trigger: IrqLineStatus)868e2841179SLoGin pub fn remove_trigger_type(&mut self, trigger: IrqLineStatus) {
869e2841179SLoGin self.bits &= !(trigger.trigger_bits() & IrqHandleFlags::IRQF_TRIGGER_MASK.bits);
870e2841179SLoGin }
871e2841179SLoGin
trigger_type(&self) -> IrqLineStatus872e2841179SLoGin pub fn trigger_type(&self) -> IrqLineStatus {
873e2841179SLoGin IrqLineStatus::from_bits_truncate(self.bits & IrqHandleFlags::IRQF_TRIGGER_MASK.bits)
874e2841179SLoGin }
875e2841179SLoGin }
876e2841179SLoGin
8773bc96fa4SLoGin #[inline(never)]
early_irq_init() -> Result<(), SystemError>8783bc96fa4SLoGin pub(super) fn early_irq_init() -> Result<(), SystemError> {
8793bc96fa4SLoGin let irqcnt = CurrentIrqArch::probe_total_irq_num();
8803bc96fa4SLoGin let mut manager = IrqDescManager::new();
8813bc96fa4SLoGin for i in 0..irqcnt {
8823bc96fa4SLoGin let irq_desc = IrqDesc::new(IrqNumber::new(i), None, IrqStatus::empty());
8833bc96fa4SLoGin manager.insert(IrqNumber::new(i), irq_desc);
8843bc96fa4SLoGin }
8853bc96fa4SLoGin
886196b75dcSLoGin unsafe {
887196b75dcSLoGin IRQ_DESC_MANAGER = Some(manager);
888196b75dcSLoGin }
889196b75dcSLoGin
8903bc96fa4SLoGin return CurrentIrqArch::arch_early_irq_init();
8913bc96fa4SLoGin }
8923bc96fa4SLoGin
893196b75dcSLoGin static mut IRQ_DESC_MANAGER: Option<IrqDescManager> = None;
894196b75dcSLoGin
895196b75dcSLoGin /// 获取中断描述符管理器的引用
896196b75dcSLoGin #[inline(always)]
irq_desc_manager() -> &'static IrqDescManager897e2841179SLoGin pub fn irq_desc_manager() -> &'static IrqDescManager {
898196b75dcSLoGin return unsafe { IRQ_DESC_MANAGER.as_ref().unwrap() };
899196b75dcSLoGin }
900196b75dcSLoGin
901e2841179SLoGin pub struct IrqDescManager {
9023bc96fa4SLoGin irq_descs: BTreeMap<IrqNumber, Arc<IrqDesc>>,
9033bc96fa4SLoGin }
9043bc96fa4SLoGin
9053bc96fa4SLoGin impl IrqDescManager {
new() -> Self9063bc96fa4SLoGin fn new() -> Self {
9073bc96fa4SLoGin IrqDescManager {
9083bc96fa4SLoGin irq_descs: BTreeMap::new(),
9093bc96fa4SLoGin }
9103bc96fa4SLoGin }
9113bc96fa4SLoGin
9123bc96fa4SLoGin /// 查找中断描述符
lookup(&self, irq: IrqNumber) -> Option<Arc<IrqDesc>>9133bc96fa4SLoGin pub fn lookup(&self, irq: IrqNumber) -> Option<Arc<IrqDesc>> {
914b5b571e0SLoGin self.irq_descs.get(&irq).cloned()
9153bc96fa4SLoGin }
9163bc96fa4SLoGin
917338f6903SLoGin /// 查找中断描述符并锁定总线(没有对irqdesc进行加锁)
918338f6903SLoGin #[allow(dead_code)]
lookup_and_lock_bus( &self, irq: IrqNumber, check_global: bool, check_percpu: bool, ) -> Option<Arc<IrqDesc>>919338f6903SLoGin pub fn lookup_and_lock_bus(
920338f6903SLoGin &self,
921338f6903SLoGin irq: IrqNumber,
922338f6903SLoGin check_global: bool,
923338f6903SLoGin check_percpu: bool,
924338f6903SLoGin ) -> Option<Arc<IrqDesc>> {
925338f6903SLoGin self.do_lookup_and_lock(irq, true, check_global, check_percpu)
926338f6903SLoGin }
927338f6903SLoGin
do_lookup_and_lock( &self, irq: IrqNumber, lock_bus: bool, check_global: bool, check_percpu: bool, ) -> Option<Arc<IrqDesc>>928338f6903SLoGin fn do_lookup_and_lock(
929338f6903SLoGin &self,
930338f6903SLoGin irq: IrqNumber,
931338f6903SLoGin lock_bus: bool,
932338f6903SLoGin check_global: bool,
933338f6903SLoGin check_percpu: bool,
934338f6903SLoGin ) -> Option<Arc<IrqDesc>> {
935338f6903SLoGin let desc = self.lookup(irq)?;
936338f6903SLoGin if check_global || check_percpu {
937338f6903SLoGin if check_percpu && !desc.inner().line_status().is_per_cpu_devid() {
938338f6903SLoGin return None;
939338f6903SLoGin }
940338f6903SLoGin
941338f6903SLoGin if check_global && desc.inner().line_status().is_per_cpu_devid() {
942338f6903SLoGin return None;
943338f6903SLoGin }
944338f6903SLoGin }
945338f6903SLoGin
946338f6903SLoGin if lock_bus {
947338f6903SLoGin desc.chip_bus_lock();
948338f6903SLoGin }
949338f6903SLoGin
950338f6903SLoGin return Some(desc);
951338f6903SLoGin }
952338f6903SLoGin
insert(&mut self, irq: IrqNumber, desc: Arc<IrqDesc>)9533bc96fa4SLoGin fn insert(&mut self, irq: IrqNumber, desc: Arc<IrqDesc>) {
9543bc96fa4SLoGin self.irq_descs.insert(irq, desc);
9553bc96fa4SLoGin }
956196b75dcSLoGin
957196b75dcSLoGin /// 释放中断描述符
958196b75dcSLoGin #[allow(dead_code)]
free_desc(&mut self, irq: IrqNumber)959196b75dcSLoGin fn free_desc(&mut self, irq: IrqNumber) {
960196b75dcSLoGin if let Some(desc) = self.irq_descs.get(&irq) {
961196b75dcSLoGin irq_sysfs_del(desc);
962196b75dcSLoGin self.irq_descs.remove(&irq);
963196b75dcSLoGin }
964196b75dcSLoGin }
965196b75dcSLoGin
966196b75dcSLoGin /// 迭代中断描述符
iter_descs(&self) -> btree_map::Iter<'_, IrqNumber, Arc<IrqDesc>>967196b75dcSLoGin pub fn iter_descs(&self) -> btree_map::Iter<'_, IrqNumber, Arc<IrqDesc>> {
968196b75dcSLoGin self.irq_descs.iter()
969196b75dcSLoGin }
970338f6903SLoGin
971338f6903SLoGin /// 设置指定irq的可用cpu为所有cpu
set_percpu_devid_all(&self, irq: IrqNumber) -> Result<(), SystemError>972338f6903SLoGin pub fn set_percpu_devid_all(&self, irq: IrqNumber) -> Result<(), SystemError> {
973338f6903SLoGin self.set_percpu_devid(irq, None)
974338f6903SLoGin }
975338f6903SLoGin
976338f6903SLoGin /// 设置指定irq的可用cpu
977338f6903SLoGin ///
978338f6903SLoGin /// 如果affinity为None,则表示设置为所有cpu
set_percpu_devid( &self, irq: IrqNumber, affinity: Option<&CpuMask>, ) -> Result<(), SystemError>979338f6903SLoGin pub fn set_percpu_devid(
980338f6903SLoGin &self,
981338f6903SLoGin irq: IrqNumber,
982338f6903SLoGin affinity: Option<&CpuMask>,
983338f6903SLoGin ) -> Result<(), SystemError> {
984338f6903SLoGin let desc = self.lookup(irq).ok_or(SystemError::EINVAL)?;
985338f6903SLoGin let mut desc_inner = desc.inner();
986338f6903SLoGin
987338f6903SLoGin if desc_inner.percpu_enabled().is_some() {
988338f6903SLoGin return Err(SystemError::EINVAL);
989338f6903SLoGin }
990338f6903SLoGin
991338f6903SLoGin *desc_inner.percpu_enabled_mut() = Some(CpuMask::new());
992338f6903SLoGin
993338f6903SLoGin if let Some(affinity) = affinity {
994338f6903SLoGin desc_inner.percpu_affinity_mut().replace(affinity.clone());
995338f6903SLoGin } else {
996338f6903SLoGin desc_inner
997338f6903SLoGin .percpu_affinity_mut()
998338f6903SLoGin .replace(smp_cpu_manager().possible_cpus().clone());
999338f6903SLoGin }
1000338f6903SLoGin
1001338f6903SLoGin drop(desc_inner);
1002338f6903SLoGin
1003338f6903SLoGin desc.set_percpu_devid_flags();
1004338f6903SLoGin
1005338f6903SLoGin return Ok(());
1006338f6903SLoGin }
10073bc96fa4SLoGin }
1008f049d1afSLoGin
1009f049d1afSLoGin pub struct GenericIrqHandler;
1010f049d1afSLoGin
1011f049d1afSLoGin #[allow(dead_code)]
1012f049d1afSLoGin impl GenericIrqHandler {
1013f049d1afSLoGin /// `handle_domain_irq` - 调用属于某个中断域的硬件中断的处理程序
1014f049d1afSLoGin ///
1015f049d1afSLoGin /// # 参数
1016f049d1afSLoGin ///
1017f049d1afSLoGin /// * `domain`: 执行查找的域
1018f049d1afSLoGin /// * `hwirq`: 要转换为逻辑中断的硬件中断号
1019f049d1afSLoGin ///
1020f049d1afSLoGin /// # 返回
1021f049d1afSLoGin ///
1022f049d1afSLoGin /// 成功时返回 `Ok(())`,如果转换失败则返回 `Err(SystemError)`
1023f049d1afSLoGin ///
1024f049d1afSLoGin /// 此函数必须在初始化了中断寄存器的中断上下文中调用
1025f049d1afSLoGin ///
1026f049d1afSLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/irq/irqdesc.c?fi=generic_handle_domain_irq#726
handle_domain_irq( domain: Arc<IrqDomain>, hwirq: HardwareIrqNumber, trap_frame: &mut TrapFrame, ) -> Result<(), SystemError>1027f049d1afSLoGin pub fn handle_domain_irq(
1028f049d1afSLoGin domain: Arc<IrqDomain>,
1029f049d1afSLoGin hwirq: HardwareIrqNumber,
1030f049d1afSLoGin trap_frame: &mut TrapFrame,
1031f049d1afSLoGin ) -> Result<(), SystemError> {
1032f049d1afSLoGin let (irq_desc, _) =
1033f049d1afSLoGin irq_domain_manager().resolve_irq_mapping(Some(domain.clone()), hwirq)?;
1034f049d1afSLoGin
1035f049d1afSLoGin irq_desc.handler().unwrap().handle(&irq_desc, trap_frame);
1036f049d1afSLoGin
1037f049d1afSLoGin return Ok(());
1038f049d1afSLoGin }
1039f049d1afSLoGin }
1040