xref: /DragonOS/kernel/src/driver/base/cpu.rs (revision fae6e9ade46a52976ad5d099643d51cc20876448)
1 use core::any::Any;
2 
3 use alloc::{
4     string::{String, ToString},
5     sync::{Arc, Weak},
6 };
7 
8 use crate::{
9     driver::acpi::acpi_manager,
10     filesystem::kernfs::KernFSInode,
11     libs::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
12 };
13 
14 use super::{
15     class::Class,
16     device::{
17         bus::{subsystem_manager, Bus},
18         driver::Driver,
19         Device, DeviceCommonData, DeviceType, IdTable,
20     },
21     kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
22     kset::KSet,
23     subsys::SubSysPrivate,
24 };
25 use crate::filesystem::sysfs::file::sysfs_emit_str;
26 use crate::filesystem::sysfs::{Attribute, AttributeGroup, SysFSOpsSupport};
27 use crate::filesystem::vfs::syscall::ModeType;
28 use crate::libs::lazy_init::Lazy;
29 use system_error::SystemError;
30 
31 static CPU_DEVICE_MANAGER: Lazy<CpuDeviceManager> = Lazy::new();
32 
33 #[derive(Debug)]
34 pub struct CpuDeviceManager {
35     _root_device: Arc<CpuSubSystemFakeRootDevice>,
36 }
37 
38 impl CpuDeviceManager {
39     /// 初始化设备驱动模型的CPU子系统
40     ///
41     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/cpu.c?fi=get_cpu_device#622
init() -> Result<(), SystemError>42     pub fn init() -> Result<(), SystemError> {
43         let cpu_subsys = CpuSubSystem::new();
44         let root_device = CpuSubSystemFakeRootDevice::new();
45         subsystem_manager()
46             .subsys_system_register(
47                 &(cpu_subsys as Arc<dyn Bus>),
48                 &(root_device.clone() as Arc<dyn Device>),
49             )
50             .expect("register cpu subsys failed");
51         let manager = Self {
52             _root_device: root_device,
53         };
54         CPU_DEVICE_MANAGER.init(manager);
55         return Ok(());
56     }
57 }
58 
59 /// cpu子系统
60 ///
61 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/cpu.c?fi=get_cpu_device#128
62 #[derive(Debug)]
63 struct CpuSubSystem {
64     subsys_private: SubSysPrivate,
65 }
66 
67 impl CpuSubSystem {
new() -> Arc<Self>68     pub fn new() -> Arc<Self> {
69         let bus = Arc::new(Self {
70             subsys_private: SubSysPrivate::new("cpu".to_string(), None, None, &[]),
71         });
72         bus.subsystem()
73             .set_bus(Some(Arc::downgrade(&(bus.clone() as Arc<dyn Bus>))));
74         return bus;
75     }
76 }
77 
78 impl Bus for CpuSubSystem {
name(&self) -> String79     fn name(&self) -> String {
80         "cpu".to_string()
81     }
82 
dev_name(&self) -> String83     fn dev_name(&self) -> String {
84         self.name()
85     }
86 
remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError>87     fn remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
88         todo!()
89     }
90 
shutdown(&self, _device: &Arc<dyn Device>)91     fn shutdown(&self, _device: &Arc<dyn Device>) {
92         todo!()
93     }
94 
resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError>95     fn resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
96         todo!()
97     }
98 
match_device( &self, device: &Arc<dyn Device>, driver: &Arc<dyn Driver>, ) -> Result<bool, SystemError>99     fn match_device(
100         &self,
101         device: &Arc<dyn Device>,
102         driver: &Arc<dyn Driver>,
103     ) -> Result<bool, SystemError> {
104         // ACPI style match is the only one that may succeed.
105         return acpi_manager().driver_match_device(driver, device);
106     }
107 
subsystem(&self) -> &SubSysPrivate108     fn subsystem(&self) -> &SubSysPrivate {
109         &self.subsys_private
110     }
111 }
112 
113 #[derive(Debug)]
114 #[cast_to([sync] Device)]
115 pub struct CpuSubSystemFakeRootDevice {
116     inner: RwLock<InnerCpuSubSystemFakeRootDevice>,
117     kobj_state: LockedKObjectState,
118 }
119 
120 impl CpuSubSystemFakeRootDevice {
new() -> Arc<Self>121     pub fn new() -> Arc<Self> {
122         return Arc::new(Self {
123             inner: RwLock::new(InnerCpuSubSystemFakeRootDevice::new()),
124             kobj_state: LockedKObjectState::new(None),
125         });
126     }
127 }
128 
129 #[derive(Debug)]
130 struct InnerCpuSubSystemFakeRootDevice {
131     kobject_common: KObjectCommonData,
132     device_common: DeviceCommonData,
133     name: String,
134 }
135 
136 impl InnerCpuSubSystemFakeRootDevice {
new() -> Self137     pub fn new() -> Self {
138         return Self {
139             kobject_common: KObjectCommonData::default(),
140             device_common: DeviceCommonData::default(),
141             name: "".to_string(),
142         };
143     }
144 }
145 
146 impl Device for CpuSubSystemFakeRootDevice {
dev_type(&self) -> DeviceType147     fn dev_type(&self) -> DeviceType {
148         todo!()
149     }
150 
id_table(&self) -> IdTable151     fn id_table(&self) -> IdTable {
152         IdTable::new("cpu".to_string(), None)
153     }
154 
set_bus(&self, bus: Option<Weak<dyn Bus>>)155     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
156         self.inner.write().device_common.bus = bus;
157     }
158 
bus(&self) -> Option<Weak<dyn Bus>>159     fn bus(&self) -> Option<Weak<dyn Bus>> {
160         self.inner.read().device_common.bus.clone()
161     }
162 
driver(&self) -> Option<Arc<dyn Driver>>163     fn driver(&self) -> Option<Arc<dyn Driver>> {
164         None
165     }
166 
set_driver(&self, _driver: Option<Weak<dyn Driver>>)167     fn set_driver(&self, _driver: Option<Weak<dyn Driver>>) {
168         todo!()
169     }
170 
is_dead(&self) -> bool171     fn is_dead(&self) -> bool {
172         false
173     }
174 
can_match(&self) -> bool175     fn can_match(&self) -> bool {
176         todo!()
177     }
178 
set_can_match(&self, _can_match: bool)179     fn set_can_match(&self, _can_match: bool) {
180         todo!()
181     }
182 
state_synced(&self) -> bool183     fn state_synced(&self) -> bool {
184         true
185     }
186 
set_class(&self, _class: Option<Weak<dyn Class>>)187     fn set_class(&self, _class: Option<Weak<dyn Class>>) {
188         todo!()
189     }
190 
dev_parent(&self) -> Option<Weak<dyn Device>>191     fn dev_parent(&self) -> Option<Weak<dyn Device>> {
192         self.inner.read().device_common.parent.clone()
193     }
194 
set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>)195     fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
196         self.inner.write().device_common.parent = dev_parent;
197     }
198 
attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>199     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
200         Some(&[&AttrGroupCpu])
201     }
202 }
203 
204 impl KObject for CpuSubSystemFakeRootDevice {
as_any_ref(&self) -> &dyn Any205     fn as_any_ref(&self) -> &dyn Any {
206         self
207     }
208 
set_inode(&self, inode: Option<Arc<KernFSInode>>)209     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
210         self.inner.write().kobject_common.kern_inode = inode;
211     }
212 
inode(&self) -> Option<Arc<KernFSInode>>213     fn inode(&self) -> Option<Arc<KernFSInode>> {
214         self.inner.read().kobject_common.kern_inode.clone()
215     }
216 
parent(&self) -> Option<Weak<dyn KObject>>217     fn parent(&self) -> Option<Weak<dyn KObject>> {
218         self.inner.read().kobject_common.parent.clone()
219     }
220 
set_parent(&self, parent: Option<Weak<dyn KObject>>)221     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
222         self.inner.write().kobject_common.parent = parent;
223     }
224 
kset(&self) -> Option<Arc<KSet>>225     fn kset(&self) -> Option<Arc<KSet>> {
226         self.inner.read().kobject_common.kset.clone()
227     }
228 
set_kset(&self, kset: Option<Arc<KSet>>)229     fn set_kset(&self, kset: Option<Arc<KSet>>) {
230         self.inner.write().kobject_common.kset = kset;
231     }
232 
kobj_type(&self) -> Option<&'static dyn KObjType>233     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
234         self.inner.read().kobject_common.kobj_type
235     }
236 
set_kobj_type(&self, ktype: Option<&'static dyn KObjType>)237     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
238         self.inner.write().kobject_common.kobj_type = ktype;
239     }
240 
name(&self) -> String241     fn name(&self) -> String {
242         self.inner.read().name.clone()
243     }
244 
set_name(&self, name: String)245     fn set_name(&self, name: String) {
246         self.inner.write().name = name;
247     }
248 
kobj_state(&self) -> RwLockReadGuard<KObjectState>249     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
250         self.kobj_state.read()
251     }
252 
kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>253     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
254         self.kobj_state.write()
255     }
256 
set_kobj_state(&self, state: KObjectState)257     fn set_kobj_state(&self, state: KObjectState) {
258         *self.kobj_state_mut() = state;
259     }
260 }
261 
262 #[derive(Debug)]
263 pub struct AttrGroupCpu;
264 
265 impl AttributeGroup for AttrGroupCpu {
name(&self) -> Option<&str>266     fn name(&self) -> Option<&str> {
267         None
268     }
attrs(&self) -> &[&'static dyn Attribute]269     fn attrs(&self) -> &[&'static dyn Attribute] {
270         &[&AttrCpuPossible, &AttrCpuOnline]
271     }
is_visible( &self, _kobj: Arc<dyn KObject>, _attr: &'static dyn Attribute, ) -> Option<ModeType>272     fn is_visible(
273         &self,
274         _kobj: Arc<dyn KObject>,
275         _attr: &'static dyn Attribute,
276     ) -> Option<ModeType> {
277         None
278     }
279 }
280 
281 #[derive(Debug)]
282 pub struct AttrCpuPossible;
283 
284 impl Attribute for AttrCpuPossible {
name(&self) -> &str285     fn name(&self) -> &str {
286         "possible"
287     }
288 
mode(&self) -> ModeType289     fn mode(&self) -> ModeType {
290         ModeType::S_IRUGO
291     }
292 
support(&self) -> SysFSOpsSupport293     fn support(&self) -> SysFSOpsSupport {
294         SysFSOpsSupport::ATTR_SHOW
295     }
296 
show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>297     fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
298         let cpu_manager = crate::smp::cpu::smp_cpu_manager();
299         let cpus = cpu_manager.possible_cpus_count();
300         let data = format!("0-{}", cpus - 1);
301         sysfs_emit_str(buf, &data)
302     }
303 }
304 
305 #[derive(Debug)]
306 pub struct AttrCpuOnline;
307 
308 impl Attribute for AttrCpuOnline {
name(&self) -> &str309     fn name(&self) -> &str {
310         "online"
311     }
312 
mode(&self) -> ModeType313     fn mode(&self) -> ModeType {
314         ModeType::S_IRUGO
315     }
316 
support(&self) -> SysFSOpsSupport317     fn support(&self) -> SysFSOpsSupport {
318         SysFSOpsSupport::ATTR_SHOW
319     }
320 
show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>321     fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
322         let cpu_manager = crate::smp::cpu::smp_cpu_manager();
323         let cpus = cpu_manager.present_cpus_count();
324         let data = format!("0-{}", cpus - 1);
325         sysfs_emit_str(buf, &data)
326     }
327 }
328