Skip to content

Commit

Permalink
Add slice and slice_mut methods to IDT (#95)
Browse files Browse the repository at this point in the history
  • Loading branch information
foxcob authored and phil-opp committed Nov 26, 2019
1 parent a18ac4b commit 6348cb3
Showing 1 changed file with 45 additions and 1 deletion.
46 changes: 45 additions & 1 deletion src/structures/idt.rs
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

0 comments on commit 6348cb3

Please sign in to comment.