1e2841179SLoGin use core::{intrinsics::unlikely, ops::BitAnd}; 23bc96fa4SLoGin 3e2841179SLoGin use alloc::sync::Arc; 4e2841179SLoGin use system_error::SystemError; 5e2841179SLoGin 6e2841179SLoGin use crate::{ 7e2841179SLoGin arch::{interrupt::TrapFrame, CurrentIrqArch}, 8e2841179SLoGin exception::irqdesc::InnerIrqDesc, 9338f6903SLoGin libs::{once::Once, spinlock::SpinLockGuard}, 10e2841179SLoGin process::{ProcessFlags, ProcessManager}, 11338f6903SLoGin smp::core::smp_get_processor_id, 12e2841179SLoGin }; 133bc96fa4SLoGin 143bc96fa4SLoGin use super::{ 15e2841179SLoGin irqdata::{IrqData, IrqHandlerData, IrqStatus}, 16e2841179SLoGin irqdesc::{ 17e2841179SLoGin InnerIrqAction, IrqDesc, IrqDescState, IrqFlowHandler, IrqReturn, ThreadedHandlerFlags, 18e2841179SLoGin }, 19e2841179SLoGin manage::{irq_manager, IrqManager}, 20e2841179SLoGin InterruptArch, IrqNumber, 213bc96fa4SLoGin }; 223bc96fa4SLoGin 233bc96fa4SLoGin /// 获取用于处理错误的中断的处理程序 243bc96fa4SLoGin #[inline(always)] 253bc96fa4SLoGin pub fn bad_irq_handler() -> &'static dyn IrqFlowHandler { 263bc96fa4SLoGin &HandleBadIrq 273bc96fa4SLoGin } 283bc96fa4SLoGin 29e2841179SLoGin /// 获取用于处理快速EOI的中断的处理程序 30e2841179SLoGin #[inline(always)] 31e2841179SLoGin pub fn fast_eoi_irq_handler() -> &'static dyn IrqFlowHandler { 32e2841179SLoGin &FastEOIIrqHandler 33e2841179SLoGin } 34e2841179SLoGin 35e2841179SLoGin /// 获取用于处理边沿触发中断的处理程序 36e2841179SLoGin #[inline(always)] 37e2841179SLoGin pub fn edge_irq_handler() -> &'static dyn IrqFlowHandler { 38e2841179SLoGin &EdgeIrqHandler 39e2841179SLoGin } 40e2841179SLoGin 413bc96fa4SLoGin /// handle spurious and unhandled irqs 423bc96fa4SLoGin #[derive(Debug)] 433bc96fa4SLoGin struct HandleBadIrq; 443bc96fa4SLoGin 453bc96fa4SLoGin impl IrqFlowHandler for HandleBadIrq { 463bc96fa4SLoGin /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/handle.c?fi=handle_bad_irq#33 47e2841179SLoGin fn handle(&self, irq_desc: &Arc<IrqDesc>, _trap_frame: &mut TrapFrame) { 483bc96fa4SLoGin // todo: print_irq_desc 493bc96fa4SLoGin // todo: 增加kstat计数 503bc96fa4SLoGin CurrentIrqArch::ack_bad_irq(irq_desc.irq()); 513bc96fa4SLoGin } 523bc96fa4SLoGin } 53e2841179SLoGin 54e2841179SLoGin #[derive(Debug)] 55e2841179SLoGin struct FastEOIIrqHandler; 56e2841179SLoGin 57e2841179SLoGin impl IrqFlowHandler for FastEOIIrqHandler { 58e2841179SLoGin fn handle(&self, _irq_desc: &Arc<IrqDesc>, _trap_frame: &mut TrapFrame) { 59e2841179SLoGin // https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/chip.c?r=&mo=17578&fi=689#689 60e2841179SLoGin todo!("FastEOIIrqHandler"); 61e2841179SLoGin } 62e2841179SLoGin } 63e2841179SLoGin 64e2841179SLoGin #[derive(Debug)] 65e2841179SLoGin struct EdgeIrqHandler; 66e2841179SLoGin 67e2841179SLoGin impl IrqFlowHandler for EdgeIrqHandler { 68e2841179SLoGin // https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/chip.c?fi=handle_edge_irq#775 69e2841179SLoGin fn handle(&self, irq_desc: &Arc<IrqDesc>, _trap_frame: &mut TrapFrame) { 70e2841179SLoGin let mut desc_inner_guard: SpinLockGuard<'_, InnerIrqDesc> = irq_desc.inner(); 71e2841179SLoGin if !irq_may_run(&desc_inner_guard) { 72e2841179SLoGin // kdebug!("!irq_may_run"); 73e2841179SLoGin desc_inner_guard 74e2841179SLoGin .internal_state_mut() 75e2841179SLoGin .insert(IrqDescState::IRQS_PENDING); 76e2841179SLoGin mask_ack_irq(desc_inner_guard.irq_data()); 77e2841179SLoGin return; 78e2841179SLoGin } 79e2841179SLoGin 80e2841179SLoGin if desc_inner_guard.common_data().disabled() { 81e2841179SLoGin // kdebug!("desc_inner_guard.common_data().disabled()"); 82e2841179SLoGin desc_inner_guard 83e2841179SLoGin .internal_state_mut() 84e2841179SLoGin .insert(IrqDescState::IRQS_PENDING); 85e2841179SLoGin mask_ack_irq(desc_inner_guard.irq_data()); 86e2841179SLoGin return; 87e2841179SLoGin } 88e2841179SLoGin 89e2841179SLoGin let irq_data = desc_inner_guard.irq_data().clone(); 90e2841179SLoGin 91e2841179SLoGin irq_data.chip_info_read_irqsave().chip().irq_ack(&irq_data); 92e2841179SLoGin 93e2841179SLoGin loop { 94e2841179SLoGin if unlikely(desc_inner_guard.actions().is_empty()) { 95e2841179SLoGin kdebug!("no action for irq {}", irq_data.irq().data()); 96e2841179SLoGin irq_manager().mask_irq(&irq_data); 97e2841179SLoGin return; 98e2841179SLoGin } 99e2841179SLoGin 100e2841179SLoGin // 当我们在处理一个中断时,如果另一个中断到来,我们本可以屏蔽它. 101e2841179SLoGin // 如果在此期间没有被禁用,请重新启用它。 102e2841179SLoGin if desc_inner_guard 103e2841179SLoGin .internal_state() 104e2841179SLoGin .contains(IrqDescState::IRQS_PENDING) 105e2841179SLoGin { 106e2841179SLoGin let status = desc_inner_guard.common_data().status(); 107*b5b571e0SLoGin if !status.disabled() && status.masked() { 108e2841179SLoGin // kdebug!("re-enable irq"); 109e2841179SLoGin irq_manager().unmask_irq(&desc_inner_guard); 110e2841179SLoGin } 111e2841179SLoGin } 112e2841179SLoGin 113e2841179SLoGin // kdebug!("handle_irq_event"); 114e2841179SLoGin 115e2841179SLoGin desc_inner_guard 116e2841179SLoGin .internal_state_mut() 117e2841179SLoGin .remove(IrqDescState::IRQS_PENDING); 118e2841179SLoGin desc_inner_guard.common_data().set_inprogress(); 119e2841179SLoGin 120e2841179SLoGin drop(desc_inner_guard); 121e2841179SLoGin 122e2841179SLoGin let _r = do_handle_irq_event(irq_desc); 123e2841179SLoGin 124e2841179SLoGin desc_inner_guard = irq_desc.inner(); 125e2841179SLoGin desc_inner_guard.common_data().clear_inprogress(); 126e2841179SLoGin 127*b5b571e0SLoGin if !desc_inner_guard 128e2841179SLoGin .internal_state() 129e2841179SLoGin .contains(IrqDescState::IRQS_PENDING) 130*b5b571e0SLoGin || desc_inner_guard.common_data().disabled() 131e2841179SLoGin { 132e2841179SLoGin break; 133e2841179SLoGin } 134e2841179SLoGin } 135e2841179SLoGin } 136e2841179SLoGin } 137e2841179SLoGin 138e2841179SLoGin /// 判断中断是否可以运行 139e2841179SLoGin fn irq_may_run(desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>) -> bool { 140e2841179SLoGin let mask = IrqStatus::IRQD_IRQ_INPROGRESS | IrqStatus::IRQD_WAKEUP_ARMED; 141e2841179SLoGin let status = desc_inner_guard.common_data().status(); 142e2841179SLoGin 143e2841179SLoGin // 如果中断不在处理中并且没有被唤醒,则可以运行 144e2841179SLoGin if status.bitand(mask).is_empty() { 145e2841179SLoGin return true; 146e2841179SLoGin } 147e2841179SLoGin 148e2841179SLoGin // todo: 检查其他处理器是否在轮询当前中断 149e2841179SLoGin return false; 150e2841179SLoGin } 151e2841179SLoGin 152338f6903SLoGin pub(super) fn mask_ack_irq(irq_data: &Arc<IrqData>) { 153e2841179SLoGin let chip = irq_data.chip_info_read_irqsave().chip(); 154e2841179SLoGin if chip.can_mask_ack() { 155*b5b571e0SLoGin chip.irq_mask_ack(irq_data); 156e2841179SLoGin irq_data.common_data().set_masked(); 157e2841179SLoGin } else { 158e2841179SLoGin irq_manager().mask_irq(irq_data); 159*b5b571e0SLoGin chip.irq_ack(irq_data); 160e2841179SLoGin } 161e2841179SLoGin } 162e2841179SLoGin 163e2841179SLoGin impl IrqManager { 164e2841179SLoGin pub(super) fn do_irq_wake_thread( 165e2841179SLoGin &self, 166e2841179SLoGin desc: &Arc<IrqDesc>, 167e2841179SLoGin action_inner: &mut SpinLockGuard<'_, InnerIrqAction>, 168e2841179SLoGin ) { 169e2841179SLoGin let thread = action_inner.thread(); 170e2841179SLoGin 171e2841179SLoGin if thread.is_none() { 172e2841179SLoGin return; 173e2841179SLoGin } 174e2841179SLoGin 175e2841179SLoGin let thread = thread.unwrap(); 176e2841179SLoGin if thread.flags().contains(ProcessFlags::EXITING) { 177e2841179SLoGin return; 178e2841179SLoGin } 179e2841179SLoGin 180e2841179SLoGin // 如果线程已经在运行,我们不需要唤醒它 181e2841179SLoGin if action_inner 182e2841179SLoGin .thread_flags_mut() 183e2841179SLoGin .test_and_set_bit(ThreadedHandlerFlags::IRQTF_RUNTHREAD) 184e2841179SLoGin { 185e2841179SLoGin return; 186e2841179SLoGin } 187e2841179SLoGin 188e2841179SLoGin desc.inc_threads_active(); 189e2841179SLoGin 190e2841179SLoGin ProcessManager::wakeup(&thread).ok(); 191e2841179SLoGin } 192e2841179SLoGin } 193e2841179SLoGin 194e2841179SLoGin /// 处理中断事件 195e2841179SLoGin /// 196e2841179SLoGin /// https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/handle.c?fi=handle_irq_event#139 197e2841179SLoGin #[inline(never)] 198e2841179SLoGin fn do_handle_irq_event(desc: &Arc<IrqDesc>) -> Result<(), SystemError> { 199e2841179SLoGin let desc_inner_guard = desc.inner(); 200e2841179SLoGin let irq_data = desc_inner_guard.irq_data().clone(); 201e2841179SLoGin let actions = desc_inner_guard.actions().clone(); 202e2841179SLoGin drop(desc_inner_guard); 203e2841179SLoGin 204e2841179SLoGin let irq = irq_data.irq(); 205e2841179SLoGin let mut r = Ok(IrqReturn::NotHandled); 206e2841179SLoGin 207e2841179SLoGin for action in actions { 208e2841179SLoGin let mut action_inner: SpinLockGuard<'_, InnerIrqAction> = action.inner(); 209e2841179SLoGin // kdebug!("do_handle_irq_event: action: {:?}", action_inner.name()); 210e2841179SLoGin let dynamic_data = action_inner 211e2841179SLoGin .dev_id() 212e2841179SLoGin .clone() 213e2841179SLoGin .map(|d| d as Arc<dyn IrqHandlerData>); 214e2841179SLoGin r = action_inner 215e2841179SLoGin .handler() 216e2841179SLoGin .unwrap() 217e2841179SLoGin .handle(irq, None, dynamic_data); 218e2841179SLoGin 219e2841179SLoGin if let Ok(IrqReturn::WakeThread) = r { 220e2841179SLoGin if unlikely(action_inner.thread_fn().is_none()) { 221e2841179SLoGin warn_no_thread(irq, &mut action_inner); 222e2841179SLoGin } else { 223e2841179SLoGin irq_manager().do_irq_wake_thread(desc, &mut action_inner); 224e2841179SLoGin } 225e2841179SLoGin }; 226e2841179SLoGin } 227e2841179SLoGin 228e2841179SLoGin return r.map(|_| ()); 229e2841179SLoGin } 230e2841179SLoGin 231e2841179SLoGin fn warn_no_thread(irq: IrqNumber, action_inner: &mut SpinLockGuard<'_, InnerIrqAction>) { 232e2841179SLoGin // warn on once 233e2841179SLoGin if action_inner 234e2841179SLoGin .thread_flags_mut() 235e2841179SLoGin .test_and_set_bit(ThreadedHandlerFlags::IRQTF_WARNED) 236e2841179SLoGin { 237e2841179SLoGin return; 238e2841179SLoGin } 239e2841179SLoGin 240e2841179SLoGin kwarn!( 241e2841179SLoGin "irq {}, device {} returned IRQ_WAKE_THREAD, but no threaded handler", 242e2841179SLoGin irq.data(), 243e2841179SLoGin action_inner.name() 244e2841179SLoGin ); 245e2841179SLoGin } 246338f6903SLoGin 247338f6903SLoGin /// `handle_percpu_devid_irq` - 带有per-CPU设备id的perCPU本地中断处理程序 248338f6903SLoGin /// 249338f6903SLoGin /// 250338f6903SLoGin /// * `desc`: 此中断的中断描述结构 251338f6903SLoGin /// 252338f6903SLoGin /// 在没有锁定要求的SMP机器上的每个CPU中断。与linux的`handle_percpu_irq()`相同,但有以下额外内容: 253338f6903SLoGin /// 254338f6903SLoGin /// `action->percpu_dev_id`是一个指向per-cpu变量的指针,这些变量 255338f6903SLoGin /// 包含调用此处理程序的cpu的真实设备id 256338f6903SLoGin #[derive(Debug)] 257338f6903SLoGin pub struct PerCpuDevIdIrqHandler; 258338f6903SLoGin 259338f6903SLoGin impl IrqFlowHandler for PerCpuDevIdIrqHandler { 260338f6903SLoGin fn handle(&self, irq_desc: &Arc<IrqDesc>, _trap_frame: &mut TrapFrame) { 261338f6903SLoGin let desc_inner_guard = irq_desc.inner(); 262338f6903SLoGin let irq_data = desc_inner_guard.irq_data().clone(); 263338f6903SLoGin let chip = irq_data.chip_info_read().chip(); 264338f6903SLoGin 265338f6903SLoGin chip.irq_ack(&irq_data); 266338f6903SLoGin 267338f6903SLoGin let irq = irq_data.irq(); 268338f6903SLoGin 269338f6903SLoGin let action = desc_inner_guard.actions().first().cloned(); 270338f6903SLoGin 271338f6903SLoGin drop(desc_inner_guard); 272338f6903SLoGin 273338f6903SLoGin if let Some(action) = action { 274338f6903SLoGin let action_inner = action.inner(); 275338f6903SLoGin let per_cpu_devid = action_inner.per_cpu_dev_id().cloned(); 276338f6903SLoGin 277338f6903SLoGin let handler = action_inner.handler().unwrap(); 278338f6903SLoGin drop(action_inner); 279338f6903SLoGin 280338f6903SLoGin let _r = handler.handle( 281338f6903SLoGin irq, 282338f6903SLoGin None, 283338f6903SLoGin per_cpu_devid.map(|d| d as Arc<dyn IrqHandlerData>), 284338f6903SLoGin ); 285338f6903SLoGin } else { 286338f6903SLoGin let cpu = smp_get_processor_id(); 287338f6903SLoGin 288338f6903SLoGin let enabled = irq_desc 289338f6903SLoGin .inner() 290338f6903SLoGin .percpu_enabled() 291338f6903SLoGin .as_ref() 292338f6903SLoGin .unwrap() 293338f6903SLoGin .get(cpu) 294338f6903SLoGin .unwrap_or(false); 295338f6903SLoGin 296338f6903SLoGin if enabled { 297338f6903SLoGin irq_manager().irq_percpu_disable(irq_desc, &irq_data, &chip, cpu); 298338f6903SLoGin } 299338f6903SLoGin static ONCE: Once = Once::new(); 300338f6903SLoGin 301338f6903SLoGin ONCE.call_once(|| { 302338f6903SLoGin kerror!( 303338f6903SLoGin "Spurious percpu irq {} on cpu {:?}, enabled: {}", 304338f6903SLoGin irq.data(), 305338f6903SLoGin cpu, 306338f6903SLoGin enabled 307338f6903SLoGin ); 308338f6903SLoGin }); 309338f6903SLoGin } 310338f6903SLoGin 311338f6903SLoGin chip.irq_eoi(&irq_data); 312338f6903SLoGin } 313338f6903SLoGin } 314