1e2841179SLoGin use core::ops::{BitXor, Deref, DerefMut};
2e2841179SLoGin
3e2841179SLoGin use alloc::{string::String, sync::Arc};
4e2841179SLoGin
5*2eab6dd7S曾俊 use log::{debug, error, warn};
6e2841179SLoGin use system_error::SystemError;
7e2841179SLoGin
8e2841179SLoGin use crate::{
9e2841179SLoGin driver::base::device::DeviceId,
10e2841179SLoGin exception::{
11e2841179SLoGin irqchip::IrqChipSetMaskResult,
12e2841179SLoGin irqdesc::{irq_desc_manager, InnerIrqDesc, IrqAction},
13e2841179SLoGin },
14e2841179SLoGin libs::{cpumask::CpuMask, spinlock::SpinLockGuard},
15e2841179SLoGin process::{kthread::KernelThreadMechanism, ProcessManager},
16e2841179SLoGin smp::cpu::ProcessorId,
17e2841179SLoGin };
18e2841179SLoGin
19e2841179SLoGin use super::{
20e2841179SLoGin dummychip::no_irq_chip,
21e2841179SLoGin irqchip::IrqChipFlags,
22e2841179SLoGin irqdata::{IrqData, IrqHandlerData, IrqLineStatus, IrqStatus},
23e2841179SLoGin irqdesc::{InnerIrqAction, IrqDesc, IrqDescState, IrqHandleFlags, IrqHandler, IrqReturn},
24e2841179SLoGin irqdomain::irq_domain_manager,
25e2841179SLoGin IrqNumber,
26e2841179SLoGin };
27e2841179SLoGin
28e2841179SLoGin lazy_static! {
29e2841179SLoGin /// 默认的中断亲和性
30e2841179SLoGin static ref IRQ_DEFAULT_AFFINITY: CpuMask = {
31e2841179SLoGin let mut mask = CpuMask::new();
32e2841179SLoGin // 默认情况下,中断处理程序将在第一个处理器上运行
33e2841179SLoGin mask.set(ProcessorId::new(0), true);
34e2841179SLoGin mask
35e2841179SLoGin };
36e2841179SLoGin }
37e2841179SLoGin
irq_manager() -> &'static IrqManager38e2841179SLoGin pub fn irq_manager() -> &'static IrqManager {
39e2841179SLoGin &IrqManager
40e2841179SLoGin }
41e2841179SLoGin
42e2841179SLoGin /// 中断管理器
43e2841179SLoGin pub struct IrqManager;
44e2841179SLoGin
45e2841179SLoGin impl IrqManager {
46e2841179SLoGin pub const IRQ_RESEND: bool = true;
47e2841179SLoGin #[allow(dead_code)]
48e2841179SLoGin pub const IRQ_NORESEND: bool = false;
49e2841179SLoGin #[allow(dead_code)]
50e2841179SLoGin pub const IRQ_START_FORCE: bool = true;
51e2841179SLoGin pub const IRQ_START_COND: bool = false;
52e2841179SLoGin
53e2841179SLoGin /// 在中断线上添加一个处理函数
54e2841179SLoGin ///
55e2841179SLoGin /// ## 参数
56e2841179SLoGin ///
57e2841179SLoGin /// - irq: 虚拟中断号(中断线号)
58e2841179SLoGin /// - name: 生成该中断的设备名称
59e2841179SLoGin /// - handler: 中断处理函数
60e2841179SLoGin /// - flags: 中断处理标志
61e2841179SLoGin /// - dev_id: 一个用于标识设备的cookie
request_irq( &self, irq: IrqNumber, name: String, handler: &'static dyn IrqHandler, flags: IrqHandleFlags, dev_id: Option<Arc<DeviceId>>, ) -> Result<(), SystemError>62e2841179SLoGin pub fn request_irq(
63e2841179SLoGin &self,
64e2841179SLoGin irq: IrqNumber,
65e2841179SLoGin name: String,
66e2841179SLoGin handler: &'static dyn IrqHandler,
67e2841179SLoGin flags: IrqHandleFlags,
68e2841179SLoGin dev_id: Option<Arc<DeviceId>>,
69e2841179SLoGin ) -> Result<(), SystemError> {
70e2841179SLoGin return self.request_threaded_irq(irq, Some(handler), None, flags, name, dev_id);
71e2841179SLoGin }
72e2841179SLoGin
73e2841179SLoGin /// 在中断线上添加一个处理函数(可以是线程化的中断)
74e2841179SLoGin ///
75e2841179SLoGin /// ## 参数
76e2841179SLoGin ///
77e2841179SLoGin /// - irq: 虚拟中断号
78e2841179SLoGin /// - handler: 当中断发生时将被调用的函数,是
79e2841179SLoGin /// 线程化中断的初级处理程序。如果handler为`None`并且thread_fn不为`None`,
80e2841179SLoGin /// 将安装默认的初级处理程序
81e2841179SLoGin /// - thread_fn: 在中断处理程序线程中调用的函数. 如果为`None`,则不会创建irq线程
82e2841179SLoGin /// - flags: 中断处理标志
83e2841179SLoGin /// - IRQF_SHARED: 中断是共享的
84e2841179SLoGin /// - IRQF_TRIGGER*: 指定中断触发方式
85e2841179SLoGin /// - IRQF_ONESHOT: 在thread_fn中运行时,中断线被遮蔽
86e2841179SLoGin /// - dev_name: 生成该中断的设备名称
87e2841179SLoGin /// - dev_id: 一个用于标识设备的cookie
88e2841179SLoGin ///
89e2841179SLoGin /// ## 说明
90e2841179SLoGin ///
91e2841179SLoGin /// 此调用分配中断资源并启用中断线和IRQ处理。
92e2841179SLoGin /// 从这一点开始,您的处理程序函数可能会被调用。
93e2841179SLoGin /// 因此,您必须确保首先初始化您的硬件,
94e2841179SLoGin /// 并确保以正确的顺序设置中断处理程序。
95e2841179SLoGin ///
96e2841179SLoGin /// 如果您想为您的设备设置线程化中断处理程序
97e2841179SLoGin /// 则需要提供@handler和@thread_fn。@handler仍然
98e2841179SLoGin /// 在硬中断上下文中调用,并且必须检查
99e2841179SLoGin /// 中断是否来自设备。如果是,它需要禁用设备上的中断
100e2841179SLoGin /// 并返回IRQ_WAKE_THREAD,这将唤醒处理程序线程并运行
101e2841179SLoGin /// @thread_fn。这种拆分处理程序设计是为了支持
102e2841179SLoGin /// 共享中断。
103e2841179SLoGin ///
104e2841179SLoGin /// dev_id必须是全局唯一的。通常使用设备数据结构的地址或者uuid
105e2841179SLoGin /// 作为cookie。由于处理程序接收这个值,因此使用它是有意义的。
106e2841179SLoGin ///
107e2841179SLoGin /// 如果您的中断是共享的,您必须传递一个非NULL的dev_id
108e2841179SLoGin /// 因为当释放中断时需要它。
request_threaded_irq( &self, irq: IrqNumber, mut handler: Option<&'static dyn IrqHandler>, thread_fn: Option<&'static dyn IrqHandler>, flags: IrqHandleFlags, dev_name: String, dev_id: Option<Arc<DeviceId>>, ) -> Result<(), SystemError>109e2841179SLoGin pub fn request_threaded_irq(
110e2841179SLoGin &self,
111e2841179SLoGin irq: IrqNumber,
112e2841179SLoGin mut handler: Option<&'static dyn IrqHandler>,
113e2841179SLoGin thread_fn: Option<&'static dyn IrqHandler>,
114e2841179SLoGin flags: IrqHandleFlags,
115e2841179SLoGin dev_name: String,
116e2841179SLoGin dev_id: Option<Arc<DeviceId>>,
117e2841179SLoGin ) -> Result<(), SystemError> {
118e2841179SLoGin if irq == IrqNumber::IRQ_NOTCONNECTED {
119e2841179SLoGin return Err(SystemError::ENOTCONN);
120e2841179SLoGin }
121e2841179SLoGin
122e2841179SLoGin // 逻辑检查:共享中断必须传入一个真正的设备ID,
123e2841179SLoGin // 否则后来我们将难以确定哪个中断是哪个(会搞乱中断释放逻辑等)。
124e2841179SLoGin // 此外,共享中断与禁用自动使能不相符。 共享中断可能在仍然禁用时请求它,然后永远等待中断。
125e2841179SLoGin // 另外,IRQF_COND_SUSPEND 仅适用于共享中断,并且它不能与 IRQF_NO_SUSPEND 同时设置。
126e2841179SLoGin
127e2841179SLoGin if ((flags.contains(IrqHandleFlags::IRQF_SHARED)) && dev_id.is_none())
128e2841179SLoGin || ((flags.contains(IrqHandleFlags::IRQF_SHARED))
129e2841179SLoGin && (flags.contains(IrqHandleFlags::IRQF_NO_AUTOEN)))
130e2841179SLoGin || (!(flags.contains(IrqHandleFlags::IRQF_SHARED))
131e2841179SLoGin && (flags.contains(IrqHandleFlags::IRQF_COND_SUSPEND)))
132e2841179SLoGin || ((flags.contains(IrqHandleFlags::IRQF_NO_SUSPEND))
133e2841179SLoGin && (flags.contains(IrqHandleFlags::IRQF_COND_SUSPEND)))
134e2841179SLoGin {
135e2841179SLoGin return Err(SystemError::EINVAL);
136e2841179SLoGin }
137e2841179SLoGin let desc = irq_desc_manager().lookup(irq).ok_or(SystemError::EINVAL)?;
138e2841179SLoGin if !desc.can_request() {
139*2eab6dd7S曾俊 warn!("desc {} can not request", desc.irq().data());
140e2841179SLoGin return Err(SystemError::EINVAL);
141e2841179SLoGin }
142e2841179SLoGin
143e2841179SLoGin if handler.is_none() {
144e2841179SLoGin if thread_fn.is_none() {
145e2841179SLoGin // 不允许中断处理函数和线程处理函数都为空
146e2841179SLoGin return Err(SystemError::EINVAL);
147e2841179SLoGin }
148e2841179SLoGin
149e2841179SLoGin // 如果中断处理函数为空,线程处理函数不为空,则使用默认的中断处理函数
150e2841179SLoGin handler = Some(&DefaultPrimaryIrqHandler);
151e2841179SLoGin }
152e2841179SLoGin
153e2841179SLoGin let irqaction = IrqAction::new(irq, dev_name, handler, thread_fn);
154e2841179SLoGin
155e2841179SLoGin let mut action_guard = irqaction.inner();
156e2841179SLoGin *action_guard.flags_mut() = flags;
157e2841179SLoGin *action_guard.dev_id_mut() = dev_id;
158e2841179SLoGin drop(action_guard);
159*2eab6dd7S曾俊 debug!("to inner_setup_irq");
160e2841179SLoGin return self.inner_setup_irq(irq, irqaction, desc);
161e2841179SLoGin }
162e2841179SLoGin
163e2841179SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c?r=&mo=59252&fi=2138#1497
164e2841179SLoGin #[inline(never)]
inner_setup_irq( &self, irq: IrqNumber, action: Arc<IrqAction>, desc: Arc<IrqDesc>, ) -> Result<(), SystemError>165e2841179SLoGin fn inner_setup_irq(
166e2841179SLoGin &self,
167e2841179SLoGin irq: IrqNumber,
168e2841179SLoGin action: Arc<IrqAction>,
169e2841179SLoGin desc: Arc<IrqDesc>,
170e2841179SLoGin ) -> Result<(), SystemError> {
171e2841179SLoGin // ==== 定义错误处理函数 ====
172e2841179SLoGin let err_out_thread =
173e2841179SLoGin |e: SystemError, mut action_guard: SpinLockGuard<'_, InnerIrqAction>| -> SystemError {
174e2841179SLoGin if let Some(thread_pcb) = action_guard.thread() {
175e2841179SLoGin action_guard.set_thread(None);
176e2841179SLoGin KernelThreadMechanism::stop(&thread_pcb).ok();
177e2841179SLoGin }
178e2841179SLoGin
179e2841179SLoGin if let Some(secondary) = action_guard.secondary() {
180e2841179SLoGin let mut secondary_guard = secondary.inner();
181e2841179SLoGin if let Some(thread_pcb) = secondary_guard.thread() {
182e2841179SLoGin secondary_guard.set_thread(None);
183e2841179SLoGin KernelThreadMechanism::stop(&thread_pcb).ok();
184e2841179SLoGin }
185e2841179SLoGin }
186e2841179SLoGin return e;
187e2841179SLoGin };
188e2841179SLoGin
189e2841179SLoGin let err_out_bus_unlock = |e: SystemError,
190e2841179SLoGin desc: Arc<IrqDesc>,
191e2841179SLoGin req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>,
192e2841179SLoGin action_guard: SpinLockGuard<'_, InnerIrqAction>|
193e2841179SLoGin -> SystemError {
194e2841179SLoGin desc.chip_bus_sync_unlock();
195e2841179SLoGin drop(req_mutex_guard);
196e2841179SLoGin return err_out_thread(e, action_guard);
197e2841179SLoGin };
198e2841179SLoGin
199e2841179SLoGin let err_out_unlock = |e: SystemError,
200e2841179SLoGin desc_guard: SpinLockGuard<'_, InnerIrqDesc>,
201e2841179SLoGin desc: Arc<IrqDesc>,
202e2841179SLoGin req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>,
203e2841179SLoGin action_guard: SpinLockGuard<'_, InnerIrqAction>|
204e2841179SLoGin -> SystemError {
205e2841179SLoGin drop(desc_guard);
206e2841179SLoGin return err_out_bus_unlock(e, desc, req_mutex_guard, action_guard);
207e2841179SLoGin };
208e2841179SLoGin
209e2841179SLoGin let err_out_mismatch = |old_action_guard: SpinLockGuard<'_, InnerIrqAction>,
210e2841179SLoGin desc_guard: SpinLockGuard<'_, InnerIrqDesc>,
211e2841179SLoGin action_guard: SpinLockGuard<'_, InnerIrqAction>,
212e2841179SLoGin desc: Arc<IrqDesc>,
213e2841179SLoGin req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>|
214e2841179SLoGin -> SystemError {
215e2841179SLoGin if !action_guard
216e2841179SLoGin .flags()
217e2841179SLoGin .contains(IrqHandleFlags::IRQF_PROBE_SHARED)
218e2841179SLoGin {
219*2eab6dd7S曾俊 error!("Flags mismatch for irq {} (name: {}, flags: {:?}). old action name: {}, old flags: {:?}", irq.data(), action_guard.name(), action_guard.flags(), old_action_guard.name(), old_action_guard.flags());
220e2841179SLoGin }
221e2841179SLoGin return err_out_unlock(
222e2841179SLoGin SystemError::EBUSY,
223e2841179SLoGin desc_guard,
224e2841179SLoGin desc,
225e2841179SLoGin req_mutex_guard,
226e2841179SLoGin action_guard,
227e2841179SLoGin );
228e2841179SLoGin };
229e2841179SLoGin
230e2841179SLoGin // ===== 代码开始 =====
231e2841179SLoGin
232e2841179SLoGin if Arc::ptr_eq(
233e2841179SLoGin &desc.irq_data().chip_info_read_irqsave().chip(),
234e2841179SLoGin &no_irq_chip(),
235e2841179SLoGin ) {
236e2841179SLoGin return Err(SystemError::ENOSYS);
237e2841179SLoGin }
238e2841179SLoGin
239e2841179SLoGin let mut action_guard = action.inner();
240e2841179SLoGin if !action_guard.flags().trigger_type_specified() {
241e2841179SLoGin // 如果没有指定触发类型,则使用默认的触发类型
242e2841179SLoGin action_guard
243e2841179SLoGin .flags_mut()
244e2841179SLoGin .insert_trigger_type(desc.irq_data().common_data().trigger_type())
245e2841179SLoGin }
246e2841179SLoGin
247e2841179SLoGin let nested = desc.nested_thread();
248e2841179SLoGin
249e2841179SLoGin if nested {
250e2841179SLoGin if action_guard.thread_fn().is_none() {
251e2841179SLoGin return Err(SystemError::EINVAL);
252e2841179SLoGin }
253e2841179SLoGin
254e2841179SLoGin action_guard.set_handler(Some(&IrqNestedPrimaryHandler));
255b5b571e0SLoGin } else if desc.can_thread() {
256e2841179SLoGin self.setup_forced_threading(action_guard.deref_mut())?;
257e2841179SLoGin }
258e2841179SLoGin
259e2841179SLoGin // 如果具有中断线程处理程序,并且中断不是嵌套的,则设置中断线程
260e2841179SLoGin if action_guard.thread_fn().is_some() && !nested {
261e2841179SLoGin self.setup_irq_thread(irq, action_guard.deref(), false)?;
262e2841179SLoGin
263e2841179SLoGin if let Some(secondary) = action_guard.secondary() {
264e2841179SLoGin let secondary_guard = secondary.inner();
265e2841179SLoGin if let Err(e) = self.setup_irq_thread(irq, secondary_guard.deref(), true) {
266e2841179SLoGin return Err(err_out_thread(e, action_guard));
267e2841179SLoGin }
268e2841179SLoGin }
269e2841179SLoGin }
270e2841179SLoGin
271e2841179SLoGin // Drivers are often written to work w/o knowledge about the
272e2841179SLoGin // underlying irq chip implementation, so a request for a
273e2841179SLoGin // threaded irq without a primary hard irq context handler
274e2841179SLoGin // requires the ONESHOT flag to be set. Some irq chips like
275e2841179SLoGin // MSI based interrupts are per se one shot safe. Check the
276e2841179SLoGin // chip flags, so we can avoid the unmask dance at the end of
277e2841179SLoGin // the threaded handler for those.
278e2841179SLoGin
279e2841179SLoGin if desc
280e2841179SLoGin .irq_data()
281e2841179SLoGin .chip_info_read_irqsave()
282e2841179SLoGin .chip()
283e2841179SLoGin .flags()
284e2841179SLoGin .contains(IrqChipFlags::IRQCHIP_ONESHOT_SAFE)
285e2841179SLoGin {
286e2841179SLoGin *action_guard.flags_mut() &= !IrqHandleFlags::IRQF_ONESHOT;
287e2841179SLoGin }
288e2841179SLoGin
289e2841179SLoGin // Protects against a concurrent __free_irq() call which might wait
290e2841179SLoGin // for synchronize_hardirq() to complete without holding the optional
291e2841179SLoGin // chip bus lock and desc->lock. Also protects against handing out
292e2841179SLoGin // a recycled oneshot thread_mask bit while it's still in use by
293e2841179SLoGin // its previous owner.
294e2841179SLoGin let req_mutex_guard = desc.request_mutex_lock();
295e2841179SLoGin
296e2841179SLoGin // Acquire bus lock as the irq_request_resources() callback below
297e2841179SLoGin // might rely on the serialization or the magic power management
298e2841179SLoGin // functions which are abusing the irq_bus_lock() callback,
299e2841179SLoGin desc.chip_bus_lock();
300e2841179SLoGin
301e2841179SLoGin // 如果当前中断线上还没有irqaction, 则先为中断线申请资源
302e2841179SLoGin if desc.actions().is_empty() {
303e2841179SLoGin if let Err(e) = self.irq_request_resources(desc.clone()) {
304*2eab6dd7S曾俊 error!(
305e2841179SLoGin "Failed to request resources for {} (irq {}) on irqchip {}, error {:?}",
306e2841179SLoGin action_guard.name(),
307e2841179SLoGin irq.data(),
308e2841179SLoGin desc.irq_data().chip_info_read_irqsave().chip().name(),
309e2841179SLoGin e
310e2841179SLoGin );
311e2841179SLoGin return Err(err_out_bus_unlock(
312e2841179SLoGin e,
313e2841179SLoGin desc.clone(),
314e2841179SLoGin req_mutex_guard,
315e2841179SLoGin action_guard,
316e2841179SLoGin ));
317e2841179SLoGin }
318e2841179SLoGin }
319e2841179SLoGin
320e2841179SLoGin let mut desc_inner_guard: SpinLockGuard<'_, InnerIrqDesc> = desc.inner();
321e2841179SLoGin
322e2841179SLoGin // 标记当前irq是否是共享的
323e2841179SLoGin let mut irq_shared = false;
324b5b571e0SLoGin if !desc_inner_guard.actions().is_empty() {
325e2841179SLoGin // 除非双方都同意并且是相同类型(级别、边沿、极性),否则不能共享中断。
326e2841179SLoGin // 因此,两个标志字段都必须设置IRQF_SHARED,并且设置触发类型的位必须匹配。
327e2841179SLoGin // 另外,所有各方都必须就ONESHOT达成一致。
328e2841179SLoGin // NMI用途的中断线不能共享。
329e2841179SLoGin if desc_inner_guard
330e2841179SLoGin .internal_state()
331e2841179SLoGin .contains(IrqDescState::IRQS_NMI)
332e2841179SLoGin {
333*2eab6dd7S曾俊 error!(
334e2841179SLoGin "Invalid attempt to share NMI for {} (irq {}) on irqchip {}",
335e2841179SLoGin action_guard.name(),
336e2841179SLoGin irq.data(),
337e2841179SLoGin desc_inner_guard
338e2841179SLoGin .irq_data()
339e2841179SLoGin .chip_info_read_irqsave()
340e2841179SLoGin .chip()
341e2841179SLoGin .name()
342e2841179SLoGin );
343e2841179SLoGin return Err(err_out_unlock(
344e2841179SLoGin SystemError::EINVAL,
345e2841179SLoGin desc_inner_guard,
346e2841179SLoGin desc.clone(),
347e2841179SLoGin req_mutex_guard,
348e2841179SLoGin action_guard,
349e2841179SLoGin ));
350e2841179SLoGin }
351e2841179SLoGin
352e2841179SLoGin let irq_data = desc_inner_guard.irq_data();
353e2841179SLoGin
354e2841179SLoGin let old_trigger_type: super::irqdata::IrqLineStatus;
355e2841179SLoGin let status = irq_data.common_data().status();
356e2841179SLoGin if status.trigger_type_was_set() {
357e2841179SLoGin old_trigger_type = status.trigger_type();
358e2841179SLoGin } else {
359e2841179SLoGin old_trigger_type = action_guard.flags().trigger_type();
360e2841179SLoGin irq_data.common_data().set_trigger_type(old_trigger_type);
361e2841179SLoGin }
362e2841179SLoGin
363e2841179SLoGin let old = &desc_inner_guard.actions()[0].clone();
364e2841179SLoGin let old_guard = old.inner();
365e2841179SLoGin
366b5b571e0SLoGin if (!(old_guard
367e2841179SLoGin .flags()
368e2841179SLoGin .intersection(*action_guard.flags())
369b5b571e0SLoGin .contains(IrqHandleFlags::IRQF_SHARED)))
370e2841179SLoGin || (old_trigger_type != (action_guard.flags().trigger_type()))
371e2841179SLoGin || ((old_guard.flags().bitxor(*action_guard.flags()))
372e2841179SLoGin .contains(IrqHandleFlags::IRQF_ONESHOT))
373e2841179SLoGin {
374*2eab6dd7S曾俊 debug!(
3750102d69fSLoGin "Flags mismatch for irq {} (name: {}, flags: {:?}). old action name: {}, old flags: {:?}",
3760102d69fSLoGin irq.data(),
3770102d69fSLoGin action_guard.name(),
3780102d69fSLoGin action_guard.flags(),
3790102d69fSLoGin old_guard.name(),
3800102d69fSLoGin old_guard.flags()
3810102d69fSLoGin );
3820102d69fSLoGin
383e2841179SLoGin return Err(err_out_mismatch(
384e2841179SLoGin old_guard,
385e2841179SLoGin desc_inner_guard,
386e2841179SLoGin action_guard,
387e2841179SLoGin desc.clone(),
388e2841179SLoGin req_mutex_guard,
389e2841179SLoGin ));
390e2841179SLoGin }
391e2841179SLoGin
392e2841179SLoGin // all handlers must agree on per-cpuness
393e2841179SLoGin if *old_guard.flags() & IrqHandleFlags::IRQF_PERCPU
394e2841179SLoGin != *action_guard.flags() & IrqHandleFlags::IRQF_PERCPU
395e2841179SLoGin {
396*2eab6dd7S曾俊 debug!(
3970102d69fSLoGin "Per-cpu mismatch for irq {} (name: {}, flags: {:?})",
3980102d69fSLoGin irq.data(),
3990102d69fSLoGin action_guard.name(),
4000102d69fSLoGin action_guard.flags()
4010102d69fSLoGin );
402e2841179SLoGin return Err(err_out_mismatch(
403e2841179SLoGin old_guard,
404e2841179SLoGin desc_inner_guard,
405e2841179SLoGin action_guard,
406e2841179SLoGin desc.clone(),
407e2841179SLoGin req_mutex_guard,
408e2841179SLoGin ));
409e2841179SLoGin }
410e2841179SLoGin
411e2841179SLoGin irq_shared = true;
412e2841179SLoGin }
413e2841179SLoGin
414e2841179SLoGin if action_guard.flags().contains(IrqHandleFlags::IRQF_ONESHOT) {
415e2841179SLoGin // todo: oneshot
416e2841179SLoGin } else if action_guard.handler().is_some_and(|h| {
417e2841179SLoGin h.type_id() == (&DefaultPrimaryIrqHandler as &dyn IrqHandler).type_id()
418b5b571e0SLoGin }) && !desc_inner_guard
419e2841179SLoGin .irq_data()
420e2841179SLoGin .chip_info_read_irqsave()
421e2841179SLoGin .chip()
422e2841179SLoGin .flags()
423e2841179SLoGin .contains(IrqChipFlags::IRQCHIP_ONESHOT_SAFE)
424e2841179SLoGin {
425e2841179SLoGin // 请求中断时 hander = NULL,因此我们为其使用默认的主处理程序。
426e2841179SLoGin // 但它没有设置ONESHOT标志。与电平触发中断结合时,
427e2841179SLoGin // 这是致命的,因为默认的主处理程序只是唤醒线程,然后重新启用 irq 线路,
428e2841179SLoGin // 但设备仍然保持电平中断生效。周而复始....
429e2841179SLoGin // 虽然这对于边缘类型中断来说可行,但我们为了安全起见,不加条件地拒绝,
430e2841179SLoGin // 因为我们不能确定这个中断实际上具有什么类型。
431e2841179SLoGin // 由于底层芯片实现可能会覆盖它们,所以类型标志并不可靠.
432e2841179SLoGin
433*2eab6dd7S曾俊 error!(
434e2841179SLoGin "Requesting irq {} without a handler, and ONESHOT flags not set for irqaction: {}",
435e2841179SLoGin irq.data(),
436e2841179SLoGin action_guard.name()
437e2841179SLoGin );
438e2841179SLoGin return Err(err_out_unlock(
439e2841179SLoGin SystemError::EINVAL,
440e2841179SLoGin desc_inner_guard,
441e2841179SLoGin desc.clone(),
442e2841179SLoGin req_mutex_guard,
443e2841179SLoGin action_guard,
444e2841179SLoGin ));
445e2841179SLoGin }
446e2841179SLoGin
447e2841179SLoGin // 第一次在当前irqdesc上注册中断处理函数
448e2841179SLoGin if !irq_shared {
449e2841179SLoGin // 设置中断触发方式
450e2841179SLoGin if action_guard.flags().trigger_type_specified() {
451e2841179SLoGin let trigger_type = action_guard.flags().trigger_type();
452e2841179SLoGin if let Err(e) =
453e2841179SLoGin self.do_set_irq_trigger(desc.clone(), &mut desc_inner_guard, trigger_type)
454e2841179SLoGin {
455*2eab6dd7S曾俊 debug!(
4560102d69fSLoGin "Failed to set trigger type for irq {} (name: {}, flags: {:?}), error {:?}",
4570102d69fSLoGin irq.data(),
4580102d69fSLoGin action_guard.name(),
4590102d69fSLoGin action_guard.flags(),
4600102d69fSLoGin e
4610102d69fSLoGin );
462e2841179SLoGin return Err(err_out_unlock(
463e2841179SLoGin e,
464e2841179SLoGin desc_inner_guard,
465e2841179SLoGin desc.clone(),
466e2841179SLoGin req_mutex_guard,
467e2841179SLoGin action_guard,
468e2841179SLoGin ));
469e2841179SLoGin }
470e2841179SLoGin }
471*2eab6dd7S曾俊 debug!("to irq_activate");
472e2841179SLoGin // 激活中断。这种激活必须独立于IRQ_NOAUTOEN进行*desc_inner_guard.internal_state_mut() |= IrqDescState::IRQS_NOREQUEST;uest.
473338f6903SLoGin if let Err(e) = self.irq_activate(&desc, &mut desc_inner_guard) {
474*2eab6dd7S曾俊 debug!(
4750102d69fSLoGin "Failed to activate irq {} (name: {}, flags: {:?}), error {:?}",
4760102d69fSLoGin irq.data(),
4770102d69fSLoGin action_guard.name(),
4780102d69fSLoGin action_guard.flags(),
4790102d69fSLoGin e
4800102d69fSLoGin );
481e2841179SLoGin return Err(err_out_unlock(
482e2841179SLoGin e,
483e2841179SLoGin desc_inner_guard,
484e2841179SLoGin desc.clone(),
485e2841179SLoGin req_mutex_guard,
486e2841179SLoGin action_guard,
487e2841179SLoGin ));
488e2841179SLoGin }
489e2841179SLoGin
490e2841179SLoGin *desc_inner_guard.internal_state_mut() &= !(IrqDescState::IRQS_AUTODETECT
491e2841179SLoGin | IrqDescState::IRQS_SPURIOUS_DISABLED
492e2841179SLoGin | IrqDescState::IRQS_ONESHOT
493e2841179SLoGin | IrqDescState::IRQS_WAITING);
494e2841179SLoGin desc_inner_guard
495e2841179SLoGin .common_data()
496e2841179SLoGin .clear_status(IrqStatus::IRQD_IRQ_INPROGRESS);
497e2841179SLoGin
498e2841179SLoGin if action_guard.flags().contains(IrqHandleFlags::IRQF_PERCPU) {
499e2841179SLoGin desc_inner_guard
500e2841179SLoGin .common_data()
501e2841179SLoGin .insert_status(IrqStatus::IRQD_PER_CPU);
502e2841179SLoGin desc_inner_guard.line_status_set_per_cpu();
503e2841179SLoGin
504e2841179SLoGin if action_guard.flags().contains(IrqHandleFlags::IRQF_NO_DEBUG) {
505e2841179SLoGin desc_inner_guard.line_status_set_no_debug();
506e2841179SLoGin }
507e2841179SLoGin }
508e2841179SLoGin
509e2841179SLoGin if action_guard.flags().contains(IrqHandleFlags::IRQF_ONESHOT) {
510e2841179SLoGin *desc_inner_guard.internal_state_mut() |= IrqDescState::IRQS_ONESHOT;
511e2841179SLoGin }
512e2841179SLoGin
513e2841179SLoGin // 如果有要求的话,则忽略IRQ的均衡。
514e2841179SLoGin if action_guard
515e2841179SLoGin .flags()
516e2841179SLoGin .contains(IrqHandleFlags::IRQF_NOBALANCING)
517e2841179SLoGin {
518e2841179SLoGin todo!("IRQF_NO_BALANCING");
519e2841179SLoGin }
520e2841179SLoGin
521e2841179SLoGin if !action_guard
522e2841179SLoGin .flags()
523e2841179SLoGin .contains(IrqHandleFlags::IRQF_NO_AUTOEN)
524e2841179SLoGin && desc_inner_guard.can_autoenable()
525e2841179SLoGin {
526e2841179SLoGin // 如果没有设置IRQF_NOAUTOEN,则自动使能中断
527e2841179SLoGin self.irq_startup(
528338f6903SLoGin &desc,
529e2841179SLoGin &mut desc_inner_guard,
530e2841179SLoGin Self::IRQ_RESEND,
531e2841179SLoGin Self::IRQ_START_COND,
532e2841179SLoGin )
533e2841179SLoGin .ok();
534e2841179SLoGin } else {
535e2841179SLoGin // 共享中断与禁用自动使能不太兼容。
536e2841179SLoGin // 共享中断可能在它仍然被禁用时请求它,然后永远等待中断。
537e2841179SLoGin
538e2841179SLoGin static mut WARNED: bool = false;
539b5b571e0SLoGin if action_guard.flags().contains(IrqHandleFlags::IRQF_SHARED) && unsafe { !WARNED }
540b5b571e0SLoGin {
541*2eab6dd7S曾俊 warn!(
542e2841179SLoGin "Shared interrupt {} for {} requested but not auto enabled",
543e2841179SLoGin irq.data(),
544e2841179SLoGin action_guard.name()
545e2841179SLoGin );
546e2841179SLoGin unsafe { WARNED = true };
547e2841179SLoGin }
548e2841179SLoGin
549e2841179SLoGin desc_inner_guard.set_depth(1);
550e2841179SLoGin }
551e2841179SLoGin } else if action_guard.flags().trigger_type_specified() {
552e2841179SLoGin let new_trigger_type = action_guard.flags().trigger_type();
553e2841179SLoGin let old_trigger_type = desc_inner_guard.common_data().trigger_type();
554e2841179SLoGin if new_trigger_type != old_trigger_type {
555*2eab6dd7S曾俊 warn!("Irq {} uses trigger type: {old_trigger_type:?}, but requested trigger type: {new_trigger_type:?}.", irq.data());
556e2841179SLoGin }
557e2841179SLoGin }
558e2841179SLoGin
559e2841179SLoGin // 在队列末尾添加新的irqaction
560e2841179SLoGin desc_inner_guard.add_action(action.clone());
561e2841179SLoGin
562e2841179SLoGin // 检查我们是否曾经通过虚构的中断处理程序禁用过irq。重新启用它并再给它一次机会。
563e2841179SLoGin if irq_shared
564e2841179SLoGin && desc_inner_guard
565e2841179SLoGin .internal_state()
566e2841179SLoGin .contains(IrqDescState::IRQS_SPURIOUS_DISABLED)
567e2841179SLoGin {
568e2841179SLoGin desc_inner_guard
569e2841179SLoGin .internal_state_mut()
570e2841179SLoGin .remove(IrqDescState::IRQS_SPURIOUS_DISABLED);
571e2841179SLoGin self.do_enable_irq(desc.clone(), &mut desc_inner_guard).ok();
572e2841179SLoGin }
573e2841179SLoGin
574e2841179SLoGin drop(desc_inner_guard);
575e2841179SLoGin desc.chip_bus_sync_unlock();
576e2841179SLoGin drop(req_mutex_guard);
577e2841179SLoGin
578e2841179SLoGin drop(action_guard);
579e2841179SLoGin self.wake_up_and_wait_for_irq_thread_ready(&desc, Some(action.clone()));
580e2841179SLoGin self.wake_up_and_wait_for_irq_thread_ready(&desc, action.inner().secondary());
581e2841179SLoGin return Ok(());
582e2841179SLoGin }
583e2841179SLoGin
584e2841179SLoGin /// 唤醒中断线程并等待中断线程准备好
585e2841179SLoGin ///
586e2841179SLoGin /// ## 参数
587e2841179SLoGin ///
588e2841179SLoGin /// - desc: 中断描述符
589e2841179SLoGin /// - action: 要唤醒的中断处理函数
590e2841179SLoGin ///
591e2841179SLoGin /// ## 锁
592e2841179SLoGin ///
593e2841179SLoGin /// 进入当前函数时,`action`的锁需要被释放
wake_up_and_wait_for_irq_thread_ready( &self, desc: &Arc<IrqDesc>, action: Option<Arc<IrqAction>>, )594e2841179SLoGin fn wake_up_and_wait_for_irq_thread_ready(
595e2841179SLoGin &self,
596e2841179SLoGin desc: &Arc<IrqDesc>,
597e2841179SLoGin action: Option<Arc<IrqAction>>,
598e2841179SLoGin ) {
599e2841179SLoGin if action.is_none() {
600e2841179SLoGin return;
601e2841179SLoGin }
602e2841179SLoGin
603e2841179SLoGin let action = action.unwrap();
604e2841179SLoGin
605e2841179SLoGin let action_guard = action.inner();
606e2841179SLoGin if action_guard.thread().is_none() {
607e2841179SLoGin return;
608e2841179SLoGin }
609e2841179SLoGin
610e2841179SLoGin ProcessManager::wakeup(&action_guard.thread().unwrap()).ok();
611e2841179SLoGin drop(action_guard);
612e2841179SLoGin action
613e2841179SLoGin .thread_completion()
614e2841179SLoGin .wait_for_completion()
615e2841179SLoGin .map_err(|e| {
616*2eab6dd7S曾俊 warn!(
617e2841179SLoGin "Failed to wait for irq thread ready for {} (irq {:?}), error {:?}",
618e2841179SLoGin action.inner().name(),
619e2841179SLoGin desc.irq_data().irq(),
620e2841179SLoGin e
621e2841179SLoGin );
622e2841179SLoGin })
623e2841179SLoGin .ok();
624e2841179SLoGin }
625e2841179SLoGin
irq_activate_and_startup( &self, desc: &Arc<IrqDesc>, desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>, resend: bool, ) -> Result<(), SystemError>626338f6903SLoGin pub(super) fn irq_activate_and_startup(
627338f6903SLoGin &self,
628338f6903SLoGin desc: &Arc<IrqDesc>,
629338f6903SLoGin desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
630338f6903SLoGin resend: bool,
631338f6903SLoGin ) -> Result<(), SystemError> {
632*2eab6dd7S曾俊 debug!(
6330102d69fSLoGin "irq_activate_and_startup: irq: {}, name: {:?}",
6340102d69fSLoGin desc.irq().data(),
6350102d69fSLoGin desc_inner_guard.name()
6360102d69fSLoGin );
637338f6903SLoGin self.irq_activate(desc, desc_inner_guard)?;
638338f6903SLoGin self.irq_startup(desc, desc_inner_guard, resend, Self::IRQ_START_FORCE)
639338f6903SLoGin }
640338f6903SLoGin
irq_activate( &self, _desc: &Arc<IrqDesc>, desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>, ) -> Result<(), SystemError>641e2841179SLoGin pub(super) fn irq_activate(
642e2841179SLoGin &self,
643338f6903SLoGin _desc: &Arc<IrqDesc>,
644e2841179SLoGin desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
645e2841179SLoGin ) -> Result<(), SystemError> {
646e2841179SLoGin let irq_data = desc_inner_guard.irq_data();
647e2841179SLoGin
648e2841179SLoGin if !desc_inner_guard.common_data().status().affinity_managed() {
649e2841179SLoGin return irq_domain_manager().activate_irq(irq_data, false);
650e2841179SLoGin }
651e2841179SLoGin
652e2841179SLoGin return Ok(());
653e2841179SLoGin }
654e2841179SLoGin
655e2841179SLoGin /// 设置CPU亲和性并开启中断
irq_startup( &self, desc: &Arc<IrqDesc>, desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>, resend: bool, force: bool, ) -> Result<(), SystemError>656e2841179SLoGin pub(super) fn irq_startup(
657e2841179SLoGin &self,
658338f6903SLoGin desc: &Arc<IrqDesc>,
659e2841179SLoGin desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
660e2841179SLoGin resend: bool,
661e2841179SLoGin force: bool,
662e2841179SLoGin ) -> Result<(), SystemError> {
663*2eab6dd7S曾俊 debug!(
6640102d69fSLoGin "irq_startup: irq: {}, name: {:?}",
6650102d69fSLoGin desc_inner_guard.irq_data().irq().data(),
6660102d69fSLoGin desc_inner_guard.name()
6670102d69fSLoGin );
668e2841179SLoGin let mut ret = Ok(());
669e2841179SLoGin let irq_data = desc_inner_guard.irq_data().clone();
670e2841179SLoGin let affinity = desc_inner_guard.common_data().affinity();
671e2841179SLoGin desc_inner_guard.set_depth(0);
672e2841179SLoGin
673e2841179SLoGin if desc_inner_guard.common_data().status().started() {
674e2841179SLoGin self.irq_enable(desc_inner_guard);
675e2841179SLoGin } else {
676e2841179SLoGin match self.__irq_startup_managed(desc_inner_guard, &affinity, force) {
677e2841179SLoGin IrqStartupResult::Normal => {
678e2841179SLoGin if irq_data
679e2841179SLoGin .chip_info_read_irqsave()
680e2841179SLoGin .chip()
681e2841179SLoGin .flags()
682e2841179SLoGin .contains(IrqChipFlags::IRQCHIP_AFFINITY_PRE_STARTUP)
683e2841179SLoGin {
684338f6903SLoGin self.irq_setup_affinity(desc, desc_inner_guard).ok();
685e2841179SLoGin }
686e2841179SLoGin
687e2841179SLoGin ret = self.__irq_startup(desc_inner_guard);
688e2841179SLoGin
689e2841179SLoGin if !irq_data
690e2841179SLoGin .chip_info_read_irqsave()
691e2841179SLoGin .chip()
692e2841179SLoGin .flags()
693e2841179SLoGin .contains(IrqChipFlags::IRQCHIP_AFFINITY_PRE_STARTUP)
694e2841179SLoGin {
695338f6903SLoGin self.irq_setup_affinity(desc, desc_inner_guard).ok();
696e2841179SLoGin }
697e2841179SLoGin }
698e2841179SLoGin IrqStartupResult::Managed => {
699b5b571e0SLoGin self.irq_do_set_affinity(&irq_data, desc_inner_guard, &affinity, false)
700e2841179SLoGin .ok();
701e2841179SLoGin ret = self.__irq_startup(desc_inner_guard);
702e2841179SLoGin }
703e2841179SLoGin IrqStartupResult::Abort => {
704e2841179SLoGin desc_inner_guard
705e2841179SLoGin .common_data()
706e2841179SLoGin .insert_status(IrqStatus::IRQD_MANAGED_SHUTDOWN);
707e2841179SLoGin return Ok(());
708e2841179SLoGin }
709e2841179SLoGin }
710e2841179SLoGin }
711e2841179SLoGin
712e2841179SLoGin if resend {
713e2841179SLoGin if let Err(e) = self.irq_check_and_resend(desc_inner_guard, false) {
714*2eab6dd7S曾俊 error!(
715e2841179SLoGin "Failed to check and resend irq {}, error {:?}",
716e2841179SLoGin irq_data.irq().data(),
717e2841179SLoGin e
718e2841179SLoGin );
719e2841179SLoGin }
720e2841179SLoGin }
721e2841179SLoGin
722e2841179SLoGin return ret;
723e2841179SLoGin }
724e2841179SLoGin
irq_enable(&self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>)725e2841179SLoGin pub fn irq_enable(&self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>) {
726e2841179SLoGin let common_data = desc_inner_guard.common_data();
727e2841179SLoGin if !common_data.status().disabled() {
728e2841179SLoGin self.unmask_irq(desc_inner_guard);
729e2841179SLoGin } else {
730e2841179SLoGin common_data.clear_disabled();
731e2841179SLoGin
732e2841179SLoGin let chip = desc_inner_guard.irq_data().chip_info_read_irqsave().chip();
733e2841179SLoGin
734b5b571e0SLoGin if let Err(e) = chip.irq_enable(desc_inner_guard.irq_data()) {
735e2841179SLoGin if e == SystemError::ENOSYS {
736e2841179SLoGin self.unmask_irq(desc_inner_guard);
737e2841179SLoGin }
738*2eab6dd7S曾俊 error!(
739e2841179SLoGin "Failed to enable irq {} (name: {:?}), error {:?}",
740e2841179SLoGin desc_inner_guard.irq_data().irq().data(),
741e2841179SLoGin desc_inner_guard.name(),
742e2841179SLoGin e
743e2841179SLoGin );
744e2841179SLoGin } else {
745e2841179SLoGin common_data.clear_masked();
746e2841179SLoGin }
747e2841179SLoGin }
748e2841179SLoGin }
749e2841179SLoGin
750e2841179SLoGin /// 自动设置中断的CPU亲和性
751e2841179SLoGin ///
752e2841179SLoGin ///
753e2841179SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c#589
irq_setup_affinity( &self, _desc: &Arc<IrqDesc>, desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>, ) -> Result<(), SystemError>754e2841179SLoGin pub fn irq_setup_affinity(
755e2841179SLoGin &self,
756e2841179SLoGin _desc: &Arc<IrqDesc>,
757e2841179SLoGin desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
758e2841179SLoGin ) -> Result<(), SystemError> {
759e2841179SLoGin let common_data = desc_inner_guard.common_data();
760e2841179SLoGin if !desc_inner_guard.can_set_affinity() {
761e2841179SLoGin return Ok(());
762e2841179SLoGin }
763e2841179SLoGin
764e2841179SLoGin let mut to_set = IRQ_DEFAULT_AFFINITY.clone();
765e2841179SLoGin if common_data.status().affinity_managed()
766e2841179SLoGin || common_data.status().contains(IrqStatus::IRQD_AFFINITY_SET)
767e2841179SLoGin {
768e2841179SLoGin // FIXME: 要判断affinity跟已上线的CPU是否有交集
769e2841179SLoGin
770e2841179SLoGin let irq_aff = common_data.affinity();
771e2841179SLoGin if irq_aff.is_empty() {
772e2841179SLoGin common_data.clear_status(IrqStatus::IRQD_AFFINITY_SET);
773e2841179SLoGin } else {
774e2841179SLoGin to_set = irq_aff;
775e2841179SLoGin }
776e2841179SLoGin }
777e2841179SLoGin
778e2841179SLoGin // FIXME: 求to_set和在线CPU的交集
779e2841179SLoGin
780e2841179SLoGin return self.irq_do_set_affinity(
781e2841179SLoGin desc_inner_guard.irq_data(),
782b5b571e0SLoGin desc_inner_guard,
783e2841179SLoGin &to_set,
784e2841179SLoGin false,
785e2841179SLoGin );
786e2841179SLoGin }
787e2841179SLoGin
irq_set_affinity( &self, irq_data: &Arc<IrqData>, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>, cpumask: &CpuMask, ) -> Result<(), SystemError>7880102d69fSLoGin pub fn irq_set_affinity(
7890102d69fSLoGin &self,
7900102d69fSLoGin irq_data: &Arc<IrqData>,
7910102d69fSLoGin desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
7920102d69fSLoGin cpumask: &CpuMask,
7930102d69fSLoGin ) -> Result<(), SystemError> {
7940102d69fSLoGin return self.irq_do_set_affinity(irq_data, desc_inner_guard, cpumask, false);
7950102d69fSLoGin }
irq_do_set_affinity( &self, irq_data: &Arc<IrqData>, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>, cpumask: &CpuMask, force: bool, ) -> Result<(), SystemError>7960102d69fSLoGin fn irq_do_set_affinity(
797e2841179SLoGin &self,
798e2841179SLoGin irq_data: &Arc<IrqData>,
799e2841179SLoGin desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
800e2841179SLoGin cpumask: &CpuMask,
801e2841179SLoGin force: bool,
802e2841179SLoGin ) -> Result<(), SystemError> {
803e2841179SLoGin let chip = irq_data.chip_info_read_irqsave().chip();
804e2841179SLoGin if !chip.can_set_affinity() {
805e2841179SLoGin return Err(SystemError::EINVAL);
806e2841179SLoGin }
807e2841179SLoGin
808e2841179SLoGin // todo: 处理CPU中断隔离相关的逻辑
809e2841179SLoGin
810e2841179SLoGin let common_data = desc_inner_guard.common_data();
811b5b571e0SLoGin let r = if force || !cpumask.is_empty() {
812b5b571e0SLoGin chip.irq_set_affinity(irq_data, cpumask, force)
813e2841179SLoGin } else {
814e2841179SLoGin return Err(SystemError::EINVAL);
815b5b571e0SLoGin };
816e2841179SLoGin
817e2841179SLoGin let mut ret = Ok(());
818e2841179SLoGin if let Ok(rs) = r {
819e2841179SLoGin match rs {
820b5b571e0SLoGin IrqChipSetMaskResult::Success | IrqChipSetMaskResult::Done => {
821e2841179SLoGin common_data.set_affinity(cpumask.clone());
822e2841179SLoGin }
823b5b571e0SLoGin IrqChipSetMaskResult::NoChange => {
824e2841179SLoGin
825e2841179SLoGin // irq_validate_effective_affinity(data);
826e2841179SLoGin // irq_set_thread_affinity(desc);
827e2841179SLoGin }
828e2841179SLoGin }
829e2841179SLoGin } else {
830e2841179SLoGin ret = Err(r.unwrap_err());
831e2841179SLoGin }
832e2841179SLoGin
833e2841179SLoGin return ret;
834e2841179SLoGin }
835e2841179SLoGin
__irq_startup( &self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>, ) -> Result<(), SystemError>836e2841179SLoGin fn __irq_startup(
837e2841179SLoGin &self,
838e2841179SLoGin desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
839e2841179SLoGin ) -> Result<(), SystemError> {
840e2841179SLoGin let common_data = desc_inner_guard.common_data();
841e2841179SLoGin
842e2841179SLoGin if let Err(e) = desc_inner_guard
843e2841179SLoGin .irq_data()
844e2841179SLoGin .chip_info_read_irqsave()
845e2841179SLoGin .chip()
846e2841179SLoGin .irq_startup(desc_inner_guard.irq_data())
847e2841179SLoGin {
848e2841179SLoGin if e == SystemError::ENOSYS {
849e2841179SLoGin self.irq_enable(desc_inner_guard);
850e2841179SLoGin } else {
851e2841179SLoGin return Err(e);
852e2841179SLoGin }
853e2841179SLoGin } else {
854e2841179SLoGin common_data.clear_disabled();
855e2841179SLoGin common_data.clear_masked();
856e2841179SLoGin }
857e2841179SLoGin
858e2841179SLoGin common_data.set_started();
859e2841179SLoGin
860e2841179SLoGin return Ok(());
861e2841179SLoGin }
862e2841179SLoGin
__irq_startup_managed( &self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>, _affinity: &CpuMask, _force: bool, ) -> IrqStartupResult863e2841179SLoGin fn __irq_startup_managed(
864e2841179SLoGin &self,
865e2841179SLoGin desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
866e2841179SLoGin _affinity: &CpuMask,
867e2841179SLoGin _force: bool,
868e2841179SLoGin ) -> IrqStartupResult {
869e2841179SLoGin let irq_data = desc_inner_guard.irq_data();
870e2841179SLoGin let common_data = desc_inner_guard.common_data();
871e2841179SLoGin
872e2841179SLoGin if !common_data.status().affinity_managed() {
873e2841179SLoGin return IrqStartupResult::Normal;
874e2841179SLoGin }
875e2841179SLoGin
876e2841179SLoGin common_data.clear_managed_shutdown();
877e2841179SLoGin
878e2841179SLoGin /*
879e2841179SLoGin - 检查Affinity掩码是否包括所有的在线CPU。如果是,这意味着有代码试图在管理的中断上使用enable_irq(),
880e2841179SLoGin 这可能是非法的。在这种情况下,如果force不是真值,函数会返回IRQ_STARTUP_ABORT,表示中断处理应该被放弃。
881e2841179SLoGin - 如果Affinity掩码中没有任何在线的CPU,那么中断请求是不可用的,因为没有任何CPU可以处理它。
882e2841179SLoGin 在这种情况下,如果force不是真值,函数同样会返回IRQ_STARTUP_ABORT。
883e2841179SLoGin - 如果以上条件都不满足,尝试激活中断,并将其设置为管理模式。这是通过调用 `irq_domain_manager().activate_irq()` 函数来实现的。
884e2841179SLoGin 如果这个调用失败,表示有保留的资源无法访问,函数会返回IRQ_STARTUP_ABORT。
885e2841179SLoGin - 如果一切顺利,函数会返回IRQ_STARTUP_MANAGED,表示中断已经被成功管理并激活。
886e2841179SLoGin */
887e2841179SLoGin
888e2841179SLoGin // if (cpumask_any_and(aff, cpu_online_mask) >= nr_cpu_ids) {
889e2841179SLoGin // /*
890e2841179SLoGin // * Catch code which fiddles with enable_irq() on a managed
891e2841179SLoGin // * and potentially shutdown IRQ. Chained interrupt
892e2841179SLoGin // * installment or irq auto probing should not happen on
893e2841179SLoGin // * managed irqs either.
894e2841179SLoGin // */
895e2841179SLoGin // if (WARN_ON_ONCE(force))
896e2841179SLoGin // return IRQ_STARTUP_ABORT;
897e2841179SLoGin // /*
898e2841179SLoGin // * The interrupt was requested, but there is no online CPU
899e2841179SLoGin // * in it's affinity mask. Put it into managed shutdown
900e2841179SLoGin // * state and let the cpu hotplug mechanism start it up once
901e2841179SLoGin // * a CPU in the mask becomes available.
902e2841179SLoGin // */
903e2841179SLoGin // return IRQ_STARTUP_ABORT;
904e2841179SLoGin // }
905e2841179SLoGin
906e2841179SLoGin let r = irq_domain_manager().activate_irq(irq_data, false);
907e2841179SLoGin if r.is_err() {
908e2841179SLoGin return IrqStartupResult::Abort;
909e2841179SLoGin }
910e2841179SLoGin
911e2841179SLoGin return IrqStartupResult::Managed;
912e2841179SLoGin }
913e2841179SLoGin
do_enable_irq( &self, _desc: Arc<IrqDesc>, _desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>, ) -> Result<(), SystemError>914e2841179SLoGin pub fn do_enable_irq(
915e2841179SLoGin &self,
916e2841179SLoGin _desc: Arc<IrqDesc>,
917e2841179SLoGin _desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
918e2841179SLoGin ) -> Result<(), SystemError> {
919e2841179SLoGin // https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c?r=&mo=59252&fi=2138#776
920e2841179SLoGin todo!("do_enable_irq")
921e2841179SLoGin }
922e2841179SLoGin
923e2841179SLoGin #[inline(never)]
do_set_irq_trigger( &self, _desc: Arc<IrqDesc>, desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>, mut trigger_type: IrqLineStatus, ) -> Result<(), SystemError>924e2841179SLoGin pub fn do_set_irq_trigger(
925e2841179SLoGin &self,
926e2841179SLoGin _desc: Arc<IrqDesc>,
927e2841179SLoGin desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
928e2841179SLoGin mut trigger_type: IrqLineStatus,
929e2841179SLoGin ) -> Result<(), SystemError> {
930e2841179SLoGin let chip = desc_inner_guard.irq_data().chip_info_read_irqsave().chip();
931e2841179SLoGin let mut to_unmask = false;
932e2841179SLoGin
933e2841179SLoGin if !chip.can_set_flow_type() {
934*2eab6dd7S曾俊 // debug!(
935e2841179SLoGin // "No set_irq_type function for irq {}, chip {}",
936e2841179SLoGin // desc_inner_guard.irq_data().irq().data(),
937e2841179SLoGin // chip.name()
938e2841179SLoGin // );
939e2841179SLoGin return Ok(());
940e2841179SLoGin }
941e2841179SLoGin
942e2841179SLoGin if chip.flags().contains(IrqChipFlags::IRQCHIP_SET_TYPE_MASKED) {
943b5b571e0SLoGin if !desc_inner_guard.common_data().status().masked() {
944e2841179SLoGin self.mask_irq(desc_inner_guard.irq_data());
945e2841179SLoGin }
946b5b571e0SLoGin if !desc_inner_guard.common_data().status().disabled() {
947e2841179SLoGin to_unmask = true;
948e2841179SLoGin }
949e2841179SLoGin }
950e2841179SLoGin
951e2841179SLoGin trigger_type &= IrqLineStatus::IRQ_TYPE_SENSE_MASK;
952e2841179SLoGin
953e2841179SLoGin let r = chip.irq_set_type(desc_inner_guard.irq_data(), trigger_type);
954e2841179SLoGin let ret;
955e2841179SLoGin if let Ok(rs) = r {
956e2841179SLoGin match rs {
957b5b571e0SLoGin IrqChipSetMaskResult::Success | IrqChipSetMaskResult::Done => {
958e2841179SLoGin let common_data = desc_inner_guard.common_data();
959e2841179SLoGin common_data.clear_status(IrqStatus::IRQD_TRIGGER_MASK);
960e2841179SLoGin let mut irqstatus = IrqStatus::empty();
961e2841179SLoGin irqstatus.set_trigger_type(trigger_type);
962e2841179SLoGin common_data.insert_status(irqstatus);
963e2841179SLoGin }
964b5b571e0SLoGin IrqChipSetMaskResult::NoChange => {
965e2841179SLoGin let flags = desc_inner_guard.common_data().trigger_type();
966e2841179SLoGin desc_inner_guard.set_trigger_type(flags);
967e2841179SLoGin desc_inner_guard
968e2841179SLoGin .common_data()
969e2841179SLoGin .clear_status(IrqStatus::IRQD_LEVEL);
970e2841179SLoGin desc_inner_guard.clear_level();
971e2841179SLoGin
972b5b571e0SLoGin if !(flags & IrqLineStatus::IRQ_TYPE_LEVEL_MASK).is_empty() {
973e2841179SLoGin desc_inner_guard.set_level();
974e2841179SLoGin desc_inner_guard
975e2841179SLoGin .common_data()
976e2841179SLoGin .insert_status(IrqStatus::IRQD_LEVEL);
977e2841179SLoGin }
978e2841179SLoGin }
979e2841179SLoGin }
980e2841179SLoGin
981e2841179SLoGin ret = Ok(());
982e2841179SLoGin } else {
983*2eab6dd7S曾俊 error!(
984e2841179SLoGin "Failed to set irq {} trigger type to {:?} on irqchip {}, error {:?}",
985e2841179SLoGin desc_inner_guard.irq_data().irq().data(),
986e2841179SLoGin trigger_type,
987e2841179SLoGin chip.name(),
988e2841179SLoGin r
989e2841179SLoGin );
990e2841179SLoGin
991e2841179SLoGin ret = Err(r.unwrap_err());
992e2841179SLoGin }
993e2841179SLoGin
994e2841179SLoGin if to_unmask {
995e2841179SLoGin self.unmask_irq(desc_inner_guard);
996e2841179SLoGin }
997e2841179SLoGin return ret;
998e2841179SLoGin }
999e2841179SLoGin
irq_request_resources(&self, desc: Arc<IrqDesc>) -> Result<(), SystemError>1000e2841179SLoGin fn irq_request_resources(&self, desc: Arc<IrqDesc>) -> Result<(), SystemError> {
1001e2841179SLoGin let irq_data = desc.irq_data();
1002e2841179SLoGin let irq_chip = irq_data.chip_info_read_irqsave().chip();
1003e2841179SLoGin irq_chip.irq_request_resources(&irq_data)
1004e2841179SLoGin }
1005e2841179SLoGin
1006e2841179SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c?r=&mo=59252&fi=2138#1448
setup_irq_thread( &self, _irq: IrqNumber, _action: &InnerIrqAction, _secondary: bool, ) -> Result<(), SystemError>1007e2841179SLoGin fn setup_irq_thread(
1008e2841179SLoGin &self,
1009e2841179SLoGin _irq: IrqNumber,
1010e2841179SLoGin _action: &InnerIrqAction,
1011e2841179SLoGin _secondary: bool,
1012e2841179SLoGin ) -> Result<(), SystemError> {
1013e2841179SLoGin // if secondary {
1014e2841179SLoGin // KernelThreadMechanism::create(func, name)
1015e2841179SLoGin // }
1016e2841179SLoGin
1017e2841179SLoGin todo!("setup_irq_thread")
1018e2841179SLoGin }
1019e2841179SLoGin
setup_forced_threading(&self, _action: &mut InnerIrqAction) -> Result<(), SystemError>1020e2841179SLoGin fn setup_forced_threading(&self, _action: &mut InnerIrqAction) -> Result<(), SystemError> {
1021e2841179SLoGin // todo: 处理强制线程化的逻辑,参考linux的`irq_setup_forced_threading()`
1022e2841179SLoGin return Ok(());
1023e2841179SLoGin }
1024e2841179SLoGin
irq_clear_status_flags( &self, irq: IrqNumber, status: IrqLineStatus, ) -> Result<(), SystemError>1025e2841179SLoGin pub fn irq_clear_status_flags(
1026e2841179SLoGin &self,
1027e2841179SLoGin irq: IrqNumber,
1028e2841179SLoGin status: IrqLineStatus,
1029e2841179SLoGin ) -> Result<(), SystemError> {
1030e2841179SLoGin let desc = irq_desc_manager().lookup(irq).ok_or(SystemError::EINVAL)?;
1031e2841179SLoGin desc.modify_status(status, IrqLineStatus::empty());
1032e2841179SLoGin return Ok(());
1033e2841179SLoGin }
1034e2841179SLoGin
1035e2841179SLoGin /// 屏蔽中断
mask_irq(&self, irq_data: &Arc<IrqData>)1036e2841179SLoGin pub(super) fn mask_irq(&self, irq_data: &Arc<IrqData>) {
1037e2841179SLoGin if irq_data.common_data().status().masked() {
1038e2841179SLoGin return;
1039e2841179SLoGin }
1040e2841179SLoGin
1041e2841179SLoGin let chip = irq_data.chip_info_read_irqsave().chip();
1042e2841179SLoGin let r = chip.irq_mask(irq_data);
1043e2841179SLoGin
1044e2841179SLoGin if r.is_ok() {
1045e2841179SLoGin irq_data.common_data().set_masked();
1046e2841179SLoGin }
1047e2841179SLoGin }
1048e2841179SLoGin
1049e2841179SLoGin /// 解除屏蔽中断
unmask_irq(&self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>)1050e2841179SLoGin pub(super) fn unmask_irq(&self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>) {
1051b5b571e0SLoGin if !desc_inner_guard.common_data().status().masked() {
1052e2841179SLoGin return;
1053e2841179SLoGin }
1054e2841179SLoGin
1055e2841179SLoGin let r = desc_inner_guard
1056e2841179SLoGin .irq_data()
1057e2841179SLoGin .chip_info_read_irqsave()
1058e2841179SLoGin .chip()
1059b5b571e0SLoGin .irq_unmask(desc_inner_guard.irq_data());
1060e2841179SLoGin
1061e2841179SLoGin if let Err(e) = r {
1062e2841179SLoGin if e != SystemError::ENOSYS {
1063*2eab6dd7S曾俊 error!(
1064e2841179SLoGin "Failed to unmask irq {} on irqchip {}, error {:?}",
1065e2841179SLoGin desc_inner_guard.irq_data().irq().data(),
1066e2841179SLoGin desc_inner_guard
1067e2841179SLoGin .irq_data()
1068e2841179SLoGin .chip_info_read_irqsave()
1069e2841179SLoGin .chip()
1070e2841179SLoGin .name(),
1071e2841179SLoGin e
1072e2841179SLoGin );
1073e2841179SLoGin }
1074e2841179SLoGin } else {
1075e2841179SLoGin desc_inner_guard
1076e2841179SLoGin .common_data()
1077e2841179SLoGin .clear_status(IrqStatus::IRQD_IRQ_MASKED);
1078e2841179SLoGin }
1079e2841179SLoGin }
1080e2841179SLoGin
1081e2841179SLoGin /// 释放使用request_irq分配的中断
1082e2841179SLoGin ///
1083e2841179SLoGin /// ## 参数
1084e2841179SLoGin ///
1085e2841179SLoGin /// - irq: 要释放的中断线
1086e2841179SLoGin /// - dev_id: 要释放的设备身份
1087e2841179SLoGin ///
1088e2841179SLoGin /// ## 返回
1089e2841179SLoGin ///
1090e2841179SLoGin /// 返回传递给request_irq的devname参数
1091e2841179SLoGin ///
1092e2841179SLoGin /// ## 说明
1093e2841179SLoGin ///
1094e2841179SLoGin /// 移除一个中断处理程序。处理程序被移除,如果该中断线不再被任何驱动程序使用,则会被禁用。
1095e2841179SLoGin ///
1096e2841179SLoGin /// 在共享IRQ的情况下,调用者必须确保在调用此功能之前,它在所驱动的卡上禁用了中断。
1097e2841179SLoGin ///
1098e2841179SLoGin /// ## 注意
1099e2841179SLoGin ///
1100e2841179SLoGin /// 此函数不可以在中断上下文中调用。
11010102d69fSLoGin ///
11020102d69fSLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/irq/manage.c#2026
free_irq(&self, _irq: IrqNumber, _dev_id: Option<Arc<DeviceId>>)1103e2841179SLoGin pub fn free_irq(&self, _irq: IrqNumber, _dev_id: Option<Arc<DeviceId>>) {
1104*2eab6dd7S曾俊 warn!("Unimplemented free_irq");
1105e2841179SLoGin }
1106e2841179SLoGin }
1107e2841179SLoGin
1108e2841179SLoGin enum IrqStartupResult {
1109e2841179SLoGin Normal,
1110e2841179SLoGin Managed,
1111e2841179SLoGin Abort,
1112e2841179SLoGin }
1113e2841179SLoGin /// 默认的初级中断处理函数
1114e2841179SLoGin ///
1115e2841179SLoGin /// 该处理函数仅仅返回`WakeThread`,即唤醒中断线程
1116e2841179SLoGin #[derive(Debug)]
1117e2841179SLoGin struct DefaultPrimaryIrqHandler;
1118e2841179SLoGin
1119e2841179SLoGin impl IrqHandler for DefaultPrimaryIrqHandler {
handle( &self, _irq: IrqNumber, _static_data: Option<&dyn IrqHandlerData>, _dynamic_data: Option<Arc<dyn IrqHandlerData>>, ) -> Result<IrqReturn, SystemError>1120e2841179SLoGin fn handle(
1121e2841179SLoGin &self,
1122e2841179SLoGin _irq: IrqNumber,
1123e2841179SLoGin _static_data: Option<&dyn IrqHandlerData>,
1124e2841179SLoGin _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
1125e2841179SLoGin ) -> Result<IrqReturn, SystemError> {
1126e2841179SLoGin return Ok(IrqReturn::WakeThread);
1127e2841179SLoGin }
1128e2841179SLoGin }
1129e2841179SLoGin
1130e2841179SLoGin /// Primary handler for nested threaded interrupts.
1131e2841179SLoGin /// Should never be called.
1132e2841179SLoGin #[derive(Debug)]
1133e2841179SLoGin struct IrqNestedPrimaryHandler;
1134e2841179SLoGin
1135e2841179SLoGin impl IrqHandler for IrqNestedPrimaryHandler {
handle( &self, irq: IrqNumber, _static_data: Option<&dyn IrqHandlerData>, _dynamic_data: Option<Arc<dyn IrqHandlerData>>, ) -> Result<IrqReturn, SystemError>1136e2841179SLoGin fn handle(
1137e2841179SLoGin &self,
1138e2841179SLoGin irq: IrqNumber,
1139e2841179SLoGin _static_data: Option<&dyn IrqHandlerData>,
1140e2841179SLoGin _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
1141e2841179SLoGin ) -> Result<IrqReturn, SystemError> {
1142*2eab6dd7S曾俊 warn!("Primary handler called for nested irq {}", irq.data());
1143e2841179SLoGin return Ok(IrqReturn::NotHandled);
1144e2841179SLoGin }
1145e2841179SLoGin }
1146