mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-30 08:41:15 +00:00
Kernel: Add interrupt support to aarch64 RPi Timer driver
Since we can now build and use the IRQHandler class, we can implement interrupt support for the Timer in the aarch64 build.
This commit is contained in:
parent
8b77c61e7d
commit
dab6dbe893
Notes:
sideshowbarker
2024-07-17 10:30:23 +09:00
Author: https://github.com/FireFox317 Commit: https://github.com/SerenityOS/serenity/commit/dab6dbe893 Pull-request: https://github.com/SerenityOS/serenity/pull/14146 Reviewed-by: https://github.com/ADKaster Reviewed-by: https://github.com/BertalanD Reviewed-by: https://github.com/Hendiadyoin1 Reviewed-by: https://github.com/nico ✅
|
@ -30,7 +30,8 @@ enum FlagBits {
|
||||||
};
|
};
|
||||||
|
|
||||||
Timer::Timer()
|
Timer::Timer()
|
||||||
: m_registers(MMIO::the().peripheral<TimerRegisters>(0x3000))
|
: IRQHandler(1)
|
||||||
|
, m_registers(MMIO::the().peripheral<TimerRegisters>(0x3000))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +52,41 @@ u64 Timer::microseconds_since_boot()
|
||||||
return (static_cast<u64>(high) << 32) | low;
|
return (static_cast<u64>(high) << 32) | low;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Timer::handle_irq(RegisterState const&)
|
||||||
|
{
|
||||||
|
dbgln("Timer fired: {} us", m_current_timer_value);
|
||||||
|
|
||||||
|
m_current_timer_value += m_interrupt_interval;
|
||||||
|
set_compare(TimerID::Timer1, m_current_timer_value);
|
||||||
|
|
||||||
|
clear_interrupt(TimerID::Timer1);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Timer::enable_interrupt_mode()
|
||||||
|
{
|
||||||
|
m_current_timer_value = microseconds_since_boot();
|
||||||
|
m_current_timer_value += m_interrupt_interval;
|
||||||
|
set_compare(TimerID::Timer1, m_current_timer_value);
|
||||||
|
|
||||||
|
enable_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer::set_interrupt_interval_usec(u32 interrupt_interval)
|
||||||
|
{
|
||||||
|
m_interrupt_interval = interrupt_interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer::clear_interrupt(TimerID id)
|
||||||
|
{
|
||||||
|
m_registers->control_and_status = 1 << to_underlying(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer::set_compare(TimerID id, u32 compare)
|
||||||
|
{
|
||||||
|
m_registers->compare[to_underlying(id)] = compare;
|
||||||
|
}
|
||||||
|
|
||||||
class SetClockRateMboxMessage : Mailbox::Message {
|
class SetClockRateMboxMessage : Mailbox::Message {
|
||||||
public:
|
public:
|
||||||
u32 clock_id;
|
u32 clock_id;
|
||||||
|
|
|
@ -7,18 +7,22 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
|
#include <Kernel/Interrupts/IRQHandler.h>
|
||||||
|
|
||||||
namespace Kernel::RPi {
|
namespace Kernel::RPi {
|
||||||
|
|
||||||
struct TimerRegisters;
|
struct TimerRegisters;
|
||||||
|
|
||||||
class Timer {
|
class Timer : public IRQHandler {
|
||||||
public:
|
public:
|
||||||
Timer();
|
Timer();
|
||||||
static Timer& the();
|
static Timer& the();
|
||||||
|
|
||||||
u64 microseconds_since_boot();
|
u64 microseconds_since_boot();
|
||||||
|
|
||||||
|
void set_interrupt_interval_usec(u32);
|
||||||
|
void enable_interrupt_mode();
|
||||||
|
|
||||||
enum class ClockID {
|
enum class ClockID {
|
||||||
Reserved = 0,
|
Reserved = 0,
|
||||||
EMMC = 1,
|
EMMC = 1,
|
||||||
|
@ -39,7 +43,21 @@ public:
|
||||||
static u32 set_clock_rate(ClockID, u32 rate_hz, bool skip_setting_turbo = true);
|
static u32 set_clock_rate(ClockID, u32 rate_hz, bool skip_setting_turbo = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum class TimerID : u32 {
|
||||||
|
Timer0 = 0,
|
||||||
|
Timer1 = 1,
|
||||||
|
Timer2 = 2,
|
||||||
|
Timer3 = 3,
|
||||||
|
};
|
||||||
|
void set_compare(TimerID, u32 compare);
|
||||||
|
void clear_interrupt(TimerID);
|
||||||
|
|
||||||
|
//^ IRQHandler
|
||||||
|
virtual bool handle_irq(RegisterState const&) override;
|
||||||
|
|
||||||
TimerRegisters volatile* m_registers;
|
TimerRegisters volatile* m_registers;
|
||||||
|
u32 m_interrupt_interval { 0 };
|
||||||
|
u32 m_current_timer_value { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue