Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion src/structures/idt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use bit_field::BitField;
use bitflags::bitflags;
use core::fmt;
use core::marker::PhantomData;
use core::ops::{Deref, Index, IndexMut};
use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::{Deref, Index, IndexMut, RangeBounds};

/// An Interrupt Descriptor Table with 256 entries.
///
Expand Down Expand Up @@ -442,6 +443,49 @@ impl InterruptDescriptorTable {

unsafe { lidt(&ptr) };
}

/// Returns a normalized and ranged check slice range from a RangeBounds trait object
///
/// Panics if range is outside the range of user interrupts (i.e. greater than 255) or if the entry is an
/// exception
fn condition_slice_bounds(&self, bounds: impl RangeBounds<usize>) -> (usize, usize) {
let lower_idx = match bounds.start_bound() {
Included(start) => *start,
Excluded(start) => *start + 1,
Unbounded => 0,
};
let upper_idx = match bounds.end_bound() {
Included(end) => *end + 1,
Excluded(end) => *end,
Unbounded => 256,
};

if lower_idx > 256 || upper_idx > 256 {
panic!("Index out of range [{}..{}]", lower_idx, upper_idx);
}
if lower_idx < 32 {
panic!("Cannot return slice from traps, faults, and exception handlers");
}
(lower_idx, upper_idx)
}

/// Returns slice of IDT entries with the specified range.
///
/// Panics if range is outside the range of user interrupts (i.e. greater than 255) or if the entry is an
/// exception
pub fn slice(&self, bounds: impl RangeBounds<usize>) -> &[Entry<HandlerFunc>] {
let (lower_idx, upper_idx) = self.condition_slice_bounds(bounds);
&self.interrupts[(lower_idx - 32)..(upper_idx - 32)]
}

/// Returns a mutable slice of IDT entries with the specified range.
///
/// Panics if range is outside the range of user interrupts (i.e. greater than 255) or if the entry is an
/// exception
pub fn slice_mut(&mut self, bounds: impl RangeBounds<usize>) -> &mut [Entry<HandlerFunc>] {
let (lower_idx, upper_idx) = self.condition_slice_bounds(bounds);
&mut self.interrupts[(lower_idx - 32)..(upper_idx - 32)]
}
}

impl Index<usize> for InterruptDescriptorTable {
Expand Down