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

Handles all interrupts and passes them to the correct handler. More...

#include <interrupts.h>

Public Member Functions

 InterruptManager ()
 Constructs the Interrupt Manager and sets up the interrupt descriptor table (does not activate interrupts)
 
 ~InterruptManager ()
 Destroys the Interrupt Manager and deactivates interrupts.
 
void set_interrupt_handler (uint8_t interrupt, InterruptHandler *handler)
 Sets the interrupt handler for the interrupt.
 
void remove_interrupt_handler (uint8_t interrupt)
 Removes the interrupt handler for the interrupt.
 
void set_apic (AdvancedProgrammableInterruptController *apic)
 Sets the APIC.
 
AdvancedProgrammableInterruptControlleractive_apic ()
 Gets the APIC.
 
void activate ()
 Activates the interrupt manager and starts interrupts (also deactivates the current interrupt manager)
 

Static Public Member Functions

static InterruptManageractive_interrupt_manager ()
 Gets the active interrupt manager.
 
static void load_current ()
 Tell the processor to use the current InterruptManager.
 
static void deactivate ()
 Deactivates the interrupt manager and stops interrupts.
 
static void ForceInterruptReturn (system::cpu_status_t *state)
 Force the CPU to return from an interrupt (see interrupts.s)
 

Protected Member Functions

system::cpu_status_thandle_interrupt_request (system::cpu_status_t *status)
 Handles the interrupt request by passing it to the appropriate handler.
 

Static Protected Member Functions

static void set_interrupt_descriptor_table_entry (uint8_t interrupt, void(*handler)(), uint8_t descriptor_privilege_level)
 Sets an entry in the Interrupt Descriptor Table.
 
static void HandleInterruptRequest0x00 ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x01 ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x02 ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x03 ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x04 ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x05 ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x06 ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x07 ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x08 ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x09 ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x0A ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x0B ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x0C ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x0D ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x0E ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x80 ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x0F ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x31 ()
 Stub (see interrupts.s)
 
static void HandleInterruptRequest0x60 ()
 Stub (see interrupts.s)
 
static void HandleException0x00 ()
 Stub (see interrupts.s)
 
static void HandleException0x01 ()
 Stub (see interrupts.s)
 
static void HandleException0x02 ()
 Stub (see interrupts.s)
 
static void HandleException0x03 ()
 Stub (see interrupts.s)
 
static void HandleException0x04 ()
 Stub (see interrupts.s)
 
static void HandleException0x05 ()
 Stub (see interrupts.s)
 
static void HandleException0x06 ()
 Stub (see interrupts.s)
 
static void HandleException0x07 ()
 Stub (see interrupts.s)
 
static void HandleInterruptError0x08 ()
 Stub (see interrupts.s)
 
static void HandleException0x09 ()
 Stub (see interrupts.s)
 
static void HandleInterruptError0x0A ()
 Stub (see interrupts.s)
 
static void HandleInterruptError0x0B ()
 Stub (see interrupts.s)
 
static void HandleInterruptError0x0C ()
 Stub (see interrupts.s)
 
static void HandleInterruptError0x0D ()
 Stub (see interrupts.s)
 
static void HandleInterruptError0x0E ()
 Stub (see interrupts.s)
 
static void HandleException0x0F ()
 Stub (see interrupts.s)
 
static void HandleException0x10 ()
 Stub (see interrupts.s)
 
static void HandleInterruptError0x11 ()
 Stub (see interrupts.s)
 
static void HandleException0x12 ()
 Stub (see interrupts.s)
 
static void HandleException0x13 ()
 Stub (see interrupts.s)
 
static void HandleException0x14 ()
 Stub (see interrupts.s)
 
static void HandleException0x15 ()
 Stub (see interrupts.s)
 
static void HandleException0x16 ()
 Stub (see interrupts.s)
 
static void HandleException0x17 ()
 Stub (see interrupts.s)
 
static void HandleException0x18 ()
 Stub (see interrupts.s)
 
static void HandleException0x19 ()
 Stub (see interrupts.s)
 
static void HandleException0x1A ()
 Stub (see interrupts.s)
 
static void HandleException0x1B ()
 Stub (see interrupts.s)
 
static void HandleException0x1C ()
 Stub (see interrupts.s)
 
static void HandleException0x1D ()
 Stub (see interrupts.s)
 
static void HandleException0x1E ()
 Stub (see interrupts.s)
 
static void HandleException0x1F ()
 Stub (see interrupts.s)
 
static system::cpu_status_tHandleInterrupt (system::cpu_status_t *status)
 Handles the interrupt request by passing it to the interrupt manager.
 

