1338f6903SLoGin use core::{any::Any, fmt::Debug, intrinsics::unlikely};
2ce5850adSLoGin
3ce5850adSLoGin use alloc::{
4338f6903SLoGin string::{String, ToString},
5ce5850adSLoGin sync::{Arc, Weak},
6ce5850adSLoGin vec::Vec,
7ce5850adSLoGin };
82eab6dd7S曾俊 use log::warn;
9ce5850adSLoGin use system_error::SystemError;
10ce5850adSLoGin
11e2841179SLoGin use crate::{
12338f6903SLoGin exception::{
13338f6903SLoGin dummychip::no_irq_chip,
14338f6903SLoGin handle::{bad_irq_handler, mask_ack_irq},
15338f6903SLoGin irqdata::IrqStatus,
16338f6903SLoGin irqdesc::irq_desc_manager,
17338f6903SLoGin manage::irq_manager,
18338f6903SLoGin },
19338f6903SLoGin libs::{
20338f6903SLoGin cpumask::CpuMask,
21338f6903SLoGin once::Once,
22338f6903SLoGin spinlock::{SpinLock, SpinLockGuard},
23338f6903SLoGin },
24e2841179SLoGin mm::VirtAddr,
25338f6903SLoGin smp::cpu::ProcessorId,
26e2841179SLoGin };
27ce5850adSLoGin
28ce5850adSLoGin use super::{
29338f6903SLoGin irqdata::{IrqData, IrqHandlerData, IrqLineStatus},
30338f6903SLoGin irqdesc::{InnerIrqDesc, IrqAction, IrqDesc, IrqFlowHandler, IrqHandler, IrqReturn},
31ce5850adSLoGin irqdomain::IrqDomain,
32e2841179SLoGin manage::IrqManager,
33ce5850adSLoGin msi::MsiMsg,
34338f6903SLoGin IrqNumber,
35ce5850adSLoGin };
36ce5850adSLoGin
37ce5850adSLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h#506
38*bd70d2d1SLoGin #[allow(dead_code)]
39ce5850adSLoGin pub trait IrqChip: Sync + Send + Any + Debug {
name(&self) -> &'static str40ce5850adSLoGin fn name(&self) -> &'static str;
41ce5850adSLoGin /// start up the interrupt (defaults to ->enable if ENOSYS)
irq_startup(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError>420102d69fSLoGin fn irq_startup(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
43ce5850adSLoGin Err(SystemError::ENOSYS)
44ce5850adSLoGin }
45ce5850adSLoGin
46ce5850adSLoGin /// shut down the interrupt (defaults to ->disable if ENOSYS)
irq_shutdown(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError>470102d69fSLoGin fn irq_shutdown(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
48ce5850adSLoGin Err(SystemError::ENOSYS)
49ce5850adSLoGin }
50ce5850adSLoGin
51ce5850adSLoGin /// enable the interrupt
52ce5850adSLoGin ///
53ce5850adSLoGin /// (defaults to ->unmask if ENOSYS)
irq_enable(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError>540102d69fSLoGin fn irq_enable(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
55ce5850adSLoGin Err(SystemError::ENOSYS)
56ce5850adSLoGin }
57ce5850adSLoGin
58ce5850adSLoGin /// disable the interrupt
irq_disable(&self, irq_data: &Arc<IrqData>)590102d69fSLoGin fn irq_disable(&self, irq_data: &Arc<IrqData>);
60ce5850adSLoGin
61ce5850adSLoGin /// start of a new interrupt
irq_ack(&self, irq_data: &Arc<IrqData>)620102d69fSLoGin fn irq_ack(&self, irq_data: &Arc<IrqData>);
63ce5850adSLoGin
64ce5850adSLoGin /// mask an interrupt source
65e2841179SLoGin ///
66e2841179SLoGin /// 用于屏蔽中断
67e2841179SLoGin ///
68338f6903SLoGin /// 如果返回ENOSYS,则表明irq_mask()不支持. 那么中断机制代码将调用irq_disable()。
69e2841179SLoGin ///
70e2841179SLoGin /// 如果返回错误,那么中断的屏蔽状态将不会改变。
irq_mask(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError>710102d69fSLoGin fn irq_mask(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
72e2841179SLoGin Err(SystemError::ENOSYS)
73e2841179SLoGin }
74e2841179SLoGin
75e2841179SLoGin /// 指示当前芯片是否实现了`irq_mask_ack`函数
can_mask_ack(&self) -> bool76e2841179SLoGin fn can_mask_ack(&self) -> bool;
77e2841179SLoGin
78ce5850adSLoGin /// ack and mask an interrupt source
irq_mask_ack(&self, _irq_data: &Arc<IrqData>)790102d69fSLoGin fn irq_mask_ack(&self, _irq_data: &Arc<IrqData>) {}
80e2841179SLoGin
81ce5850adSLoGin /// unmask an interrupt source
82e2841179SLoGin ///
83e2841179SLoGin /// 用于取消屏蔽中断
84e2841179SLoGin ///
85e2841179SLoGin /// 如果返回ENOSYS,则表明irq_unmask()不支持.
irq_unmask(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError>860102d69fSLoGin fn irq_unmask(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
87e2841179SLoGin Err(SystemError::ENOSYS)
88e2841179SLoGin }
89ce5850adSLoGin /// end of interrupt
irq_eoi(&self, _irq_data: &Arc<IrqData>)900102d69fSLoGin fn irq_eoi(&self, _irq_data: &Arc<IrqData>) {}
91ce5850adSLoGin
92e2841179SLoGin /// 指示当前芯片是否可以设置中断亲和性。
can_set_affinity(&self) -> bool93e2841179SLoGin fn can_set_affinity(&self) -> bool;
94e2841179SLoGin
95e2841179SLoGin /// 在SMP机器上设置CPU亲和性。
96e2841179SLoGin ///
97e2841179SLoGin /// 如果force参数为真,它告诉驱动程序无条件地应用亲和性设置。
98e2841179SLoGin /// 不需要对提供的亲和性掩码进行完整性检查。这用于CPU热插拔,其中目标CPU尚未在cpu_online_mask中设置。
irq_set_affinity( &self, _irq_data: &Arc<IrqData>, _cpu: &CpuMask, _force: bool, ) -> Result<IrqChipSetMaskResult, SystemError>99e2841179SLoGin fn irq_set_affinity(
100e2841179SLoGin &self,
1010102d69fSLoGin _irq_data: &Arc<IrqData>,
102e2841179SLoGin _cpu: &CpuMask,
103e2841179SLoGin _force: bool,
104e2841179SLoGin ) -> Result<IrqChipSetMaskResult, SystemError> {
105e2841179SLoGin Err(SystemError::ENOSYS)
106e2841179SLoGin }
107ce5850adSLoGin
108ce5850adSLoGin /// retrigger an IRQ to the CPU
retrigger(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError>1090102d69fSLoGin fn retrigger(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
110e2841179SLoGin Err(SystemError::ENOSYS)
111e2841179SLoGin }
112e2841179SLoGin
113e2841179SLoGin /// 指示当前芯片是否可以设置中断流类型。
114e2841179SLoGin ///
115e2841179SLoGin /// 如果返回true,则可以调用irq_set_type()。
can_set_flow_type(&self) -> bool116e2841179SLoGin fn can_set_flow_type(&self) -> bool;
117ce5850adSLoGin
118ce5850adSLoGin /// set the flow type of an interrupt
119ce5850adSLoGin ///
120ce5850adSLoGin /// flow_type: the flow type to set
121ce5850adSLoGin ///
irq_set_type( &self, _irq_data: &Arc<IrqData>, _flow_type: IrqLineStatus, ) -> Result<IrqChipSetMaskResult, SystemError>122ce5850adSLoGin fn irq_set_type(
123ce5850adSLoGin &self,
1240102d69fSLoGin _irq_data: &Arc<IrqData>,
125ce5850adSLoGin _flow_type: IrqLineStatus,
126e2841179SLoGin ) -> Result<IrqChipSetMaskResult, SystemError> {
127ce5850adSLoGin Err(SystemError::ENOSYS)
128ce5850adSLoGin }
129ce5850adSLoGin
130ce5850adSLoGin /// enable/disable power management wake-on of an interrupt
131*bd70d2d1SLoGin #[allow(dead_code)]
irq_set_wake(&self, _irq_data: &Arc<IrqData>, _on: bool) -> Result<(), SystemError>1320102d69fSLoGin fn irq_set_wake(&self, _irq_data: &Arc<IrqData>, _on: bool) -> Result<(), SystemError> {
133ce5850adSLoGin Err(SystemError::ENOSYS)
134ce5850adSLoGin }
135ce5850adSLoGin
136ce5850adSLoGin /// function to lock access to slow bus (i2c) chips
irq_bus_lock(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError>1370102d69fSLoGin fn irq_bus_lock(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
138ce5850adSLoGin Ok(())
139ce5850adSLoGin }
140ce5850adSLoGin
141ce5850adSLoGin /// function to sync and unlock slow bus (i2c) chips
irq_bus_sync_unlock(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError>1420102d69fSLoGin fn irq_bus_sync_unlock(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
143ce5850adSLoGin Ok(())
144ce5850adSLoGin }
145ce5850adSLoGin
146ce5850adSLoGin /// function called from core code on suspend once per
147ce5850adSLoGin /// chip, when one or more interrupts are installed
irq_suspend(&self, _irq_data: &Arc<IrqData>)1480102d69fSLoGin fn irq_suspend(&self, _irq_data: &Arc<IrqData>) {}
149ce5850adSLoGin
150ce5850adSLoGin /// function called from core code on resume once per chip,
151ce5850adSLoGin /// when one ore more interrupts are installed
irq_resume(&self, _irq_data: &Arc<IrqData>)1520102d69fSLoGin fn irq_resume(&self, _irq_data: &Arc<IrqData>) {}
153ce5850adSLoGin
154ce5850adSLoGin /// function called from core code on shutdown once per chip
irq_pm_shutdown(&self, _irq_data: &Arc<IrqData>)1550102d69fSLoGin fn irq_pm_shutdown(&self, _irq_data: &Arc<IrqData>) {}
156ce5850adSLoGin
157ce5850adSLoGin /// Optional function to set irq_data.mask for special cases
irq_calc_mask(&self, _irq_data: &Arc<IrqData>)1580102d69fSLoGin fn irq_calc_mask(&self, _irq_data: &Arc<IrqData>) {}
159ce5850adSLoGin
160ce5850adSLoGin // todo: print chip
161ce5850adSLoGin
162ce5850adSLoGin /// optional to request resources before calling
163ce5850adSLoGin /// any other callback related to this irq
irq_request_resources(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError>1640102d69fSLoGin fn irq_request_resources(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
165ce5850adSLoGin Ok(())
166ce5850adSLoGin }
167ce5850adSLoGin
168ce5850adSLoGin /// optional to release resources acquired with
169ce5850adSLoGin /// irq_request_resources
irq_release_resources(&self, _irq_data: &Arc<IrqData>)1700102d69fSLoGin fn irq_release_resources(&self, _irq_data: &Arc<IrqData>) {}
171ce5850adSLoGin
172ce5850adSLoGin /// optional to compose message content for MSI
173e2841179SLoGin ///
174e2841179SLoGin /// 组装MSI消息并返回到msg中
irq_compose_msi_msg(&self, _irq_data: &Arc<IrqData>, _msg: &mut MsiMsg)1750102d69fSLoGin fn irq_compose_msi_msg(&self, _irq_data: &Arc<IrqData>, _msg: &mut MsiMsg) {}
176ce5850adSLoGin
177ce5850adSLoGin /// optional to write message content for MSI
irq_write_msi_msg(&self, _irq_data: &Arc<IrqData>, _msg: &MsiMsg)1780102d69fSLoGin fn irq_write_msi_msg(&self, _irq_data: &Arc<IrqData>, _msg: &MsiMsg) {}
179ce5850adSLoGin
180ce5850adSLoGin /// return the internal state of an interrupt
irqchip_state( &self, _irq_data: &Arc<IrqData>, _which: IrqChipState, ) -> Result<bool, SystemError>181ce5850adSLoGin fn irqchip_state(
182ce5850adSLoGin &self,
1830102d69fSLoGin _irq_data: &Arc<IrqData>,
184ce5850adSLoGin _which: IrqChipState,
185ce5850adSLoGin ) -> Result<bool, SystemError> {
186ce5850adSLoGin Err(SystemError::ENOSYS)
187ce5850adSLoGin }
188ce5850adSLoGin
189ce5850adSLoGin /// set the internal state of an interrupt
set_irqchip_state( &self, _irq_data: &Arc<IrqData>, _which: IrqChipState, _state: bool, ) -> Result<(), SystemError>190ce5850adSLoGin fn set_irqchip_state(
191ce5850adSLoGin &self,
1920102d69fSLoGin _irq_data: &Arc<IrqData>,
193ce5850adSLoGin _which: IrqChipState,
194ce5850adSLoGin _state: bool,
195ce5850adSLoGin ) -> Result<(), SystemError> {
196ce5850adSLoGin Err(SystemError::ENOSYS)
197ce5850adSLoGin }
198ce5850adSLoGin
199ce5850adSLoGin // todo: set vcpu affinity
200ce5850adSLoGin
201ce5850adSLoGin /// send a single IPI to destination cpus
send_single_ipi(&self, _irq_data: &Arc<IrqData>, _cpu: u32)2020102d69fSLoGin fn send_single_ipi(&self, _irq_data: &Arc<IrqData>, _cpu: u32) {}
203ce5850adSLoGin
204ce5850adSLoGin // todo: send ipi with cpu mask
205ce5850adSLoGin
206ce5850adSLoGin /// function called from core code before enabling an NMI
irq_nmi_setup(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError>2070102d69fSLoGin fn irq_nmi_setup(&self, _irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
208ce5850adSLoGin Err(SystemError::ENOSYS)
209ce5850adSLoGin }
210ce5850adSLoGin
211ce5850adSLoGin /// function called from core code after disabling an NMI
irq_nmi_teardown(&self, _irq_data: &Arc<IrqData>)2120102d69fSLoGin fn irq_nmi_teardown(&self, _irq_data: &Arc<IrqData>) {}
2133bc96fa4SLoGin
flags(&self) -> IrqChipFlags2143bc96fa4SLoGin fn flags(&self) -> IrqChipFlags;
215ce5850adSLoGin }
216ce5850adSLoGin
217ce5850adSLoGin #[allow(dead_code)]
218ce5850adSLoGin #[derive(Debug, Clone, Copy)]
219ce5850adSLoGin pub enum IrqChipState {
220ce5850adSLoGin /// Is the interrupt pending?
221ce5850adSLoGin Pending,
222ce5850adSLoGin /// Is the interrupt in progress?
223ce5850adSLoGin Active,
224ce5850adSLoGin /// Is the interrupt masked?
225ce5850adSLoGin Masked,
226ce5850adSLoGin /// Is Irq line high?
227ce5850adSLoGin LineLevel,
228ce5850adSLoGin }
229ce5850adSLoGin
230e2841179SLoGin /// 中断芯片的数据(per-irq的)
231e2841179SLoGin pub trait IrqChipData: Sync + Send + Any + Debug {
as_any_ref(&self) -> &dyn Any232e2841179SLoGin fn as_any_ref(&self) -> &dyn Any;
233e2841179SLoGin }
234ce5850adSLoGin
235ce5850adSLoGin bitflags! {
236ce5850adSLoGin /// 定义 IrqGcFlags 位标志
237ce5850adSLoGin pub struct IrqGcFlags: u32 {
238ce5850adSLoGin /// 通过读取mask reg来初始化mask_cache
239ce5850adSLoGin const IRQ_GC_INIT_MASK_CACHE = 1 << 0;
240ce5850adSLoGin /// 对于需要在父irq上调用irq_set_wake()的irq芯片, 将irqs的锁类设置为嵌套。Usually GPIO implementations
241ce5850adSLoGin const IRQ_GC_INIT_NESTED_LOCK = 1 << 1;
242ce5850adSLoGin /// Mask cache是芯片类型私有的
243ce5850adSLoGin const IRQ_GC_MASK_CACHE_PER_TYPE = 1 << 2;
244ce5850adSLoGin /// 不计算irqData->mask
245ce5850adSLoGin const IRQ_GC_NO_MASK = 1 << 3;
246ce5850adSLoGin /// 使用大端字节序的寄存器访问(默认:小端LE)
247ce5850adSLoGin const IRQ_GC_BE_IO = 1 << 4;
248ce5850adSLoGin }
249ce5850adSLoGin }
250ce5850adSLoGin
251ce5850adSLoGin #[allow(dead_code)]
252ce5850adSLoGin #[derive(Debug)]
253ce5850adSLoGin pub struct IrqChipGeneric {
254ce5850adSLoGin inner: SpinLock<InnerIrqChipGeneric>,
255ce5850adSLoGin }
256ce5850adSLoGin
257ce5850adSLoGin #[allow(dead_code)]
258ce5850adSLoGin #[derive(Debug)]
259ce5850adSLoGin struct InnerIrqChipGeneric {
260ce5850adSLoGin /// Register base address
261ce5850adSLoGin reg_base: VirtAddr,
262ce5850adSLoGin ops: &'static dyn IrqChipGenericOps,
263ce5850adSLoGin /// Interrupt base num for this chip
264ce5850adSLoGin irq_base: u32,
265ce5850adSLoGin /// Number of interrupts handled by this chip
266ce5850adSLoGin irq_cnt: u32,
267ce5850adSLoGin /// Cached mask register shared between all chip types
268ce5850adSLoGin mask_cache: u32,
269ce5850adSLoGin /// Cached type register
270ce5850adSLoGin type_cache: u32,
271ce5850adSLoGin /// Cached polarity register
272ce5850adSLoGin polarity_cache: u32,
273ce5850adSLoGin /// Interrupt can wakeup from suspend
274ce5850adSLoGin wake_enabled: bool,
275ce5850adSLoGin /// Interrupt is marked as an wakeup from suspend source
276ce5850adSLoGin wake_active: bool,
277ce5850adSLoGin /// Number of available irq_chip_type instances (usually 1)
278ce5850adSLoGin num_chip_type: u32,
279ce5850adSLoGin private_data: Option<Arc<dyn IrqChipGenericPrivateData>>,
280ce5850adSLoGin installed: u64,
281ce5850adSLoGin unused: u64,
282ce5850adSLoGin domain: Weak<IrqDomain>,
283ce5850adSLoGin chip_types: Vec<IrqChipType>,
284ce5850adSLoGin }
285ce5850adSLoGin
286*bd70d2d1SLoGin #[allow(dead_code)]
2873bc96fa4SLoGin pub trait IrqChipGenericOps: Debug + Send + Sync {
288ce5850adSLoGin /// Alternate I/O accessor (defaults to readl if NULL)
reg_readl(&self, addr: VirtAddr) -> u32289ce5850adSLoGin unsafe fn reg_readl(&self, addr: VirtAddr) -> u32;
290ce5850adSLoGin
291ce5850adSLoGin /// Alternate I/O accessor (defaults to writel if NULL)
reg_writel(&self, addr: VirtAddr, val: u32)292ce5850adSLoGin unsafe fn reg_writel(&self, addr: VirtAddr, val: u32);
293ce5850adSLoGin
294ce5850adSLoGin /// Function called from core code on suspend once per
295ce5850adSLoGin /// chip; can be useful instead of irq_chip::suspend to
296ce5850adSLoGin /// handle chip details even when no interrupts are in use
suspend(&self, gc: &Arc<IrqChipGeneric>)297ce5850adSLoGin fn suspend(&self, gc: &Arc<IrqChipGeneric>);
298ce5850adSLoGin /// Function called from core code on resume once per chip;
299ce5850adSLoGin /// can be useful instead of irq_chip::resume to handle chip
300ce5850adSLoGin /// details even when no interrupts are in use
resume(&self, gc: &Arc<IrqChipGeneric>)301ce5850adSLoGin fn resume(&self, gc: &Arc<IrqChipGeneric>);
302ce5850adSLoGin }
303ce5850adSLoGin
304ce5850adSLoGin pub trait IrqChipGenericPrivateData: Sync + Send + Any + Debug {}
305ce5850adSLoGin
306ce5850adSLoGin #[derive(Debug)]
307ce5850adSLoGin pub struct IrqChipType {
308ce5850adSLoGin // todo https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h#1024
309ce5850adSLoGin }
3103bc96fa4SLoGin
311e2841179SLoGin #[allow(dead_code)]
312e2841179SLoGin #[derive(Debug)]
313e2841179SLoGin pub enum IrqChipSetMaskResult {
314e2841179SLoGin /// core updates mask ok.
315b5b571e0SLoGin Success,
316e2841179SLoGin /// core updates mask ok. No change.
317b5b571e0SLoGin NoChange,
318e2841179SLoGin /// core updates mask ok. Done.(same as SetMaskOk)
319e2841179SLoGin ///
320e2841179SLoGin /// 支持堆叠irq芯片的特殊代码, 表示跳过所有子irq芯片。
321b5b571e0SLoGin Done,
322e2841179SLoGin }
323e2841179SLoGin
3243bc96fa4SLoGin bitflags! {
3253bc96fa4SLoGin /// IrqChip specific flags
3263bc96fa4SLoGin pub struct IrqChipFlags: u32 {
327e2841179SLoGin /// 在调用chip.irq_set_type()之前屏蔽中断
3283bc96fa4SLoGin const IRQCHIP_SET_TYPE_MASKED = 1 << 0;
3293bc96fa4SLoGin /// 只有在irq被处理时才发出irq_eoi()
3303bc96fa4SLoGin const IRQCHIP_EOI_IF_HANDLED = 1 << 1;
3313bc96fa4SLoGin /// 在挂起路径中屏蔽非唤醒irq
3323bc96fa4SLoGin const IRQCHIP_MASK_ON_SUSPEND = 1 << 2;
3333bc96fa4SLoGin /// 只有在irq启用时才调用irq_on/off_line回调
3343bc96fa4SLoGin const IRQCHIP_ONOFFLINE_ENABLED = 1 << 3;
3353bc96fa4SLoGin /// 跳过chip.irq_set_wake(),对于这个irq芯片
3363bc96fa4SLoGin const IRQCHIP_SKIP_SET_WAKE = 1 << 4;
3373bc96fa4SLoGin /// 单次触发不需要屏蔽/取消屏蔽
3383bc96fa4SLoGin const IRQCHIP_ONESHOT_SAFE = 1 << 5;
3393bc96fa4SLoGin /// 芯片在线程模式下需要在取消屏蔽时eoi()
3403bc96fa4SLoGin const IRQCHIP_EOI_THREADED = 1 << 6;
3413bc96fa4SLoGin /// 芯片可以为Level MSIs提供两个门铃
3423bc96fa4SLoGin const IRQCHIP_SUPPORTS_LEVEL_MSI = 1 << 7;
3433bc96fa4SLoGin /// 芯片可以传递NMIs,仅适用于根irqchips
3443bc96fa4SLoGin const IRQCHIP_SUPPORTS_NMI = 1 << 8;
3453bc96fa4SLoGin /// 在挂起路径中,如果它们处于禁用状态,则调用__enable_irq()/__disable_irq()以唤醒irq
3463bc96fa4SLoGin const IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND = 1 << 9;
3473bc96fa4SLoGin /// 在启动前更新默认亲和性
3483bc96fa4SLoGin const IRQCHIP_AFFINITY_PRE_STARTUP = 1 << 10;
3493bc96fa4SLoGin /// 不要在这个芯片中改变任何东西
3503bc96fa4SLoGin const IRQCHIP_IMMUTABLE = 1 << 11;
3513bc96fa4SLoGin }
3523bc96fa4SLoGin }
353e2841179SLoGin
354e2841179SLoGin impl IrqManager {
355e2841179SLoGin /// Acknowledge the parent interrupt
356e2841179SLoGin #[allow(dead_code)]
irq_chip_ack_parent(&self, irq_data: &Arc<IrqData>)357e2841179SLoGin pub fn irq_chip_ack_parent(&self, irq_data: &Arc<IrqData>) {
358b5b571e0SLoGin let parent_data = irq_data.parent_data().and_then(|p| p.upgrade());
359e2841179SLoGin
360e2841179SLoGin if let Some(parent_data) = parent_data {
361e2841179SLoGin let parent_chip = parent_data.chip_info_read_irqsave().chip();
362e2841179SLoGin parent_chip.irq_ack(&parent_data);
363e2841179SLoGin }
364e2841179SLoGin }
365e2841179SLoGin
366e2841179SLoGin /// 在硬件中重新触发中断
367e2841179SLoGin ///
368e2841179SLoGin /// 遍历中断域的层次结构,并检查是否存在一个硬件重新触发函数。如果存在则调用它
irq_chip_retrigger_hierarchy(&self, irq_data: &Arc<IrqData>) -> Result<(), SystemError>369e2841179SLoGin pub fn irq_chip_retrigger_hierarchy(&self, irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
370e2841179SLoGin let mut data: Option<Arc<IrqData>> = Some(irq_data.clone());
371b5b571e0SLoGin while let Some(d) = data {
372e2841179SLoGin if let Err(e) = d.chip_info_read_irqsave().chip().retrigger(&d) {
373e2841179SLoGin if e == SystemError::ENOSYS {
374b5b571e0SLoGin data = d.parent_data().and_then(|p| p.upgrade());
375e2841179SLoGin } else {
376e2841179SLoGin return Err(e);
377e2841179SLoGin }
378e2841179SLoGin } else {
379e2841179SLoGin return Ok(());
380e2841179SLoGin }
381e2841179SLoGin }
382e2841179SLoGin
383e2841179SLoGin return Ok(());
384e2841179SLoGin }
385338f6903SLoGin
__irq_set_handler( &self, irq: IrqNumber, handler: &'static dyn IrqFlowHandler, is_chained: bool, name: Option<String>, )386338f6903SLoGin pub(super) fn __irq_set_handler(
387338f6903SLoGin &self,
388338f6903SLoGin irq: IrqNumber,
389338f6903SLoGin handler: &'static dyn IrqFlowHandler,
390338f6903SLoGin is_chained: bool,
391338f6903SLoGin name: Option<String>,
392338f6903SLoGin ) {
393338f6903SLoGin let r = irq_desc_manager().lookup_and_lock_bus(irq, false, false);
394338f6903SLoGin if r.is_none() {
395338f6903SLoGin return;
396338f6903SLoGin }
397338f6903SLoGin
398338f6903SLoGin let irq_desc = r.unwrap();
399338f6903SLoGin
400338f6903SLoGin let mut desc_inner = irq_desc.inner();
401338f6903SLoGin self.__irq_do_set_handler(&irq_desc, &mut desc_inner, Some(handler), is_chained, name);
402338f6903SLoGin
403338f6903SLoGin drop(desc_inner);
404338f6903SLoGin irq_desc.chip_bus_sync_unlock();
405338f6903SLoGin }
406338f6903SLoGin
__irq_do_set_handler( &self, desc: &Arc<IrqDesc>, desc_inner: &mut SpinLockGuard<'_, InnerIrqDesc>, mut handler: Option<&'static dyn IrqFlowHandler>, is_chained: bool, name: Option<String>, )407338f6903SLoGin fn __irq_do_set_handler(
408338f6903SLoGin &self,
409338f6903SLoGin desc: &Arc<IrqDesc>,
410338f6903SLoGin desc_inner: &mut SpinLockGuard<'_, InnerIrqDesc>,
411338f6903SLoGin mut handler: Option<&'static dyn IrqFlowHandler>,
412338f6903SLoGin is_chained: bool,
413338f6903SLoGin name: Option<String>,
414338f6903SLoGin ) {
415338f6903SLoGin if handler.is_none() {
416338f6903SLoGin handler = Some(bad_irq_handler());
417338f6903SLoGin } else {
418338f6903SLoGin let mut irq_data = Some(desc_inner.irq_data().clone());
419338f6903SLoGin
420338f6903SLoGin /*
421338f6903SLoGin * 在具有中断域继承的domain中,我们可能会遇到这样的情况,
422338f6903SLoGin * 最外层的芯片还没有设置好,但是内部的芯片已经存在了。
423338f6903SLoGin * 我们选择安装处理程序,而不是退出,
424338f6903SLoGin * 但显然我们此时无法启用/启动中断。
425338f6903SLoGin */
426338f6903SLoGin while irq_data.is_some() {
427338f6903SLoGin let dt = irq_data.as_ref().unwrap().clone();
428338f6903SLoGin
429338f6903SLoGin let chip_info = dt.chip_info_read_irqsave();
430338f6903SLoGin
431338f6903SLoGin if !Arc::ptr_eq(&chip_info.chip(), &no_irq_chip()) {
432338f6903SLoGin break;
433338f6903SLoGin }
434338f6903SLoGin
435338f6903SLoGin /*
436338f6903SLoGin * 如果最外层的芯片没有设置好,并且预期立即开始中断,
437338f6903SLoGin * 则放弃。
438338f6903SLoGin */
439338f6903SLoGin if unlikely(is_chained) {
4402eab6dd7S曾俊 warn!(
441338f6903SLoGin "Chained handler for irq {} is not supported",
442338f6903SLoGin dt.irq().data()
443338f6903SLoGin );
444338f6903SLoGin return;
445338f6903SLoGin }
446338f6903SLoGin
447338f6903SLoGin // try the parent
448b5b571e0SLoGin let parent_data = dt.parent_data().and_then(|p| p.upgrade());
449338f6903SLoGin
450338f6903SLoGin irq_data = parent_data;
451338f6903SLoGin }
452338f6903SLoGin
453338f6903SLoGin if unlikely(
454338f6903SLoGin irq_data.is_none()
455338f6903SLoGin || Arc::ptr_eq(
456338f6903SLoGin &irq_data.as_ref().unwrap().chip_info_read_irqsave().chip(),
457338f6903SLoGin &no_irq_chip(),
458338f6903SLoGin ),
459338f6903SLoGin ) {
4602eab6dd7S曾俊 warn!("No irq chip for irq {}", desc_inner.irq_data().irq().data());
461338f6903SLoGin return;
462338f6903SLoGin }
463338f6903SLoGin }
464338f6903SLoGin let handler = handler.unwrap();
465b5b571e0SLoGin if handler.type_id() == bad_irq_handler().type_id()
466b5b571e0SLoGin && Arc::ptr_eq(
467338f6903SLoGin &desc_inner.irq_data().chip_info_read_irqsave().chip(),
468338f6903SLoGin &no_irq_chip(),
469b5b571e0SLoGin )
470b5b571e0SLoGin {
471338f6903SLoGin let irq_data = desc_inner.irq_data();
472338f6903SLoGin mask_ack_irq(irq_data);
473338f6903SLoGin
474338f6903SLoGin irq_data.irqd_set(IrqStatus::IRQD_IRQ_DISABLED);
475338f6903SLoGin
476338f6903SLoGin if is_chained {
477338f6903SLoGin desc_inner.clear_actions();
478338f6903SLoGin }
479338f6903SLoGin desc_inner.set_depth(1);
480338f6903SLoGin }
481338f6903SLoGin let chip = desc_inner.irq_data().chip_info_read_irqsave().chip();
482338f6903SLoGin desc.set_handler_no_lock_inner(handler, desc_inner.irq_data(), &chip);
483338f6903SLoGin desc_inner.set_name(name);
484338f6903SLoGin
485b5b571e0SLoGin if handler.type_id() != bad_irq_handler().type_id() && is_chained {
486338f6903SLoGin let trigger_type = desc_inner.common_data().trigger_type();
487338f6903SLoGin
488338f6903SLoGin /*
489338f6903SLoGin * 我们即将立即启动这个中断,
490338f6903SLoGin * 因此需要设置触发配置。
491338f6903SLoGin * 但是 .irq_set_type 回调可能已经覆盖了
492338f6903SLoGin * irqflowhandler,忽略了我们正在处理的
493338f6903SLoGin * 是一个链式中断。立即重置它,因为我们
494338f6903SLoGin * 确实知道更好的处理方式。
495338f6903SLoGin */
496338f6903SLoGin
497338f6903SLoGin if trigger_type != IrqLineStatus::IRQ_TYPE_NONE {
498338f6903SLoGin irq_manager()
499338f6903SLoGin .do_set_irq_trigger(desc.clone(), desc_inner, trigger_type)
500338f6903SLoGin .ok();
501338f6903SLoGin desc.set_handler(handler);
502338f6903SLoGin }
503338f6903SLoGin
504338f6903SLoGin desc_inner.set_noprobe();
505338f6903SLoGin desc_inner.set_norequest();
506338f6903SLoGin desc_inner.set_nothread();
507338f6903SLoGin
508338f6903SLoGin desc_inner.clear_actions();
509338f6903SLoGin desc_inner.add_action(chained_action());
510338f6903SLoGin
511338f6903SLoGin irq_manager()
512338f6903SLoGin .irq_activate_and_startup(desc, desc_inner, IrqManager::IRQ_RESEND)
513338f6903SLoGin .ok();
514338f6903SLoGin }
515338f6903SLoGin
516338f6903SLoGin return;
517338f6903SLoGin }
518338f6903SLoGin
irq_set_handler_data( &self, irq: IrqNumber, data: Option<Arc<dyn IrqHandlerData>>, ) -> Result<(), SystemError>519338f6903SLoGin pub fn irq_set_handler_data(
520338f6903SLoGin &self,
521338f6903SLoGin irq: IrqNumber,
522338f6903SLoGin data: Option<Arc<dyn IrqHandlerData>>,
523338f6903SLoGin ) -> Result<(), SystemError> {
524338f6903SLoGin let desc = irq_desc_manager().lookup(irq).ok_or(SystemError::EINVAL)?;
525338f6903SLoGin desc.inner().common_data().inner().set_handler_data(data);
526338f6903SLoGin
527338f6903SLoGin return Ok(());
528338f6903SLoGin }
529338f6903SLoGin
irq_percpu_disable( &self, desc: &Arc<IrqDesc>, irq_data: &Arc<IrqData>, irq_chip: &Arc<dyn IrqChip>, cpu: ProcessorId, )530338f6903SLoGin pub fn irq_percpu_disable(
531338f6903SLoGin &self,
532338f6903SLoGin desc: &Arc<IrqDesc>,
533338f6903SLoGin irq_data: &Arc<IrqData>,
534338f6903SLoGin irq_chip: &Arc<dyn IrqChip>,
535338f6903SLoGin cpu: ProcessorId,
536338f6903SLoGin ) {
537338f6903SLoGin if let Err(e) = irq_chip.irq_mask(irq_data) {
538338f6903SLoGin if e == SystemError::ENOSYS {
539338f6903SLoGin irq_chip.irq_disable(irq_data);
540338f6903SLoGin }
541338f6903SLoGin }
542338f6903SLoGin
543338f6903SLoGin desc.inner()
544338f6903SLoGin .percpu_enabled_mut()
545338f6903SLoGin .as_mut()
546338f6903SLoGin .unwrap()
547338f6903SLoGin .set(cpu, false);
548338f6903SLoGin }
549338f6903SLoGin }
550338f6903SLoGin
551338f6903SLoGin lazy_static! {
552338f6903SLoGin pub(super) static ref CHAINED_ACTION: Arc<IrqAction> = IrqAction::new(
553338f6903SLoGin IrqNumber::new(0),
554338f6903SLoGin "".to_string(),
555338f6903SLoGin Some(&ChainedActionHandler),
556338f6903SLoGin None,
557338f6903SLoGin );
558338f6903SLoGin }
559338f6903SLoGin
560338f6903SLoGin #[allow(dead_code)]
chained_action() -> Arc<IrqAction>561338f6903SLoGin pub(super) fn chained_action() -> Arc<IrqAction> {
562338f6903SLoGin CHAINED_ACTION.clone()
563338f6903SLoGin }
564338f6903SLoGin
565338f6903SLoGin /// Chained handlers 永远不应该在它们的IRQ上调用irqaction。如果发生这种情况,
566338f6903SLoGin /// 这个默认irqaction将发出警告。
567338f6903SLoGin #[derive(Debug)]
568338f6903SLoGin struct ChainedActionHandler;
569338f6903SLoGin
570338f6903SLoGin impl IrqHandler for ChainedActionHandler {
handle( &self, irq: IrqNumber, _static_data: Option<&dyn IrqHandlerData>, _dynamic_data: Option<Arc<dyn IrqHandlerData>>, ) -> Result<IrqReturn, SystemError>571338f6903SLoGin fn handle(
572338f6903SLoGin &self,
573338f6903SLoGin irq: IrqNumber,
574338f6903SLoGin _static_data: Option<&dyn IrqHandlerData>,
575338f6903SLoGin _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
576338f6903SLoGin ) -> Result<IrqReturn, SystemError> {
577338f6903SLoGin static ONCE: Once = Once::new();
578338f6903SLoGin ONCE.call_once(|| {
5792eab6dd7S曾俊 warn!("Chained irq {} should not call an action.", irq.data());
580338f6903SLoGin });
581338f6903SLoGin
582338f6903SLoGin Ok(IrqReturn::NotHandled)
583338f6903SLoGin }
584e2841179SLoGin }
585