From 88fee50dc78a5c6ec0597af152b79ab4a51c98c6 Mon Sep 17 00:00:00 2001 From: Tom Dohrmann Date: Sun, 7 Nov 2021 21:26:25 +0100 Subject: [PATCH 1/4] change `Index` to `Index` --- src/structures/idt.rs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/structures/idt.rs b/src/structures/idt.rs index a4f74a8bb..d325fc985 100644 --- a/src/structures/idt.rs +++ b/src/structures/idt.rs @@ -504,15 +504,14 @@ impl InterruptDescriptorTable { } } -impl Index for InterruptDescriptorTable { +impl Index for InterruptDescriptorTable { type Output = Entry; /// Returns the IDT entry with the specified index. /// - /// Panics if index is outside the IDT (i.e. greater than 255) or if the entry is an - /// exception that pushes an error code (use the struct fields for accessing these entries). + /// Panics if the entry is an exception that pushes an error code (use the struct fields for accessing these entries). #[inline] - fn index(&self, index: usize) -> &Self::Output { + fn index(&self, index: u8) -> &Self::Output { match index { 0 => &self.divide_error, 1 => &self.debug, @@ -526,24 +525,22 @@ impl Index for InterruptDescriptorTable { 16 => &self.x87_floating_point, 19 => &self.simd_floating_point, 20 => &self.virtualization, - i @ 32..=255 => &self.interrupts[i - 32], + i @ 32..=255 => &self.interrupts[(i - 32) as usize], i @ 15 | i @ 31 | i @ 21..=29 => panic!("entry {} is reserved", i), i @ 8 | i @ 10..=14 | i @ 17 | i @ 30 => { panic!("entry {} is an exception with error code", i) } i @ 18 => panic!("entry {} is an diverging exception (must not return)", i), - i => panic!("no entry with index {}", i), } } } -impl IndexMut for InterruptDescriptorTable { +impl IndexMut for InterruptDescriptorTable { /// Returns a mutable reference to the IDT entry with the specified index. /// - /// Panics if index is outside the IDT (i.e. greater than 255) or if the entry is an - /// exception that pushes an error code (use the struct fields for accessing these entries). + /// Panics if the entry is an exception that pushes an error code (use the struct fields for accessing these entries). #[inline] - fn index_mut(&mut self, index: usize) -> &mut Self::Output { + fn index_mut(&mut self, index: u8) -> &mut Self::Output { match index { 0 => &mut self.divide_error, 1 => &mut self.debug, @@ -557,13 +554,12 @@ impl IndexMut for InterruptDescriptorTable { 16 => &mut self.x87_floating_point, 19 => &mut self.simd_floating_point, 20 => &mut self.virtualization, - i @ 32..=255 => &mut self.interrupts[i - 32], + i @ 32..=255 => &mut self.interrupts[(i - 32) as usize], i @ 15 | i @ 31 | i @ 21..=29 => panic!("entry {} is reserved", i), i @ 8 | i @ 10..=14 | i @ 17 | i @ 30 => { panic!("entry {} is an exception with error code", i) } i @ 18 => panic!("entry {} is an diverging exception (must not return)", i), - i => panic!("no entry with index {}", i), } } } From 99a334c4a4bd05babeb54aedbb7d2faf284e0004 Mon Sep 17 00:00:00 2001 From: Tom Dohrmann Date: Sun, 7 Nov 2021 21:26:55 +0100 Subject: [PATCH 2/4] use `u8` instead of `usize` for `slice` --- src/structures/idt.rs | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/structures/idt.rs b/src/structures/idt.rs index d325fc985..b4ffa568b 100644 --- a/src/structures/idt.rs +++ b/src/structures/idt.rs @@ -458,25 +458,21 @@ impl InterruptDescriptorTable { } } - /// Returns a normalized and ranged check slice range from a RangeBounds trait object + /// 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) { + /// Panics if the entry is an exception. + fn condition_slice_bounds(&self, bounds: impl RangeBounds) -> (usize, usize) { let lower_idx = match bounds.start_bound() { - Included(start) => *start, - Excluded(start) => *start + 1, + Included(start) => (*start as usize), + Excluded(start) => (*start as usize) + 1, Unbounded => 0, }; let upper_idx = match bounds.end_bound() { - Included(end) => *end + 1, - Excluded(end) => *end, + Included(end) => (*end as usize) + 1, + Excluded(end) => (*end as usize), 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"); } @@ -485,20 +481,18 @@ impl InterruptDescriptorTable { /// 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 + /// Panics if the entry is an exception. #[inline] - pub fn slice(&self, bounds: impl RangeBounds) -> &[Entry] { + pub fn slice(&self, bounds: impl RangeBounds) -> &[Entry] { 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 + /// Panics if the entry is an exception. #[inline] - pub fn slice_mut(&mut self, bounds: impl RangeBounds) -> &mut [Entry] { + pub fn slice_mut(&mut self, bounds: impl RangeBounds) -> &mut [Entry] { let (lower_idx, upper_idx) = self.condition_slice_bounds(bounds); &mut self.interrupts[(lower_idx - 32)..(upper_idx - 32)] } From 5be7446d46d08b0e25bf8c75d9b941125a5ae01d Mon Sep 17 00:00:00 2001 From: Tom Dohrmann Date: Sun, 7 Nov 2021 21:39:32 +0100 Subject: [PATCH 3/4] implement ranged index for idt --- src/structures/idt.rs | 47 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/structures/idt.rs b/src/structures/idt.rs index b4ffa568b..4c2def6da 100644 --- a/src/structures/idt.rs +++ b/src/structures/idt.rs @@ -26,7 +26,10 @@ use bitflags::bitflags; use core::fmt; use core::marker::PhantomData; use core::ops::Bound::{Excluded, Included, Unbounded}; -use core::ops::{Deref, Index, IndexMut, RangeBounds}; +use core::ops::{ + Bound, Deref, Index, IndexMut, Range, RangeBounds, RangeFrom, RangeFull, RangeInclusive, + RangeTo, RangeToInclusive, +}; use volatile::Volatile; use super::gdt::SegmentSelector; @@ -558,6 +561,48 @@ impl IndexMut for InterruptDescriptorTable { } } +macro_rules! impl_index_for_idt { + ($ty:ty) => { + impl Index<$ty> for InterruptDescriptorTable { + type Output = [Entry]; + + /// Returns the IDT entry with the specified index. + /// + /// Panics if index is outside the IDT (i.e. greater than 255) or if the entry is an + /// exception that pushes an error code (use the struct fields for accessing these entries). + #[inline] + fn index(&self, index: $ty) -> &Self::Output { + self.slice(index) + } + } + + impl IndexMut<$ty> for InterruptDescriptorTable { + /// Returns a mutable reference to the IDT entry with the specified index. + /// + /// Panics if the entry is an exception that pushes an error code (use the struct fields for accessing these entries). + #[inline] + fn index_mut(&mut self, index: $ty) -> &mut Self::Output { + self.slice_mut(index) + } + } + }; +} + +// this list was stolen from the list of implementors in https://doc.rust-lang.org/core/ops/trait.RangeBounds.html +impl_index_for_idt!((Bound<&u8>, Bound<&u8>)); +impl_index_for_idt!((Bound, Bound)); +impl_index_for_idt!(Range<&u8>); +impl_index_for_idt!(Range); +impl_index_for_idt!(RangeFrom<&u8>); +impl_index_for_idt!(RangeFrom); +impl_index_for_idt!(RangeInclusive<&u8>); +impl_index_for_idt!(RangeInclusive); +impl_index_for_idt!(RangeTo); +impl_index_for_idt!(RangeTo<&u8>); +impl_index_for_idt!(RangeToInclusive<&u8>); +impl_index_for_idt!(RangeToInclusive); +impl_index_for_idt!(RangeFull); + /// An Interrupt Descriptor Table entry. /// /// The generic parameter is some [`InterruptFn`], depending on the interrupt vector. From 6eee5a8602a65ea06f48966801977ffd3206c635 Mon Sep 17 00:00:00 2001 From: Tom Dohrmann Date: Mon, 8 Nov 2021 10:44:56 +0100 Subject: [PATCH 4/4] use `usize::from` instead of casting --- src/structures/idt.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/structures/idt.rs b/src/structures/idt.rs index 4c2def6da..27cb7f64e 100644 --- a/src/structures/idt.rs +++ b/src/structures/idt.rs @@ -466,13 +466,13 @@ impl InterruptDescriptorTable { /// Panics if the entry is an exception. fn condition_slice_bounds(&self, bounds: impl RangeBounds) -> (usize, usize) { let lower_idx = match bounds.start_bound() { - Included(start) => (*start as usize), - Excluded(start) => (*start as usize) + 1, + Included(start) => usize::from(*start), + Excluded(start) => usize::from(*start) + 1, Unbounded => 0, }; let upper_idx = match bounds.end_bound() { - Included(end) => (*end as usize) + 1, - Excluded(end) => (*end as usize), + Included(end) => usize::from(*end) + 1, + Excluded(end) => usize::from(*end), Unbounded => 256, }; @@ -522,7 +522,7 @@ impl Index for InterruptDescriptorTable { 16 => &self.x87_floating_point, 19 => &self.simd_floating_point, 20 => &self.virtualization, - i @ 32..=255 => &self.interrupts[(i - 32) as usize], + i @ 32..=255 => &self.interrupts[usize::from(i - 32)], i @ 15 | i @ 31 | i @ 21..=29 => panic!("entry {} is reserved", i), i @ 8 | i @ 10..=14 | i @ 17 | i @ 30 => { panic!("entry {} is an exception with error code", i) @@ -551,7 +551,7 @@ impl IndexMut for InterruptDescriptorTable { 16 => &mut self.x87_floating_point, 19 => &mut self.simd_floating_point, 20 => &mut self.virtualization, - i @ 32..=255 => &mut self.interrupts[(i - 32) as usize], + i @ 32..=255 => &mut self.interrupts[usize::from(i - 32)], i @ 15 | i @ 31 | i @ 21..=29 => panic!("entry {} is reserved", i), i @ 8 | i @ 10..=14 | i @ 17 | i @ 30 => { panic!("entry {} is an exception with error code", i)