Protected Attributes

InterruptHandlerm_interrupt_handlers [MAX_INTERRUPT_HANDLERS] = { }
 A map of index-to-interrupt of interrupt handlers to fire when an interrupt occurs.
 

Static Protected Attributes

static InterruptManagers_active_interrupt_manager = nullptr
 The interrupt manger that is currently handling interrupts and is loaded into the IDTR.
 
static InterruptDescriptor s_interrupt_descriptor_table [MAX_INTERRUPT_HANDLERS] = { }
 The Interrupt Descriptor Table (IDT)
 

Friends

class InterruptHandler
 

Detailed Description

Handles all interrupts and passes them to the correct handler.

Todo:

Remove the max array of handler make vector, add static handlers for page faults and gpe. Make it so that multiple handlers can be registered for the same interrupt

Have a single stub so that we don't need to have 256 different functions for each interrupt

Definition at line 84 of file interrupts.h.

Constructor & Destructor Documentation

◆ InterruptManager()

InterruptManager::InterruptManager ( )

Constructs the Interrupt Manager and sets up the interrupt descriptor table (does not activate interrupts)

Definition at line 90 of file interrupts.cpp.

90 {
91
92 Logger::INFO() << "Setting up Interrupt Manager\n";
94
95 // Clear the table
97 descriptor.address_low_bits = 0;
98 descriptor.address_mid_bits = 0;
99 descriptor.address_high_bits = 0;
100 descriptor.segment_selector = 0;
101 descriptor.ist = 0;
102 descriptor.flags = 0;
103 }
104
105 //Set Up the base interrupts
106 set_interrupt_descriptor_table_entry(0x00, &HandleException0x00, 0); // Division by zero
108 set_interrupt_descriptor_table_entry(0x02, &HandleException0x02, 0); // Non-maskable interrupt
111 set_interrupt_descriptor_table_entry(0x05, &HandleException0x05, 0); // Bound Range Exceeded
113 set_interrupt_descriptor_table_entry(0x06, &HandleException0x07, 0); // Device Not Available
115 set_interrupt_descriptor_table_entry(0x09, &HandleException0x09, 0); // Coprocessor Segment Overrun
117 set_interrupt_descriptor_table_entry(0x0B, &HandleInterruptError0x0B, 0); // Segment Not Present
118 set_interrupt_descriptor_table_entry(0x0C, &HandleInterruptError0x0C, 0); // Stack-Segment Fault
119 set_interrupt_descriptor_table_entry(0x0D, &HandleInterruptError0x0D, 0); // General Protection Fault
122 set_interrupt_descriptor_table_entry(0x10, &HandleException0x10, 0); // x87 Floating-Point Exception
125 set_interrupt_descriptor_table_entry(0x13, &HandleException0x13, 0); // SIMD Floating-Point Exception
126 set_interrupt_descriptor_table_entry(0x14, &HandleException0x14, 0); // Reserved: Virtualization Exception
136 set_interrupt_descriptor_table_entry(0x1E, &HandleException0x1E, 0); // Security Exception
138
139 // Set up the hardware interrupts
140 set_interrupt_descriptor_table_entry(HARDWARE_INTERRUPT_OFFSET + 0x00, &HandleInterruptRequest0x00, 0); // APIC Timer Interrupt
141 set_interrupt_descriptor_table_entry(HARDWARE_INTERRUPT_OFFSET + 0x01, &HandleInterruptRequest0x01, 0); // Keyboard Interrupt
142 set_interrupt_descriptor_table_entry(HARDWARE_INTERRUPT_OFFSET + 0x02, &HandleInterruptRequest0x02, 0); // PIT Interrupt
143 set_interrupt_descriptor_table_entry(HARDWARE_INTERRUPT_OFFSET + 0x0C, &HandleInterruptRequest0x0C, 0); // Mouse Interrupt
144
145 // Set up the system call interrupt
146 set_interrupt_descriptor_table_entry(HARDWARE_INTERRUPT_OFFSET + 0x60, &HandleInterruptRequest0x60, 3); // System Call Interrupt - Privilege Level 3 so that user space can call it
147
148 // Tell the processor to use the IDT
149 load_current();
150}
static Logger INFO()
Gets active logger set to info level.
Definition logger.cpp:171
Stores the left, top, width and height of a rectangle.
Definition rectangle.h:22
static InterruptManager * s_active_interrupt_manager
The interrupt manger that is currently handling interrupts and is loaded into the IDTR.
Definition interrupts.h:95
static void HandleException0x15()
Stub (see interrupts.s)
static void HandleInterruptError0x0A()
Stub (see interrupts.s)
static void HandleException0x14()
Stub (see interrupts.s)
static void HandleException0x00()
Stub (see interrupts.s)
static void HandleInterruptRequest0x0C()
Stub (see interrupts.s)
static void HandleException0x07()
Stub (see interrupts.s)
static void HandleInterruptError0x0D()
Stub (see interrupts.s)
static void HandleInterruptError0x08()
Stub (see interrupts.s)
static void HandleException0x13()
Stub (see interrupts.s)
static void HandleInterruptError0x0C()
Stub (see interrupts.s)
static void HandleException0x04()
Stub (see interrupts.s)
static void HandleException0x02()
Stub (see interrupts.s)
static void HandleException0x17()
Stub (see interrupts.s)
static void HandleException0x10()
Stub (see interrupts.s)
static void HandleInterruptRequest0x01()
Stub (see interrupts.s)
static void HandleInterruptError0x11()
Stub (see interrupts.s)
static void HandleException0x1E()
Stub (see interrupts.s)
static void HandleInterruptRequest0x60()
Stub (see interrupts.s)
static void HandleException0x1F()
Stub (see interrupts.s)
static void load_current()
Tell the processor to use the current InterruptManager.
static void HandleException0x05()
Stub (see interrupts.s)
static void HandleInterruptError0x0B()
Stub (see interrupts.s)
static void HandleException0x19()
Stub (see interrupts.s)
static void HandleException0x1A()
Stub (see interrupts.s)
static void HandleException0x01()
Stub (see interrupts.s)
static void HandleException0x18()
Stub (see interrupts.s)
static void HandleException0x1B()
Stub (see interrupts.s)
static void set_interrupt_descriptor_table_entry(uint8_t interrupt, void(*handler)(), uint8_t descriptor_privilege_level)
Sets an entry in the Interrupt Descriptor Table.
static InterruptDescriptor s_interrupt_descriptor_table[MAX_INTERRUPT_HANDLERS]
The Interrupt Descriptor Table (IDT)
Definition interrupts.h:98
static void HandleException0x12()
Stub (see interrupts.s)
static void HandleInterruptRequest0x00()
Stub (see interrupts.s)
static void HandleException0x09()
Stub (see interrupts.s)
static void HandleException0x16()
Stub (see interrupts.s)
static void HandleInterruptError0x0E()
Stub (see interrupts.s)
static void HandleException0x06()
Stub (see interrupts.s)
static void HandleException0x03()
Stub (see interrupts.s)
static void HandleException0x0F()
Stub (see interrupts.s)
static void HandleException0x1C()
Stub (see interrupts.s)
static void HandleInterruptRequest0x02()
Stub (see interrupts.s)
static void HandleException0x1D()
Stub (see interrupts.s)

