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 /// 注意,由于还需要进行其他的初始化操作,因此这个函数并不是公开的构造函数。 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 83 fn inner(&self) -> SpinLockGuard<InnerRtcGeneralDevice> { 84 self.inner.lock() 85 } 86 87 pub fn set_class_ops(&self, class_ops: &'static dyn RtcClassOps) { 88 self.inner().class_ops = Some(class_ops); 89 } 90 91 pub fn class_ops(&self) -> Option<&'static dyn RtcClassOps> { 92 self.inner().class_ops 93 } 94 95 pub fn priority(&self) -> GeneralRtcPriority { 96 self.priority 97 } 98 99 pub(super) fn set_hc2sys_result(&self, val: Result<(), SystemError>) { 100 self.inner().hc2sysfs_result = val; 101 } 102 103 pub(super) fn hc2sysfs_result(&self) -> Result<(), SystemError> { 104 self.inner().hc2sysfs_result.clone() 105 } 106 } 107 108 impl Drop for RtcGeneralDevice { 109 fn drop(&mut self) { 110 RTC_GENERAL_DEVICE_IDA.lock().free(self.id); 111 } 112 } 113 114 impl RtcDevice for RtcGeneralDevice { 115 fn class_ops(&self) -> &'static dyn super::RtcClassOps { 116 todo!() 117 } 118 } 119 120 impl Device for RtcGeneralDevice { 121 fn dev_type(&self) -> DeviceType { 122 DeviceType::Rtc 123 } 124 125 fn id_table(&self) -> IdTable { 126 IdTable::new(self.name.clone(), None) 127 } 128 129 fn set_bus(&self, bus: Option<Weak<dyn Bus>>) { 130 self.inner().device_common.bus = bus; 131 } 132 133 fn bus(&self) -> Option<Weak<dyn Bus>> { 134 self.inner().device_common.get_bus_weak_or_clear() 135 } 136 137 fn set_class(&self, class: Option<Weak<dyn Class>>) { 138 self.inner().device_common.class = class; 139 } 140 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 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 155 fn set_driver(&self, driver: Option<Weak<dyn Driver>>) { 156 self.inner().device_common.driver = driver; 157 } 158 159 fn is_dead(&self) -> bool { 160 false 161 } 162 163 fn can_match(&self) -> bool { 164 false 165 } 166 167 fn set_can_match(&self, _can_match: bool) { 168 // do nothing 169 } 170 171 fn state_synced(&self) -> bool { 172 true 173 } 174 fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { 175 Some(&[&RtcAttrGroup]) 176 } 177 178 fn dev_parent(&self) -> Option<Weak<dyn Device>> { 179 self.inner().device_common.get_parent_weak_or_clear() 180 } 181 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 { 188 fn as_any_ref(&self) -> &dyn core::any::Any { 189 self 190 } 191 192 fn set_inode(&self, inode: Option<Arc<KernFSInode>>) { 193 self.inner().kobject_common.kern_inode = inode; 194 } 195 196 fn inode(&self) -> Option<Arc<KernFSInode>> { 197 self.inner().kobject_common.kern_inode.clone() 198 } 199 200 fn parent(&self) -> Option<Weak<dyn KObject>> { 201 self.inner().kobject_common.parent.clone() 202 } 203 204 fn set_parent(&self, parent: Option<Weak<dyn KObject>>) { 205 self.inner().kobject_common.parent = parent; 206 } 207 208 fn kset(&self) -> Option<Arc<KSet>> { 209 self.inner().kobject_common.kset.clone() 210 } 211 212 fn set_kset(&self, kset: Option<Arc<KSet>>) { 213 self.inner().kobject_common.kset = kset; 214 } 215 216 fn kobj_type(&self) -> Option<&'static dyn KObjType> { 217 self.inner().kobject_common.kobj_type 218 } 219 220 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { 221 self.inner().kobject_common.kobj_type = ktype; 222 } 223 224 fn name(&self) -> String { 225 self.name.clone() 226 } 227 228 fn set_name(&self, _name: String) { 229 // do nothing 230 } 231 232 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 233 self.kobj_state.read() 234 } 235 236 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 237 self.kobj_state.write() 238 } 239 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设备的父设备。 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 { 269 fn name(&self) -> Option<&str> { 270 None 271 } 272 273 fn attrs(&self) -> &[&'static dyn Attribute] { 274 &[&AttrName, &AttrDate, &AttrTime, &AttrHcToSys] 275 } 276 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 { 292 fn name(&self) -> &str { 293 "name" 294 } 295 296 fn mode(&self) -> ModeType { 297 SYSFS_ATTR_MODE_RO 298 } 299 300 fn support(&self) -> SysFSOpsSupport { 301 SysFSOpsSupport::ATTR_SHOW 302 } 303 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 { 321 fn name(&self) -> &str { 322 "date" 323 } 324 325 fn mode(&self) -> ModeType { 326 SYSFS_ATTR_MODE_RO 327 } 328 329 fn support(&self) -> SysFSOpsSupport { 330 SysFSOpsSupport::ATTR_SHOW 331 } 332 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 { 345 fn name(&self) -> &str { 346 "time" 347 } 348 349 fn mode(&self) -> ModeType { 350 SYSFS_ATTR_MODE_RO 351 } 352 353 fn support(&self) -> SysFSOpsSupport { 354 SysFSOpsSupport::ATTR_SHOW 355 } 356 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 { 368 fn name(&self) -> &str { 369 "hctosys" 370 } 371 372 fn mode(&self) -> ModeType { 373 SYSFS_ATTR_MODE_RO 374 } 375 376 fn support(&self) -> SysFSOpsSupport { 377 SysFSOpsSupport::ATTR_SHOW 378 } 379 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