Max OS 0.3
Loading...
Searching...
No Matches
MaxOS::hardwarecommunication::Clock Class Reference

Driver for the APIC clock. More...

#include <clock.h>

Inheritance diagram for MaxOS::hardwarecommunication::Clock:
MaxOS::hardwarecommunication::InterruptHandler

Public Member Functions

 Clock (AdvancedProgrammableInterruptController *apic, uint16_t time_between_events=10)
 Constructor for the Clock class.
 
void delay (uint32_t milliseconds) const
 Delays the program for a specified number of milliseconds (rounded up to the nearest degree of accuracy - ensured the delay is at least the specified number of milliseconds). This on the kernel level is a busy wait, for user level see the sleep function in the Thread class.
 
void calibrate (uint64_t ms_per_tick=1)
 Configures the APIC clock to fire an interrupt at a specified interval in milliseconds.
 
void setup_apic_clock (LocalAPIC *local_apic) const
 Sets up the APIC clock to fire interrupts at the desired rate.
 
common::time_t get_time ()
 Reads the current time from the APIC clock (in 24hr time)
 
- Public Member Functions inherited from MaxOS::hardwarecommunication::InterruptHandler
virtual system::cpu_status_t * handle_interrupt (system::cpu_status_t *status)
 Handles an interrupt and returns the status.
 

Static Public Member Functions

static Clock * active_clock ()
 Gets the currently active clock.
 

Public Attributes

uint64_t clock_accuracy = 1
 How accurate the clock is in microseconds (how often should an interrupt be raised)
 

Additional Inherited Members

- Protected Member Functions inherited from MaxOS::hardwarecommunication::InterruptHandler
 InterruptHandler (uint8_t interrupt_number, int64_t redirect=-1, uint64_t redirect_index=0)
 Creates a new interrupt handler and registers it with the interrupt manager.
 
virtual ~InterruptHandler ()
 Destroys the interrupt handler and unregisters it from the interrupt manager.
 
- Protected Attributes inherited from MaxOS::hardwarecommunication::InterruptHandler
uint8_t m_interrupt_number
 The interrupt number this handler handles.
 

Detailed Description

Driver for the APIC clock.

Definition at line 124 of file clock.h.

Constructor & Destructor Documentation

◆ Clock()

Clock::Clock ( AdvancedProgrammableInterruptController *  apic,
uint16_t  time_between_events = 10 
)
explicit

Constructor for the Clock class.

Parameters
apicThe apic controller for this core
time_between_eventsThe time between events in 10ths of a second

Definition at line 22 of file clock.cpp.

23: InterruptHandler(0x20),
24 m_apic(apic),
25 m_ticks_between_events(time_between_events)
26{
27 Logger::INFO() << "Setting up Clock \n";
28
29 s_active_clock = this;
30
31 // Get the stats from the clock
32 uint8_t status = read_hardware_clock(0xB);
33
34 // Store the clock status
35 m_24_hour_clock = status & 0x02;
36 m_binary = status & 0x04;
37}
static LogRecord INFO()
Gets the active logger for info logs.
Definition logger.cpp:195
Handles a certain interrupt number.
Definition interrupts.h:44

References MaxOS::Logger::INFO().

Member Function Documentation

◆ active_clock()

Clock * Clock::active_clock ( )
static

Gets the currently active clock.

Returns
The clock being used by the kernel

Definition at line 182 of file clock.cpp.

182 {
183 return s_active_clock;
184}

Referenced by MaxOS::system::Core::init(), and MaxOS::system::Core::wake_up().

◆ calibrate()

void Clock::calibrate ( uint64_t  ms_per_tick = 1)

Configures the APIC clock to fire an interrupt at a specified interval in milliseconds.

Parameters
ms_per_tickHow many milliseconds per interrupt

Definition at line 118 of file clock.cpp.