References HandleException0x00(), HandleException0x01(), HandleException0x02(), HandleException0x03(), HandleException0x04(), HandleException0x05(), HandleException0x06(), HandleException0x07(), HandleException0x09(), HandleException0x0F(), HandleException0x10(), HandleException0x12(), HandleException0x13(), HandleException0x14(), HandleException0x15(), HandleException0x16(), HandleException0x17(), HandleException0x18(), HandleException0x19(), HandleException0x1A(), HandleException0x1B(), HandleException0x1C(), HandleException0x1D(), HandleException0x1E(), HandleException0x1F(), HandleInterruptError0x08(), HandleInterruptError0x0A(), HandleInterruptError0x0B(), HandleInterruptError0x0C(), HandleInterruptError0x0D(), HandleInterruptError0x0E(), HandleInterruptError0x11(), HandleInterruptRequest0x00(), HandleInterruptRequest0x01(), HandleInterruptRequest0x02(), HandleInterruptRequest0x0C(), HandleInterruptRequest0x60(), MaxOS::hardwarecommunication::HARDWARE_INTERRUPT_OFFSET, MaxOS::Logger::INFO(), load_current(), s_active_interrupt_manager, s_interrupt_descriptor_table, and set_interrupt_descriptor_table_entry().

◆ ~InterruptManager()

InterruptManager::~InterruptManager ( )

Destroys the Interrupt Manager and deactivates interrupts.

Definition at line 155 of file interrupts.cpp.

155 {
156 deactivate();
157}
static void deactivate()
Deactivates the interrupt manager and stops interrupts.

References deactivate().

Member Function Documentation

◆ activate()

void InterruptManager::activate ( )

Activates the interrupt manager and starts interrupts (also deactivates the current interrupt manager)

Definition at line 201 of file interrupts.cpp.

