mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 14:16:47 +00:00
parent
3bc96fa4a9
commit
196b75dc17
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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> {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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> {
|
||||
|
@ -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> {
|
||||
|
@ -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)]
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
63
kernel/src/misc/ksysfs.rs
Normal 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
1
kernel/src/misc/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod ksysfs;
|
Loading…
x
Reference in New Issue
Block a user