summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorTimon Kruiper <timonkruiper@gmail.com>2022-10-17 19:04:41 +0200
committerGunnar Beutner <gunnar@beutner.name>2022-10-17 20:11:31 +0200
commitde0bb998934c7b7a56b9de12e186d9824b6b1ea3 (patch)
tree2a4ce7d613985fe5ca9126844a040699ae8393b1 /Kernel
parent668024177389ee4c083a851f9f50f2f6f444d357 (diff)
downloadserenity-de0bb998934c7b7a56b9de12e186d9824b6b1ea3.zip
Kernel: Correctly calculate delta_ticks when 64-bit counter wraps around
We never caught this bug in the HPET, since it takes ages for a 64-bit counter to wrap around. Also remove an unnecessary if check.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Arch/x86/Time/HPET.cpp16
1 files changed, 8 insertions, 8 deletions
diff --git a/Kernel/Arch/x86/Time/HPET.cpp b/Kernel/Arch/x86/Time/HPET.cpp
index 725d767bd5..fc470a7a84 100644
--- a/Kernel/Arch/x86/Time/HPET.cpp
+++ b/Kernel/Arch/x86/Time/HPET.cpp
@@ -262,18 +262,18 @@ u64 HPET::update_time(u64& seconds_since_boot, u32& ticks_this_second, bool quer
delta_ticks += current_value - m_main_counter_last_read;
} else {
// the counter wrapped around
- delta_ticks += m_main_counter_last_read - current_value;
- if (!m_main_counter_64bits)
+ if (m_main_counter_64bits) {
+ delta_ticks += (NumericLimits<u64>::max() - m_main_counter_last_read + 1) + current_value;
+ } else {
+ delta_ticks += (NumericLimits<u32>::max() - m_main_counter_last_read + 1) + current_value;
m_32bit_main_counter_wraps++;
+ }
}
+
u64 ticks_since_last_second = (u64)ticks_this_second + delta_ticks;
auto ticks_per_second = frequency();
- if (ticks_since_last_second >= ticks_per_second) {
- seconds_since_boot += ticks_since_last_second / ticks_per_second;
- ticks_this_second = ticks_since_last_second % ticks_per_second;
- } else {
- ticks_this_second = ticks_since_last_second;
- }
+ seconds_since_boot += ticks_since_last_second / ticks_per_second;
+ ticks_this_second = ticks_since_last_second % ticks_per_second;
if (!query_only) {
m_main_counter_drift = 0;