把irqdesc添加到sysfs (#525)

* 把irqdesc添加到sysfs
This commit is contained in:
LoGin 2024-02-19 00:56:58 +08:00 committed by GitHub
parent 3bc96fa4a9
commit 196b75dc17
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 515 additions and 56 deletions

View File

@ -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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
@ -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,

View File

@ -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
}
}

View File

@ -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<dyn KObject>, buf: &[u8]) -> Result<usize, SystemError> {

View File

@ -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
}
}

View File

@ -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

View File

@ -57,7 +57,7 @@ impl Attribute for AttrName {
}
fn support(&self) -> SysFSOpsSupport {
SysFSOpsSupport::SHOW
SysFSOpsSupport::ATTR_SHOW
}
fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
@ -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<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
@ -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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
@ -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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
@ -249,7 +249,7 @@ impl Attribute for AttrStride {
}
fn support(&self) -> SysFSOpsSupport {
SysFSOpsSupport::SHOW
SysFSOpsSupport::ATTR_SHOW
}
fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
@ -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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
@ -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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {

View File

@ -575,7 +575,7 @@ impl Attribute for AnonAttrPhysAddr {
}
fn support(&self) -> SysFSOpsSupport {
SysFSOpsSupport::SHOW
SysFSOpsSupport::ATTR_SHOW
}
fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {

View File

@ -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<dyn IrqChip> {
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)]

View File

@ -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<Arc<IrqAction>> {
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<IrqData> {
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<String> {
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<Arc<KernFSInode>>,
kset: Option<Arc<KSet>>,
@ -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<InnerIrqAction> {
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<IrqDescManager> = 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<IrqNumber, Arc<IrqDesc>>,
}
@ -291,4 +375,18 @@ impl IrqDescManager {
fn insert(&mut self, irq: IrqNumber, desc: Arc<IrqDesc>) {
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<IrqDesc>> {
self.irq_descs.iter()
}
}

View File

@ -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<Arc<KSet>> = None;
#[inline(always)]
#[allow(dead_code)]
pub fn sys_kernel_irq_kset() -> Arc<KSet> {
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<IrqDesc>) {
if unsafe { SYS_KERNEL_IRQ_KSET_INSTANCE.is_none() } {
return;
}
let kset = sys_kernel_irq_kset();
KObjectManager::add_kobj(desc.clone() as Arc<dyn KObject>, 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<IrqDesc>) {
if desc.in_sysfs() {
KObjectManager::remove_kobj(desc.clone() as Arc<dyn KObject>);
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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
let irq_desc = kobj
.arc_any()
.downcast::<IrqDesc>()
.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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
let irq_desc = kobj
.arc_any()
.downcast::<IrqDesc>()
.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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
let irq_desc = kobj
.arc_any()
.downcast::<IrqDesc>()
.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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
let irq_desc = kobj
.arc_any()
.downcast::<IrqDesc>()
.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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
let irq_desc = kobj
.arc_any()
.downcast::<IrqDesc>()
.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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
let irq_desc = kobj
.arc_any()
.downcast::<IrqDesc>()
.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);
}
}

View File

@ -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;

View File

@ -110,6 +110,13 @@ pub trait AttributeGroup: Debug + Send + Sync {
fn is_visible(&self, kobj: Arc<dyn KObject>, attr: &'static dyn Attribute) -> Option<ModeType>;
}
/// 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;
}
}

View File

@ -45,6 +45,7 @@ mod exception;
mod filesystem;
mod init;
mod ipc;
mod misc;
mod mm;
mod net;
mod process;

63
kernel/src/misc/ksysfs.rs Normal file
View File

@ -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<Arc<KSet>> = None;
#[inline(always)]
#[allow(dead_code)]
pub fn sys_kernel_kset() -> Arc<KSet> {
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<dyn KObject>,
attr: &'static dyn Attribute,
) -> Option<ModeType> {
Some(attr.mode())
}
}

1
kernel/src/misc/mod.rs Normal file
View File

@ -0,0 +1 @@
pub mod ksysfs;