1 use core::any::Any; 2 3 use alloc::{ 4 string::{String, ToString}, 5 sync::{Arc, Weak}, 6 }; 7 use system_error::SystemError; 8 use unified_init::macros::unified_init; 9 10 use crate::{ 11 arch::{io::PortIOArch, CurrentIrqArch, CurrentPortIOArch}, 12 driver::{ 13 base::{ 14 class::Class, 15 device::{ 16 bus::Bus, device_manager, driver::Driver, Device, DeviceCommonData, DeviceState, 17 DeviceType, IdTable, 18 }, 19 kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, 20 kset::KSet, 21 platform::platform_device::{platform_device_manager, PlatformDevice}, 22 }, 23 rtc::{RtcClassOps, RtcDevice, RtcTime}, 24 }, 25 exception::InterruptArch, 26 filesystem::kernfs::KernFSInode, 27 init::initcall::INITCALL_DEVICE, 28 kerror, 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 168 impl KObject for CmosRtcDevice { 169 fn as_any_ref(&self) -> &dyn Any { 170 self 171 } 172 173 fn set_inode(&self, inode: Option<Arc<KernFSInode>>) { 174 self.inner().kobject_common.kern_inode = inode; 175 } 176 177 fn inode(&self) -> Option<Arc<KernFSInode>> { 178 self.inner().kobject_common.kern_inode.clone() 179 } 180 181 fn parent(&self) -> Option<Weak<dyn KObject>> { 182 self.inner().kobject_common.get_parent_or_clear_weak() 183 } 184 185 fn set_parent(&self, parent: Option<Weak<dyn KObject>>) { 186 self.inner().kobject_common.parent = parent; 187 } 188 189 fn kset(&self) -> Option<Arc<KSet>> { 190 self.inner().kobject_common.kset.clone() 191 } 192 193 fn set_kset(&self, kset: Option<Arc<KSet>>) { 194 self.inner().kobject_common.kset = kset; 195 } 196 197 fn kobj_type(&self) -> Option<&'static dyn KObjType> { 198 self.inner().kobject_common.kobj_type 199 } 200 201 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { 202 self.inner().kobject_common.kobj_type = ktype; 203 } 204 205 fn name(&self) -> String { 206 Self::NAME.to_string() 207 } 208 209 fn set_name(&self, _name: String) { 210 // Do nothing 211 } 212 213 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 214 self.locked_kobjstate.read() 215 } 216 217 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 218 self.locked_kobjstate.write() 219 } 220 221 fn set_kobj_state(&self, state: KObjectState) { 222 *self.locked_kobjstate.write() = state; 223 } 224 } 225 226 #[derive(Debug)] 227 pub struct CmosRtcClassOps; 228 229 impl RtcClassOps for CmosRtcClassOps { 230 fn read_time(&self, dev: &Arc<dyn RtcDevice>) -> Result<RtcTime, SystemError> { 231 // 检查是否为cmos rtc 232 let dev = dev 233 .as_any_ref() 234 .downcast_ref::<CmosRtcDevice>() 235 .ok_or(SystemError::EINVAL)?; 236 237 let _guard = dev.ops_mutex.lock(); 238 239 // 为防止中断请求打断该过程,需要先关中断 240 let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 241 //0x0B 242 let status_register_b: u8 = dev.read_cmos(0x0B); // 读取状态寄存器B 243 let is_24h: bool = (status_register_b & 0x02) != 0; 244 // 判断是否启用24小时模式 245 let is_binary: bool = (status_register_b & 0x04) != 0; // 判断是否为二进制码 246 let mut res = RtcTime::default(); 247 248 loop { 249 res.year = dev.read_cmos(CMOSTimeSelector::Year as u8) as i32; 250 res.month = dev.read_cmos(CMOSTimeSelector::Month as u8) as i32; 251 res.mday = dev.read_cmos(CMOSTimeSelector::Day as u8) as i32; 252 res.hour = dev.read_cmos(CMOSTimeSelector::Hour as u8) as i32; 253 res.minute = dev.read_cmos(CMOSTimeSelector::Minute as u8) as i32; 254 res.second = dev.read_cmos(CMOSTimeSelector::Second as u8) as i32; 255 256 if res.second == dev.read_cmos(CMOSTimeSelector::Second as u8) as i32 { 257 break; 258 } // 若读取时间过程中时间发生跳变则重新读取 259 } 260 261 unsafe { 262 CurrentPortIOArch::out8(0x70, 0x00); 263 } 264 265 if !is_binary 266 // 把BCD转为二进制 267 { 268 res.second = (res.second & 0xf) + (res.second >> 4) * 10; 269 res.minute = (res.minute & 0xf) + (res.minute >> 4) * 10; 270 res.hour = ((res.hour & 0xf) + ((res.hour & 0x70) >> 4) * 10) | (res.hour & 0x80); 271 res.mday = (res.mday & 0xf) + ((res.mday / 16) * 10); 272 res.month = (res.month & 0xf) + (res.month >> 4) * 10; 273 res.year = (res.year & 0xf) + (res.year >> 4) * 10; 274 } 275 res.year += 100; 276 277 if (!is_24h) && (res.hour & 0x80) != 0 { 278 res.hour = ((res.hour & 0x7f) + 12) % 24; 279 } // 将十二小时制转为24小时 280 281 res.month -= 1; 282 283 drop(irq_guard); 284 285 return Ok(res); 286 } 287 288 fn set_time(&self, _dev: &Arc<dyn RtcDevice>, _time: &RtcTime) -> Result<(), SystemError> { 289 kerror!("set_time is not implemented for CmosRtcClassOps"); 290 Err(SystemError::ENOSYS) 291 } 292 } 293 294 /// used in the form of u8 295 #[repr(u8)] 296 enum CMOSTimeSelector { 297 Second = 0x00, 298 Minute = 0x02, 299 Hour = 0x04, 300 Day = 0x07, 301 Month = 0x08, 302 Year = 0x09, 303 } 304 305 #[unified_init(INITCALL_DEVICE)] 306 pub fn cmos_rtc_device_init() -> Result<(), SystemError> { 307 let device = CmosRtcDevice::new(); 308 device_manager().device_default_initialize(&(device.clone() as Arc<dyn Device>)); 309 platform_device_manager().device_add(device)?; 310 311 return Ok(()); 312 } 313