@@ -779,34 +779,47 @@ impl<F> Entry<F> {
779
779
}
780
780
}
781
781
782
- macro_rules! impl_set_handler_fn {
783
- ( $h: ty) => {
784
- #[ cfg( all( feature = "instructions" , feature = "abi_x86_interrupt" ) ) ]
785
- impl Entry <$h> {
786
- /// Set the handler function for the IDT entry and sets the present bit.
787
- ///
788
- /// For the code selector field, this function uses the code segment selector currently
789
- /// active in the CPU.
790
- ///
791
- /// The function returns a mutable reference to the entry's options that allows
792
- /// further customization.
793
- ///
794
- /// This method is only usable with the `abi_x86_interrupt` feature enabled. Without it, the
795
- /// unsafe [`Entry::set_handler_addr`] method has to be used instead.
782
+ #[ cfg( feature = "instructions" ) ]
783
+ impl < F : HandlerFuncType > Entry < F > {
784
+ /// Set the handler function for the IDT entry and sets the present bit.
785
+ ///
786
+ /// For the code selector field, this function uses the code segment selector currently
787
+ /// active in the CPU.
788
+ ///
789
+ /// The function returns a mutable reference to the entry's options that allows
790
+ /// further customization.
791
+ ///
792
+ /// This method is only usable with the `abi_x86_interrupt` feature enabled. Without it, the
793
+ /// unsafe [`Entry::set_handler_addr`] method has to be used instead.
794
+ #[ inline]
795
+ pub fn set_handler_fn ( & mut self , handler : F ) -> & mut EntryOptions {
796
+ unsafe { self . set_handler_addr ( handler. to_virt_addr ( ) ) }
797
+ }
798
+ }
799
+
800
+ /// A common trait for all handler functions usable in [`Entry`].
801
+ pub trait HandlerFuncType {
802
+ /// Get the virtual address of the handler function.
803
+ fn to_virt_addr ( self ) -> VirtAddr ;
804
+ }
805
+
806
+ macro_rules! impl_handler_func_type {
807
+ ( $f: ty) => {
808
+ #[ cfg( feature = "abi_x86_interrupt" ) ]
809
+ impl HandlerFuncType for $f {
796
810
#[ inline]
797
- pub fn set_handler_fn( & mut self , handler: $h) -> & mut EntryOptions {
798
- let handler = VirtAddr :: new( handler as u64 ) ;
799
- unsafe { self . set_handler_addr( handler) }
811
+ fn to_virt_addr( self ) -> VirtAddr {
812
+ VirtAddr :: new( self as u64 )
800
813
}
801
814
}
802
815
} ;
803
816
}
804
817
805
- impl_set_handler_fn ! ( HandlerFunc ) ;
806
- impl_set_handler_fn ! ( HandlerFuncWithErrCode ) ;
807
- impl_set_handler_fn ! ( PageFaultHandlerFunc ) ;
808
- impl_set_handler_fn ! ( DivergingHandlerFunc ) ;
809
- impl_set_handler_fn ! ( DivergingHandlerFuncWithErrCode ) ;
818
+ impl_handler_func_type ! ( HandlerFunc ) ;
819
+ impl_handler_func_type ! ( HandlerFuncWithErrCode ) ;
820
+ impl_handler_func_type ! ( PageFaultHandlerFunc ) ;
821
+ impl_handler_func_type ! ( DivergingHandlerFunc ) ;
822
+ impl_handler_func_type ! ( DivergingHandlerFuncWithErrCode ) ;
810
823
811
824
/// Represents the options field of an IDT entry.
812
825
#[ repr( transparent) ]
0 commit comments