aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Gerd Zellweger <mail@gerdzellweger.com> 2017-11-14 15:28:53 +0100
committerGravatar GitHub <noreply@github.com> 2017-11-14 15:28:53 +0100
commit7afc050be9266413f9104e51a59e061b9a918bbc (patch)
tree77e08dbae4481be886f3e7b5ce4e30cdba26562f /src
parent3be39d1c4346ec39af572b12784b21bd60bebf2c (diff)
parent07b527e510ced52960a5051368828822f1672a0c (diff)
downloadrust-x86-7afc050be9266413f9104e51a59e061b9a918bbc.tar.gz
rust-x86-7afc050be9266413f9104e51a59e061b9a918bbc.tar.zst
rust-x86-7afc050be9266413f9104e51a59e061b9a918bbc.zip
Merge pull request #38 from ColinFinck/irq-fix
Update IdtEntry to the actual descriptor in Intel 3a, Figure 6-7 (including ist_index)
Diffstat (limited to 'src')
-rw-r--r--src/bits64/irq.rs40
1 files changed, 26 insertions, 14 deletions
diff --git a/src/bits64/irq.rs b/src/bits64/irq.rs
index 84ee0e6..0f8f9ce 100644
--- a/src/bits64/irq.rs
+++ b/src/bits64/irq.rs
@@ -2,6 +2,7 @@
use core::fmt;
+use bits64::segmentation::SegmentSelector;
use shared::descriptor::*;
use shared::paging::VAddr;
use shared::PrivilegeLevel;
@@ -9,16 +10,16 @@ use shared::PrivilegeLevel;
/// An interrupt gate descriptor.
///
/// See Intel manual 3a for details, specifically section "6.14.1 64-Bit Mode
-/// IDT" and "Table 3-2. System-Segment and Gate-Descriptor Types".
+/// IDT" and "Figure 6-7. 64-Bit IDT Gate Descriptors".
#[derive(Debug, Clone, Copy)]
#[repr(C, packed)]
pub struct IdtEntry {
/// Lower 16 bits of ISR.
pub base_lo: u16,
/// Segment selector.
- pub selector: u16,
+ pub selector: SegmentSelector,
/// This must always be zero.
- pub reserved0: u8,
+ pub ist_index: u8,
/// Flags.
pub flags: Flags,
/// The upper 48 bits of ISR (the last 16 bits must be zero).
@@ -27,6 +28,20 @@ pub struct IdtEntry {
pub reserved1: u16,
}
+pub enum Type {
+ InterruptGate,
+ TrapGate,
+}
+
+impl Type {
+ pub fn pack(self) -> Flags {
+ match self {
+ Type::InterruptGate => FLAGS_TYPE_SYS_NATIVE_INTERRUPT_GATE,
+ Type::TrapGate => FLAGS_TYPE_SYS_NATIVE_TRAP_GATE,
+ }
+ }
+}
+
impl IdtEntry {
/// A "missing" IdtEntry.
///
@@ -35,8 +50,8 @@ impl IdtEntry {
/// some other data stored in the error code.
pub const MISSING: IdtEntry = IdtEntry {
base_lo: 0,
- selector: 0,
- reserved0: 0,
+ selector: SegmentSelector::from_raw(0),
+ ist_index: 0,
flags: Flags::BLANK,
base_hi: 0,
reserved1: 0,
@@ -49,20 +64,17 @@ impl IdtEntry {
///
/// The "Present" flag set, which is the most common case. If you need
/// something else, you can construct it manually.
- pub const fn new(handler: VAddr, gdt_code_selector: u16,
- dpl: PrivilegeLevel, block: bool) -> IdtEntry {
+ pub fn new(handler: VAddr, gdt_code_selector: SegmentSelector,
+ dpl: PrivilegeLevel, ty: Type, ist_index: u8) -> IdtEntry {
+ assert!(ist_index < 0b1000);
IdtEntry {
base_lo: ((handler.as_usize() as u64) & 0xFFFF) as u16,
base_hi: handler.as_usize() as u64 >> 16,
selector: gdt_code_selector,
- reserved0: 0,
- // Nice bitflags operations don't work in const fn, hence these
- // ad-hoc methods.
+ ist_index: ist_index,
flags: Flags::from_priv(dpl)
- .const_or(FLAGS_TYPE_SYS_NATIVE_INTERRUPT_GATE
- .const_mux(FLAGS_TYPE_SYS_NATIVE_TRAP_GATE,
- block))
- .const_or(FLAGS_PRESENT),
+ | ty.pack()
+ | FLAGS_PRESENT,
reserved1: 0,
}
}