201 {
202
203 Logger::INFO() << "Activating Interrupts \n";
204
205 // Deactivate the current (old) interrupt manager
207
208 // Set the current interrupt manager and start interrupts
210 asm("sti");
211}

References deactivate(), MaxOS::Logger::INFO(), and s_active_interrupt_manager.

◆ active_apic()

AdvancedProgrammableInterruptController * InterruptManager::active_apic ( )

Gets the APIC.

Returns
The APIC

Definition at line 382 of file interrupts.cpp.

382 {
383
384 return m_apic;
385}

◆ active_interrupt_manager()

InterruptManager * InterruptManager::active_interrupt_manager ( )
static

Gets the active interrupt manager.

Returns
The active interrupt manager

Definition at line 392 of file interrupts.cpp.

392 {
393
395}

References s_active_interrupt_manager.

Referenced by MaxOS::hardwarecommunication::AdvancedProgrammableInterruptController::AdvancedProgrammableInterruptController().

◆ deactivate()

void InterruptManager::deactivate ( )
static

Deactivates the interrupt manager and stops interrupts.

Definition at line 216 of file interrupts.cpp.

216 {
217
218 // Cant deactivate if it isn't the system one
219 if (s_active_interrupt_manager != nullptr)
220 return;
221
222 // Prevent interrupts from firing when nothing is set up to handle them
223 asm("cli");
225}

References s_active_interrupt_manager.

Referenced by activate(), and ~InterruptManager().

◆ ForceInterruptReturn()

static void MaxOS::hardwarecommunication::InterruptManager::ForceInterruptReturn ( system::cpu_status_t state)
static

Force the CPU to return from an interrupt (see interrupts.s)

Parameters
statethe state to return to

Referenced by MaxOS::common::BlockingLock::acquire().

◆ handle_interrupt_request()

cpu_status_t * InterruptManager::handle_interrupt_request ( system::cpu_status_t status)
protected

Handles the interrupt request by passing it to the appropriate handler.

Parameters
statusThe current cpu status
Returns
The updated cpu status

Definition at line 284 of file interrupts.cpp.

284 {
285
286 // Where to go afterward
287 cpu_status_t* new_status = status;
288
289 // If there is an interrupt manager, handle the interrupt
290 if (m_interrupt_handlers[status->interrupt_number] != nullptr)
291 new_status = m_interrupt_handlers[status->interrupt_number]->handle_interrupt(status);
292 else
293 Logger::WARNING() << "Interrupt " << (int) status->interrupt_number << " not handled\n";
294
295 // Send the EOI to the APIC
296 if (HARDWARE_INTERRUPT_OFFSET <= status->interrupt_number && status->interrupt_number < HARDWARE_INTERRUPT_OFFSET + 16)
297 CPU::executing_core()->local_apic->send_eoi();
298
299 // Return the status
300 return new_status;
301}
static Logger WARNING()
Gets active logger set to WARNING level.
Definition logger.cpp:205
virtual void handle_interrupt()
Handles an interrupt.
InterruptHandler * m_interrupt_handlers[MAX_INTERRUPT_HANDLERS]
A map of index-to-interrupt of interrupt handlers to fire when an interrupt occurs.
Definition interrupts.h:97
static Core * executing_core()
Gets the core that is currently executing.
Definition cpu.cpp:623
struct PACKED MaxOS::system::CPUStatus cpu_status_t
Alias for CPUStatus struct.

References MaxOS::system::CPU::executing_core(), MaxOS::hardwarecommunication::InterruptHandler::handle_interrupt(), MaxOS::hardwarecommunication::HARDWARE_INTERRUPT_OFFSET, m_interrupt_handlers, and MaxOS::Logger::WARNING().

◆ HandleInterrupt()

system::cpu_status_t * InterruptManager::HandleInterrupt ( system::cpu_status_t status)
staticprotected

Handles the interrupt request by passing it to the interrupt manager.

Parameters
statusThe current cpu status
Returns
The updated cpu status

Definition at line 233 of file interrupts.cpp.

233 {
234
235 // Default Fault Handlers
236 switch (status->interrupt_number) {
237
238 case 0x7:
239 CPU::PANIC("Device Not Available: FPU Not Enabled", status);
240 break;
241
242 case 0x0D:
243 return general_protection_fault(status);
244
245 case 0x0E:
246 return page_fault(status);
247 }
248
249 // If there is an interrupt manager handle interrupt
250 if (s_active_interrupt_manager != nullptr)
251 return s_active_interrupt_manager->handle_interrupt_request(status);
252
253 // CPU Can continue
254 return status;
255}
static void PANIC(const char *message, cpu_status_t *status=nullptr)
Puts the CPU into a panic state and halts it. Dumps the stack trace and registers.
Definition cpu.cpp:439

References MaxOS::system::CPU::PANIC(), and s_active_interrupt_manager.

◆ load_current()

void InterruptManager::load_current ( )
static

Tell the processor to use the current InterruptManager.

Definition at line 190 of file interrupts.cpp.

190 {
191
192 IDTR idt = {};
193 idt.limit = 256 * sizeof(InterruptDescriptor) - 1;
195 asm volatile("lidt %0" : : "m" (idt));
196}
A struct that holds the Interrupt Descriptor Table Register (IDTR)
Definition interrupts.h:50
An entry in the Interrupt Descriptor Table (IDT)
Definition interrupts.h:62

References s_interrupt_descriptor_table.

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

◆ remove_interrupt_handler()

void InterruptManager::remove_interrupt_handler ( uint8_t  interrupt)

Removes the interrupt handler for the interrupt.

Parameters
interruptThe interrupt number

Definition at line 273 of file interrupts.cpp.

273 {
274
275 m_interrupt_handlers[interrupt] = nullptr;
276}

References m_interrupt_handlers.

◆ set_apic()

void InterruptManager::set_apic ( AdvancedProgrammableInterruptController apic)

Sets the APIC.

Parameters
apicThe APIC

Definition at line 308 of file interrupts.cpp.

308 {
309
310 m_apic = apic;
311}

Referenced by MaxOS::hardwarecommunication::AdvancedProgrammableInterruptController::AdvancedProgrammableInterruptController().

◆ set_interrupt_descriptor_table_entry()

void InterruptManager::set_interrupt_descriptor_table_entry ( uint8_t  interrupt,
void(*)()  handler,
uint8_t  descriptor_privilege_level 
)
staticprotected

Sets an entry in the Interrupt Descriptor Table.

Parameters
interruptInterrupt number
handlerInterrupt Handler
descriptor_privilege_levelDescriptor Privilege Level

Definition at line 166 of file interrupts.cpp.

166 {
167
168 // Get the address of the handler and the entry in the IDT
171
172 // Set the handler address
173 interrupt_descriptor->address_low_bits = handler_address & 0xFFFF;
174 interrupt_descriptor->address_mid_bits = (handler_address >> 16) & 0xFFFF;
175 interrupt_descriptor->address_high_bits = (handler_address >> 32) & 0xFFFFFFFF;
176
177 // Set the kernel code segment offset
178 interrupt_descriptor->segment_selector = 0x08;
179
180 // Disable IST
181 interrupt_descriptor->ist = 0;
182
183 // Set the flags (Trap Gate, Present and the Descriptor Privilege Level)
184 interrupt_descriptor->flags = 0b1110 | ((descriptor_privilege_level & 0b11) << 5) | (1 << 7);
185}

References s_interrupt_descriptor_table.

Referenced by InterruptManager().

◆ set_interrupt_handler()

void InterruptManager::set_interrupt_handler ( uint8_t  interrupt,
InterruptHandler handler 
)

Sets the interrupt handler for the interrupt.

Parameters
interruptThe interrupt number
handlerThe interrupt handler

Definition at line 263 of file interrupts.cpp.

263 {
264
265 m_interrupt_handlers[interrupt] = handler;
266}

References m_interrupt_handlers.

Friends And Related Symbol Documentation

◆ InterruptHandler

friend class InterruptHandler
friend

Definition at line 85 of file interrupts.h.

Member Data Documentation

◆ m_interrupt_handlers

InterruptHandler* MaxOS::hardwarecommunication::InterruptManager::m_interrupt_handlers[MAX_INTERRUPT_HANDLERS] = { }
protected

A map of index-to-interrupt of interrupt handlers to fire when an interrupt occurs.

Definition at line 97 of file interrupts.h.

97{ };

Referenced by handle_interrupt_request(), remove_interrupt_handler(), and set_interrupt_handler().

◆ s_active_interrupt_manager

InterruptManager* MaxOS::hardwarecommunication::InterruptManager::s_active_interrupt_manager = nullptr
inlinestaticprotected

◆ s_interrupt_descriptor_table

InterruptDescriptor MaxOS::hardwarecommunication::InterruptManager::s_interrupt_descriptor_table[MAX_INTERRUPT_HANDLERS] = { }
inlinestaticprotected

The Interrupt Descriptor Table (IDT)

Definition at line 98 of file interrupts.h.

98{ };

Referenced by InterruptManager(), load_current(), and set_interrupt_descriptor_table_entry().


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