From 59abb5d344d46609edcf0016f4bfd70a90aa87b2 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Fri, 23 Feb 2024 13:42:04 +0200 Subject: [PATCH] Kernel: Make HPET read_main_counter() atomic with 32 bit main counter --- kernel/kernel/Timer/HPET.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/kernel/kernel/Timer/HPET.cpp b/kernel/kernel/Timer/HPET.cpp index 72635e0411..f1c238142d 100644 --- a/kernel/kernel/Timer/HPET.cpp +++ b/kernel/kernel/Timer/HPET.cpp @@ -153,7 +153,7 @@ namespace Kernel m_is_64bit = regs.capabilities & COUNT_SIZE_CAP; - // Disable main counter and reset value + // Disable and reset main counter regs.configuration.low = regs.configuration.low & ~ENABLE_CNF; regs.main_counter.high = 0; regs.main_counter.low = 0; @@ -244,27 +244,28 @@ namespace Kernel if (m_is_64bit) return regs.main_counter.full; - uint32_t current = regs.main_counter.low; - uint64_t wraps = m_32bit_wraps; - if (current < (uint32_t)m_last_ticks) + CriticalScope _; + uint32_t current_low = regs.main_counter.low; + uint32_t wraps = m_32bit_wraps; + if (current_low < (uint32_t)m_last_ticks) wraps++; - return (wraps << 32) | current; + return ((uint64_t)wraps << 32) | current_low; } void HPET::handle_irq() { auto& regs = registers(); - uint64_t current_ticks { 0 }; + uint64_t current_ticks; if (m_is_64bit) current_ticks = regs.main_counter.full; else { - uint32_t current = regs.main_counter.low; - if (current < (uint32_t)m_last_ticks) + uint32_t current_low = regs.main_counter.low; + if (current_low < (uint32_t)m_last_ticks) m_32bit_wraps++; - current_ticks = ((uint64_t)m_32bit_wraps << 32) | current; + current_ticks = ((uint64_t)m_32bit_wraps << 32) | current_low; } m_last_ticks = current_ticks;