1 use alloc::{
2 string::String,
3 sync::{Arc, Weak},
4 };
5 use ida::IdAllocator;
6 use system_error::SystemError;
7
8 use crate::{
9 driver::base::{
10 class::Class,
11 device::{
12 bus::Bus, device_manager, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable,
13 },
14 kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
15 kset::KSet,
16 },
17 filesystem::{
18 kernfs::KernFSInode,
19 sysfs::{
20 file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport, SYSFS_ATTR_MODE_RO,
21 },
22 vfs::syscall::ModeType,
23 },
24 libs::{
25 rwlock::{RwLockReadGuard, RwLockWriteGuard},
26 spinlock::{SpinLock, SpinLockGuard},
27 },
28 };
29
30 use super::{
31 class::sys_class_rtc_instance,
32 interface::rtc_read_time,
33 utils::{kobj2rtc_device, kobj2rtc_general_device},
34 GeneralRtcPriority, RtcClassOps, RtcDevice,
35 };
36
37 static RTC_GENERAL_DEVICE_IDA: SpinLock<IdAllocator> =
38 SpinLock::new(IdAllocator::new(0, usize::MAX).unwrap());
39
40 pub(super) const RTC_HCTOSYS_DEVICE: &str = "rtc0";
41
42 #[derive(Debug)]
43 #[cast_to([sync] KObject, Device, RtcDevice)]
44 pub struct RtcGeneralDevice {
45 name: String,
46 id: usize,
47 inner: SpinLock<InnerRtcGeneralDevice>,
48 kobj_state: LockedKObjectState,
49 priority: GeneralRtcPriority,
50 }
51
52 #[derive(Debug)]
53 struct InnerRtcGeneralDevice {
54 device_common: DeviceCommonData,
55 kobject_common: KObjectCommonData,
56
57 class_ops: Option<&'static dyn RtcClassOps>,
58 /// 上一次调用`rtc_hctosys()`把时间同步到timekeeper的时候的返回值
59 hc2sysfs_result: Result<(), SystemError>,
60 }
61
62 impl RtcGeneralDevice {
63 /// 创建一个新的通用RTC设备实例
64 ///
65 /// 注意,由于还需要进行其他的初始化操作,因此这个函数并不是公开的构造函数。
new(priority: GeneralRtcPriority) -> Arc<Self>66 fn new(priority: GeneralRtcPriority) -> Arc<Self> {
67 let id = RTC_GENERAL_DEVICE_IDA.lock().alloc().unwrap();
68 let name = format!("rtc{}", id);
69 Arc::new(Self {
70 name,
71 id,
72 inner: SpinLock::new(InnerRtcGeneralDevice {
73 device_common: DeviceCommonData::default(),
74 kobject_common: KObjectCommonData::default(),
75 class_ops: None,
76 hc2sysfs_result: Err(SystemError::ENODEV),
77 }),
78 kobj_state: LockedKObjectState::new(None),
79 priority,
80 })
81 }
82
inner(&self) -> SpinLockGuard<InnerRtcGeneralDevice>83 fn inner(&self) -> SpinLockGuard<InnerRtcGeneralDevice> {
84 self.inner.lock()
85 }
86
set_class_ops(&self, class_ops: &'static dyn RtcClassOps)87 pub fn set_class_ops(&self, class_ops: &'static dyn RtcClassOps) {
88 self.inner().class_ops = Some(class_ops);
89 }
90
class_ops(&self) -> Option<&'static dyn RtcClassOps>91 pub fn class_ops(&self) -> Option<&'static dyn RtcClassOps> {
92 self.inner().class_ops
93 }
94
priority(&self) -> GeneralRtcPriority95 pub fn priority(&self) -> GeneralRtcPriority {
96 self.priority
97 }
98
set_hc2sys_result(&self, val: Result<(), SystemError>)99 pub(super) fn set_hc2sys_result(&self, val: Result<(), SystemError>) {
100 self.inner().hc2sysfs_result = val;
101 }
102
hc2sysfs_result(&self) -> Result<(), SystemError>103 pub(super) fn hc2sysfs_result(&self) -> Result<(), SystemError> {
104 self.inner().hc2sysfs_result.clone()
105 }
106 }
107
108 impl Drop for RtcGeneralDevice {
drop(&mut self)109 fn drop(&mut self) {
110 RTC_GENERAL_DEVICE_IDA.lock().free(self.id);
111 }
112 }
113
114 impl RtcDevice for RtcGeneralDevice {
class_ops(&self) -> &'static dyn super::RtcClassOps115 fn class_ops(&self) -> &'static dyn super::RtcClassOps {
116 todo!()
117 }
118 }
119
120 impl Device for RtcGeneralDevice {
dev_type(&self) -> DeviceType121 fn dev_type(&self) -> DeviceType {
122 DeviceType::Rtc
123 }
124
id_table(&self) -> IdTable125 fn id_table(&self) -> IdTable {
126 IdTable::new(self.name.clone(), None)
127 }
128
set_bus(&self, bus: Option<Weak<dyn Bus>>)129 fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
130 self.inner().device_common.bus = bus;
131 }
132
bus(&self) -> Option<Weak<dyn Bus>>133 fn bus(&self) -> Option<Weak<dyn Bus>> {
134 self.inner().device_common.get_bus_weak_or_clear()
135 }
136
set_class(&self, class: Option<Weak<dyn Class>>)137 fn set_class(&self, class: Option<Weak<dyn Class>>) {
138 self.inner().device_common.class = class;
139 }
140
class(&self) -> Option<Arc<dyn Class>>141 fn class(&self) -> Option<Arc<dyn Class>> {
142 self.inner()
143 .device_common
144 .get_class_weak_or_clear()
145 .and_then(|x| x.upgrade())
146 }
147
driver(&self) -> Option<Arc<dyn Driver>>148 fn driver(&self) -> Option<Arc<dyn Driver>> {
149 self.inner()
150 .device_common
151 .get_driver_weak_or_clear()
152 .and_then(|x| x.upgrade())
153 }
154
set_driver(&self, driver: Option<Weak<dyn Driver>>)155 fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
156 self.inner().device_common.driver = driver;
157 }
158
is_dead(&self) -> bool159 fn is_dead(&self) -> bool {
160 false
161 }
162
can_match(&self) -> bool163 fn can_match(&self) -> bool {
164 false
165 }
166
set_can_match(&self, _can_match: bool)167 fn set_can_match(&self, _can_match: bool) {
168 // do nothing
169 }
170
state_synced(&self) -> bool171 fn state_synced(&self) -> bool {
172 true
173 }
attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>174 fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
175 Some(&[&RtcAttrGroup])
176 }
177
dev_parent(&self) -> Option<Weak<dyn Device>>178 fn dev_parent(&self) -> Option<Weak<dyn Device>> {
179 self.inner().device_common.get_parent_weak_or_clear()
180 }
181
set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>)182 fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
183 self.inner().device_common.parent = dev_parent;
184 }
185 }
186
187 impl KObject for RtcGeneralDevice {
as_any_ref(&self) -> &dyn core::any::Any188 fn as_any_ref(&self) -> &dyn core::any::Any {
189 self
190 }
191
set_inode(&self, inode: Option<Arc<KernFSInode>>)192 fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
193 self.inner().kobject_common.kern_inode = inode;
194 }
195
inode(&self) -> Option<Arc<KernFSInode>>196 fn inode(&self) -> Option<Arc<KernFSInode>> {
197 self.inner().kobject_common.kern_inode.clone()
198 }
199
parent(&self) -> Option<Weak<dyn KObject>>200 fn parent(&self) -> Option<Weak<dyn KObject>> {
201 self.inner().kobject_common.parent.clone()
202 }
203
set_parent(&self, parent: Option<Weak<dyn KObject>>)204 fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
205 self.inner().kobject_common.parent = parent;
206 }
207
kset(&self) -> Option<Arc<KSet>>208 fn kset(&self) -> Option<Arc<KSet>> {
209 self.inner().kobject_common.kset.clone()
210 }
211
set_kset(&self, kset: Option<Arc<KSet>>)212 fn set_kset(&self, kset: Option<Arc<KSet>>) {
213 self.inner().kobject_common.kset = kset;
214 }
215
kobj_type(&self) -> Option<&'static dyn KObjType>216 fn kobj_type(&self) -> Option<&'static dyn KObjType> {
217 self.inner().kobject_common.kobj_type
218 }
219
set_kobj_type(&self, ktype: Option<&'static dyn KObjType>)220 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
221 self.inner().kobject_common.kobj_type = ktype;
222 }
223
name(&self) -> String224 fn name(&self) -> String {
225 self.name.clone()
226 }
227
set_name(&self, _name: String)228 fn set_name(&self, _name: String) {
229 // do nothing
230 }
231
kobj_state(&self) -> RwLockReadGuard<KObjectState>232 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
233 self.kobj_state.read()
234 }
235
kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>236 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
237 self.kobj_state.write()
238 }
239
set_kobj_state(&self, state: KObjectState)240 fn set_kobj_state(&self, state: KObjectState) {
241 *self.kobj_state_mut() = state;
242 }
243 }
244
245 ///
246 /// 用于创建一个通用的RTC设备实例。
247 ///
248 /// ## 参数
249 ///
250 /// - `real_dev`: 一个对实际RTC设备的引用,这个设备将作为通用RTC设备的父设备。
rtc_general_device_create( real_dev: &Arc<dyn RtcDevice>, priority: Option<GeneralRtcPriority>, ) -> Arc<RtcGeneralDevice>251 pub fn rtc_general_device_create(
252 real_dev: &Arc<dyn RtcDevice>,
253 priority: Option<GeneralRtcPriority>,
254 ) -> Arc<RtcGeneralDevice> {
255 let dev = RtcGeneralDevice::new(priority.unwrap_or_default());
256 device_manager().device_default_initialize(&(dev.clone() as Arc<dyn Device>));
257 dev.set_dev_parent(Some(Arc::downgrade(real_dev) as Weak<dyn Device>));
258 dev.set_class(Some(Arc::downgrade(
259 &(sys_class_rtc_instance().cloned().unwrap() as Arc<dyn Class>),
260 )));
261
262 return dev;
263 }
264
265 #[derive(Debug)]
266 struct RtcAttrGroup;
267
268 impl AttributeGroup for RtcAttrGroup {
name(&self) -> Option<&str>269 fn name(&self) -> Option<&str> {
270 None
271 }
272
attrs(&self) -> &[&'static dyn Attribute]273 fn attrs(&self) -> &[&'static dyn Attribute] {
274 &[&AttrName, &AttrDate, &AttrTime, &AttrHcToSys]
275 }
276
is_visible( &self, _kobj: Arc<dyn KObject>, attr: &'static dyn Attribute, ) -> Option<ModeType>277 fn is_visible(
278 &self,
279 _kobj: Arc<dyn KObject>,
280 attr: &'static dyn Attribute,
281 ) -> Option<ModeType> {
282 // todo: https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/rtc/sysfs.c#280
283
284 return Some(attr.mode());
285 }
286 }
287
288 #[derive(Debug)]
289 struct AttrName;
290
291 impl Attribute for AttrName {
name(&self) -> &str292 fn name(&self) -> &str {
293 "name"
294 }
295
mode(&self) -> ModeType296 fn mode(&self) -> ModeType {
297 SYSFS_ATTR_MODE_RO
298 }
299
support(&self) -> SysFSOpsSupport300 fn support(&self) -> SysFSOpsSupport {
301 SysFSOpsSupport::ATTR_SHOW
302 }
303
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>304 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
305 let rtc_device = kobj
306 .parent()
307 .and_then(|x| x.upgrade())
308 .ok_or(SystemError::ENODEV)?;
309 let rtc_device = kobj2rtc_device(rtc_device).ok_or(SystemError::EINVAL)?;
310
311 let driver_name = rtc_device.driver().ok_or(SystemError::ENODEV)?.name();
312 let device_name = rtc_device.name();
313 sysfs_emit_str(buf, &format!("{} {}\n", driver_name, device_name))
314 }
315 }
316
317 #[derive(Debug)]
318 struct AttrDate;
319
320 impl Attribute for AttrDate {
name(&self) -> &str321 fn name(&self) -> &str {
322 "date"
323 }
324
mode(&self) -> ModeType325 fn mode(&self) -> ModeType {
326 SYSFS_ATTR_MODE_RO
327 }
328
support(&self) -> SysFSOpsSupport329 fn support(&self) -> SysFSOpsSupport {
330 SysFSOpsSupport::ATTR_SHOW
331 }
332
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>333 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
334 let rtc_device: Arc<RtcGeneralDevice> =
335 kobj2rtc_general_device(kobj).ok_or(SystemError::EINVAL)?;
336 let time = rtc_read_time(&rtc_device)?;
337 sysfs_emit_str(buf, &time.date_string())
338 }
339 }
340
341 #[derive(Debug)]
342 struct AttrTime;
343
344 impl Attribute for AttrTime {
name(&self) -> &str345 fn name(&self) -> &str {
346 "time"
347 }
348
mode(&self) -> ModeType349 fn mode(&self) -> ModeType {
350 SYSFS_ATTR_MODE_RO
351 }
352
support(&self) -> SysFSOpsSupport353 fn support(&self) -> SysFSOpsSupport {
354 SysFSOpsSupport::ATTR_SHOW
355 }
356
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>357 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
358 let rtc_device = kobj2rtc_general_device(kobj).ok_or(SystemError::EINVAL)?;
359 let time = rtc_read_time(&rtc_device)?;
360 sysfs_emit_str(buf, &time.time_string())
361 }
362 }
363
364 #[derive(Debug)]
365 struct AttrHcToSys;
366
367 impl Attribute for AttrHcToSys {
name(&self) -> &str368 fn name(&self) -> &str {
369 "hctosys"
370 }
371
mode(&self) -> ModeType372 fn mode(&self) -> ModeType {
373 SYSFS_ATTR_MODE_RO
374 }
375
support(&self) -> SysFSOpsSupport376 fn support(&self) -> SysFSOpsSupport {
377 SysFSOpsSupport::ATTR_SHOW
378 }
379
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>380 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
381 let rtc_device = kobj2rtc_general_device(kobj).ok_or(SystemError::EINVAL)?;
382 if rtc_device.hc2sysfs_result().is_ok() && rtc_device.name().eq(RTC_HCTOSYS_DEVICE) {
383 return sysfs_emit_str(buf, "1\n");
384 }
385
386 return sysfs_emit_str(buf, "0\n");
387 }
388 }
389