1 use core::any::Any; 2 3 use alloc::{ 4 string::{String, ToString}, 5 sync::{Arc, Weak}, 6 }; 7 use log::error; 8 use system_error::SystemError; 9 use unified_init::macros::unified_init; 10 11 use crate::{ 12 arch::{io::PortIOArch, CurrentIrqArch, CurrentPortIOArch}, 13 driver::{ 14 base::{ 15 class::Class, 16 device::{ 17 bus::Bus, device_manager, driver::Driver, Device, DeviceCommonData, DeviceState, 18 DeviceType, IdTable, 19 }, 20 kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, 21 kset::KSet, 22 platform::platform_device::{platform_device_manager, PlatformDevice}, 23 }, 24 rtc::{RtcClassOps, RtcDevice, RtcTime}, 25 }, 26 exception::InterruptArch, 27 filesystem::kernfs::KernFSInode, 28 init::initcall::INITCALL_DEVICE, 29 libs::{ 30 mutex::Mutex, 31 rwlock::{RwLockReadGuard, RwLockWriteGuard}, 32 spinlock::{SpinLock, SpinLockGuard}, 33 }, 34 }; 35 36 #[derive(Debug)] 37 #[cast_to([sync] Device, PlatformDevice, RtcDevice)] 38 struct CmosRtcDevice { 39 inner: SpinLock<InnerCmosRtc>, 40 locked_kobjstate: LockedKObjectState, 41 ops_mutex: Mutex<()>, 42 } 43 44 impl CmosRtcDevice { 45 const NAME: &str = "rtc_cmos"; 46 pub fn new() -> Arc<Self> { 47 let r = CmosRtcDevice { 48 inner: SpinLock::new(InnerCmosRtc { 49 device_common: DeviceCommonData::default(), 50 kobject_common: KObjectCommonData::default(), 51 device_state: DeviceState::NotInitialized, 52 }), 53 locked_kobjstate: LockedKObjectState::new(None), 54 ops_mutex: Mutex::new(()), 55 }; 56 57 r.inner().device_common.can_match = true; 58 59 Arc::new(r) 60 } 61 62 fn inner(&self) -> SpinLockGuard<InnerCmosRtc> { 63 self.inner.lock() 64 } 65 66 ///置位0x70的第7位,禁止不可屏蔽中断 67 #[inline] 68 fn read_cmos(&self, addr: u8) -> u8 { 69 unsafe { 70 CurrentPortIOArch::out8(0x70, 0x80 | addr); 71 return CurrentPortIOArch::in8(0x71); 72 } 73 } 74 } 75 76 #[derive(Debug)] 77 struct InnerCmosRtc { 78 device_common: DeviceCommonData, 79 kobject_common: KObjectCommonData, 80 81 device_state: DeviceState, 82 } 83 84 impl RtcDevice for CmosRtcDevice { 85 fn class_ops(&self) -> &'static dyn RtcClassOps { 86 &CmosRtcClassOps 87 } 88 } 89 90 impl PlatformDevice for CmosRtcDevice { 91 fn pdev_name(&self) -> &str { 92 Self::NAME 93 } 94 95 fn set_pdev_id(&self, _id: i32) { 96 todo!() 97 } 98 99 fn set_pdev_id_auto(&self, _id_auto: bool) { 100 todo!() 101 } 102 103 fn is_initialized(&self) -> bool { 104 self.inner().device_state == DeviceState::Initialized 105 } 106 107 fn set_state(&self, set_state: DeviceState) { 108 self.inner().device_state = set_state; 109 } 110 } 111 112 impl Device for CmosRtcDevice { 113 fn dev_type(&self) -> DeviceType { 114 DeviceType::Rtc 115 } 116 117 fn id_table(&self) -> IdTable { 118 IdTable::new(Self::NAME.to_string(), None) 119 } 120 121 fn set_bus(&self, bus: Option<Weak<dyn Bus>>) { 122 self.inner().device_common.bus = bus; 123 } 124 125 fn set_class(&self, class: Option<Weak<dyn Class>>) { 126 self.inner().device_common.class = class; 127 } 128 129 fn class(&self) -> Option<Arc<dyn Class>> { 130 self.inner() 131 .device_common 132 .get_class_weak_or_clear() 133 .and_then(|c| c.upgrade()) 134 } 135 136 fn driver(&self) -> Option<Arc<dyn Driver>> { 137 self.inner() 138 .device_common 139 .get_driver_weak_or_clear() 140 .and_then(|d| d.upgrade()) 141 } 142 143 fn set_driver(&self, driver: Option<Weak<dyn Driver>>) { 144 self.inner().device_common.driver = driver; 145 } 146 147 fn is_dead(&self) -> bool { 148 self.inner().device_common.dead 149 } 150 151 fn can_match(&self) -> bool { 152 self.inner().device_common.can_match 153 } 154 155 fn set_can_match(&self, can_match: bool) { 156 self.inner().device_common.can_match = can_match; 157 } 158 159 fn state_synced(&self) -> bool { 160 true 161 } 162 163 fn bus(&self) -> Option<Weak<dyn Bus>> { 164 self.inner().device_common.get_bus_weak_or_clear() 165 } 166 167 fn dev_parent(&self) -> Option<Weak<dyn Device>> { 168 self.inner().device_common.get_parent_weak_or_clear() 169 } 170 171 fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) { 172 self.inner().device_common.parent = parent; 173 } 174 } 175 176 impl KObject for CmosRtcDevice { 177 fn as_any_ref(&self) -> &dyn Any { 178 self 179 } 180 181 fn set_inode(&self, inode: Option<Arc<KernFSInode>>) { 182 self.inner().kobject_common.kern_inode = inode; 183 } 184 185 fn inode(&self) -> Option<Arc<KernFSInode>> { 186 self.inner().kobject_common.kern_inode.clone() 187 } 188 189 fn parent(&self) -> Option<Weak<dyn KObject>> { 190 self.inner().kobject_common.get_parent_or_clear_weak() 191 } 192 193 fn set_parent(&self, parent: Option<Weak<dyn KObject>>) { 194 self.inner().kobject_common.parent = parent; 195 } 196 197 fn kset(&self) -> Option<Arc<KSet>> { 198 self.inner().kobject_common.kset.clone() 199 } 200 201 fn set_kset(&self, kset: Option<Arc<KSet>>) { 202 self.inner().kobject_common.kset = kset; 203 } 204 205 fn kobj_type(&self) -> Option<&'static dyn KObjType> { 206 self.inner().kobject_common.kobj_type 207 } 208 209 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { 210 self.inner().kobject_common.kobj_type = ktype; 211 } 212 213 fn name(&self) -> String { 214 Self::NAME.to_string() 215 } 216 217 fn set_name(&self, _name: String) { 218 // Do nothing 219 } 220 221 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 222 self.locked_kobjstate.read() 223 } 224 225 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 226 self.locked_kobjstate.write() 227 } 228 229 fn set_kobj_state(&self, state: KObjectState) { 230 *self.locked_kobjstate.write() = state; 231 } 232 } 233 234 #[derive(Debug)] 235 pub struct CmosRtcClassOps; 236 237 impl RtcClassOps for CmosRtcClassOps { 238 fn read_time(&self, dev: &Arc<dyn RtcDevice>) -> Result<RtcTime, SystemError> { 239 // 检查是否为cmos rtc 240 let dev = dev 241 .as_any_ref() 242 .downcast_ref::<CmosRtcDevice>() 243 .ok_or(SystemError::EINVAL)?; 244 245 let _guard = dev.ops_mutex.lock(); 246 247 // 为防止中断请求打断该过程,需要先关中断 248 let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 249 //0x0B 250 let status_register_b: u8 = dev.read_cmos(0x0B); // 读取状态寄存器B 251 let is_24h: bool = (status_register_b & 0x02) != 0; 252 // 判断是否启用24小时模式 253 let is_binary: bool = (status_register_b & 0x04) != 0; // 判断是否为二进制码 254 let mut res = RtcTime::default(); 255 256 loop { 257 res.year = dev.read_cmos(CMOSTimeSelector::Year as u8) as i32; 258 res.month = dev.read_cmos(CMOSTimeSelector::Month as u8) as i32; 259 res.mday = dev.read_cmos(CMOSTimeSelector::Day as u8) as i32; 260 res.hour = dev.read_cmos(CMOSTimeSelector::Hour as u8) as i32; 261 res.minute = dev.read_cmos(CMOSTimeSelector::Minute as u8) as i32; 262 res.second = dev.read_cmos(CMOSTimeSelector::Second as u8) as i32; 263 264 if res.second == dev.read_cmos(CMOSTimeSelector::Second as u8) as i32 { 265 break; 266 } // 若读取时间过程中时间发生跳变则重新读取 267 } 268 269 unsafe { 270 CurrentPortIOArch::out8(0x70, 0x00); 271 } 272 273 if !is_binary 274 // 把BCD转为二进制 275 { 276 res.second = (res.second & 0xf) + (res.second >> 4) * 10; 277 res.minute = (res.minute & 0xf) + (res.minute >> 4) * 10; 278 res.hour = ((res.hour & 0xf) + ((res.hour & 0x70) >> 4) * 10) | (res.hour & 0x80); 279 res.mday = (res.mday & 0xf) + ((res.mday / 16) * 10); 280 res.month = (res.month & 0xf) + (res.month >> 4) * 10; 281 res.year = (res.year & 0xf) + (res.year >> 4) * 10; 282 } 283 res.year += 100; 284 285 if (!is_24h) && (res.hour & 0x80) != 0 { 286 res.hour = ((res.hour & 0x7f) + 12) % 24; 287 } // 将十二小时制转为24小时 288 289 res.month -= 1; 290 291 drop(irq_guard); 292 293 return Ok(res); 294 } 295 296 fn set_time(&self, _dev: &Arc<dyn RtcDevice>, _time: &RtcTime) -> Result<(), SystemError> { 297 error!("set_time is not implemented for CmosRtcClassOps"); 298 Err(SystemError::ENOSYS) 299 } 300 } 301 302 /// used in the form of u8 303 #[repr(u8)] 304 enum CMOSTimeSelector { 305 Second = 0x00, 306 Minute = 0x02, 307 Hour = 0x04, 308 Day = 0x07, 309 Month = 0x08, 310 Year = 0x09, 311 } 312 313 #[unified_init(INITCALL_DEVICE)] 314 pub fn cmos_rtc_device_init() -> Result<(), SystemError> { 315 let device = CmosRtcDevice::new(); 316 device_manager().device_default_initialize(&(device.clone() as Arc<dyn Device>)); 317 platform_device_manager().device_add(device)?; 318 319 return Ok(()); 320 } 321