From 196b75dc17b5cc2ed84301bce776e496ddfe1ed1 Mon Sep 17 00:00:00 2001 From: LoGin Date: Mon, 19 Feb 2024 00:56:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=8Airqdesc=E6=B7=BB=E5=8A=A0=E5=88=B0sysf?= =?UTF-8?q?s=20(#525)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 把irqdesc添加到sysfs --- kernel/src/driver/acpi/sysfs.rs | 11 +- kernel/src/driver/base/device/bus.rs | 16 +- kernel/src/driver/base/device/dd.rs | 10 +- kernel/src/driver/base/device/mod.rs | 6 +- kernel/src/driver/video/fbdev/base/fbcon.rs | 6 +- kernel/src/driver/video/fbdev/base/fbsysfs.rs | 20 +- kernel/src/driver/video/fbdev/vesafb.rs | 2 +- kernel/src/exception/irqdata.rs | 29 ++ kernel/src/exception/irqdesc.rs | 106 ++++++- kernel/src/exception/sysfs.rs | 269 +++++++++++++++++- kernel/src/filesystem/sysfs/file.rs | 16 +- kernel/src/filesystem/sysfs/mod.rs | 15 +- kernel/src/lib.rs | 1 + kernel/src/misc/ksysfs.rs | 63 ++++ kernel/src/misc/mod.rs | 1 + 15 files changed, 515 insertions(+), 56 deletions(-) create mode 100644 kernel/src/misc/ksysfs.rs create mode 100644 kernel/src/misc/mod.rs diff --git a/kernel/src/driver/acpi/sysfs.rs b/kernel/src/driver/acpi/sysfs.rs index f96abf7a..de0df2fd 100644 --- a/kernel/src/driver/acpi/sysfs.rs +++ b/kernel/src/driver/acpi/sysfs.rs @@ -4,7 +4,10 @@ use crate::{ base::{kobject::KObject, kset::KSet}, }, filesystem::{ - sysfs::{file::sysfs_emit_str, sysfs_instance, Attribute, BinAttribute, SysFSOpsSupport}, + sysfs::{ + file::sysfs_emit_str, sysfs_instance, Attribute, BinAttribute, SysFSOpsSupport, + SYSFS_ATTR_MODE_RO, + }, vfs::syscall::ModeType, }, libs::rwlock::RwLock, @@ -131,11 +134,11 @@ impl Attribute for AttrForceRemove { } fn mode(&self) -> ModeType { - return ModeType::from_bits_truncate(0o444); + SYSFS_ATTR_MODE_RO } fn support(&self) -> SysFSOpsSupport { - return SysFSOpsSupport::SHOW; + return SysFSOpsSupport::ATTR_SHOW; } fn show(&self, _kobj: Arc, buf: &mut [u8]) -> Result { @@ -224,7 +227,7 @@ impl Attribute for AttrAcpiTable { impl BinAttribute for AttrAcpiTable { fn support_battr(&self) -> SysFSOpsSupport { - return SysFSOpsSupport::READ; + return SysFSOpsSupport::BATTR_READ; } fn write( &self, diff --git a/kernel/src/driver/base/device/bus.rs b/kernel/src/driver/base/device/bus.rs index 8cbb20ee..5cf7d95c 100644 --- a/kernel/src/driver/base/device/bus.rs +++ b/kernel/src/driver/base/device/bus.rs @@ -12,7 +12,7 @@ use crate::{ filesystem::{ sysfs::{ file::sysfs_emit_str, sysfs_instance, Attribute, AttributeGroup, SysFSOps, - SysFSOpsSupport, + SysFSOpsSupport, SYSFS_ATTR_MODE_RW, SYSFS_ATTR_MODE_WO, }, vfs::syscall::ModeType, }, @@ -598,7 +598,7 @@ impl Attribute for BusAttrDriversProbe { } fn support(&self) -> SysFSOpsSupport { - return SysFSOpsSupport::STORE; + return SysFSOpsSupport::ATTR_STORE; } /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/bus.c?r=&mo=5649&fi=241#241 @@ -628,7 +628,7 @@ struct BusAttrDriversAutoprobe; impl Attribute for BusAttrDriversAutoprobe { fn mode(&self) -> ModeType { - return ModeType::from_bits_truncate(0o644); + SYSFS_ATTR_MODE_RW } fn name(&self) -> &str { @@ -636,7 +636,7 @@ impl Attribute for BusAttrDriversAutoprobe { } fn support(&self) -> SysFSOpsSupport { - return SysFSOpsSupport::STORE | SysFSOpsSupport::SHOW; + return SysFSOpsSupport::ATTR_STORE | SysFSOpsSupport::ATTR_SHOW; } /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/bus.c?r=&mo=5649&fi=241#231 @@ -738,7 +738,7 @@ struct DriverAttrUnbind; impl Attribute for DriverAttrUnbind { fn mode(&self) -> ModeType { - ModeType::from_bits_truncate(0o200) + SYSFS_ATTR_MODE_WO } fn name(&self) -> &str { @@ -774,7 +774,7 @@ impl Attribute for DriverAttrUnbind { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::STORE + SysFSOpsSupport::ATTR_STORE } } @@ -787,7 +787,7 @@ impl Attribute for DriverAttrBind { } fn mode(&self) -> ModeType { - ModeType::from_bits_truncate(0o200) + SYSFS_ATTR_MODE_WO } /* @@ -825,7 +825,7 @@ impl Attribute for DriverAttrBind { return Err(SystemError::ENODEV); } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::STORE + SysFSOpsSupport::ATTR_STORE } } diff --git a/kernel/src/driver/base/device/dd.rs b/kernel/src/driver/base/device/dd.rs index c386337e..8bdadacc 100644 --- a/kernel/src/driver/base/device/dd.rs +++ b/kernel/src/driver/base/device/dd.rs @@ -6,7 +6,9 @@ use intertrait::cast::CastArc; use crate::{ driver::base::kobject::KObject, filesystem::{ - sysfs::{file::sysfs_emit_str, sysfs_instance, Attribute, SysFSOpsSupport}, + sysfs::{ + file::sysfs_emit_str, sysfs_instance, Attribute, SysFSOpsSupport, SYSFS_ATTR_MODE_WO, + }, vfs::syscall::ModeType, }, libs::wait_queue::WaitQueue, @@ -615,7 +617,7 @@ impl Attribute for DeviceAttrStateSynced { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::SHOW + SysFSOpsSupport::ATTR_SHOW } } @@ -628,11 +630,11 @@ impl Attribute for DeviceAttrCoredump { } fn mode(&self) -> ModeType { - ModeType::from_bits_truncate(0o200) + SYSFS_ATTR_MODE_WO } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::STORE + SysFSOpsSupport::ATTR_STORE } fn store(&self, kobj: Arc, buf: &[u8]) -> Result { diff --git a/kernel/src/driver/base/device/mod.rs b/kernel/src/driver/base/device/mod.rs index f020d292..4f325a2c 100644 --- a/kernel/src/driver/base/device/mod.rs +++ b/kernel/src/driver/base/device/mod.rs @@ -711,7 +711,7 @@ impl DeviceManager { ) -> Result<(), SystemError> { if unlikely( attr.mode().contains(ModeType::S_IRUGO) - && (!attr.support().contains(SysFSOpsSupport::SHOW)), + && (!attr.support().contains(SysFSOpsSupport::ATTR_SHOW)), ) { kwarn!( "Attribute '{}': read permission without 'show'", @@ -720,7 +720,7 @@ impl DeviceManager { } if unlikely( attr.mode().contains(ModeType::S_IWUGO) - && (!attr.support().contains(SysFSOpsSupport::STORE)), + && (!attr.support().contains(SysFSOpsSupport::ATTR_STORE)), ) { kwarn!( "Attribute '{}': write permission without 'store'", @@ -847,7 +847,7 @@ impl Attribute for DeviceAttrDev { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::SHOW + SysFSOpsSupport::ATTR_SHOW } } diff --git a/kernel/src/driver/video/fbdev/base/fbcon.rs b/kernel/src/driver/video/fbdev/base/fbcon.rs index d1ff6714..73ae422d 100644 --- a/kernel/src/driver/video/fbdev/base/fbcon.rs +++ b/kernel/src/driver/video/fbdev/base/fbcon.rs @@ -268,7 +268,7 @@ impl Attribute for AttrRotate { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE + SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE } /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3226 @@ -297,7 +297,7 @@ impl Attribute for AttrRotateAll { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::STORE + SysFSOpsSupport::ATTR_STORE } /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3204 @@ -320,7 +320,7 @@ impl Attribute for AttrCursorBlink { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE + SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE } /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3245 diff --git a/kernel/src/driver/video/fbdev/base/fbsysfs.rs b/kernel/src/driver/video/fbdev/base/fbsysfs.rs index df6aa938..0020ec1d 100644 --- a/kernel/src/driver/video/fbdev/base/fbsysfs.rs +++ b/kernel/src/driver/video/fbdev/base/fbsysfs.rs @@ -57,7 +57,7 @@ impl Attribute for AttrName { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::SHOW + SysFSOpsSupport::ATTR_SHOW } fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { @@ -81,7 +81,7 @@ impl Attribute for AttrBitsPerPixel { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE + SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE } fn store(&self, _kobj: Arc, _buf: &[u8]) -> Result { @@ -111,7 +111,7 @@ impl Attribute for AttrBlank { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::STORE + SysFSOpsSupport::ATTR_STORE } // todo: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbsysfs.c#309 @@ -134,7 +134,7 @@ impl Attribute for AttrMode { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE + SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE } /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbsysfs.c#166 @@ -161,7 +161,7 @@ impl Attribute for AttrModes { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE + SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE } /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbsysfs.c#206 @@ -188,7 +188,7 @@ impl Attribute for AttrPan { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE + SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE } fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { @@ -217,7 +217,7 @@ impl Attribute for AttrVirtualSize { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE + SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE } fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { @@ -249,7 +249,7 @@ impl Attribute for AttrStride { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::SHOW + SysFSOpsSupport::ATTR_SHOW } fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { @@ -273,7 +273,7 @@ impl Attribute for AttrRotate { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE + SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE } fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { @@ -303,7 +303,7 @@ impl Attribute for AttrState { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE + SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE } fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { diff --git a/kernel/src/driver/video/fbdev/vesafb.rs b/kernel/src/driver/video/fbdev/vesafb.rs index c71d78dd..a673e9bd 100644 --- a/kernel/src/driver/video/fbdev/vesafb.rs +++ b/kernel/src/driver/video/fbdev/vesafb.rs @@ -575,7 +575,7 @@ impl Attribute for AnonAttrPhysAddr { } fn support(&self) -> SysFSOpsSupport { - SysFSOpsSupport::SHOW + SysFSOpsSupport::ATTR_SHOW } fn show(&self, _kobj: Arc, buf: &mut [u8]) -> Result { diff --git a/kernel/src/exception/irqdata.rs b/kernel/src/exception/irqdata.rs index 7fe9bb68..e57a10c4 100644 --- a/kernel/src/exception/irqdata.rs +++ b/kernel/src/exception/irqdata.rs @@ -60,6 +60,35 @@ impl IrqData { pub fn irq(&self) -> IrqNumber { self.irq } + + pub fn hardware_irq(&self) -> HardwareIrqNumber { + self.inner.lock_irqsave().hwirq + } + + pub fn chip(&self) -> Arc { + self.inner.lock_irqsave().chip.clone() + } + + /// 是否为电平触发 + pub fn is_level_type(&self) -> bool { + self.inner + .lock_irqsave() + .common_data + .inner + .lock() + .state + .is_level_type() + } + + pub fn is_wakeup_set(&self) -> bool { + self.inner + .lock_irqsave() + .common_data + .inner + .lock() + .state + .is_wakeup_set() + } } #[allow(dead_code)] diff --git a/kernel/src/exception/irqdesc.rs b/kernel/src/exception/irqdesc.rs index c7e558db..067c20d9 100644 --- a/kernel/src/exception/irqdesc.rs +++ b/kernel/src/exception/irqdesc.rs @@ -1,8 +1,8 @@ use core::{any::Any, fmt::Debug}; use alloc::{ - collections::BTreeMap, - string::String, + collections::{btree_map, BTreeMap}, + string::{String, ToString}, sync::{Arc, Weak}, vec::Vec, }; @@ -27,7 +27,7 @@ use super::{ dummychip::no_irq_chip, handle::bad_irq_handler, irqdata::{IrqCommonData, IrqData, IrqStatus}, - sysfs::IrqKObjType, + sysfs::{irq_sysfs_del, IrqKObjType}, HardwareIrqNumber, InterruptArch, IrqNumber, }; @@ -65,6 +65,7 @@ impl IrqDesc { inner: SpinLock::new(InnerIrqDesc { common_data, irq_data, + desc_internal_state: IrqDescState::empty(), actions: Vec::new(), name, parent_irq: None, @@ -93,9 +94,45 @@ impl IrqDesc { self.inner.lock_irqsave() } + pub fn actions(&self) -> Vec> { + self.inner().actions.clone() + } + pub fn irq(&self) -> IrqNumber { self.inner().irq_data.irq() } + + pub fn hardware_irq(&self) -> HardwareIrqNumber { + self.inner().irq_data.hardware_irq() + } + + pub fn irq_data(&self) -> Arc { + self.inner().irq_data.clone() + } + + /// 标记当前irq描述符已经被添加到sysfs + pub fn mark_in_sysfs(&self) { + self.inner() + .desc_internal_state + .insert(IrqDescState::IRQS_SYSFS); + } + + pub fn mark_not_in_sysfs(&self) { + self.inner() + .desc_internal_state + .remove(IrqDescState::IRQS_SYSFS); + } + + /// 判断当前描述符是否已经添加到了sysfs + pub fn in_sysfs(&self) -> bool { + self.inner() + .desc_internal_state + .contains(IrqDescState::IRQS_SYSFS) + } + + pub fn name(&self) -> Option { + self.inner().name.clone() + } } #[allow(dead_code)] @@ -111,6 +148,7 @@ struct InnerIrqDesc { depth: u32, /// nested wake enables wake_depth: u32, + desc_internal_state: IrqDescState, kern_inode: Option>, kset: Option>, @@ -153,7 +191,7 @@ impl KObject for IrqDesc { fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {} fn name(&self) -> String { - self.inner().name.clone().unwrap_or_else(|| format!("")) + self.inner().irq_data.irq().data().to_string() } fn set_name(&self, _name: String) {} @@ -171,6 +209,32 @@ impl KObject for IrqDesc { } } +bitflags! { + /// Bit masks for desc->desc_internal_state + struct IrqDescState: u32 { + /// autodetection in progress + const IRQS_AUTODETECT = 0x00000001; + /// was disabled due to spurious interrupt detection + const IRQS_SPURIOUS_DISABLED = 0x00000002; + /// polling in progress + const IRQS_POLL_INPROGRESS = 0x00000008; + /// irq is not unmasked in primary handler + const IRQS_ONESHOT = 0x00000020; + /// irq is replayed + const IRQS_REPLAY = 0x00000040; + /// irq is waiting + const IRQS_WAITING = 0x00000080; + /// irq is pending and replayed later + const IRQS_PENDING = 0x00000200; + /// irq is suspended + const IRQS_SUSPENDED = 0x00000800; + /// irq line is used to deliver NMIs + const IRQS_NMI = 0x00002000; + /// descriptor has been added to sysfs + const IRQS_SYSFS = 0x00004000; + } +} + /// 每个中断的响应动作的描述符 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/interrupt.h#118 #[allow(dead_code)] @@ -201,6 +265,14 @@ impl IrqAction { return Arc::new(action); } + + pub fn name(&self) -> String { + self.inner().name.clone() + } + + fn inner(&self) -> SpinLockGuard { + self.inner.lock_irqsave() + } } #[allow(dead_code)] @@ -268,9 +340,21 @@ pub(super) fn early_irq_init() -> Result<(), SystemError> { manager.insert(IrqNumber::new(i), irq_desc); } + unsafe { + IRQ_DESC_MANAGER = Some(manager); + } + return CurrentIrqArch::arch_early_irq_init(); } +static mut IRQ_DESC_MANAGER: Option = None; + +/// 获取中断描述符管理器的引用 +#[inline(always)] +pub(super) fn irq_desc_manager() -> &'static IrqDescManager { + return unsafe { IRQ_DESC_MANAGER.as_ref().unwrap() }; +} + pub(super) struct IrqDescManager { irq_descs: BTreeMap>, } @@ -291,4 +375,18 @@ impl IrqDescManager { fn insert(&mut self, irq: IrqNumber, desc: Arc) { self.irq_descs.insert(irq, desc); } + + /// 释放中断描述符 + #[allow(dead_code)] + fn free_desc(&mut self, irq: IrqNumber) { + if let Some(desc) = self.irq_descs.get(&irq) { + irq_sysfs_del(desc); + self.irq_descs.remove(&irq); + } + } + + /// 迭代中断描述符 + pub fn iter_descs(&self) -> btree_map::Iter<'_, IrqNumber, Arc> { + self.irq_descs.iter() + } } diff --git a/kernel/src/exception/sysfs.rs b/kernel/src/exception/sysfs.rs index 7efd5991..31e60567 100644 --- a/kernel/src/exception/sysfs.rs +++ b/kernel/src/exception/sysfs.rs @@ -1,16 +1,37 @@ -use alloc::sync::Arc; +use alloc::{string::ToString, sync::Arc}; use system_error::SystemError; use unified_init::macros::unified_init; use crate::{ - driver::base::kobject::{KObjType, KObject, KObjectSysFSOps}, + driver::base::{ + kobject::{KObjType, KObject, KObjectManager, KObjectSysFSOps}, + kset::KSet, + }, filesystem::{ - sysfs::{Attribute, AttributeGroup, SysFSOps}, + sysfs::{ + file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport, + SYSFS_ATTR_MODE_RO, + }, vfs::syscall::ModeType, }, init::initcall::INITCALL_POSTCORE, + misc::ksysfs::sys_kernel_kset, }; +use super::{ + irqdesc::{irq_desc_manager, IrqDesc}, + IrqNumber, +}; + +/// `/sys/kernel/irq`的kset +static mut SYS_KERNEL_IRQ_KSET_INSTANCE: Option> = None; + +#[inline(always)] +#[allow(dead_code)] +pub fn sys_kernel_irq_kset() -> Arc { + unsafe { SYS_KERNEL_IRQ_KSET_INSTANCE.clone().unwrap() } +} + /// 中断描述符的kobjtype /// /// https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdesc.c#280 @@ -40,9 +61,20 @@ impl AttributeGroup for IrqAttrGroup { None } + /// 所有的属性 + /// + /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdesc.c#268 fn attrs(&self) -> &[&'static dyn Attribute] { - todo!("irq_attr_group.attrs") - // todo: https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdesc.c#268 + // 每个irq的属性 + // todo: 添加per_cpu_count属性 + &[ + &AttrChipName, + &AttrHardwareIrq, + &AttrType, + &AttrWakeup, + &AttrName, + &AttrActions, + ] } fn is_visible( @@ -60,6 +92,229 @@ impl AttributeGroup for IrqAttrGroup { #[unified_init(INITCALL_POSTCORE)] fn irq_sysfs_init() -> Result<(), SystemError> { // todo!("irq_sysfs_init"); - kwarn!("Unimplemented: irq_sysfs_init"); - Ok(()) + + let irq_kset = KSet::new("irq".to_string()); + irq_kset + .register(Some(sys_kernel_kset())) + .expect("register irq kset failed"); + unsafe { + SYS_KERNEL_IRQ_KSET_INSTANCE = Some(irq_kset); + } + + // 把所有的irq都注册到/sys/kernel/irq下 + for (irq, desc) in irq_desc_manager().iter_descs() { + irq_sysfs_add(irq, desc); + } + + return Ok(()); +} + +/// 把irqdesc添加到sysfs +fn irq_sysfs_add(irq: &IrqNumber, desc: &Arc) { + if unsafe { SYS_KERNEL_IRQ_KSET_INSTANCE.is_none() } { + return; + } + + let kset = sys_kernel_irq_kset(); + KObjectManager::add_kobj(desc.clone() as Arc, Some(kset)).unwrap_or_else(|e| { + kwarn!("Failed to add irq({irq:?}) kobject to sysfs: {:?}", e); + }); + + desc.mark_in_sysfs(); +} + +/// 从sysfs中删除irqdesc +#[allow(dead_code)] +pub(super) fn irq_sysfs_del(desc: &Arc) { + if desc.in_sysfs() { + KObjectManager::remove_kobj(desc.clone() as Arc); + desc.mark_not_in_sysfs(); + } +} +#[derive(Debug)] +struct AttrChipName; + +impl Attribute for AttrChipName { + fn name(&self) -> &str { + "chip_name" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { + let irq_desc = kobj + .arc_any() + .downcast::() + .map_err(|_| SystemError::EINVAL)?; + let chip = irq_desc.irq_data().chip(); + let name = chip.name(); + let len = core::cmp::min(name.len() + 1, buf.len()); + let name = format!("{}\n", name); + buf[..len].copy_from_slice(name.as_bytes()); + return Ok(len); + } +} + +#[derive(Debug)] +struct AttrHardwareIrq; + +impl Attribute for AttrHardwareIrq { + fn name(&self) -> &str { + "hwirq" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { + let irq_desc = kobj + .arc_any() + .downcast::() + .map_err(|_| SystemError::EINVAL)?; + let hwirq = irq_desc.hardware_irq(); + return sysfs_emit_str(buf, &format!("{}\n", hwirq.data())); + } +} + +#[derive(Debug)] +struct AttrType; + +impl Attribute for AttrType { + fn name(&self) -> &str { + "type" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { + let irq_desc = kobj + .arc_any() + .downcast::() + .map_err(|_| SystemError::EINVAL)?; + let irq_type = if irq_desc.irq_data().is_level_type() { + "level" + } else { + "edge" + }; + + return sysfs_emit_str(buf, &format!("{}\n", irq_type)); + } +} + +#[derive(Debug)] +struct AttrWakeup; + +impl Attribute for AttrWakeup { + fn name(&self) -> &str { + "wakeup" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { + let irq_desc = kobj + .arc_any() + .downcast::() + .map_err(|_| SystemError::EINVAL)?; + let wakeup = irq_desc.irq_data().is_wakeup_set(); + return sysfs_emit_str(buf, &format!("{}\n", wakeup)); + } +} + +#[derive(Debug)] +struct AttrName; + +impl Attribute for AttrName { + fn name(&self) -> &str { + "name" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { + let irq_desc = kobj + .arc_any() + .downcast::() + .map_err(|_| SystemError::EINVAL)?; + + if let Some(name) = irq_desc.name() { + return sysfs_emit_str(buf, &format!("{}\n", name)); + } + + return Ok(0); + } +} + +#[derive(Debug)] +struct AttrActions; + +impl Attribute for AttrActions { + fn name(&self) -> &str { + "actions" + } + + fn mode(&self) -> ModeType { + SYSFS_ATTR_MODE_RO + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::ATTR_SHOW + } + + fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { + let irq_desc = kobj + .arc_any() + .downcast::() + .map_err(|_| SystemError::EINVAL)?; + + let actions = irq_desc.actions(); + let mut len = 0; + + for action in actions { + if len != 0 { + len += sysfs_emit_str(&mut buf[len..], &format!(",{}", action.name())).unwrap(); + } else { + len += sysfs_emit_str(&mut buf[len..], &format!("{}", action.name())).unwrap(); + } + + if len >= buf.len() { + break; + } + } + + if len != 0 && len < buf.len() { + len += sysfs_emit_str(&mut buf[len..], "\n").unwrap(); + } + + return Ok(len); + } } diff --git a/kernel/src/filesystem/sysfs/file.rs b/kernel/src/filesystem/sysfs/file.rs index 93fd706b..033a5389 100644 --- a/kernel/src/filesystem/sysfs/file.rs +++ b/kernel/src/filesystem/sysfs/file.rs @@ -139,13 +139,13 @@ impl SysFS { let sys_support = sysfs_ops.support(attr); let kern_callback: &'static dyn KernFSCallback; - if sys_support.contains(SysFSOpsSupport::SHOW) - && sys_support.contains(SysFSOpsSupport::STORE) + if sys_support.contains(SysFSOpsSupport::ATTR_SHOW) + && sys_support.contains(SysFSOpsSupport::ATTR_STORE) { kern_callback = &PreallocKFOpsRW; - } else if sys_support.contains(SysFSOpsSupport::SHOW) { + } else if sys_support.contains(SysFSOpsSupport::ATTR_SHOW) { kern_callback = &PreallocKFOpsReadOnly; - } else if sys_support.contains(SysFSOpsSupport::STORE) { + } else if sys_support.contains(SysFSOpsSupport::ATTR_STORE) { kern_callback = &PreallocKFOpsWriteOnly; } else { kern_callback = &PreallocKFOpsEmpty; @@ -250,13 +250,13 @@ impl SysFS { let kern_callback: &'static dyn KernFSCallback; let bin_support = attr.support_battr(); - if bin_support.contains(SysFSOpsSupport::READ) - && bin_support.contains(SysFSOpsSupport::WRITE) + if bin_support.contains(SysFSOpsSupport::BATTR_READ) + && bin_support.contains(SysFSOpsSupport::BATTR_WRITE) { kern_callback = &PreallocKFOpsRW; - } else if bin_support.contains(SysFSOpsSupport::READ) { + } else if bin_support.contains(SysFSOpsSupport::BATTR_READ) { kern_callback = &PreallocKFOpsReadOnly; - } else if bin_support.contains(SysFSOpsSupport::WRITE) { + } else if bin_support.contains(SysFSOpsSupport::BATTR_WRITE) { kern_callback = &PreallocKFOpsWriteOnly; } else { kern_callback = &PreallocKFOpsEmpty; diff --git a/kernel/src/filesystem/sysfs/mod.rs b/kernel/src/filesystem/sysfs/mod.rs index 5049bc7b..f35b519c 100644 --- a/kernel/src/filesystem/sysfs/mod.rs +++ b/kernel/src/filesystem/sysfs/mod.rs @@ -110,6 +110,13 @@ pub trait AttributeGroup: Debug + Send + Sync { fn is_visible(&self, kobj: Arc, attr: &'static dyn Attribute) -> Option; } +/// sysfs只读属性文件的权限 +pub const SYSFS_ATTR_MODE_RO: ModeType = ModeType::from_bits_truncate(0o444); +/// sysfs只写属性文件的权限 +pub const SYSFS_ATTR_MODE_WO: ModeType = ModeType::from_bits_truncate(0o200); +/// sysfs读写属性文件的权限 +pub const SYSFS_ATTR_MODE_RW: ModeType = ModeType::from_bits_truncate(0o644); + /// sysfs文件的属性 pub trait Attribute: Debug + Send + Sync { fn name(&self) -> &str; @@ -178,11 +185,11 @@ pub trait SysFSOps: Debug { bitflags! { pub struct SysFSOpsSupport: u8{ // === for attribute === - const SHOW = 1 << 0; - const STORE = 1 << 1; + const ATTR_SHOW = 1 << 0; + const ATTR_STORE = 1 << 1; // === for bin attribute === - const READ = 1 << 2; - const WRITE = 1 << 3; + const BATTR_READ = 1 << 2; + const BATTR_WRITE = 1 << 3; } } diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 3ea26851..6eb7334c 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -45,6 +45,7 @@ mod exception; mod filesystem; mod init; mod ipc; +mod misc; mod mm; mod net; mod process; diff --git a/kernel/src/misc/ksysfs.rs b/kernel/src/misc/ksysfs.rs new file mode 100644 index 00000000..f4f45248 --- /dev/null +++ b/kernel/src/misc/ksysfs.rs @@ -0,0 +1,63 @@ +use crate::{ + driver::base::{kobject::KObject, kset::KSet}, + filesystem::{ + sysfs::{sysfs_instance, Attribute, AttributeGroup}, + vfs::syscall::ModeType, + }, + init::initcall::INITCALL_CORE, +}; +use alloc::{string::ToString, sync::Arc}; +use system_error::SystemError; +use unified_init::macros::unified_init; + +/// `/sys/kernel`的kset +static mut KERNEL_KSET_INSTANCE: Option> = None; + +#[inline(always)] +#[allow(dead_code)] +pub fn sys_kernel_kset() -> Arc { + unsafe { KERNEL_KSET_INSTANCE.clone().unwrap() } +} + +#[unified_init(INITCALL_CORE)] +fn ksysfs_init() -> Result<(), SystemError> { + let kernel_kset = KSet::new("kernel".to_string()); + kernel_kset + .register(None) + .expect("register kernel kset failed"); + + sysfs_instance() + .create_groups(&kernel_kset.as_kobject(), &[&KernelAttrGroup]) + .map_err(|e| { + kerror!("Failed to create sysfs groups for kernel kset: {:?}", e); + kernel_kset.unregister(); + SystemError::ENOMEM + })?; + + unsafe { + KERNEL_KSET_INSTANCE = Some(kernel_kset); + } + + return Ok(()); +} + +#[derive(Debug)] +struct KernelAttrGroup; + +impl AttributeGroup for KernelAttrGroup { + fn name(&self) -> Option<&str> { + None + } + + fn attrs(&self) -> &[&'static dyn Attribute] { + &[] + } + + fn is_visible( + &self, + _kobj: Arc, + attr: &'static dyn Attribute, + ) -> Option { + Some(attr.mode()) + } +} diff --git a/kernel/src/misc/mod.rs b/kernel/src/misc/mod.rs new file mode 100644 index 00000000..9d8a9774 --- /dev/null +++ b/kernel/src/misc/mod.rs @@ -0,0 +1 @@ +pub mod ksysfs;