mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 21:22:46 +00:00 
			
		
		
		
	Kernel: Make IDT Entries their one struct
This is to make them a bit more transparent, and with a bit of Compiler magic we get the 64-bit implementation in the same package
This commit is contained in:
		
							parent
							
								
									0d934fc991
								
							
						
					
					
						commit
						61240aaad3
					
				
					 2 changed files with 74 additions and 5 deletions
				
			
		|  | @ -58,7 +58,7 @@ extern FlatPtr end_of_ro_after_init; | |||
| namespace Kernel { | ||||
| 
 | ||||
| READONLY_AFTER_INIT static DescriptorTablePointer s_idtr; | ||||
| READONLY_AFTER_INIT static Descriptor s_idt[256]; | ||||
| READONLY_AFTER_INIT static IDTEntry s_idt[256]; | ||||
| 
 | ||||
| static GenericInterruptHandler* s_interrupt_handler[GENERIC_INTERRUPT_HANDLERS_COUNT]; | ||||
| 
 | ||||
|  | @ -484,14 +484,18 @@ void unregister_generic_interrupt_handler(u8 interrupt_number, GenericInterruptH | |||
| 
 | ||||
| UNMAP_AFTER_INIT void register_interrupt_handler(u8 index, void (*handler)()) | ||||
| { | ||||
|     s_idt[index].low = 0x00080000 | LSW((FlatPtr)(handler)); | ||||
|     s_idt[index].high = ((FlatPtr)(handler)&0xffff0000) | 0x8e00; | ||||
|     // FIXME: Why is that with selector 8?
 | ||||
|     // FIXME: Is the Gate Type really required to be an Interupt
 | ||||
|     // FIXME: Whats up with that storage segment 0?
 | ||||
|     s_idt[index] = IDTEntry((FlatPtr)handler, 8, IDTEntryType::InterruptGate32, 0, 0); | ||||
| } | ||||
| 
 | ||||
| UNMAP_AFTER_INIT void register_user_callable_interrupt_handler(u8 index, void (*handler)()) | ||||
| { | ||||
|     s_idt[index].low = 0x00080000 | LSW(((FlatPtr)handler)); | ||||
|     s_idt[index].high = ((FlatPtr)(handler)&0xffff0000) | 0xef00; | ||||
|     // FIXME: Why is that with selector 8?
 | ||||
|     // FIXME: Is the Gate Type really required to be a Trap
 | ||||
|     // FIXME: Whats up with that storage segment 0?
 | ||||
|     s_idt[index] = IDTEntry((FlatPtr)handler, 8, IDTEntryType::TrapGate32, 0, 3); | ||||
| } | ||||
| 
 | ||||
| UNMAP_AFTER_INIT void flush_idt() | ||||
|  |  | |||
|  | @ -111,4 +111,69 @@ union [[gnu::packed]] Descriptor { | |||
|     } | ||||
| }; | ||||
| 
 | ||||
| enum class IDTEntryType { | ||||
|     TaskGate32 = 0b0101, | ||||
|     InterruptGate16 = 0b110, | ||||
|     TrapGate16 = 0b111, | ||||
|     InterruptGate32 = 0b1110, | ||||
|     TrapGate32 = 0b1111, | ||||
| }; | ||||
| 
 | ||||
| // Clang doesn't format this right due to the compiler magic
 | ||||
| // clang-format off
 | ||||
| struct [[gnu::packed]] IDTEntry | ||||
| { | ||||
| 
 | ||||
|     u16 offset_1; // offset bits 0..15
 | ||||
|     u16 selector; // a code segment selector in GDT or LDT
 | ||||
| 
 | ||||
|     u8 zero; // unused, set to 0 (maybe used on amd64)
 | ||||
|     struct { | ||||
|         // FIXME: Is the order correct?
 | ||||
|         u8 gate_type : 4; | ||||
|         u8 storage_segment : 1; | ||||
|         u8 descriptor_privilege_level : 2; | ||||
|         u8 present : 1; | ||||
|     } type_attr;  // type and attributes
 | ||||
|     u16 offset_2; // offset bits 16..31
 | ||||
| #if !ARCH(I386) | ||||
| // we may need to switch those around?
 | ||||
|     u32 offset_3; | ||||
|     u32 zeros; | ||||
| #endif | ||||
| 
 | ||||
|     IDTEntry() = default; | ||||
|     IDTEntry(FlatPtr callback, u16 selector_, IDTEntryType type, u8 storage_segment, u8 privilige_level) | ||||
|         : offset_1 { (u16)((FlatPtr)callback & 0xFFFF) } | ||||
|         , selector { selector_ } | ||||
|         , zero { 0 } | ||||
|         , type_attr { | ||||
|             .gate_type = (u8)type, | ||||
|             .storage_segment = storage_segment, | ||||
|             .descriptor_privilege_level = (u8)(privilige_level & 0b11), | ||||
|             .present = 1, | ||||
|         } | ||||
|         , offset_2 { (u16)((FlatPtr)callback >> 16) } | ||||
| #if !ARCH(I386) | ||||
|         , offset_3 { (u32)(((FlatPtr)callback) >> 32) } | ||||
|         , zeros { 0 } | ||||
| #endif | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     u32 off() | ||||
|     { | ||||
| #if ARCH(I386) | ||||
|         return (u32)offset_2 << 16 & (u32)offset_1; | ||||
| #else | ||||
|         return (u64)offset_3 << 32 & (u64)offset_2 << 16 & (u64)offset_1; | ||||
| #endif | ||||
|     } | ||||
|     IDTEntryType type() | ||||
|     { | ||||
|         return IDTEntryType(type_attr.gate_type); | ||||
|     } | ||||
| }; | ||||
| // clang-format on
 | ||||
| 
 | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Hendiadyoin1
						Hendiadyoin1