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 { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| READONLY_AFTER_INIT static DescriptorTablePointer s_idtr; | 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]; | 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)()) | UNMAP_AFTER_INIT void register_interrupt_handler(u8 index, void (*handler)()) | ||||||
| { | { | ||||||
|     s_idt[index].low = 0x00080000 | LSW((FlatPtr)(handler)); |     // FIXME: Why is that with selector 8?
 | ||||||
|     s_idt[index].high = ((FlatPtr)(handler)&0xffff0000) | 0x8e00; |     // 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)()) | UNMAP_AFTER_INIT void register_user_callable_interrupt_handler(u8 index, void (*handler)()) | ||||||
| { | { | ||||||
|     s_idt[index].low = 0x00080000 | LSW(((FlatPtr)handler)); |     // FIXME: Why is that with selector 8?
 | ||||||
|     s_idt[index].high = ((FlatPtr)(handler)&0xffff0000) | 0xef00; |     // 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() | 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