Skip to content

Commit fbf0424

Browse files
committed
[interrupt-handlers] added IDT
- added IdtEntry structure, - created IDT static mut array, and - made fxns to init_idt and set_idt_entry. Signed-off-by: danbugs <[email protected]>
1 parent 1bd70e1 commit fbf0424

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

src/hyperlight_guest/src/idt.rs

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
Copyright 2024 The Hyperlight Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
use crate::interrupt_entry::{
18+
_do_excp0, _do_excp1, _do_excp10, _do_excp11, _do_excp12, _do_excp13, _do_excp15, _do_excp16,
19+
_do_excp17, _do_excp18, _do_excp19, _do_excp2, _do_excp20, _do_excp3, _do_excp30, _do_excp4,
20+
_do_excp5, _do_excp6, _do_excp7, _do_excp9,
21+
};
22+
23+
// An entry in the Interrupt Descriptor Table (IDT)
24+
// For reference, see page 7-20 Vol. 3A of Intel 64 and IA-32
25+
// Architectures Software Developer's Manual, figure 7-8
26+
// (i.e., https://i.imgur.com/N4rEjHj.png).
27+
// From the bottom, we have:
28+
// - offset 15..0 = offset_low
29+
// - segment selector 31..16 = selector
30+
// - 000 0 0 Interrupt Stack Table 7..0 = interrupt_stack_table_offset
31+
// - p dpl 0 type 15..8 = type_attr
32+
// - offset 31..16 = offset_mid
33+
// - offset 63..32 = offset_high
34+
// - reserved 31..0 = zero
35+
#[repr(C, align(16))]
36+
pub(crate) struct IdtEntry {
37+
offset_low: u16, // Lower 16 bits of handler address
38+
selector: u16, // code segment selector in GDT
39+
interrupt_stack_table_offset: u8, // Interrupt Stack Table offset
40+
type_attr: u8, // Gate type and flags
41+
offset_mid: u16, // Middle 16 bits of handler address
42+
offset_high: u32, // High 32 bits of handler address
43+
zero: u32, // Reserved (always 0)
44+
}
45+
46+
impl IdtEntry {
47+
fn new(handler: u64) -> Self {
48+
Self {
49+
offset_low: (handler & 0xFFFF) as u16,
50+
selector: 0x08, // Kernel Code Segment
51+
interrupt_stack_table_offset: 0, // No interrupt stack table used
52+
type_attr: 0x8E,
53+
// 0x8E = 10001110b
54+
// 1 00 0 1110
55+
// 1 = Present
56+
// 00 = Descriptor Privilege Level (0)
57+
// 0 = Storage Segment (0)
58+
// 1110 = Gate Type (0b1110 = 14 = 0xE)
59+
// 0xE means it's an interrupt gate
60+
offset_mid: ((handler >> 16) & 0xFFFF) as u16,
61+
offset_high: ((handler >> 32) & 0xFFFFFFFF) as u32,
62+
zero: 0,
63+
}
64+
}
65+
}
66+
67+
// The IDT is an array of 256 IDT entries
68+
// (for reference, see page 7-9 Vol. 3A of Intel 64 and IA-32
69+
// Architectures Software Developer's Manual).
70+
pub(crate) static mut IDT: [IdtEntry; 256] = unsafe { core::mem::zeroed() };
71+
72+
pub(crate) fn init_idt() {
73+
set_idt_entry(0, _do_excp0); // Divide by zero
74+
set_idt_entry(1, _do_excp1); // Debug
75+
set_idt_entry(2, _do_excp2); // Non-maskable interrupt
76+
set_idt_entry(3, _do_excp3); // Breakpoint
77+
set_idt_entry(4, _do_excp4); // Overflow
78+
set_idt_entry(5, _do_excp5); // Bound Range Exceeded
79+
set_idt_entry(6, _do_excp6); // Invalid Opcode
80+
set_idt_entry(7, _do_excp7); // Device Not Available
81+
// TODO: uncomment when pagefault is implemented
82+
// set_idt_entry(8, _do_excp8); // Double Fault
83+
set_idt_entry(9, _do_excp9); // Coprocessor Segment Overrun
84+
set_idt_entry(10, _do_excp10); // Invalid TSS
85+
set_idt_entry(11, _do_excp11); // Segment Not Present
86+
set_idt_entry(12, _do_excp12); // Stack-Segment Fault
87+
set_idt_entry(13, _do_excp13); // General Protection Fault
88+
// TODO: uncomment when pagefault is implemented
89+
// set_idt_entry(14, _do_excp14); // Page Fault
90+
set_idt_entry(15, _do_excp15); // Reserved
91+
set_idt_entry(16, _do_excp16); // x87 Floating-Point Exception
92+
set_idt_entry(17, _do_excp17); // Alignment Check
93+
set_idt_entry(18, _do_excp18); // Machine Check
94+
set_idt_entry(19, _do_excp19); // SIMD Floating-Point Exception
95+
set_idt_entry(20, _do_excp20); // Virtualization Exception
96+
set_idt_entry(30, _do_excp30); // Security Exception
97+
}
98+
99+
fn set_idt_entry(index: usize, handler: unsafe extern "sysv64" fn()) {
100+
let handler_addr = handler as *const () as u64;
101+
unsafe {
102+
IDT[index] = IdtEntry::new(handler_addr);
103+
}
104+
}

src/hyperlight_guest/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub mod error;
5353
pub mod logging;
5454
pub mod interrupt_entry;
5555
pub mod interrupt_handlers;
56+
pub mod idt;
5657

5758
// Unresolved symbols
5859
///cbindgen:ignore

0 commit comments

Comments
 (0)