1 use alloc::{string::ToString, sync::Arc};
2 use system_error::SystemError;
3 use unified_init::macros::unified_init;
4
5 use crate::{
6 driver::base::{
7 kobject::{KObjType, KObject, KObjectManager, KObjectSysFSOps},
8 kset::KSet,
9 },
10 filesystem::{
11 sysfs::{
12 file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport,
13 SYSFS_ATTR_MODE_RO,
14 },
15 vfs::syscall::ModeType,
16 },
17 init::initcall::INITCALL_POSTCORE,
18 misc::ksysfs::sys_kernel_kset,
19 };
20
21 use super::{
22 irqdesc::{irq_desc_manager, IrqDesc},
23 IrqNumber,
24 };
25
26 /// `/sys/kernel/irq`的kset
27 static mut SYS_KERNEL_IRQ_KSET_INSTANCE: Option<Arc<KSet>> = None;
28
29 #[inline(always)]
30 #[allow(dead_code)]
sys_kernel_irq_kset() -> Arc<KSet>31 pub fn sys_kernel_irq_kset() -> Arc<KSet> {
32 unsafe { SYS_KERNEL_IRQ_KSET_INSTANCE.clone().unwrap() }
33 }
34
35 /// 中断描述符的kobjtype
36 ///
37 /// https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdesc.c#280
38 #[derive(Debug)]
39 pub(super) struct IrqKObjType;
40
41 impl KObjType for IrqKObjType {
sysfs_ops(&self) -> Option<&dyn SysFSOps>42 fn sysfs_ops(&self) -> Option<&dyn SysFSOps> {
43 Some(&KObjectSysFSOps)
44 }
45
attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>46 fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
47 Some(&[&IrqAttrGroup])
48 }
49
release(&self, _kobj: Arc<dyn KObject>)50 fn release(&self, _kobj: Arc<dyn KObject>) {
51
52 // https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdesc.c#428
53 }
54 }
55
56 #[derive(Debug)]
57 struct IrqAttrGroup;
58
59 impl AttributeGroup for IrqAttrGroup {
name(&self) -> Option<&str>60 fn name(&self) -> Option<&str> {
61 None
62 }
63
64 /// 所有的属性
65 ///
66 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdesc.c#268
attrs(&self) -> &[&'static dyn Attribute]67 fn attrs(&self) -> &[&'static dyn Attribute] {
68 // 每个irq的属性
69 // todo: 添加per_cpu_count属性
70 &[
71 &AttrChipName,
72 &AttrHardwareIrq,
73 &AttrType,
74 &AttrWakeup,
75 &AttrName,
76 &AttrActions,
77 ]
78 }
79
is_visible( &self, _kobj: Arc<dyn KObject>, attr: &'static dyn Attribute, ) -> Option<ModeType>80 fn is_visible(
81 &self,
82 _kobj: Arc<dyn KObject>,
83 attr: &'static dyn Attribute,
84 ) -> Option<ModeType> {
85 Some(attr.mode())
86 }
87 }
88
89 /// 初始化irq模块在sysfs中的目录
90 ///
91 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdesc.c#313
92 #[unified_init(INITCALL_POSTCORE)]
irq_sysfs_init() -> Result<(), SystemError>93 fn irq_sysfs_init() -> Result<(), SystemError> {
94 // todo!("irq_sysfs_init");
95
96 let irq_kset = KSet::new("irq".to_string());
97 irq_kset
98 .register(Some(sys_kernel_kset()))
99 .expect("register irq kset failed");
100 unsafe {
101 SYS_KERNEL_IRQ_KSET_INSTANCE = Some(irq_kset);
102 }
103
104 // 把所有的irq都注册到/sys/kernel/irq下
105 for (irq, desc) in irq_desc_manager().iter_descs() {
106 irq_sysfs_add(irq, desc);
107 }
108
109 return Ok(());
110 }
111
112 /// 把irqdesc添加到sysfs
irq_sysfs_add(irq: &IrqNumber, desc: &Arc<IrqDesc>)113 fn irq_sysfs_add(irq: &IrqNumber, desc: &Arc<IrqDesc>) {
114 if unsafe { SYS_KERNEL_IRQ_KSET_INSTANCE.is_none() } {
115 return;
116 }
117
118 let kset = sys_kernel_irq_kset();
119 KObjectManager::add_kobj(desc.clone() as Arc<dyn KObject>, Some(kset)).unwrap_or_else(|e| {
120 kwarn!("Failed to add irq({irq:?}) kobject to sysfs: {:?}", e);
121 });
122
123 desc.mark_in_sysfs();
124 }
125
126 /// 从sysfs中删除irqdesc
127 #[allow(dead_code)]
irq_sysfs_del(desc: &Arc<IrqDesc>)128 pub(super) fn irq_sysfs_del(desc: &Arc<IrqDesc>) {
129 if desc.in_sysfs() {
130 KObjectManager::remove_kobj(desc.clone() as Arc<dyn KObject>);
131 desc.mark_not_in_sysfs();
132 }
133 }
134 #[derive(Debug)]
135 struct AttrChipName;
136
137 impl Attribute for AttrChipName {
name(&self) -> &str138 fn name(&self) -> &str {
139 "chip_name"
140 }
141
mode(&self) -> ModeType142 fn mode(&self) -> ModeType {
143 SYSFS_ATTR_MODE_RO
144 }
145
support(&self) -> SysFSOpsSupport146 fn support(&self) -> SysFSOpsSupport {
147 SysFSOpsSupport::ATTR_SHOW
148 }
149
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>150 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
151 let irq_desc = kobj
152 .arc_any()
153 .downcast::<IrqDesc>()
154 .map_err(|_| SystemError::EINVAL)?;
155
156 let chip = irq_desc.irq_data().chip_info_read_irqsave().chip();
157 let name = chip.name();
158 let len = core::cmp::min(name.len() + 1, buf.len());
159 let name = format!("{}\n", name);
160 buf[..len].copy_from_slice(name.as_bytes());
161 return Ok(len);
162 }
163 }
164
165 #[derive(Debug)]
166 struct AttrHardwareIrq;
167
168 impl Attribute for AttrHardwareIrq {
name(&self) -> &str169 fn name(&self) -> &str {
170 "hwirq"
171 }
172
mode(&self) -> ModeType173 fn mode(&self) -> ModeType {
174 SYSFS_ATTR_MODE_RO
175 }
176
support(&self) -> SysFSOpsSupport177 fn support(&self) -> SysFSOpsSupport {
178 SysFSOpsSupport::ATTR_SHOW
179 }
180
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>181 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
182 let irq_desc = kobj
183 .arc_any()
184 .downcast::<IrqDesc>()
185 .map_err(|_| SystemError::EINVAL)?;
186 let hwirq = irq_desc.hardware_irq();
187 return sysfs_emit_str(buf, &format!("{}\n", hwirq.data()));
188 }
189 }
190
191 #[derive(Debug)]
192 struct AttrType;
193
194 impl Attribute for AttrType {
name(&self) -> &str195 fn name(&self) -> &str {
196 "type"
197 }
198
mode(&self) -> ModeType199 fn mode(&self) -> ModeType {
200 SYSFS_ATTR_MODE_RO
201 }
202
support(&self) -> SysFSOpsSupport203 fn support(&self) -> SysFSOpsSupport {
204 SysFSOpsSupport::ATTR_SHOW
205 }
206
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>207 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
208 let irq_desc = kobj
209 .arc_any()
210 .downcast::<IrqDesc>()
211 .map_err(|_| SystemError::EINVAL)?;
212 let irq_type = if irq_desc.irq_data().is_level_type() {
213 "level"
214 } else {
215 "edge"
216 };
217
218 return sysfs_emit_str(buf, &format!("{}\n", irq_type));
219 }
220 }
221
222 #[derive(Debug)]
223 struct AttrWakeup;
224
225 impl Attribute for AttrWakeup {
name(&self) -> &str226 fn name(&self) -> &str {
227 "wakeup"
228 }
229
mode(&self) -> ModeType230 fn mode(&self) -> ModeType {
231 SYSFS_ATTR_MODE_RO
232 }
233
support(&self) -> SysFSOpsSupport234 fn support(&self) -> SysFSOpsSupport {
235 SysFSOpsSupport::ATTR_SHOW
236 }
237
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>238 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
239 let irq_desc = kobj
240 .arc_any()
241 .downcast::<IrqDesc>()
242 .map_err(|_| SystemError::EINVAL)?;
243 let wakeup = irq_desc.irq_data().is_wakeup_set();
244 return sysfs_emit_str(buf, &format!("{}\n", wakeup));
245 }
246 }
247
248 #[derive(Debug)]
249 struct AttrName;
250
251 impl Attribute for AttrName {
name(&self) -> &str252 fn name(&self) -> &str {
253 "name"
254 }
255
mode(&self) -> ModeType256 fn mode(&self) -> ModeType {
257 SYSFS_ATTR_MODE_RO
258 }
259
support(&self) -> SysFSOpsSupport260 fn support(&self) -> SysFSOpsSupport {
261 SysFSOpsSupport::ATTR_SHOW
262 }
263
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>264 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
265 let irq_desc = kobj
266 .arc_any()
267 .downcast::<IrqDesc>()
268 .map_err(|_| SystemError::EINVAL)?;
269
270 if let Some(name) = irq_desc.name() {
271 return sysfs_emit_str(buf, &format!("{}\n", name));
272 }
273
274 return Ok(0);
275 }
276 }
277
278 #[derive(Debug)]
279 struct AttrActions;
280
281 impl Attribute for AttrActions {
name(&self) -> &str282 fn name(&self) -> &str {
283 "actions"
284 }
285
mode(&self) -> ModeType286 fn mode(&self) -> ModeType {
287 SYSFS_ATTR_MODE_RO
288 }
289
support(&self) -> SysFSOpsSupport290 fn support(&self) -> SysFSOpsSupport {
291 SysFSOpsSupport::ATTR_SHOW
292 }
293
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>294 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
295 let irq_desc = kobj
296 .arc_any()
297 .downcast::<IrqDesc>()
298 .map_err(|_| SystemError::EINVAL)?;
299
300 let actions = irq_desc.actions();
301 let mut len = 0;
302
303 for action in actions {
304 if len != 0 {
305 len += sysfs_emit_str(&mut buf[len..], &format!(",{}", action.inner().name()))
306 .unwrap();
307 } else {
308 len +=
309 sysfs_emit_str(&mut buf[len..], &format!("{}", action.inner().name())).unwrap();
310 }
311
312 if len >= buf.len() {
313 break;
314 }
315 }
316
317 if len != 0 && len < buf.len() {
318 len += sysfs_emit_str(&mut buf[len..], "\n").unwrap();
319 }
320
321 return Ok(len);
322 }
323 }
324