|
@@ -20,7 +20,7 @@ use system_error::SystemError;
|
|
// 参考:https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/clocksource/acpi_pm.c
|
|
// 参考:https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/clocksource/acpi_pm.c
|
|
|
|
|
|
/// acpi_pmtmr所在的I/O端口
|
|
/// acpi_pmtmr所在的I/O端口
|
|
-pub static mut PMTMR_IO_PORT: AtomicU32 = AtomicU32::new(0);
|
|
|
|
|
|
+pub static PMTMR_IO_PORT: AtomicU32 = AtomicU32::new(0);
|
|
|
|
|
|
/// # 读取acpi_pmtmr当前值,并对齐进行掩码操作
|
|
/// # 读取acpi_pmtmr当前值,并对齐进行掩码操作
|
|
#[inline(always)]
|
|
#[inline(always)]
|
|
@@ -206,12 +206,13 @@ fn find_acpi_pm_clock() -> Result<(), SystemError> {
|
|
let pm_timer_block = fadt.pm_timer_block().map_err(|_| SystemError::ENODEV)?;
|
|
let pm_timer_block = fadt.pm_timer_block().map_err(|_| SystemError::ENODEV)?;
|
|
let pm_timer_block = pm_timer_block.ok_or(SystemError::ENODEV)?;
|
|
let pm_timer_block = pm_timer_block.ok_or(SystemError::ENODEV)?;
|
|
let pmtmr_addr = pm_timer_block.address;
|
|
let pmtmr_addr = pm_timer_block.address;
|
|
- unsafe {
|
|
|
|
- PMTMR_IO_PORT.store(pmtmr_addr as u32, Ordering::SeqCst);
|
|
|
|
- }
|
|
|
|
- kinfo!("apic_pmtmr I/O port: {}", unsafe {
|
|
|
|
|
|
+
|
|
|
|
+ PMTMR_IO_PORT.store(pmtmr_addr as u32, Ordering::SeqCst);
|
|
|
|
+
|
|
|
|
+ kinfo!(
|
|
|
|
+ "apic_pmtmr I/O port: {}",
|
|
PMTMR_IO_PORT.load(Ordering::SeqCst)
|
|
PMTMR_IO_PORT.load(Ordering::SeqCst)
|
|
- });
|
|
|
|
|
|
+ );
|
|
|
|
|
|
return Ok(());
|
|
return Ok(());
|
|
}
|
|
}
|
|
@@ -222,18 +223,19 @@ fn find_acpi_pm_clock() -> Result<(), SystemError> {
|
|
#[allow(dead_code)]
|
|
#[allow(dead_code)]
|
|
pub fn init_acpi_pm_clocksource() -> Result<(), SystemError> {
|
|
pub fn init_acpi_pm_clocksource() -> Result<(), SystemError> {
|
|
let acpi_pm = Acpipm::new();
|
|
let acpi_pm = Acpipm::new();
|
|
- unsafe {
|
|
|
|
- CLOCKSOURCE_ACPI_PM = Some(acpi_pm);
|
|
|
|
- }
|
|
|
|
|
|
|
|
// 解析fadt
|
|
// 解析fadt
|
|
find_acpi_pm_clock()?;
|
|
find_acpi_pm_clock()?;
|
|
|
|
|
|
// 检查pmtmr_io_port是否被设置
|
|
// 检查pmtmr_io_port是否被设置
|
|
- if unsafe { PMTMR_IO_PORT.load(Ordering::SeqCst) } == 0 {
|
|
|
|
|
|
+ if PMTMR_IO_PORT.load(Ordering::SeqCst) == 0 {
|
|
return Err(SystemError::ENODEV);
|
|
return Err(SystemError::ENODEV);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ unsafe {
|
|
|
|
+ CLOCKSOURCE_ACPI_PM = Some(acpi_pm);
|
|
|
|
+ }
|
|
|
|
+
|
|
// 验证ACPI PM Timer作为时钟源的稳定性和一致性
|
|
// 验证ACPI PM Timer作为时钟源的稳定性和一致性
|
|
for j in 0..ACPI_PM_MONOTONIC_CHECKS {
|
|
for j in 0..ACPI_PM_MONOTONIC_CHECKS {
|
|
let mut cnt = 100 * j;
|
|
let mut cnt = 100 * j;
|
|
@@ -256,25 +258,23 @@ pub fn init_acpi_pm_clocksource() -> Result<(), SystemError> {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
kinfo!("PM Timer had inconsistens results: {} {}", value1, value2);
|
|
kinfo!("PM Timer had inconsistens results: {} {}", value1, value2);
|
|
- unsafe {
|
|
|
|
- PMTMR_IO_PORT.store(0, Ordering::SeqCst);
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ PMTMR_IO_PORT.store(0, Ordering::SeqCst);
|
|
|
|
+
|
|
return Err(SystemError::EINVAL);
|
|
return Err(SystemError::EINVAL);
|
|
}
|
|
}
|
|
if i == ACPI_PM_READ_CHECKS {
|
|
if i == ACPI_PM_READ_CHECKS {
|
|
kinfo!("PM Timer failed consistency check: {}", value1);
|
|
kinfo!("PM Timer failed consistency check: {}", value1);
|
|
- unsafe {
|
|
|
|
- PMTMR_IO_PORT.store(0, Ordering::SeqCst);
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ PMTMR_IO_PORT.store(0, Ordering::SeqCst);
|
|
|
|
+
|
|
return Err(SystemError::EINVAL);
|
|
return Err(SystemError::EINVAL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// 检查ACPI PM Timer的频率是否正确
|
|
// 检查ACPI PM Timer的频率是否正确
|
|
if !verify_pmtmr_rate() {
|
|
if !verify_pmtmr_rate() {
|
|
- unsafe {
|
|
|
|
- PMTMR_IO_PORT.store(0, Ordering::SeqCst);
|
|
|
|
- }
|
|
|
|
|
|
+ PMTMR_IO_PORT.store(0, Ordering::SeqCst);
|
|
}
|
|
}
|
|
|
|
|
|
// 检查TSC时钟源的监视器是否被禁用,如果被禁用则将时钟源的标志设置为CLOCK_SOURCE_MUST_VERIFY
|
|
// 检查TSC时钟源的监视器是否被禁用,如果被禁用则将时钟源的标志设置为CLOCK_SOURCE_MUST_VERIFY
|