@@ -26,7 +26,10 @@ use bitflags::bitflags;
26
26
use core:: fmt;
27
27
use core:: marker:: PhantomData ;
28
28
use core:: ops:: Bound :: { Excluded , Included , Unbounded } ;
29
- use core:: ops:: { Deref , Index , IndexMut , RangeBounds } ;
29
+ use core:: ops:: {
30
+ Bound , Deref , Index , IndexMut , Range , RangeBounds , RangeFrom , RangeFull , RangeInclusive ,
31
+ RangeTo , RangeToInclusive ,
32
+ } ;
30
33
use volatile:: Volatile ;
31
34
32
35
use super :: gdt:: SegmentSelector ;
@@ -458,25 +461,21 @@ impl InterruptDescriptorTable {
458
461
}
459
462
}
460
463
461
- /// Returns a normalized and ranged check slice range from a RangeBounds trait object
464
+ /// Returns a normalized and ranged check slice range from a RangeBounds trait object.
462
465
///
463
- /// Panics if range is outside the range of user interrupts (i.e. greater than 255) or if the entry is an
464
- /// exception
465
- fn condition_slice_bounds ( & self , bounds : impl RangeBounds < usize > ) -> ( usize , usize ) {
466
+ /// Panics if the entry is an exception.
467
+ fn condition_slice_bounds ( & self , bounds : impl RangeBounds < u8 > ) -> ( usize , usize ) {
466
468
let lower_idx = match bounds. start_bound ( ) {
467
- Included ( start) => * start,
468
- Excluded ( start) => * start + 1 ,
469
+ Included ( start) => usize :: from ( * start) ,
470
+ Excluded ( start) => usize :: from ( * start) + 1 ,
469
471
Unbounded => 0 ,
470
472
} ;
471
473
let upper_idx = match bounds. end_bound ( ) {
472
- Included ( end) => * end + 1 ,
473
- Excluded ( end) => * end,
474
+ Included ( end) => usize :: from ( * end) + 1 ,
475
+ Excluded ( end) => usize :: from ( * end) ,
474
476
Unbounded => 256 ,
475
477
} ;
476
478
477
- if lower_idx > 256 || upper_idx > 256 {
478
- panic ! ( "Index out of range [{}..{}]" , lower_idx, upper_idx) ;
479
- }
480
479
if lower_idx < 32 {
481
480
panic ! ( "Cannot return slice from traps, faults, and exception handlers" ) ;
482
481
}
@@ -485,34 +484,31 @@ impl InterruptDescriptorTable {
485
484
486
485
/// Returns slice of IDT entries with the specified range.
487
486
///
488
- /// Panics if range is outside the range of user interrupts (i.e. greater than 255) or if the entry is an
489
- /// exception
487
+ /// Panics if the entry is an exception.
490
488
#[ inline]
491
- pub fn slice ( & self , bounds : impl RangeBounds < usize > ) -> & [ Entry < HandlerFunc > ] {
489
+ pub fn slice ( & self , bounds : impl RangeBounds < u8 > ) -> & [ Entry < HandlerFunc > ] {
492
490
let ( lower_idx, upper_idx) = self . condition_slice_bounds ( bounds) ;
493
491
& self . interrupts [ ( lower_idx - 32 ) ..( upper_idx - 32 ) ]
494
492
}
495
493
496
494
/// Returns a mutable slice of IDT entries with the specified range.
497
495
///
498
- /// Panics if range is outside the range of user interrupts (i.e. greater than 255) or if the entry is an
499
- /// exception
496
+ /// Panics if the entry is an exception.
500
497
#[ inline]
501
- pub fn slice_mut ( & mut self , bounds : impl RangeBounds < usize > ) -> & mut [ Entry < HandlerFunc > ] {
498
+ pub fn slice_mut ( & mut self , bounds : impl RangeBounds < u8 > ) -> & mut [ Entry < HandlerFunc > ] {
502
499
let ( lower_idx, upper_idx) = self . condition_slice_bounds ( bounds) ;
503
500
& mut self . interrupts [ ( lower_idx - 32 ) ..( upper_idx - 32 ) ]
504
501
}
505
502
}
506
503
507
- impl Index < usize > for InterruptDescriptorTable {
504
+ impl Index < u8 > for InterruptDescriptorTable {
508
505
type Output = Entry < HandlerFunc > ;
509
506
510
507
/// Returns the IDT entry with the specified index.
511
508
///
512
- /// Panics if index is outside the IDT (i.e. greater than 255) or if the entry is an
513
- /// exception that pushes an error code (use the struct fields for accessing these entries).
509
+ /// Panics if the entry is an exception that pushes an error code (use the struct fields for accessing these entries).
514
510
#[ inline]
515
- fn index ( & self , index : usize ) -> & Self :: Output {
511
+ fn index ( & self , index : u8 ) -> & Self :: Output {
516
512
match index {
517
513
0 => & self . divide_error ,
518
514
1 => & self . debug ,
@@ -526,24 +522,22 @@ impl Index<usize> for InterruptDescriptorTable {
526
522
16 => & self . x87_floating_point ,
527
523
19 => & self . simd_floating_point ,
528
524
20 => & self . virtualization ,
529
- i @ 32 ..=255 => & self . interrupts [ i - 32 ] ,
525
+ i @ 32 ..=255 => & self . interrupts [ usize :: from ( i - 32 ) ] ,
530
526
i @ 15 | i @ 31 | i @ 21 ..=29 => panic ! ( "entry {} is reserved" , i) ,
531
527
i @ 8 | i @ 10 ..=14 | i @ 17 | i @ 30 => {
532
528
panic ! ( "entry {} is an exception with error code" , i)
533
529
}
534
530
i @ 18 => panic ! ( "entry {} is an diverging exception (must not return)" , i) ,
535
- i => panic ! ( "no entry with index {}" , i) ,
536
531
}
537
532
}
538
533
}
539
534
540
- impl IndexMut < usize > for InterruptDescriptorTable {
535
+ impl IndexMut < u8 > for InterruptDescriptorTable {
541
536
/// Returns a mutable reference to the IDT entry with the specified index.
542
537
///
543
- /// Panics if index is outside the IDT (i.e. greater than 255) or if the entry is an
544
- /// exception that pushes an error code (use the struct fields for accessing these entries).
538
+ /// Panics if the entry is an exception that pushes an error code (use the struct fields for accessing these entries).
545
539
#[ inline]
546
- fn index_mut ( & mut self , index : usize ) -> & mut Self :: Output {
540
+ fn index_mut ( & mut self , index : u8 ) -> & mut Self :: Output {
547
541
match index {
548
542
0 => & mut self . divide_error ,
549
543
1 => & mut self . debug ,
@@ -557,17 +551,58 @@ impl IndexMut<usize> for InterruptDescriptorTable {
557
551
16 => & mut self . x87_floating_point ,
558
552
19 => & mut self . simd_floating_point ,
559
553
20 => & mut self . virtualization ,
560
- i @ 32 ..=255 => & mut self . interrupts [ i - 32 ] ,
554
+ i @ 32 ..=255 => & mut self . interrupts [ usize :: from ( i - 32 ) ] ,
561
555
i @ 15 | i @ 31 | i @ 21 ..=29 => panic ! ( "entry {} is reserved" , i) ,
562
556
i @ 8 | i @ 10 ..=14 | i @ 17 | i @ 30 => {
563
557
panic ! ( "entry {} is an exception with error code" , i)
564
558
}
565
559
i @ 18 => panic ! ( "entry {} is an diverging exception (must not return)" , i) ,
566
- i => panic ! ( "no entry with index {}" , i) ,
567
560
}
568
561
}
569
562
}
570
563
564
+ macro_rules! impl_index_for_idt {
565
+ ( $ty: ty) => {
566
+ impl Index <$ty> for InterruptDescriptorTable {
567
+ type Output = [ Entry <HandlerFunc >] ;
568
+
569
+ /// Returns the IDT entry with the specified index.
570
+ ///
571
+ /// Panics if index is outside the IDT (i.e. greater than 255) or if the entry is an
572
+ /// exception that pushes an error code (use the struct fields for accessing these entries).
573
+ #[ inline]
574
+ fn index( & self , index: $ty) -> & Self :: Output {
575
+ self . slice( index)
576
+ }
577
+ }
578
+
579
+ impl IndexMut <$ty> for InterruptDescriptorTable {
580
+ /// Returns a mutable reference to the IDT entry with the specified index.
581
+ ///
582
+ /// Panics if the entry is an exception that pushes an error code (use the struct fields for accessing these entries).
583
+ #[ inline]
584
+ fn index_mut( & mut self , index: $ty) -> & mut Self :: Output {
585
+ self . slice_mut( index)
586
+ }
587
+ }
588
+ } ;
589
+ }
590
+
591
+ // this list was stolen from the list of implementors in https://doc.rust-lang.org/core/ops/trait.RangeBounds.html
592
+ impl_index_for_idt ! ( ( Bound <& u8 >, Bound <& u8 >) ) ;
593
+ impl_index_for_idt ! ( ( Bound <u8 >, Bound <u8 >) ) ;
594
+ impl_index_for_idt ! ( Range <& u8 >) ;
595
+ impl_index_for_idt ! ( Range <u8 >) ;
596
+ impl_index_for_idt ! ( RangeFrom <& u8 >) ;
597
+ impl_index_for_idt ! ( RangeFrom <u8 >) ;
598
+ impl_index_for_idt ! ( RangeInclusive <& u8 >) ;
599
+ impl_index_for_idt ! ( RangeInclusive <u8 >) ;
600
+ impl_index_for_idt ! ( RangeTo <u8 >) ;
601
+ impl_index_for_idt ! ( RangeTo <& u8 >) ;
602
+ impl_index_for_idt ! ( RangeToInclusive <& u8 >) ;
603
+ impl_index_for_idt ! ( RangeToInclusive <u8 >) ;
604
+ impl_index_for_idt ! ( RangeFull ) ;
605
+
571
606
/// An Interrupt Descriptor Table entry.
572
607
///
573
608
/// The generic parameter is some [`InterruptFn`], depending on the interrupt vector.
0 commit comments