13using namespace MaxOS::common;
14using namespace MaxOS::hardwarecommunication;
15using namespace MaxOS::drivers;
16using namespace MaxOS::drivers::clock;
32Clock::~Clock() =
default;
38void Clock::handle_interrupt() {
42 m_ticks_until_next_event--;
45 if (m_ticks_until_next_event != 0)
53 m_ticks_until_next_event = m_ticks_between_events;
65 m_command_port.
write(address);
66 return m_data_port.
read();
90 s_active_clock =
this;
93 uint8_t status = read_hardware_clock(0xB);
96 m_24_hour_clock = status & 0x02;
97 m_binary = status & 0x04;
151 m_pit_ticks_per_ms =
pit.ticks_per_ms();
185 while (read_hardware_clock(0xA) & 0x80)
190 time.year = binary_representation(read_hardware_clock(0x9)) + 2000;
191 time.month = binary_representation(read_hardware_clock(0x8));
192 time.day = binary_representation(read_hardware_clock(0x7));
193 time.hour = binary_representation(read_hardware_clock(0x4));
194 time.minute = binary_representation(read_hardware_clock(0x2));
195 time.second = binary_representation(read_hardware_clock(0x0));
198 if (!m_24_hour_clock && (
time.hour & 0x80) != 0)
199 time.hour = ((
time.hour & 0x7F) + 12) % 24;
209 return s_active_clock;
219 m_command_port(0x43),
220 m_local_apic(apic->local_apic()),
221 m_io_apic(apic->io_apic())
226PIT::~PIT() =
default;
231void PIT::handle_interrupt() {
256 .operating_mode = (
uint8_t) OperatingMode::RATE_GENERATOR,
257 .access_mode = (
uint8_t) AccessMode::LOW_HIGH_BYTE,
258 .channel = (
uint8_t) Channel::INTERRUPT
268 m_local_apic->
write(0x380, 0x00);
271 m_local_apic->
write(0x3E0, 0x0);
280 while (m_ticks < TICK_CALIBRATE_LENGTH)
289 m_local_apic->
write(0x380, 0x00);
static Logger DEBUG()
Gets active logger set to DEBUG level.
static Logger INFO()
Gets active logger set to info level.
Stores the left, top, width and height of a rectangle.
Driver for the APIC clock.
common::time_t get_time()
Reads the current time from the APIC clock (in 24hr time)
void activate() override
Activates the clock, setting the binary coded decimal representation flag.
string device_name() final
Gets the name of the device.
void setup_apic_clock(hardwarecommunication::LocalAPIC *local_apic) const
Sets up the APIC clock to fire interrupts at the desired rate.
uint64_t clock_accuracy
How accurate the clock is in microseconds (how often should an interrupt be raised)
void delay(uint32_t milliseconds) const
Delays the program for a specified number of milliseconds (rounded up to the nearest degree of accura...
Clock(hardwarecommunication::AdvancedProgrammableInterruptController *apic, uint16_t time_between_events=10)
Constructor for the Clock class.
string vendor_name() final
Gets the vendor who created the device.
static Clock * active_clock()
Gets the currently active clock.
void calibrate(uint64_t ms_per_tick=1)
Configures the APIC clock to fire an interrupt at a specified interval in milliseconds.
Driver for the Programmable Interval Timer.
PIT(hardwarecommunication::AdvancedProgrammableInterruptController *apic)
Constructor for the PIT class. Registers a handler for interrupt 0x22 and initialises ports.
Handles both the Local APIC (boot core) and IO APIC.
LocalAPIC * local_apic() const
Get the local apic.
void set_redirect(interrupt_redirect_t *redirect)
Redirect a system interrupt to a different IRQ.
void set_redirect_mask(uint8_t index, bool mask)
Enables/Disables an interrupt redirect by masking it.
Handles a certain interrupt number.
Handles the local APIC for the current core.
void write(uint32_t reg, uint32_t value) const
write a value to the apic register using the MSR or memory I/O depending on the local apic version
uint32_t read(uint32_t reg) const
read a value from the apic register using the MSR or memory I/O depending on the local apic version
virtual uint8_t read()
read a byte from the port
virtual void write(uint8_t data)
write a byte to the port
Defines drivers for the Programmable Interval Timer (PIT) and APIC Clock.
constexpr uint16_t TICK_CALIBRATE_LENGTH
How many loops to spin for calibration.
Defines a Logger class for logging messages with different severity levels to multiple output streams...
Stores the year, month, day, hour, minute and second of a time.
The command byte to send to the PIT, specifies the channel, access mode, operating mode and BCD mode.
uint8_t bcd_mode
0 = binary, 1 = BCD
Defines how an interrupt input is redirected to a specific processor via the I/O APIC.