118 {
119
120 Logger::INFO() << "Calibrating Clock \n";
121 clock_accuracy = ms_per_tick;
122
123 // Get the ticks per ms
124 PIT pit(m_apic);
125 m_pit_ticks_per_ms = pit.ticks_per_ms();
126
127 // Calibrate the BSP apic to the desired time
128 setup_apic_clock(m_apic->local_apic());
129
130 Logger::DEBUG() << "Clock: Calibrated to " << ms_per_tick << "ms per kernel tick\n";
131}
static LogRecord DEBUG()
Gets the active logger for debug logs.
Definition logger.cpp:204
uint64_t clock_accuracy
How accurate the clock is in microseconds (how often should an interrupt be raised)
Definition clock.h:156
void setup_apic_clock(LocalAPIC *local_apic) const
Sets up the APIC clock to fire interrupts at the desired rate.
Definition clock.cpp:137
Driver for the Programmable Interval Timer.
Definition clock.h:96

References clock_accuracy, MaxOS::Logger::DEBUG(), MaxOS::Logger::INFO(), MaxOS::hardwarecommunication::AdvancedProgrammableInterruptController::local_apic(), and setup_apic_clock().

Referenced by kernel_main().

◆ delay()

void Clock::delay ( uint32_t  milliseconds) const

Delays the program for a specified number of milliseconds (rounded up to the nearest degree of accuracy - ensured the delay is at least the specified number of milliseconds). This on the kernel level is a busy wait, for user level see the sleep function in the Thread class.

See also
Thread::sleep
Parameters
millisecondsHow many milliseconds to delay the program for.

Definition at line 102 of file clock.cpp.

102 {
103
104 // Round the number of milliseconds UP to the nearest clock accuracy
105 uint64_t rounded_milliseconds = (milliseconds + clock_accuracy - 1) / clock_accuracy;
106
107 // Wait until the time has passed
108 uint64_t ticks_until_delay_is_over = m_ticks + rounded_milliseconds;
109 while (m_ticks < ticks_until_delay_is_over)
110 asm volatile("nop");
111}

References clock_accuracy.

Referenced by MaxOS::system::Core::wake_up().

◆ get_time()

common::time_t Clock::get_time ( )

Reads the current time from the APIC clock (in 24hr time)

Returns
The current time in a Time struct format

Definition at line 156 of file clock.cpp.

156 {
157
158 // Wait for the clock to be ready
159 while (read_hardware_clock(0xA) & 0x80)
160 asm volatile("nop");
161
162 // Read the time from the clock
163 time_t time{};
164 time.year = binary_representation(read_hardware_clock(0x9)) + 2000;
165 time.month = binary_representation(read_hardware_clock(0x8));
166 time.day = binary_representation(read_hardware_clock(0x7));
167 time.hour = binary_representation(read_hardware_clock(0x4));
168 time.minute = binary_representation(read_hardware_clock(0x2));
169 time.second = binary_representation(read_hardware_clock(0x0));
170
171 // If the clock is using 12hr format and PM is set then add 12 to the hour
172 if (!m_24_hour_clock && (time.hour & 0x80) != 0)
173 time.hour = ((time.hour & 0x7F) + 12) % 24;
174
175 return time;
176}

◆ setup_apic_clock()

void Clock::setup_apic_clock ( hardwarecommunication::LocalAPIC *  local_apic) const

Sets up the APIC clock to fire interrupts at the desired rate.

Parameters
local_apicThe local APIC to setup the clock on

Definition at line 137 of file clock.cpp.

137 {
138
139 // Configure the clock to periodic mode
140 uint32_t lvt = 0x20 | (1 << 17);
141 local_apic->write(0x320, lvt);
142
143 // Set the initial count
144 local_apic->write(0x380, m_pit_ticks_per_ms * clock_accuracy);
145
146 // Clear the interrupt mask for the clock
147 lvt &= ~(1 << 16);
148 local_apic->write(0x320, lvt);
149}
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
Definition apic.cpp:91

References clock_accuracy, and MaxOS::hardwarecommunication::LocalAPIC::write().

Referenced by calibrate(), and MaxOS::system::Core::init().

Member Data Documentation

◆ clock_accuracy

uint64_t MaxOS::hardwarecommunication::Clock::clock_accuracy = 1

How accurate the clock is in microseconds (how often should an interrupt be raised)

Definition at line 156 of file clock.h.

Referenced by calibrate(), delay(), and setup_apic_clock().


The documentation for this class was generated from the following files: