You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			36 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			C++
		
	
			
		
		
	
	
			36 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			C++
		
	
| #include "idt.h"
 | |
| 
 | |
| #include "core_interrupt.h"
 | |
| 
 | |
| namespace IDT {
 | |
| 
 | |
| // Interrupt Descriptor Table, 8 Byte aligned
 | |
| constinit struct InterruptDescriptor idt[256] = {};
 | |
| 
 | |
| // Struct used for loading (the address of) the Interrupt Descriptor Table into
 | |
| // the IDT-Register
 | |
| struct Register {
 | |
|   uint16_t limit;  // Address of the last valid byte (relative to base)
 | |
|   struct InterruptDescriptor* base;
 | |
|   explicit Register(uint8_t max = 255) {
 | |
|     limit = (max + static_cast<uint16_t>(1)) * sizeof(InterruptDescriptor) - 1;
 | |
|     base = idt;
 | |
|   }
 | |
| } __attribute__((packed));
 | |
| 
 | |
| static_assert(sizeof(InterruptDescriptor) == 16,
 | |
|               "IDT::InterruptDescriptor has wrong size");
 | |
| static_assert(sizeof(Register) == 10, "IDT::Register has wrong size");
 | |
| static_assert(alignof(decltype(idt)) % 8 == 0, "IDT must be 8 byte aligned!");
 | |
| 
 | |
| void load() {
 | |
|   // Create structure required for writing to idtr and load via lidt
 | |
|   Register idtr(Core::Interrupt::VECTORS - 1);
 | |
|   asm volatile("lidt %0\n\t" ::"m"(idtr));
 | |
| }
 | |
| 
 | |
| void set(Core::Interrupt::Vector vector, InterruptDescriptor descriptor) {
 | |
|   idt[(uint8_t)vector] = descriptor;
 | |
| }
 | |
| }  // namespace IDT
 |