LoGin 7eda31b2f0
在Sysfs中引入ACPI Firmware (#405)
- bugfix: multiboot2启动的信息因为没及时转存导致后面无法从其中进行查询的bug
- feature: 把acpi表、acpi bus加入sysfs
2023-10-22 22:00:16 +08:00

220 lines
5.7 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use alloc::{
string::String,
sync::{Arc, Weak},
vec::Vec,
};
use core::hash::Hash;
use crate::{
filesystem::kernfs::KernFSInode,
libs::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
syscall::SystemError,
};
use super::kobject::{
DynamicKObjKType, KObjType, KObject, KObjectManager, KObjectState, LockedKObjectState,
};
#[derive(Debug)]
pub struct KSet {
/// 属于当前kset的kobject
kobjects: RwLock<Vec<Weak<dyn KObject>>>,
/// 节点的一些信息
inner: RwLock<InnerKSet>,
/// kobject的状态
kobj_state: LockedKObjectState,
/// 与父节点有关的一些信息
parent_data: RwLock<KSetParentData>,
self_ref: Weak<KSet>,
}
impl Hash for KSet {
fn hash<H: ~const core::hash::Hasher>(&self, state: &mut H) {
self.self_ref.as_ptr().hash(state);
self.inner.read().name.hash(state);
}
}
impl core::cmp::Eq for KSet {}
impl core::cmp::PartialEq for KSet {
fn eq(&self, other: &Self) -> bool {
self.self_ref.as_ptr() == other.self_ref.as_ptr()
}
}
impl KSet {
pub fn new(name: String) -> Arc<Self> {
let r = Self {
kobjects: RwLock::new(Vec::new()),
inner: RwLock::new(InnerKSet::new(name)),
kobj_state: LockedKObjectState::new(None),
parent_data: RwLock::new(KSetParentData::new(None, None)),
self_ref: Weak::default(),
};
let r = Arc::new(r);
unsafe {
let p = r.as_ref() as *const Self as *mut Self;
(*p).self_ref = Arc::downgrade(&r);
}
return r;
}
/// 创建一个kset并且设置它的父亲为parent_kobj。然后把这个kset注册到sysfs
///
/// ## 参数
///
/// - name: kset的名字
/// - parent_kobj: 父亲kobject
/// - join_kset: 如果不为None那么这个kset会加入到join_kset中
pub fn new_and_add(
name: String,
parent_kobj: Option<Arc<dyn KObject>>,
join_kset: Option<Arc<KSet>>,
) -> Result<Arc<Self>, SystemError> {
let kset = KSet::new(name);
if let Some(parent_kobj) = parent_kobj {
kset.set_parent(Some(Arc::downgrade(&parent_kobj)));
}
kset.register(join_kset)?;
return Ok(kset);
}
pub fn register(&self, join_kset: Option<Arc<KSet>>) -> Result<(), SystemError> {
return KObjectManager::add_kobj(self.self_ref.upgrade().unwrap(), join_kset);
// todo: 引入uevent之后发送uevent
}
/// 把一个kobject加入到当前kset中。
///
/// 该函数不会修改kobj的parent需要调用者自己视情况修改。
///
/// ## Panic
///
/// 这个kobject的kset必须是None否则会panic
pub fn join(&self, kobj: &Arc<dyn KObject>) {
assert!(kobj.kset().is_none());
kobj.set_kset(self.self_ref.upgrade());
self.kobjects.write().push(Arc::downgrade(&kobj));
}
/// 把一个kobject从当前kset中移除。
pub fn leave(&self, kobj: &Arc<dyn KObject>) {
let mut kobjects = self.kobjects.write();
let index = kobjects.iter().position(|x| {
if let Some(x) = x.upgrade() {
return Arc::ptr_eq(&x, kobj);
}
return false;
});
if let Some(index) = index {
let x = kobjects.remove(index);
let x = x.upgrade().unwrap();
drop(kobjects);
x.set_kset(None);
}
}
/// 清除所有已经被释放的kobject
#[allow(dead_code)]
pub fn cleanup_weak(&self) {
let mut kobjects = self.kobjects.write();
kobjects.drain_filter(|x| x.upgrade().is_none());
}
pub fn as_kobject(&self) -> Arc<dyn KObject> {
return self.self_ref.upgrade().unwrap();
}
}
impl KObject for KSet {
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
fn inode(&self) -> Option<Arc<KernFSInode>> {
self.inner.read().kern_inode.clone()
}
fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
self.inner.write().kern_inode = inode;
}
fn parent(&self) -> Option<Weak<dyn KObject>> {
self.parent_data.read().parent.clone()
}
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
self.parent_data.write().parent = parent;
}
fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
self.kobj_state.read()
}
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
self.kobj_state.write()
}
fn kobj_type(&self) -> Option<&'static dyn KObjType> {
self.inner.read().ktype
}
fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
self.inner.write().ktype = ktype;
}
fn kset(&self) -> Option<Arc<KSet>> {
self.parent_data.read().kset.clone()
}
fn set_kset(&self, kset: Option<Arc<KSet>>) {
self.parent_data.write().kset = kset;
}
fn name(&self) -> String {
return self.inner.read().name.clone();
}
fn set_name(&self, name: String) {
self.inner.write().name = name;
}
fn set_kobj_state(&self, state: KObjectState) {
*self.kobj_state.write() = state;
}
}
#[derive(Debug)]
struct KSetParentData {
parent: Option<Weak<dyn KObject>>,
kset: Option<Arc<KSet>>,
}
impl KSetParentData {
fn new(parent: Option<Weak<dyn KObject>>, kset: Option<Arc<KSet>>) -> Self {
Self { parent, kset }
}
}
#[derive(Debug)]
struct InnerKSet {
kern_inode: Option<Arc<KernFSInode>>,
name: String,
ktype: Option<&'static dyn KObjType>,
}
impl InnerKSet {
fn new(name: String) -> Self {
Self {
kern_inode: None,
name,
ktype: Some(&DynamicKObjKType),
}
}
}